Skip to content
Download PDF

Documentation Site Generator ​

forge docsite hosts two architecturally separate families under one noun. They share no state, no manifest, no config key, and no output directory.

  • install / dev / build — scaffold and run a generator toolchain inside .forge/ itself, so you can browse forge's own live state (specs, changes, decisions, branding) as a real site while you work.
  • publish — renders forge's .forge/ state into a public documentation site you already own — VitePress, Docusaurus, Starlight, Mintlify, or MkDocs Material — detecting the generator already in use and never destroying a hand-written page.

Not the same thing as forge docs

forge docs build\|serve renders forge's own internal dashboard — spec inventory, breaker/budget chips, the session timeline. docsite publish renders a public documentation site for people outside the team. docsite install/dev/build is a third thing again — forge's own live-content site, browsed locally while you work. All three read the same .forge/ state but produce different artifacts for different audiences.

Browse forge's own state live ​

The fastest way to see what is in .forge/ without leaving your terminal:

sh
forge docsite install --target vitepress   # once: scaffolds .forge/.vitepress + package.json
forge docsite dev                          # foreground dev server, Ctrl-C to stop

install scaffolds a VitePress project into .forge/ itself and installs its dependencies. dev execs that project's dev server in the foreground, serving live .forge/ content — specs, changes, decisions, branding tokens with color swatches, mermaid diagrams — regenerated automatically as files change on disk.

sh
forge docsite build --out .forge/.vitepress/dist

build runs the same generator's static build — no separate derive stage: it produces exactly what dev already serves, over the same generated config, so there is never more than one coherent generator project living in .forge/.

Both dev and build require install to have run first: they read the installed target from .forge/.docsite-install.json, never from .forge/config.yaml, and error naming install if nothing is installed yet. dev --print / build --print show the exact command instead of running it.

Publish a specification site from .forge/ ​

This is the fastest path to a shippable public site — one command, no staging tree to hand-write:

sh
forge docsite publish --target vitepress --out site

publish reads .forge/specs/, the active .forge/changes/, and the immutable .forge/changes/archive/ directly, and produces three sections:

SectionSourceContent
capabilities/.forge/specs/<domain>/spec.mdRequirements and their Given/When/Then scenarios — what the system canonically does
active/.forge/changes/<name>/Proposal intent/scope, design decisions, and the task list with status
releases/.forge/changes/archive/<date>-<name>/The same shape as active/, minus tasks — an archived change has none open by definition

plus a generated index.md landing page with counts for each section. When present, data model and contract definitions are included alongside the design decisions.

Deliberately not a dashboard

Operational fields a change carries for the team running forge — session events, spend, breaker/secscan counters — never reach these pages. This is a client-facing artifact: proposal, design, and task substance only. For the operational view, see the spec-viewer dashboard.

publish always derives fresh from .forge/ before rendering — there is no separate stage-then-render step to run by hand. --source-only stops after staging, leaving .forge/docsite/staging/ in place for manual review without ever rendering.

sh
forge docsite publish --source-only                    # stage only; review .forge/docsite/staging/
forge docsite publish --target vitepress --out site    # derive + render

The full pipeline ​

sh
forge docsite install [--target <t>] [--force] [--no-gitignore]
forge docsite dev     [--print]
forge docsite build   [--out <dir>] [--print]
forge docsite publish [--target <t>] [--out <dir>] [--source-only]
  • install scaffolds the chosen generator's template set into .forge/ and installs its dependencies. Refuses a conflicting already-installed target unless --force (which removes the old target's owned files, preserving anything hand-edited).
  • dev execs the installed generator's dev server in the foreground. Errors naming install if nothing is installed; errors by name — never silently substituting VitePress — if the installed target has no dev backend.
  • build runs the installed generator's static build.
  • publish derives fresh from .forge/, resolves the adapter, applies the ownership rules, writes the site, and emits /llms.txt when docsite.llms_txt is true (the default).

detect, plan, render, and derive were removed

No aliases, no deprecation window. Running one names its replacement: detect → install --dry-run, render/derive → publish, plan → no direct replacement (its bounded staleness work list had no other caller once publish always derives the whole site fresh every run).

Ownership: forge owns files, not directories ​

publish tracks what it wrote in .forge/docsite/owned.json — a completely separate manifest from install's own .forge/.docsite-install.json; the two families never touch each other's files. A page you hand-edit after publish wrote it is detected and skipped on the next run rather than overwritten; a page that exists on disk but forge never wrote is invisible to it and stays untouched. publish always derives the whole site, so pruning — deleting a page forge owns that is no longer produced — is unconditional; there is no partial or incremental mode to opt out of it.

Configuration ​

target, out, pattern, sections, scaffold, llms_txt, auto_on_archive, and exclude are all set under docsite: in .forge/config.yaml and apply to publish only — see Configuration. install/dev/build read no configuration at all: which target is installed lives entirely in .forge/.docsite-install.json. With no docsite: configuration, publish still needs zero setup for an existing public site: it resolves the generator and output directory from files already on disk.

Next steps ​