User Documentation and Screenshots

How the user documentation at /docs/user is structured and how its real-app screenshots are captured and refreshed.

The end-user guide at /docs/user is written in Markdown per language and illustrated with real screenshots of the running app. Screenshots come from an isolated demo workspace, never from a real instance, and every screenshot carries numbered markers that are measured from the live DOM.

Content layout

PathPurpose
docs/user-guide/<de|en|it>/<slug>.mdOne chapter per file, with title and description frontmatter. German is the source of truth.
src/lib/docs/user-guide/chapters.tsChapter order, navigation groups, icons, and the app route each chapter opens.
src/lib/docs/user-guide/screenshots.jsonGenerated manifest: image path, size, and marker boxes per shot and language.
public/docs/user/screens/<lang>/<shot>.webpGenerated screenshots.
src/app/docs/user/page.tsx, src/app/docs/user/[slug]/page.tsxOverview and chapter routes; ?lang=en or ?lang=it switches the language.

A screenshot is placed in a chapter with the opening tag on its own line and the closing tag on the next line, followed by the numbered legend:

<docs-shot id="emails-inbox" alt="Posteingang in der Normal-Ansicht">
</docs-shot>

1. **Ordner** – …
2. **Postfach** – …

The legend must have exactly one item per marker. src/lib/docs/user-guide/content.test.ts enforces this, the tag format, alt text, identical shot order across languages, that every captured shot is used, and that every /docs/user/<slug>#anchor link resolves. Anchors come from ## headings of the target language.

Screenshot pipeline

All tooling lives in scripts/docs/:

ScriptRole
user-docs-server.mjsStarts Next on port 3220 against the separate clapilot_docs database. Workspace, state, and media directories live in .userdocs-workspace/; the agent runtime, mail servers, and model providers point at dead endpoints so nothing leaves the machine. --app-dir <checkout> serves a production build instead of next dev.
prepare-user-docs-db.mjsCreates and migrates the docs database and the fictional team (Carla Lindner as admin, Henrik Seidel, Mira Hartwig). With --content it runs the preview demo seed through the running server, rewrites display text (umlauts instead of ae/oe/ue, example.com/example.org addresses, phone numbers from the fictional 040 66969-xxx range), then seeds chats, team chat, notes, wiki pages, automations, a pending approval, extra modules, and workspace skills.
user-docs-shots.mjsShot definitions: route, preparation steps, and marker targets. Labels are written in German and resolved per language through the i18n dictionaries; key:<i18n key> targets templated labels.
capture-user-docs-screenshots.mjsCaptures every shot per language in a fresh browser context at 1440×900 (scale 1.25), measures markers, writes WebP files and the manifest.

Refreshing screenshots

node scripts/docs/prepare-user-docs-db.mjs
node scripts/docs/user-docs-server.mjs --app-dir <clean production build>
node scripts/docs/prepare-user-docs-db.mjs --content
node scripts/docs/capture-user-docs-screenshots.mjs --lang de,en,it

Useful options: --only <id,id> captures selected shots, --preview <dir> additionally writes PNGs with the markers drawn in for review, and --survey <dir> captures raw pages without markers.

Notes:

  • Build the app for --app-dir from a clean checkout with CLAPILOT_NEXT_DIST_DIR=.next-userdocs npm run build. next dev works too, but recompiles triggered by other edits can break captures.
  • The capture pins the browser clock to 09:40 Europe/Berlin on the seeding day, uses Playwright's headless shell so native date inputs follow the capture language, and refreshes the demo mail cache before each shot because the fictional mailbox is served from cache.
  • Two shots mask details of the offline demo environment in the page only: the admin agent page hides the "agent cron unreachable" banner, and the admin mailbox page shows mail.example.com instead of the dead local mail host. Nothing is saved.
  • Views that need a live model response, such as regenerating an email reply draft, cannot be captured; describe them in text instead.