usm/cli-docs [planned]
usm docs serve and usm docs build — serves generated docs locally via VitePress dev server with live reload for the spec-first review workflow, and builds a static site for Cloudflare Pages deployment. Unifies all generated docs into a single docs/ directory with auto-generated sidebar navigation.
Status: planned
Intent
The spec-first workflow requires a human to review generated feature docs before the agent builds. Currently the only way to read generated docs is raw markdown in a code editor — no rendering, no navigation, no hot reload. This makes the review step painful and breaks the workflow loop. This feature adds a dev server that serves generated docs with proper rendering, sidebar navigation, search, and live reload when .usm files change. It also unifies the scattered docs output (currently split across .agents-workspace/docs/ and apps/*/.agents-workspace/docs/) into a single docs/ directory with a clear hierarchy that maps to the .usm file structure.
Decisions
vitepress-over-custom [accepted]
Decision: Use VitePress as the rendering layer instead of building a custom server
Rationale: Building a custom markdown server with navigation, search, themes, and live reload is a whole separate product. VitePress is purpose-built for docs: markdown-native, Vite-powered HMR, built-in sidebar/search/dark mode, static build output. USM owns the content (generating markdown from .usm), VitePress owns the experience (rendering, nav, search). Clean separation of concerns. Used by Vue, Vitest, Pinia — battle-tested. Alternatives considered: custom Express+marked.js (rejected — reinventing the wheel, permanent maintenance burden), Docsify (rejected — client-side rendering, poor SEO), Nextra (rejected — heavyweight, pulls in Next.js).
unified-docs-directory [accepted]
Decision: All generated docs write to a single docs/ directory instead of scattered .agents-workspace/ paths
Rationale: Currently feature docs land in apps/<service>/.agents-workspace/docs/ and service docs in .agents-workspace/docs/shared-services/. This scattering makes navigation impossible and paths unpredictable. A unified docs/ directory with services/, features/, architecture/ subdirectories creates a clean hierarchy that maps 1:1 to the .usm file structure and works as VitePress input.
sidebar-from-system-index [accepted]
Decision: Auto-generate VitePress sidebar config from system.usm index + feature directory structure
Rationale: system.usm already has an index[] with feature id, name, ref, status, and tags. This is the authoritative source of what features exist and how they're grouped. Generating the sidebar from this index means the navigation is always in sync with the spec — no manual sidebar maintenance. Feature grouping (CLI, generators, mcp) comes from the directory structure of .usm/features/.
vitepress-optional-dependency [accepted]
Decision: VitePress is an optional peer dependency, not bundled with USM
Rationale: Not every USM user needs the docs server — some just want the CLI and MCP tools. Making VitePress optional keeps the core install lightweight. usm docs serve checks for VitePress and prints install instructions if missing, rather than failing at install time.
dont-commit-generated-docs [accepted]
Decision: Generated docs are not committed to the repo — served locally and deployed via CI
Rationale: Committing generated files creates diff noise and merge conflicts. The docs/ directory is gitignored. usm docs serve reads from the local generated output. CI runs usm generate && usm docs build for deployment. GitHub browsing links to the deployed site. This matches the current .gitignore strategy for .agents-workspace/.
Flows
Start docs dev server (docs-serve)
User runs usm docs serve. USM generates markdown from .usm files into docs/, generates VitePress config (sidebar, nav) from system.usm index, starts VitePress dev server with hot reload. When .usm files change, affected markdown regenerates and VitePress HMR updates the browser.
- check → VitePress installed in project (optional peer dep)
- expects: installed: true
- generate → markdown docs from .usm files into docs/ directory (unified structure)
- generate → .vitepress/config.ts with sidebar and nav from system.usm index
- start → VitePress dev server on configurable port (default 5173)
- watch → .usm/ directory for file changes
- regenerate → affected markdown when .usm file changes
- observe → VitePress HMR updates browser automatically
Build static docs site (docs-build)
User runs usm docs build. USM generates markdown + VitePress config, then runs vitepress build to produce a static site in docs/.vitepress/dist/ ready for Cloudflare Pages or any static host.
- generate → markdown docs from .usm files into docs/ directory
- generate → .vitepress/config.ts with sidebar and nav
- build → vitepress build docs/ → static HTML in docs/.vitepress/dist/
- observe → output directory ready for deployment
Generate VitePress sidebar and nav config (generate-vitepress-config)
Generate .vitepress/config.ts from system.usm index and feature directory structure. Sidebar groups mirror .usm/features/ subdirectories. Feature status shown as badge in nav. Services listed from system.usm services[].
- parse → system.usm for identity, services[], index[]
- scan → .usm/features/ subdirectories for grouping (cli, generators, mcp, schema)
- map → each index entry to a sidebar item with link, label, status badge
- generate → .vitepress/config.ts with sidebar tree, nav bar, theme config
- write → docs/.vitepress/config.ts
Generate docs into unified docs/ directory (unified-output-structure)
The generate command writes all output to a single docs/ directory with a clear hierarchy: services/, features/<area>/, architecture/, cross-cutting (risks, roadmap, decisions). This replaces the current scattered output across .agents-workspace/docs/ and apps/*/.agents-workspace/docs/.
- generate → docs/index.md from system.usm (overview, stats, principles)
- generate → docs/services/<service>.md from each service .usm
- generate → docs/features/<area>/<feature>.md from each feature .usm
- generate → docs/architecture/ (diagrams, data models, dependencies)
- generate → docs/risks.md, docs/roadmap.md, docs/decisions/ from system.usm
- generate → docs/api/openapi.yaml from features with routes
Contracts
serve-starts-on-configurable-port
usm docs serve must start on a configurable port with sensible default
Acceptance criteria:
- [ ] Default port is 5173 (VitePress default)
- [ ] --port flag overrides default
- [ ] Server accessible at http://localhost:<port>
- [ ] Clear console output with URL and QR code for mobile review
sidebar-matches-system-index
VitePress sidebar must reflect all features from system.usm index
Acceptance criteria:
- [ ] Every index entry appears in the sidebar
- [ ] Sidebar groups match .usm/features/ subdirectory names
- [ ] Feature status (planned, active, deprecated) shown as badge
- [ ] Services listed in sidebar from system.usm services[]
hot-reload-on-usm-change
Editing a .usm file must trigger regeneration and browser update
Acceptance criteria:
- [ ] File watcher monitors .usm/ directory recursively
- [ ] Only affected markdown regenerated (not full rebuild)
- [ ] VitePress HMR updates browser within 1 second
- [ ] Console shows which file changed and was regenerated
build-produces-static-output
usm docs build must produce a deployable static site
Acceptance criteria:
- [ ] Static HTML output in docs/.vitepress/dist/
- [ ] All assets (CSS, JS, images) bundled
- [ ] No server runtime required to serve output
- [ ] Output works on Cloudflare Pages, GitHub Pages, Netlify, or any static host
unified-structure-is-flat-and-navigable
All docs in a single docs/ directory with predictable paths
Acceptance criteria:
- [ ] One markdown file per .usm feature
- [ ] Path pattern: docs/features/<area>/<feature>.md
- [ ] Services at docs/services/<service>.md
- [ ] No docs scattered across apps/ or .agents-workspace/
vitepress-missing-graceful-error
If VitePress is not installed, show helpful error not a crash
Acceptance criteria:
- [ ] Error message explains VitePress is optional dependency
- [ ] Install command shown (pnpm add -D vitepress)
- [ ] Exit code 1 with clear message, not a stack trace
Tests
serve-starts-and-accessible
Given:
- vitepress_installed: true
- usm_files_present: true
Then:
- assertion: server starts on port 5173
- assertion: http://localhost:5173 returns rendered HTML
- assertion: sidebar visible with feature list
serve-custom-port
Given:
- vitepress_installed: true
- port_flag: "--port 3000"
Then:
- assertion: server starts on port 3000
- assertion: console output shows correct URL
sidebar-reflects-all-features
Given:
- system_usm_with_27_features: true
Then:
- assertion: sidebar contains all 27 features from index
- assertion: features grouped by directory (cli, generators, mcp, schema)
- assertion: planned features show badge
hot-reload-on-edit
Given:
- dev_server_running: true
Then:
- assertion: editing a .usm file triggers regeneration
- assertion: browser updates within 1 second
- assertion: only affected markdown file regenerated
build-produces-static-site
Given:
- vitepress_installed: true
- usm_files_present: true
Then:
- assertion: docs/.vitepress/dist/ directory created
- assertion: index.html present
- assertion: all pages rendered as static HTML
vitepress-missing-error
Given:
- vitepress_not_installed: true
Then:
- assertion: clear error message about missing VitePress
- assertion: install command shown in output
- assertion: exit code 1
unified-structure-paths
Given:
- generate_run: true
Then:
- assertion: docs/services/cli.md exists
- assertion: docs/features/mcp/write.md exists
- assertion: docs/features/generators/feature-review.md exists
- assertion: no files in apps/*/.agents-workspace/docs/
Implementation
- Primary: src/cli/docs.ts
- Test code status: none
See Also
- usm/cli-generate
- usm/gen-feature-review
- usm/gen-markdown