Move the reference out of the README and into a docs site - #1
Conversation
The README had become the whole manual: 350 lines covering the design, the role contract, plugin manifests, both CLI surfaces, the environment, and the package split. That reads as one linear scroll, and every one of those sections wants to stand alone. site/ is Astro + Starlight, published to https://morse-ai.com as an assets-only Cloudflare Worker. Fifteen pages, split the way someone arrives at them: getting started, then why it works this way, then how to configure it, then reference. Nothing is invented — every page is derived from the README, SECURITY.md, or the source, and the two places the README left a schema unstated (plugin manifest fields) are filled in from packages/registry/src/plugins.ts rather than guessed. The README keeps the banner, the description, the diagram, the quick start, the security warning, and links. Detail moved rather than being duplicated, so there is one place to fix a wrong sentence. Keeping it that way is the part that needs machinery: - AGENTS.md maps each documented surface to the page that describes it, and CLAUDE.md points at it, so every harness reads the same rules - .github/workflows/docs.yml fails a pull request that changes one of those surfaces without touching site/src/content/docs/. "docs: n/a" in the PR body is the escape hatch when a change genuinely is not described anywhere - npm run build in site/ also checks every internal link, anchors included, against what was actually emitted site/ is a standalone npm project, deliberately outside the workspace packages/* glob: npm ci at the root installs no Astro, and a docs dependency has no route into a published package. Its only dependencies are astro and @astrojs/starlight. Root scripts docs:dev, docs:build and docs:deploy install it on demand, so a fresh clone needs no extra step. Deploys run from main on a push touching site/ or wrangler.jsonc, using a CLOUDFLARE_API_TOKEN secret. The custom domain is attached in the dashboard rather than declared in wrangler.jsonc, so a deploy cannot fail on a zone the config cannot see. npm test is unchanged and green at 138. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V8CHi3o1YanuKYvQzS1giK
The git integration does what the workflow was doing, and does it with a token this repository never has to hold: Cloudflare clones on push, runs the build command, then `wrangler deploy` — the same shape engel.dev already uses, wrangler config at the root with assets pointing into the subdirectory that builds them. - docs.yml keeps the half Cloudflare cannot do — build and link-check a pull request before it merges — and deploys nothing. The comment says why, so the next person does not helpfully add it back and race the integration for the same Worker. - No CLOUDFLARE_API_TOKEN secret. Workers Builds mints its own. - The Worker is named `morse`, matching the project the repository is connected to. A mismatch here is silent: wrangler deploys the name in the file and leaves the connected Worker alone. - CONTRIBUTING.md records the dashboard settings, since they are invisible from the repository. Only the build command differs from the defaults: `npm run docs:build`, not `npm run build`, which at the workspace root is tsc over the three packages and produces no site. `npm run docs:deploy` stays as break-glass from a laptop. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V8CHi3o1YanuKYvQzS1giK
|
Switched deployment to Cloudflare Workers Builds (0c9e712), same shape In the dialog you screenshotted, change one field:
Under Advanced settings, two things worth setting (both documented in
The build image defaults to Node 24, which clears both this repo's 22.13 floor and Astro's. What changed in the repo: Still outstanding on your side: attaching Generated by Claude Code |
Astro + Starlight in
site/, published to https://morse-ai.com by Cloudflare Workers Builds.What is here
The site — 15 pages under
site/src/content/docs/, split the way someone arrives at them rather than as one scroll:index.mdx(splash: tagline, room diagram, three cards)The sidebar is explicit in
astro.config.mjs, not autogenerated. Every page is derived fromREADME.md,SECURITY.md, or the source — no invented behaviour.The README is trimmed to banner, description, diagram, quick start, the security warning, and links. Detail moved rather than being duplicated, so there is one place to fix a wrong sentence.
Keeping it that way is the part that needed machinery, since drift stops being visible in review once the detail leaves the README:
AGENTS.mdmaps each documented surface to the page that describes it;CLAUDE.mdpoints at it so every harness reads the same rules..github/workflows/docs.ymlhas asyncjob that fails a PR touching a documented surface (CLI, MCP tools, env vars, role/plugin contract,SECURITY.md) without touchingsite/src/content/docs/. Escape hatch:docs: n/ain the PR body.npm run buildinsite/also checks every internal link — anchors included — against what was actually emitted (site/scripts/check-links.mjs).Deploys belong to Cloudflare, not to CI.
wrangler.jsoncat the root, assets-only, serving./site/dist— the same shapeengel.devuses. Workers Builds clones on push, runs the build command, thennpx wrangler deploy, so there is no API token in this repository. The workflow keeps only the half Cloudflare cannot do: failing a pull request before it merges.Dashboard settings, also recorded in
CONTRIBUTING.mdandwrangler.jsoncsince they are invisible from the repo:npm run docs:buildnpx wrangler deploy(default)npx wrangler versions upload(default)/(default)Isolation:
site/is a standalone npm project, deliberately outside the workspacepackages/*glob and marked"private": true.npm ciat the root installs no Astro, and a docs dependency has no route into a published package. Onlyastroand@astrojs/starlight. Nothing underpackages/,test/,scripts/ordocs/plans/was touched.Verified
npm run docs:build— 16 pages, 357 internal links, all resolvenpm ci+npm run buildinsidesite/(what CI does) — greennpm test— 138 pass, unchangedThings worth your feedback
Only one dashboard field differs from the defaults, and it is load-bearing: the build command must be
npm run docs:build, notnpm run build— at the workspace root that meanstscover the three packages and produces no site. Two optional settings are worth adding too, both inCONTRIBUTING.md: build watch paths (site/*,wrangler.jsonc) so a code-only commit does not rebuild the site, andSKIP_DEPENDENCY_INSTALL=1so the build image does not install the root workspace and runtscfor a docs deploy that does not need it.The Worker name is
morse, matching the project name in your setup screenshot. If you would rather call itmorse-docs, change both — a mismatch is silent, wrangler deploys the name inwrangler.jsoncand leaves the connected Worker untouched.morse-ai.comstill has to be attached to the Worker in the dashboard.wrangler.jsoncdeliberately declares noroutes, so a deploy cannot fail on a zone the config cannot see; until the domain is attached it serves onworkers.dev.The scaffold command could not run here. This sandbox's egress policy blocks
codeload.github.com(403), andnpm create astro@latest -- --template starlightfetches the template from GitHub. So I built the same files by hand against the published packages (astro@7.2.1,@astrojs/starlight@0.41.7):astro.config.mjs,src/content.config.tswithdocsLoader/docsSchema, atsconfig.jsonextendingastro/tsconfigs/strict,public/favicon.svg,.gitignore. It builds clean, but if you want it byte-identical to the official template, re-running the scaffold locally and diffing is the check I could not do.Two small additions beyond the spec you gave me, both easy to revert:
not_found_handling: "404-page"inwrangler.jsoncplus a real 404 page, so an unknown URL gets the site's own 404; and the rootdocs:*scripts runnpm --prefix site installbefore the underlying command, sonpm run docs:buildworks from a fresh clone instead of failing withastro: not found.The sync guard is opinionated and will affect contributors, not just agents. The surface list is a regex in
docs.yml— I scoped it to what a docs reader would notice (cli/main.ts,cli/agent.ts, the threemcp.tsfiles,prompt.ts,roles.ts,plugins.ts,toml.ts,README.md,SECURITY.md). If it turns out noisy, narrowing that regex is a one-line change. Tell me if you would rather it warned than failed.No
<!-- TODO -->markers survived. The one place the README left a schema unstated — the plugin manifest fields — I filled in frompackages/registry/src/plugins.ts(id,project,personal,depth,extensions,format,map) rather than guessing or leaving a hole. Same for the rejection reason strings (outside the searched directory/unreadable/unparseable) and the thread-id example format. Worth a skim onguides/agent-folders.mdin particular.Small README fix carried along: the old quick start said "In a seventh terminal" after a three-agent example — a leftover from the six-agent version. The site says "In another terminal".
The splash has no hero image.
assets/social/morse-linkedin.pngexists, but using it would mean copying a binary intosite/; I left the hero text-only. Easy to add if you want it. The favicon is a plain dot-dash SVG I drew — swap it if there is real brand art.🤖 Generated with Claude Code
https://claude.ai/code/session_01V8CHi3o1YanuKYvQzS1giK