Documentation set: features, manuals (user/pond-admin/site-admin), API, MCP, developer guide
All checks were successful
CD / Build and push images (push) Successful in 1m9s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m7s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m34s
CI / Import/export fidelity gate (push) Successful in 47s
All checks were successful
CD / Build and push images (push) Successful in 1m9s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m10s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m7s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m34s
CI / Import/export fidelity gate (push) Successful in 47s
Seven audience-targeted documents (English first, German translation to follow), linked from the README and a new docs/manual/ index: - docs/features.md — public-facing feature overview: what Dorfteich can do and why that matters - docs/manual/user-guide.md — everyday use: editor, wikilinks, labels, search, comments, watches/digests, import/export, settings - docs/manual/pond-admin-guide.md — pond configuration: members/roles, access rules incl. label scoping and public pages, labels, comment policy, plugins, API/MCP opt-ins, files, export - docs/manual/site-admin-guide.md — instance administration: wizard, settings, quotas, uploads, API/MCP switches, legal pages, plugins, users, and the system panel (jobs/backups/audit/storage) - docs/manual/api-guide.md — example-driven public-API walkthrough (tokens, reading, writing through the collab-safe path, labels, comments, error semantics) - docs/manual/mcp-guide.md — connecting AI assistants: switches, token scopes, Claude Code one-liner, mcp-remote bridge, tool table, audit and safety properties - docs/developer/extending.md — plugin development (sandbox contract, SDK, block plugins, bundled apps/fullscreen, shipping) and core contributions (stack, dev environment, gates, house rules) README: documentation index, repository-layout rows for docs/manual and docs/developer, and the stale "architecture phase" status brought up to reality. All relative links verified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
This commit is contained in:
parent
6d710caa50
commit
eeb0ef6794
21
README.md
21
README.md
@ -32,10 +32,22 @@ offline support.
|
|||||||
first-run setup wizard yields a working instance. Start here:
|
first-run setup wizard yields a working instance. Start here:
|
||||||
[`docs/self-hosting/README.md`](docs/self-hosting/README.md).
|
[`docs/self-hosting/README.md`](docs/self-hosting/README.md).
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- **What is Dorfteich?** — [`docs/features.md`](docs/features.md)
|
||||||
|
- **Manuals** (user / pond admin / site admin / API / MCP) —
|
||||||
|
[`docs/manual/`](docs/manual/README.md)
|
||||||
|
- **Extending it** (plugins, core) —
|
||||||
|
[`docs/developer/extending.md`](docs/developer/extending.md)
|
||||||
|
- **Running it** — [`docs/self-hosting/`](docs/self-hosting/README.md)
|
||||||
|
- **How it works inside** — [`docs/architecture/`](docs/architecture/README.md)
|
||||||
|
|
||||||
## Repository layout
|
## Repository layout
|
||||||
|
|
||||||
| Path | Contents |
|
| Path | Contents |
|
||||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `docs/manual/` | User-facing manuals: user, pond-admin, site-admin, API, and MCP guides (start at [`docs/manual/README.md`](docs/manual/README.md)) |
|
||||||
|
| `docs/developer/` | Extending Dorfteich: plugin development and core contributions |
|
||||||
| `docs/architecture/` | Architecture documentation: ADRs, data model, permission model, collaboration and plugin concepts, deployment and operations |
|
| `docs/architecture/` | Architecture documentation: ADRs, data model, permission model, collaboration and plugin concepts, deployment and operations |
|
||||||
| `docs/self-hosting/` | Install, update, backup, and troubleshooting guide for running your own instance |
|
| `docs/self-hosting/` | Install, update, backup, and troubleshooting guide for running your own instance |
|
||||||
| `apps/` | Application packages (web frontend, API server, collaboration server) — created as implementation proceeds |
|
| `apps/` | Application packages (web frontend, API server, collaboration server) — created as implementation proceeds |
|
||||||
@ -60,9 +72,10 @@ imported as `@dorfteich/shared` — never copy code between apps.
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
The project is in the architecture and backlog phase. Implementation stories
|
Feature-complete for a 1.0: collaboration, permissions, import/export,
|
||||||
are tracked as issues in this repository. Start reading at
|
plugins, public REST API + MCP, backups with off-host copies and in-app
|
||||||
[`docs/architecture/README.md`](docs/architecture/README.md).
|
restore — all shipped and release-gated. Work is tracked as issues in
|
||||||
|
this repository.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
154
docs/developer/extending.md
Normal file
154
docs/developer/extending.md
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
# Developer guide — extending Dorfteich
|
||||||
|
|
||||||
|
Two ways to make Dorfteich do more: write a **plugin** (no fork, no
|
||||||
|
redeploy, safe by construction) or contribute to the **core**. Start
|
||||||
|
with a plugin unless you need to change how the product itself works.
|
||||||
|
|
||||||
|
## Writing a plugin
|
||||||
|
|
||||||
|
Read [`docs/architecture/plugin-architecture.md`](../architecture/plugin-architecture.md)
|
||||||
|
once — it is the contract. The short version:
|
||||||
|
|
||||||
|
A plugin is a ZIP with a `manifest.json`, a single ES-module bundle
|
||||||
|
`plugin.js`, optional `styles.css`, `i18n/*.json`, and `assets/…`. It
|
||||||
|
contributes one or more **extension points**:
|
||||||
|
|
||||||
|
| Type | You build | Example |
|
||||||
|
| -------------- | ------------------------------------------------------ | ---------------------- |
|
||||||
|
| `sectionStyle` | named CSS styles for content sections (no code at all) | `section-styles-basic` |
|
||||||
|
| `pageTool` | a read-only widget in the page-tools panel | `toc`, `page-index` |
|
||||||
|
| `block` | a custom editor block with its own data and edit UI | `mermaid`, `drawio` |
|
||||||
|
|
||||||
|
### The sandbox — what your code can and cannot do
|
||||||
|
|
||||||
|
Your `plugin.js` runs in an `<iframe sandbox="allow-scripts">` with an
|
||||||
|
opaque origin and a strict CSP: **no cookies, no storage, no parent DOM,
|
||||||
|
and network/frames only to your own bundled assets** — never to the api
|
||||||
|
or any external host. Everything else goes through the typed RPC the
|
||||||
|
SDK provides, executed with the _viewing user's_ permissions:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { createPlugin, windowTransport } from '@dorfteich/plugin-sdk';
|
||||||
|
|
||||||
|
const { host } = createPlugin({
|
||||||
|
transport: windowTransport({
|
||||||
|
target: { postMessage: (m) => window.parent.postMessage(m, '*') },
|
||||||
|
source: window,
|
||||||
|
}),
|
||||||
|
onRender: async (ctx) => {
|
||||||
|
const outline = await host.readCurrentPage.getOutline();
|
||||||
|
document.body.textContent = outline.map((e) => e.text).join('\n');
|
||||||
|
void host.ui.resize(document.body.scrollHeight + 16);
|
||||||
|
},
|
||||||
|
onEdit: async (ctx) => {
|
||||||
|
/* block plugins: editing UI; persist via host.blockData.setData(...) */
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Capabilities you may declare in the manifest `permissions` and what they
|
||||||
|
unlock: `readCurrentPage` (outline/content/meta), `readPond` (page
|
||||||
|
lists + contents), `readBlock` (cross-page block reads), `blockData`
|
||||||
|
(your block's `getData`/`setData` — writes become normal document
|
||||||
|
changes, replicated and versioned), `ui` (`resize`, `openPage`, `toast`,
|
||||||
|
`scrollToHeading`, `enterFullscreen`/`exitFullscreen`). Calls outside
|
||||||
|
the declared set are rejected at runtime.
|
||||||
|
|
||||||
|
### Block plugins in three sentences
|
||||||
|
|
||||||
|
The host mounts your frame per block and calls `render` (view) or
|
||||||
|
`edit` (the user pressed the block's edit button). Persist
|
||||||
|
`{ …yourData }` via `host.blockData.setData` — collaborators' frames
|
||||||
|
re-render live when the data changes under them. Store a static
|
||||||
|
snapshot (e.g. an `svg` string) alongside your source data: exports and
|
||||||
|
the public view show it through the manifest `fallback` machinery
|
||||||
|
without ever executing plugin code.
|
||||||
|
|
||||||
|
### Bundled apps and fullscreen
|
||||||
|
|
||||||
|
A plugin may ship an entire sub-application as assets and run it in a
|
||||||
|
child iframe of its own asset path — that is how the `drawio` plugin
|
||||||
|
embeds the real draw.io editor. Combine with
|
||||||
|
`host.ui.enterFullscreen()` for editors that need the whole screen.
|
||||||
|
Size limits: 64 MiB ZIP, 256 MiB unpacked.
|
||||||
|
|
||||||
|
### Developing and shipping
|
||||||
|
|
||||||
|
The reference plugins under `packages/plugins/` are the templates —
|
||||||
|
copy the closest one. Each has a `build.mjs` that bundles `src/plugin.ts`
|
||||||
|
with esbuild and packs the installable ZIP into `dist/`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd packages/plugins/<your-plugin>
|
||||||
|
pnpm build # → dist/<id>-<version>.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the ZIP via Admin → Plugins (or the dropzone), open the
|
||||||
|
sandboxed preview at `/admin/plugins/<id>/preview`, iterate. The install
|
||||||
|
gate validates structure, manifest, size and CSS scoping and rejects
|
||||||
|
with a precise error code. Publishing an update = same id, higher
|
||||||
|
version.
|
||||||
|
|
||||||
|
Conventions that will be enforced on review: UI strings via the plugin's
|
||||||
|
`i18n/` files in **both** `de` and `en`; the fallback must make sense in
|
||||||
|
a printed document.
|
||||||
|
|
||||||
|
## Working on the core
|
||||||
|
|
||||||
|
### Stack at a glance
|
||||||
|
|
||||||
|
TypeScript monorepo (pnpm workspaces): `apps/api` (NestJS + Prisma,
|
||||||
|
PostgreSQL), `apps/collab` (Hocuspocus/Yjs realtime server),
|
||||||
|
`apps/web` (React + Vite + TipTap), `apps/backup` (backup sidecar),
|
||||||
|
`packages/shared` (types, schemas, editor schema, i18n catalogs),
|
||||||
|
`packages/plugin-sdk`, `packages/plugins/*`. Architecture decisions live
|
||||||
|
in [`docs/architecture/adr/`](../architecture/adr/) — read the relevant
|
||||||
|
ADR before touching a subsystem; `docs/architecture/` has the deep dives
|
||||||
|
(permissions, data model, realtime collaboration, security, plugins).
|
||||||
|
|
||||||
|
### Getting a dev environment
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm install
|
||||||
|
cd deploy/compose && cp .env.example .env
|
||||||
|
# Full containerized dev stack (hot reload; first start installs deps):
|
||||||
|
docker compose -f docker-compose.yml -f compose.dev.yml up
|
||||||
|
# → web http://localhost:5173, api :3001, db :5434
|
||||||
|
```
|
||||||
|
|
||||||
|
Fastest feedback: run only the database in Docker and web/api natively —
|
||||||
|
the exact recipe is documented at the top of
|
||||||
|
[`deploy/compose/compose.dev.yml`](../../deploy/compose/compose.dev.yml).
|
||||||
|
Seed fixture users/ponds with `pnpm --filter @dorfteich/api db:seed`
|
||||||
|
(fixture password: see `apps/api/prisma/seed.ts`).
|
||||||
|
|
||||||
|
### The gates every change must pass
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm lint # ESLint + Prettier — no pipes that swallow exit codes
|
||||||
|
pnpm typecheck
|
||||||
|
pnpm test # vitest everywhere; DB-backed suites need TEST_DATABASE_URL
|
||||||
|
pnpm i18n:check # every UI string in de AND en
|
||||||
|
```
|
||||||
|
|
||||||
|
DB-backed tests run against the compose dev database:
|
||||||
|
`TEST_DATABASE_URL=postgresql://dorfteich:dorfteich@localhost:5434/dorfteich pnpm test`.
|
||||||
|
Playwright e2e packs live in `apps/web/e2e/` and run against a seeded
|
||||||
|
local stack (see `.gitea/workflows/ci.yml` for the exact recipe).
|
||||||
|
|
||||||
|
### House rules worth knowing before your first PR
|
||||||
|
|
||||||
|
- **Permissions**: never answer an access question outside
|
||||||
|
`PermissionService`/the route decorators; denied reads are 404, denied
|
||||||
|
writes on readable things are 403
|
||||||
|
([permissions.md](../architecture/permissions.md)).
|
||||||
|
- **i18n**: no hard-coded UI strings; add keys to
|
||||||
|
`packages/shared/i18n/{de,en}/…` (ADR 0012).
|
||||||
|
- **No third-party requests** from the product, ever — fonts, editors,
|
||||||
|
everything ships self-hosted (ADR 0016 sets the precedent).
|
||||||
|
- **Migrations**: additive and reversible within one minor release; the
|
||||||
|
release pipeline's QA gate replays an upgrade from the previous
|
||||||
|
release against real data.
|
||||||
|
- **Document contracts**: anything two services share (status files,
|
||||||
|
NOTIFY channels, wire types) lives in `packages/shared` with a comment
|
||||||
|
saying who reads and who writes.
|
||||||
111
docs/features.md
Normal file
111
docs/features.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
# Dorfteich — what it is and why you might want it
|
||||||
|
|
||||||
|
Dorfteich is an open-source wiki for people who want to think and write
|
||||||
|
together — in real time, on their own server, without handing their
|
||||||
|
knowledge to a cloud company.
|
||||||
|
|
||||||
|
The name means "village pond": the place where everyone in the village
|
||||||
|
comes together. Your wiki is organized into **ponds** — one personal pond
|
||||||
|
for every member, plus shared ponds for teams, clubs, families, or
|
||||||
|
projects.
|
||||||
|
|
||||||
|
## Writing together, live
|
||||||
|
|
||||||
|
- **Real-time collaboration.** Open the same page as a colleague and
|
||||||
|
watch each other type — with named cursors and a presence strip showing
|
||||||
|
who is on the page. No locking, no "someone else is editing" dialogs,
|
||||||
|
no lost changes.
|
||||||
|
- **Works offline.** Keep typing when the connection drops; your edits
|
||||||
|
merge back in automatically when you are online again.
|
||||||
|
- **A friendly editor.** Headings, lists, task lists, tables, quotes,
|
||||||
|
code blocks, and images — with full **Markdown** round-trip: what you
|
||||||
|
write can always leave the system as clean Markdown again.
|
||||||
|
- **Wikilinks.** Type `[[page-name]]` to link pages. Links to pages that
|
||||||
|
do not exist yet are collected for you, one click creates them.
|
||||||
|
Backlinks show you where every page is referenced.
|
||||||
|
|
||||||
|
## Never lose anything
|
||||||
|
|
||||||
|
- **Version history.** Every page keeps automatic snapshots plus named
|
||||||
|
versions you save yourself. Compare, see who contributed, and restore
|
||||||
|
any earlier state — restores are visible live in every open editor.
|
||||||
|
- **Trash with a grace period.** Deleted pages sit in a per-pond trash
|
||||||
|
and can be restored for weeks before they are purged.
|
||||||
|
- **Real backups.** Nightly database + file backups, optional off-host
|
||||||
|
copies to any **Nextcloud** you control, and a tested one-click restore
|
||||||
|
— including a documented path to rebuild an instance from nothing.
|
||||||
|
|
||||||
|
## Organize the way you think
|
||||||
|
|
||||||
|
- **Labels**, hierarchical if you like, to slice a pond any way you want
|
||||||
|
— and to scope access rules (see below).
|
||||||
|
- **Fast full-text search** across everything you may read — accent- and
|
||||||
|
umlaut-insensitive, with substring matching.
|
||||||
|
- **A table of contents, page indexes, diagrams** and more through
|
||||||
|
built-in plugins (see "Extensible" below).
|
||||||
|
|
||||||
|
## Share exactly as much as you want
|
||||||
|
|
||||||
|
- **Fine-grained permissions.** Grant read or write access per pond, per
|
||||||
|
label, or per page — to individual people, to all signed-in members, or
|
||||||
|
to the public internet. Deny rules carve out exceptions. A built-in
|
||||||
|
inspector explains _why_ someone can or cannot see a page.
|
||||||
|
- **Public pages.** Publish selected pages read-only to the world, with
|
||||||
|
clean URLs — the rest of the pond stays private.
|
||||||
|
- **Comments.** Discuss in threads next to the content, resolve what is
|
||||||
|
settled, and choose per pond whether every reader or only editors may
|
||||||
|
comment.
|
||||||
|
- **Notifications you control.** Watch pages or whole ponds, get an
|
||||||
|
in-app inbox, and choose e-mail digests (hourly, daily, or off) with a
|
||||||
|
working unsubscribe link.
|
||||||
|
|
||||||
|
## Your documents come and go freely
|
||||||
|
|
||||||
|
- **Import** Word (`.docx`), LibreOffice (`.odt`), and Markdown files —
|
||||||
|
including embedded images.
|
||||||
|
- **Export** any page as Markdown, Word, LibreOffice, or **PDF** (with
|
||||||
|
your pond's typography), and any pond as a ZIP of Markdown files. No
|
||||||
|
lock-in, ever.
|
||||||
|
|
||||||
|
## Machines are welcome too — on your terms
|
||||||
|
|
||||||
|
- **REST API.** A clean, token-authenticated public API to read, write,
|
||||||
|
search, label, and comment — with an OpenAPI description. Tokens carry
|
||||||
|
exactly the permissions of their owner, never more.
|
||||||
|
- **Built-in MCP endpoint.** Connect Claude Code or any MCP-capable AI
|
||||||
|
assistant directly to your wiki — it can search, read, and (if you
|
||||||
|
allow it) write pages. Both interfaces are **off by default** and each
|
||||||
|
pond opts in separately.
|
||||||
|
|
||||||
|
## Extensible, but safely
|
||||||
|
|
||||||
|
- **Plugins** add block types (Mermaid diagrams, full **draw.io**
|
||||||
|
editing), page tools (table of contents, page index), and section
|
||||||
|
styles. Every plugin runs in a strict sandbox: no cookies, no storage,
|
||||||
|
no network — it cannot read more than the person looking at it.
|
||||||
|
- Reference plugins ship with the product and double as documented
|
||||||
|
examples for writing your own.
|
||||||
|
|
||||||
|
## Private by design
|
||||||
|
|
||||||
|
- **Self-hosted.** One `docker compose up`, a friendly first-run wizard,
|
||||||
|
and it is yours. Everything — fonts included — is served from your own
|
||||||
|
domain: pages make **zero requests to third parties**.
|
||||||
|
- **GDPR-friendly.** Imprint and privacy-policy pages built in (with
|
||||||
|
templates), personal data export as ZIP, account deletion with
|
||||||
|
content-preserving pseudonymization, and an audit trail of
|
||||||
|
administrative actions.
|
||||||
|
- **Bilingual.** The entire interface speaks German and English; every
|
||||||
|
user picks their language.
|
||||||
|
|
||||||
|
## Honest operations
|
||||||
|
|
||||||
|
- Health endpoints that distinguish "down" from "degraded", an admin
|
||||||
|
system panel with job status, backup state, audit log and storage
|
||||||
|
overview, monthly automated restore drills — the operator can _prove_
|
||||||
|
the backups work, not just hope.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_Dorfteich is MIT-licensed open source. If you can run Docker, you can
|
||||||
|
run Dorfteich — see [self-hosting](self-hosting/README.md)._
|
||||||
18
docs/manual/README.md
Normal file
18
docs/manual/README.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Dorfteich manuals
|
||||||
|
|
||||||
|
User-facing documentation, by audience. (German translations are
|
||||||
|
planned; English is authoritative for now.)
|
||||||
|
|
||||||
|
| Guide | For |
|
||||||
|
| -------------------------------------------- | ------------------------------------ |
|
||||||
|
| [Feature overview](../features.md) | anyone wondering what Dorfteich is |
|
||||||
|
| [User guide](user-guide.md) | everyday members |
|
||||||
|
| [Pond-admin guide](pond-admin-guide.md) | people administering a pond |
|
||||||
|
| [Site-admin guide](site-admin-guide.md) | instance administrators |
|
||||||
|
| [API guide](api-guide.md) | scripts and integrations |
|
||||||
|
| [MCP guide](mcp-guide.md) | connecting AI assistants |
|
||||||
|
| [Developer guide](../developer/extending.md) | plugin authors and core contributors |
|
||||||
|
|
||||||
|
Operating an instance (install, update, backup, monitoring):
|
||||||
|
[self-hosting](../self-hosting/README.md). Internals:
|
||||||
|
[architecture](../architecture/README.md).
|
||||||
131
docs/manual/api-guide.md
Normal file
131
docs/manual/api-guide.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# API guide
|
||||||
|
|
||||||
|
How to talk to Dorfteich from scripts and integrations. The public REST
|
||||||
|
API lives at `/api/public/v1`; its machine-readable description is
|
||||||
|
served at `/api/public/v1/openapi.json`.
|
||||||
|
|
||||||
|
## Switching it on
|
||||||
|
|
||||||
|
The API is **off by default**, twice:
|
||||||
|
|
||||||
|
1. A **site admin** enables the instance switch (Admin → Settings →
|
||||||
|
Public API).
|
||||||
|
2. Each **pond** that should be reachable opts in (pond settings →
|
||||||
|
"Expose this pond through the public API").
|
||||||
|
|
||||||
|
Anything not enabled answers `404` — indistinguishable from an instance
|
||||||
|
without the feature.
|
||||||
|
|
||||||
|
## Personal access tokens
|
||||||
|
|
||||||
|
Create tokens under **Settings → API tokens**: a name, a scope
|
||||||
|
(`read` or `read+write`), an optional expiry date, and optionally a
|
||||||
|
restriction to selected ponds. The secret (`dt_pat_…`) is shown **once**
|
||||||
|
— copy it immediately. Tokens are revocable and show their last use.
|
||||||
|
|
||||||
|
A token acts **as you**: it can read and write exactly what you can,
|
||||||
|
narrowed by its scope and pond restriction — never more. Token
|
||||||
|
management itself always requires the browser session; a leaked token
|
||||||
|
cannot mint new tokens.
|
||||||
|
|
||||||
|
Authenticate with a bearer header:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -H "Authorization: Bearer dt_pat_..." \
|
||||||
|
https://wiki.example.com/api/public/v1/me
|
||||||
|
```
|
||||||
|
|
||||||
|
`GET /me` is the smoke test — it returns your user, the token scope,
|
||||||
|
and any pond restriction.
|
||||||
|
|
||||||
|
## Reading
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# The ponds this token can reach
|
||||||
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds
|
||||||
|
|
||||||
|
# Pages of a pond: slug, title, labels, timestamps
|
||||||
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages
|
||||||
|
|
||||||
|
# One page — Markdown source AND rendered, sanitized HTML
|
||||||
|
curl -H "$AUTH" https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
||||||
|
|
||||||
|
# Full-text search (optionally ?pond=<slug>&label=<labelId>)
|
||||||
|
curl -H "$AUTH" "https://wiki.example.com/api/public/v1/search?q=seerose"
|
||||||
|
|
||||||
|
# The whole pond as a Markdown ZIP
|
||||||
|
curl -H "$AUTH" -o team.zip \
|
||||||
|
https://wiki.example.com/api/public/v1/ponds/team/export/markdown
|
||||||
|
```
|
||||||
|
|
||||||
|
Search snippets mark hits with `**…**`; results carry pond and page
|
||||||
|
slugs for follow-up calls.
|
||||||
|
|
||||||
|
## Writing (requires the `write` scope)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Create a page from Markdown
|
||||||
|
curl -H "$AUTH" -H 'Content-Type: application/json' \
|
||||||
|
-d '{"title": "Meeting notes", "markdown": "# Agenda\n\n- Ducks\n"}' \
|
||||||
|
https://wiki.example.com/api/public/v1/ponds/team/pages
|
||||||
|
|
||||||
|
# Rename and/or REPLACE the content
|
||||||
|
curl -X PATCH -H "$AUTH" -H 'Content-Type: application/json' \
|
||||||
|
-d '{"markdown": "New content."}' \
|
||||||
|
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
||||||
|
|
||||||
|
# Move a page to the trash
|
||||||
|
curl -X DELETE -H "$AUTH" \
|
||||||
|
https://wiki.example.com/api/public/v1/ponds/team/pages/meeting-notes
|
||||||
|
```
|
||||||
|
|
||||||
|
A content `PATCH` **replaces** the whole page. It is applied through the
|
||||||
|
live collaborative document: anyone editing the page at that moment sees
|
||||||
|
the change appear, nothing forks, and the previous state remains in the
|
||||||
|
version history as a restorable snapshot (the update itself shows up as
|
||||||
|
a version named "API update").
|
||||||
|
|
||||||
|
## Labels
|
||||||
|
|
||||||
|
```sh
|
||||||
|
GET /ponds/{pond}/labels # the label tree
|
||||||
|
POST /ponds/{pond}/labels # {name, color?, parentId?}
|
||||||
|
PATCH /ponds/{pond}/labels/{labelId} # rename/recolor/move in one call
|
||||||
|
DELETE /ponds/{pond}/labels/{labelId}
|
||||||
|
PUT /ponds/{pond}/pages/{page}/labels/{labelId} # assign
|
||||||
|
DELETE /ponds/{pond}/pages/{page}/labels/{labelId} # unassign
|
||||||
|
```
|
||||||
|
|
||||||
|
Label-tree management needs pond-admin rights (like in the app).
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
```sh
|
||||||
|
GET /ponds/{pond}/pages/{page}/comments?filter=all|open|resolved
|
||||||
|
POST /ponds/{pond}/pages/{page}/comments # {body, parentId?} — Markdown
|
||||||
|
POST /ponds/{pond}/pages/{page}/comments/{id}/resolve
|
||||||
|
DELETE /ponds/{pond}/pages/{page}/comments/{id}/resolve # reopen
|
||||||
|
```
|
||||||
|
|
||||||
|
The pond's comment policy applies exactly as in the app.
|
||||||
|
|
||||||
|
## Errors, limits, semantics
|
||||||
|
|
||||||
|
- Errors carry the uniform body `{ "code": "...", "message": "...",
|
||||||
|
"details": {...} }`. The `code` is stable and machine-checkable.
|
||||||
|
- **404 vs 403**: what you may not _read_ answers 404 (existence stays
|
||||||
|
hidden — including ponds without the API opt-in); a write on
|
||||||
|
something you may read but not change answers 403. A token without
|
||||||
|
the `write` scope gets `403 scope_required` on every write route.
|
||||||
|
- **Rate limit** per token; `429` responses carry a `Retry-After`
|
||||||
|
header.
|
||||||
|
- No cookies are involved anywhere — there is no CSRF surface, and
|
||||||
|
browser sessions cannot call the public API.
|
||||||
|
|
||||||
|
## Out of scope (for now)
|
||||||
|
|
||||||
|
Attachment upload, version endpoints, and webhooks are deliberately not
|
||||||
|
part of v1.
|
||||||
|
|
||||||
|
_Operator's view of the same feature (switches, security notes):
|
||||||
|
[`docs/self-hosting/public-api.md`](../self-hosting/public-api.md)._
|
||||||
100
docs/manual/mcp-guide.md
Normal file
100
docs/manual/mcp-guide.md
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# MCP guide — connecting your AI to Dorfteich
|
||||||
|
|
||||||
|
Dorfteich ships its own [MCP](https://modelcontextprotocol.io) endpoint
|
||||||
|
at `/api/mcp` (Streamable HTTP). Any MCP-capable assistant — Claude
|
||||||
|
Code, Claude Desktop via a bridge, and others — can search, read, and
|
||||||
|
(if you allow it) write your wiki, with **exactly your permissions**.
|
||||||
|
There is no extra server to run: the endpoint is part of the instance.
|
||||||
|
|
||||||
|
## Switching it on
|
||||||
|
|
||||||
|
Like the REST API, MCP is **off by default** and has its **own,
|
||||||
|
independent switches**:
|
||||||
|
|
||||||
|
1. **Site admin**: Admin → Settings → Public API → "Enable the built-in
|
||||||
|
MCP endpoint".
|
||||||
|
2. **Each pond** that the assistant should see: pond settings → "Expose
|
||||||
|
this pond to AI assistants (MCP)".
|
||||||
|
|
||||||
|
A pond without the opt-in is invisible to MCP clients — even to your own
|
||||||
|
token.
|
||||||
|
|
||||||
|
## Get a token
|
||||||
|
|
||||||
|
MCP uses the same **personal access tokens** as the REST API: create one
|
||||||
|
under **Settings → API tokens**. Pick the scope deliberately:
|
||||||
|
|
||||||
|
- `read` — the assistant can list, read, and search, nothing else.
|
||||||
|
- `read+write` — it may also create/update pages, comment, and set
|
||||||
|
labels.
|
||||||
|
|
||||||
|
Consider restricting the token to the specific pond(s) you want the
|
||||||
|
assistant to work in.
|
||||||
|
|
||||||
|
## Connect Claude Code
|
||||||
|
|
||||||
|
```sh
|
||||||
|
claude mcp add --transport http dorfteich https://wiki.example.com/api/mcp \
|
||||||
|
--header "Authorization: Bearer dt_pat_..."
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it — Claude Code lists the tools on the next start. Stdio-only
|
||||||
|
clients bridge with `mcp-remote`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"dorfteich": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": [
|
||||||
|
"mcp-remote",
|
||||||
|
"https://wiki.example.com/api/mcp",
|
||||||
|
"--header",
|
||||||
|
"Authorization: Bearer dt_pat_..."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## What the assistant can do
|
||||||
|
|
||||||
|
| Tool | Does |
|
||||||
|
| -------------------------------------------- | ------------------------------------------- |
|
||||||
|
| `list_ponds` | the ponds this token can reach |
|
||||||
|
| `list_pages(pond)` | pages with slug, title, labels, timestamps |
|
||||||
|
| `read_page(pond, page)` | a page as Markdown plus metadata |
|
||||||
|
| `search(query, pond?, label?)` | full-text search with snippets |
|
||||||
|
| `create_page(pond, title, markdown)` | new page from Markdown _(write)_ |
|
||||||
|
| `update_page(pond, page, markdown?, title?)` | rename and/or replace content _(write)_ |
|
||||||
|
| `add_comment(pond, page, text)` | comment on a page _(write)_ |
|
||||||
|
| `list_labels(pond)` | the pond's label tree |
|
||||||
|
| `set_page_labels(pond, page, labelIds)` | replace a page's labels _(write)_ |
|
||||||
|
| `export_pond(pond)` | a download link for the Markdown-ZIP export |
|
||||||
|
|
||||||
|
Content updates travel the same collaborative path as human edits: open
|
||||||
|
editors converge live, and the previous state stays in the version
|
||||||
|
history — an AI edit can always be reviewed and reverted like any other
|
||||||
|
change.
|
||||||
|
|
||||||
|
## Good to know
|
||||||
|
|
||||||
|
- **Permissions are yours.** The assistant sees precisely the pages your
|
||||||
|
account may read; label-scoped rules, public/private, everything
|
||||||
|
applies unchanged.
|
||||||
|
- **Every write is audit-logged** with the token attributed — the site
|
||||||
|
admin's audit viewer shows what the assistant changed.
|
||||||
|
- **Rate-limited** per token; a runaway agent gets `429`, not a melted
|
||||||
|
instance.
|
||||||
|
- **Stateless**: each request stands alone; revoking the token under
|
||||||
|
Settings → API tokens cuts the assistant off immediately.
|
||||||
|
- The endpoint speaks MCP over Streamable HTTP (POST). GET/SSE session
|
||||||
|
resumption is not offered — clients fall back to plain request/response,
|
||||||
|
which every current client supports.
|
||||||
|
|
||||||
|
## A sensible first session
|
||||||
|
|
||||||
|
Ask your assistant to `list_ponds`, then `search` for something you know
|
||||||
|
is there, `read_page` it, and — with a write token — draft a new page.
|
||||||
|
Check the page's version history afterwards: you will find the
|
||||||
|
assistant's edit as a normal, restorable version.
|
||||||
104
docs/manual/pond-admin-guide.md
Normal file
104
docs/manual/pond-admin-guide.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# Pond-admin guide
|
||||||
|
|
||||||
|
What you can configure on a pond you administer. You are a pond admin on
|
||||||
|
your own personal pond and on every pond where you hold the
|
||||||
|
`pond_admin` role. All of this lives behind the **gear icon** in the top
|
||||||
|
bar (visible on pond routes when you may modify the pond).
|
||||||
|
|
||||||
|
## Ponds in one minute
|
||||||
|
|
||||||
|
Every member gets a **personal pond** automatically. Additional
|
||||||
|
**shared ponds** are created through the API (`POST /api/v1/ponds`) and
|
||||||
|
are subject to the per-user quota the site admin sets ("additional
|
||||||
|
shared ponds per user", default 0). The creator becomes the pond admin.
|
||||||
|
|
||||||
|
## Name, description, appearance
|
||||||
|
|
||||||
|
- **Name and description** of the pond.
|
||||||
|
- **Fonts**: pick heading/body/code typefaces per pond from the built-in,
|
||||||
|
self-hosted catalog (browse it at `/fonts`) — they apply to the app
|
||||||
|
view, public pages, and PDF exports.
|
||||||
|
- **Sidebar sort** for everyone: A–Z, creation date, or manual order.
|
||||||
|
|
||||||
|
## Members and roles
|
||||||
|
|
||||||
|
The **members** section manages who is in the pond:
|
||||||
|
|
||||||
|
| Role | May |
|
||||||
|
| ------------ | ----------------------------------------------- |
|
||||||
|
| `reader` | read pages (as far as rules allow) |
|
||||||
|
| `editor` | read + write pages, upload files |
|
||||||
|
| `pond_admin` | everything, including settings, members, labels |
|
||||||
|
|
||||||
|
Member counts are limited by the instance quotas (editors/readers per
|
||||||
|
pond). Personal ponds take members too — that is how you share yours.
|
||||||
|
|
||||||
|
## Access rules (the fine print)
|
||||||
|
|
||||||
|
Beyond plain membership, the **access rules** section edits grants
|
||||||
|
directly. A grant is: _subject_ (a user, all signed-in users, or the
|
||||||
|
public) + _role_ (reader/editor/pond admin) + _scope_ (whole pond, one
|
||||||
|
label, or one page) + _effect_ (allow or deny).
|
||||||
|
|
||||||
|
- **Label-scoped rules** are the power tool: give the "board" label to
|
||||||
|
the confidential pages and allow only the board members' grant on that
|
||||||
|
label — or deny a label to someone who may otherwise read everything.
|
||||||
|
- **Public pages:** an _allow, reader, public_ grant on a page (or a
|
||||||
|
label) publishes it read-only at `/public/<pond>/<page>`.
|
||||||
|
- Deny beats allow; reads that are denied look like "not found" (the
|
||||||
|
system never reveals what exists).
|
||||||
|
- The **permission inspector** on a page explains the effective result
|
||||||
|
for any user — use it whenever a rule combination surprises you.
|
||||||
|
|
||||||
|
## Labels
|
||||||
|
|
||||||
|
Manage the pond's label tree (create, rename, recolor, nest, move,
|
||||||
|
delete). Deleting a label that is still on pages asks for confirmation.
|
||||||
|
Labels also appear in the page label picker, where creating new ones is
|
||||||
|
reserved for you.
|
||||||
|
|
||||||
|
## Comments policy
|
||||||
|
|
||||||
|
Choose whether **all readers** may comment or **editors only**. Existing
|
||||||
|
comments stay readable either way.
|
||||||
|
|
||||||
|
## Watching the pond
|
||||||
|
|
||||||
|
The bell in the pond settings header watches the whole pond — you will
|
||||||
|
be notified about every page change and comment in it.
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Plugins the site admin has installed with mode _optional_ appear here
|
||||||
|
with a per-pond toggle. _Required_ plugins are always active; _disabled_
|
||||||
|
ones never show up. (Which plugins exist and what they do:
|
||||||
|
[site-admin guide](site-admin-guide.md#plugins).)
|
||||||
|
|
||||||
|
## Machine access: API and MCP opt-in
|
||||||
|
|
||||||
|
Two separate switches expose this pond to token-based access — **both
|
||||||
|
off by default**, and both only effective if the site admin has enabled
|
||||||
|
the matching instance switch:
|
||||||
|
|
||||||
|
- **Public REST API** (`apiEnabled`): scripts and integrations may reach
|
||||||
|
the pond with personal access tokens — with exactly the permissions of
|
||||||
|
the token's owner.
|
||||||
|
- **MCP / AI assistants** (`mcpEnabled`): MCP clients such as Claude
|
||||||
|
Code may reach the pond the same way.
|
||||||
|
|
||||||
|
A pond that has not opted in is invisible through those interfaces, even
|
||||||
|
to its own members' tokens.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
The **file manager** lists the pond's uploads with their usage (which
|
||||||
|
page references them) and lets you delete orphans. Storage counts
|
||||||
|
against the pond's quota; the current usage is shown.
|
||||||
|
|
||||||
|
## Export and deletion
|
||||||
|
|
||||||
|
- **Export**: the whole pond as a ZIP of Markdown files plus media.
|
||||||
|
- **Delete pond**: shared ponds can be moved to the site-level trash by
|
||||||
|
their admin via the API (`DELETE /api/v1/ponds/<id>` — there is no UI
|
||||||
|
button yet); a site admin can restore them. Your personal pond cannot
|
||||||
|
be deleted — it is your account's home.
|
||||||
132
docs/manual/site-admin-guide.md
Normal file
132
docs/manual/site-admin-guide.md
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
# Site-admin guide
|
||||||
|
|
||||||
|
How to administer a Dorfteich instance from the browser. Installation,
|
||||||
|
updates, and host-level operations are covered by the
|
||||||
|
[self-hosting guide](../self-hosting/README.md); this guide is about the
|
||||||
|
two admin pages: **Admin → Settings** (`/admin`) and **Admin → System**
|
||||||
|
(`/admin/system`).
|
||||||
|
|
||||||
|
A site admin sees and may do everything — use a normal account for
|
||||||
|
daily work.
|
||||||
|
|
||||||
|
## First contact: the setup wizard
|
||||||
|
|
||||||
|
A fresh instance greets you with a six-step wizard: language → the
|
||||||
|
site-admin account → instance name and default language → SMTP relay
|
||||||
|
(with a live test mail; skippable) → registration mode → done. Until it
|
||||||
|
finishes, the instance answers everything with `503 setup_required`.
|
||||||
|
Unattended installs pre-seed the wizard via `SETUP_ADMIN_*` environment
|
||||||
|
variables.
|
||||||
|
|
||||||
|
## Admin → Settings
|
||||||
|
|
||||||
|
### Instance
|
||||||
|
|
||||||
|
- **Name** (shown in the top bar and mails) and **default language**
|
||||||
|
(used for anonymous visitors and server-rendered pages).
|
||||||
|
- **Registration mode**: `open` (anyone may sign up, with e-mail
|
||||||
|
verification) or `closed` (only existing accounts sign in).
|
||||||
|
|
||||||
|
### Quotas
|
||||||
|
|
||||||
|
Instance-wide defaults: editors/readers per pond, additional shared
|
||||||
|
ponds per user (default 0 — raise it or grant per-user overrides to let
|
||||||
|
people create shared ponds), storage per pond, maximum file size. The
|
||||||
|
**quota manager** below sets per-user/per-pond overrides that win over
|
||||||
|
the defaults.
|
||||||
|
|
||||||
|
### Uploads
|
||||||
|
|
||||||
|
The allow-list of non-image file extensions users may attach, and the
|
||||||
|
SVG policy (`sanitize` strips scripts from uploaded SVGs, `reject`
|
||||||
|
refuses them).
|
||||||
|
|
||||||
|
### Public API and MCP
|
||||||
|
|
||||||
|
Two independent master switches, both **off by default**:
|
||||||
|
|
||||||
|
- **Public REST API**: lets users mint personal access tokens and use
|
||||||
|
`/api/public/v1` (see the [API guide](api-guide.md)).
|
||||||
|
- **Built-in MCP endpoint**: exposes `/api/mcp` for AI assistants
|
||||||
|
([MCP guide](mcp-guide.md)).
|
||||||
|
|
||||||
|
Either switch alone does nothing per pond — each pond additionally opts
|
||||||
|
in via its pond settings. Off means the endpoints answer 404.
|
||||||
|
|
||||||
|
### Legal pages
|
||||||
|
|
||||||
|
Imprint and privacy policy as Markdown, published at `/legal/imprint`
|
||||||
|
and `/legal/privacy` and linked from every page footer. A template with
|
||||||
|
a review checklist ships in
|
||||||
|
[`docs/self-hosting/legal-template.md`](../self-hosting/legal-template.md).
|
||||||
|
Until configured, the pages show a notice (and you a warning banner).
|
||||||
|
|
||||||
|
### Backups
|
||||||
|
|
||||||
|
See **Admin → System → Backups** below.
|
||||||
|
|
||||||
|
### Plugins
|
||||||
|
|
||||||
|
Install plugins by uploading a ZIP (alternatively: drop the ZIP into the
|
||||||
|
`_dropzone/` folder on the plugins volume — a watcher installs it within
|
||||||
|
seconds and moves rejected packages to `_quarantine/` with the reason).
|
||||||
|
|
||||||
|
Each installed plugin has an **instance mode**:
|
||||||
|
|
||||||
|
| Mode | Meaning |
|
||||||
|
| ---------- | ----------------------------------------------- |
|
||||||
|
| `disabled` | inactive everywhere (the default after install) |
|
||||||
|
| `optional` | pond admins decide per pond |
|
||||||
|
| `required` | active in every pond, no opt-out |
|
||||||
|
|
||||||
|
Every plugin has a sandboxed **preview** page for trying it before
|
||||||
|
enabling. Uninstalling is blocked while a plugin is `required`;
|
||||||
|
documents keep their plugin blocks either way and show the plugin's
|
||||||
|
fallback text when it is missing.
|
||||||
|
|
||||||
|
Shipped reference plugins: `toc` (table of contents), `page-index`
|
||||||
|
(label-filtered page list), `mermaid` (diagram blocks), `drawio`
|
||||||
|
(full draw.io editing), `section-styles-basic` (colored callouts).
|
||||||
|
|
||||||
|
### Users
|
||||||
|
|
||||||
|
The user manager: search accounts, disable/enable, resend verification
|
||||||
|
mails, promote/demote site admins, and delete accounts. Deletion offers
|
||||||
|
**pseudonymization**: the account and its personal data disappear, but
|
||||||
|
shared content survives attributed to a neutral placeholder. Guards
|
||||||
|
prevent disabling yourself or removing the last site admin.
|
||||||
|
|
||||||
|
## Admin → System
|
||||||
|
|
||||||
|
The operator's single glance:
|
||||||
|
|
||||||
|
- **Jobs**: every maintenance job (trash purge, version thinning, page
|
||||||
|
compaction, data-export purge, notification digests) with cadence,
|
||||||
|
last run, duration and outcome — plus a manual **Run** button (itself
|
||||||
|
audit-logged).
|
||||||
|
- **Backups**: the status card mirrors the sidecar's last run and its
|
||||||
|
freshness verdict, with a **Back up now** button. Below it:
|
||||||
|
- **Backup settings**: local retention (overrides the container
|
||||||
|
default), and the **Nextcloud target** — server address, username,
|
||||||
|
app password (kept in the file-based secret store on the secrets
|
||||||
|
volume, never in the database), folder, upload schedule (after every backup / weekly
|
||||||
|
/ manual), remote retention, and a **Test connection** button that
|
||||||
|
verifies credentials and creates the folder.
|
||||||
|
- **Restore**: lists local and Nextcloud sets; restoring asks you to
|
||||||
|
re-type the backup id, then the instance enters maintenance mode,
|
||||||
|
restores itself, and restarts. Everything else about backups (mirror
|
||||||
|
to a private host, disaster recovery) lives in the
|
||||||
|
[self-hosting guide](../self-hosting/README.md#backups--restore) and
|
||||||
|
the [restore runbook](../operations/restore-runbook.md).
|
||||||
|
- **Audit log**: administrative and auth events (grants, members, user
|
||||||
|
admin, quotas, plugins, settings, setup, tokens, API writes, backup
|
||||||
|
actions) with actor/action/time filters, 50 per page.
|
||||||
|
- **Storage**: the twenty largest ponds and the instance total.
|
||||||
|
|
||||||
|
## Health, monitoring, go-live
|
||||||
|
|
||||||
|
- `GET /api/v1/readyz` is the instance's own diagnosis; monitor it
|
||||||
|
(down vs. degraded semantics and a ready-made monitor set:
|
||||||
|
[`deploy/monitoring.md`](../../deploy/monitoring.md)).
|
||||||
|
- Going live checklist for a fresh production instance:
|
||||||
|
[`deploy/go-live.md`](../../deploy/go-live.md).
|
||||||
118
docs/manual/user-guide.md
Normal file
118
docs/manual/user-guide.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# User guide
|
||||||
|
|
||||||
|
How to find your way around Dorfteich as a regular member. For pond
|
||||||
|
configuration see the [pond-admin guide](pond-admin-guide.md); for
|
||||||
|
instance administration the [site-admin guide](site-admin-guide.md).
|
||||||
|
|
||||||
|
## Signing up and signing in
|
||||||
|
|
||||||
|
- **Sign up** (if the instance allows open registration): username,
|
||||||
|
e-mail, display name, password, language. You confirm your e-mail via
|
||||||
|
the link in the verification mail; that also creates your **personal
|
||||||
|
pond** — your own space that only you can see until you share it.
|
||||||
|
- **Sign in** with username _or_ e-mail. Forgot your password? The
|
||||||
|
sign-in page has a reset link (requires the instance to have mail
|
||||||
|
configured).
|
||||||
|
- Your sessions are listed under **Settings → Sessions**; you can revoke
|
||||||
|
any device from there.
|
||||||
|
|
||||||
|
## Ponds and pages
|
||||||
|
|
||||||
|
- The **pond switcher** in the top bar moves you between the ponds you
|
||||||
|
can see. The **sidebar** lists the pages of the current pond — sort
|
||||||
|
them A–Z, by creation date, or drag them into a manual order (the sort
|
||||||
|
mode is a pond setting).
|
||||||
|
- **+ New page** at the bottom of the sidebar creates a page. Page
|
||||||
|
addresses are readable: `/p/<pond>/<page>`.
|
||||||
|
- The **trash** link sits at the very bottom of the sidebar: deleted
|
||||||
|
pages can be restored from there until the retention period ends.
|
||||||
|
|
||||||
|
## The editor
|
||||||
|
|
||||||
|
Click the **pencil icon** in the top bar to switch a page between
|
||||||
|
reading and editing. In edit mode a toolbar offers paragraph styles
|
||||||
|
(H1–H4), bold/italic/strikethrough/inline code, bullet/numbered/task
|
||||||
|
lists, quotes, code blocks, horizontal rules, images, and tables. The
|
||||||
|
toolbar stays visible while you scroll.
|
||||||
|
|
||||||
|
- **Everyone edits together.** Other people on the page appear in the
|
||||||
|
presence strip in the top bar and as named cursors in the text.
|
||||||
|
There is no save button for content — every keystroke is persisted and
|
||||||
|
replicated live.
|
||||||
|
- **Offline?** The status icon in the footer (bottom left) shows your
|
||||||
|
connection. You can keep typing offline; changes sync on reconnect.
|
||||||
|
- **Markdown in, Markdown out.** You can paste or type Markdown; the
|
||||||
|
page can always be copied or downloaded as Markdown again (**…**
|
||||||
|
overflow menu → Copy/Download Markdown).
|
||||||
|
- **Wikilinks:** type `[[page-slug]]` or `[[page-slug|shown text]]`.
|
||||||
|
Links to pages that do not exist yet are listed on the pond home page
|
||||||
|
("phantom pages") — one click creates the target. The **backlinks**
|
||||||
|
panel of a page shows every page that links to it.
|
||||||
|
- **Images and attachments:** paste or drag images straight into the
|
||||||
|
text. Other file types (PDFs etc., as allowed by the instance) attach
|
||||||
|
to the page via the **paperclip icon**.
|
||||||
|
- **Named versions:** the **save icon** in edit mode stores a named
|
||||||
|
snapshot ("before the big rewrite"). The **history icon** lists all
|
||||||
|
versions — automatic and named — with their contributors; you can view
|
||||||
|
any version and restore it. Restoring never deletes history.
|
||||||
|
|
||||||
|
## The top-bar page actions
|
||||||
|
|
||||||
|
When a page is open you find, next to the pencil: **watch** (bell for
|
||||||
|
this page), **comments** (with unread count), **attachments**,
|
||||||
|
**plugin tools** (table of contents, page index — when enabled),
|
||||||
|
**labels**, **history**, and the **…** overflow menu (copy/download
|
||||||
|
Markdown, export to Word/LibreOffice/PDF, delete).
|
||||||
|
|
||||||
|
## Labels
|
||||||
|
|
||||||
|
Open the **label icon** to tag the page. You can pick existing labels or
|
||||||
|
create one on the spot (creating is for pond admins). Labels organize
|
||||||
|
pages and can carry access rules — a page inherits every rule of its
|
||||||
|
labels.
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
The search field in the top bar searches every page you are allowed to
|
||||||
|
read, across all ponds — tolerant of accents ("Baume" finds "Bäume") and
|
||||||
|
of partial words. Recent searches are remembered (and can be cleared).
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
The **speech-bubble icon** opens the comment panel: threads with one
|
||||||
|
reply level, Markdown supported, edit and delete for your own comments,
|
||||||
|
**resolve** to fold finished discussions away. Whether every reader or
|
||||||
|
only editors may comment is a pond setting.
|
||||||
|
|
||||||
|
## Watches, notifications, digests
|
||||||
|
|
||||||
|
- **Watch** a page (bell in the page actions) or a whole pond (bell in
|
||||||
|
the pond settings header) to be notified about changes and comments.
|
||||||
|
By default you automatically watch pages you create or comment on —
|
||||||
|
both switches live under **Settings → Profile**.
|
||||||
|
- The **bell in the top bar** is your notification inbox; entries link
|
||||||
|
straight to the change (comment notifications open the panel).
|
||||||
|
- **E-mail digests** bundle unread notifications hourly or daily —
|
||||||
|
configure under Settings, unsubscribe from any digest mail directly.
|
||||||
|
|
||||||
|
## Import and export
|
||||||
|
|
||||||
|
- **Import a document** (sidebar link): `.docx`, `.odt`, or `.md`
|
||||||
|
becomes a new page, embedded images included.
|
||||||
|
- **Export a page**: overflow menu → Markdown / Word / LibreOffice /
|
||||||
|
PDF. **Export a pond**: pond settings → ZIP of all pages you may read,
|
||||||
|
as Markdown plus media.
|
||||||
|
|
||||||
|
## Your settings (top-right → Settings)
|
||||||
|
|
||||||
|
Profile (display name, e-mail, language, watch defaults, digest
|
||||||
|
frequency), password, active sessions, your watches, **API tokens** (for
|
||||||
|
scripts and AI assistants — see the [API guide](api-guide.md) and
|
||||||
|
[MCP guide](mcp-guide.md)), and **data export**: a ZIP with your profile
|
||||||
|
data and the full content of your own ponds.
|
||||||
|
|
||||||
|
## Public pages
|
||||||
|
|
||||||
|
If a pond admin has published a page for the public, it is readable
|
||||||
|
without an account at `/public/<pond>/<page>` — with the pond's
|
||||||
|
typography and a link to the instance's legal pages.
|
||||||
Loading…
Reference in New Issue
Block a user