bifrost-documentation
Refresh the gobifrost site by re-capturing screenshots and (optionally) authoring missing pages. Trigger phrases - "refresh docs", "update screenshots", "/bifrost-documentation", "rebuild docs site". Has three modes - bootstrap (one-shot manifest generation, mandatory first run), diff (default - onl
Install
mkdir -p .claude/skills/bifrost-documentation && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13353" && unzip -o skill.zip -d .claude/skills/bifrost-documentation && rm skill.zipInstalls to .claude/skills/bifrost-documentation
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Refresh the gobifrost site by re-capturing screenshots and (optionally) authoring missing pages. Trigger phrases - "refresh docs", "update screenshots", "/bifrost-documentation", "rebuild docs site". Has three modes - bootstrap (one-shot manifest generation, mandatory first run), diff (default - only refresh entries whose Bifrost source changed), full (re-capture and re-author everything).About this skill
Bifrost Documentation Pipeline
Refresh gobifrost programmatically: re-capture screenshots, author missing Diátaxis-shaped pages, open a docs PR with a TL;DR.
The docs repo is at ~/GitHub/gobifrost (or clone it from [email protected]:gobifrost/website.git if missing). The bifrost repo's worktree is the source of truth for the running app.
Default behavior — "catch up everything since the last documented commit"
When invoked with no mode, do the whole job in one pass — both existing and net-new surface. The user's expectation: "run it, figure it all out — all new features, all existing features. Know the last commit it fully documented, document all changes and features since, and update it with screenshots." Don't ask which mode; just bring the docs current.
The watermark already lives in the manifest: each entry carries captured_at.bifrost_sha. The lowest sha across all entries is the "fully documented through" commit. Net-new surface is discovered by router-walk ∖ manifest.
Run this sequence (fan out the per-page work with Workflow — one agent per page — when there's more than a handful):
- Establish the watermark.
WATERMARK=$(min captured_at.bifrost_sha across screenshots.yaml entries). Everything ingit log $WATERMARK..HEAD(bifrost) is in scope. - Discover undocumented routes. Enumerate client routes from
client/src/App.tsx(grep -oE 'path="[^"]+"'), normalize, and subtract everyroute:already inscreenshots.yaml. The remainder is net-new surface needing MDX + a manifest entry + fixtures. (Skip non-visual routes:*/callback*,device,mfa-setup,auth/*, param-only redirects.) - Discover stale existing entries. Entries whose
source_globschanged in$WATERMARK..HEAD, or whosecaptured_at.bifrost_shais behind HEAD — these need a re-capture (and a prose check if the feature changed, not just pixels). - Author (fan out). For each net-new route: pick the Diátaxis quadrant, write the MDX page, add the sidebar entry, and add a
screenshots.yamlentry (id,route,seed,diataxis.{page,type}, per-entrymocks/fixtures). For each stale page: update prose if the feature changed. Apply the anti-bloat self-review. MDX comments are{/* */}, never<!-- -->. - Capture in one loop.
scripts/docs/run-pipeline.sh --docs-repo $DOCS --bifrost-repo $BIFROST --full(or--ids <new+stale ids>). Runs headless in the playwright-runner container on this host — no external browser. Pixel-diff gates commits. - Stamp the watermark forward. Every captured entry's
captured_at.bifrost_shais set to the bifrost HEAD it was captured against. That advances the watermark so the next run starts exactly here. - Build + lint + PR.
npm run lint:manifestandnpm run buildmust pass; commit; open the docs PR with the TL;DR.
The named modes below are the surgical primitives this default orchestrates. Reach for a single mode only when you explicitly want just that slice (e.g. lint after hand-editing). The default path is what a release or a monthly catch-up should use.
Modes
| Mode | When | What it does |
|---|---|---|
bootstrap | First run, or after major doc reorganization. Aborts if screenshots.yaml exists unless --force. | Generates screenshots.yaml and bootstrap-report.md from MDX inventory + bifrost router walk. No captures. |
diff (default) | Daily refresh. | Short-lists entries whose source_globs changed since captured_at.bifrost_sha. Captures and pixel-diffs. Commits only PNGs that actually changed. |
full | Major UI shift, theme change, or post-bootstrap first run. | Bypasses the source-glob shortlist. Pixel diff still gates commits, so identical re-renders don't churn git. Also runs the authoring pass for any pages without screenshots. |
lint | After hand-editing the manifest. | Validates screenshots.yaml against schema, MDX cross-references, file existence. No captures. |
Workflow
-
Preflight
- Locate docs repo. Try
~/GitHub/gobifrostthen/tmp/gobifrost. If missing, clone to~/GitHub/. - Verify clean tree (
git status --porcelainempty). If dirty, ask the user to commit/stash before continuing. - Pull
main(git pull --ff-only origin main). - Compare last-update timestamps as a sanity signal:
Print both. IfBIFROST_LAST=$(cd ~/GitHub/bifrost && git log -1 --format=%cI origin/main) DOCS_LAST=$(cd ~/GitHub/gobifrost && git log -1 --format=%cI origin/main) echo "bifrost: $BIFROST_LAST" echo "docs: $DOCS_LAST"BIFROST_LAST > DOCS_LAST, that's normal — diff mode handles it. IfDOCS_LAST > BIFROST_LAST, something is unusual (docs ahead of code); flag it but proceed. - Cut a fresh branch:
docs/screenshot-refresh-YYYY-MM-DD-<short-sha>. - Verify bifrost test stack is up:
./test.sh stack statusin the bifrost worktree. If down,./test.sh stack up. The boot is ~2-5 minutes; warn the user up front. - Set
DOCS_REPO_PATH=<absolute path to docs repo>for downstream tools.
- Locate docs repo. Try
-
Mode dispatch
-
bootstrap:node $BIFROST/scripts/docs/bootstrap-manifest.mjs \ --docs-repo $DOCS_REPO --bifrost-repo $BIFROST $FORCEThen
cd $DOCS_REPO && npm run lint:manifestto confirm schema validity. Commitscreenshots.yaml+bootstrap-report.md. Open PR titled "Bootstrap docs screenshot manifest" with body =bootstrap-report.md. Stop here — do not continue to capture in the same run. -
diff/full:$BIFROST/scripts/docs/run-pipeline.sh \ --docs-repo $DOCS_REPO --bifrost-repo $BIFROST $MODE_FLAGReads JSON output for the TL;DR.
-
lint:cd $DOCS_REPO && npm run lint:manifest. Print result. No PR.
-
-
Authoring pass (full mode only) For each MDX page in
bootstrap-report.md's "Pages without screenshots" list that the user wants documented, generate a Diátaxis-templated stub. Usetemplates/as starting points.- Apply the anti-bloat self-review (below) before committing.
- The skill must NOT silently overwrite hand-written prose; only fills empty/stub pages.
-
Anti-bloat self-review (every prose change) After writing or editing any MDX, sweep for these patterns and cut them:
- "In this section, we'll explore..."
- "It's important to note that..."
- "Let's dive into..."
- "As we mentioned earlier..."
- Any paragraph longer than 80 words in a tutorial or how-to (split, condense, or move to an explanation page).
- Preamble before numbered steps (just start the steps). Reference + explanation pages can be denser. Tutorials and how-tos are terse by Diátaxis discipline.
-
Finalize
- Run
cd $DOCS_REPO && npm run lint:manifestto confirm. - Optionally
npm run buildfor a smoke build. - Stage and commit. Title:
Refresh screenshots and docs (<N> changed, <M> authored). - Push branch.
- Open PR via
gh pr create. Body = TL;DR (template below).
- Run
TL;DR template
## Mode
<bootstrap | diff | full>
## Bifrost SHA range
`<old>..<HEAD>` (or `<HEAD>` if bootstrap)
## Counts
- Candidates short-listed: <N>
- Captures attempted: <N>
- PNGs committed (passed pixel diff): <N>
- Entries unchanged (visual no-op): <N>
- Authored pages (full mode): <N>
## Manual review needed
<list any low-confidence flags from bootstrap-report.md or capture errors>
## Failures
<list any entries that errored, with route + reason>
Diátaxis quadrant rules
When authoring or editing prose, pick the right quadrant and stay in it:
- Tutorial (
getting-started/,*first-*): goal-oriented, a single happy path, no detours. Numbered steps, ≤2 sentences each. - How-to (
how-to-guides/**): one specific task. "How to <verb> <noun>" title. No teaching — assume the reader already understands the concept. - Reference (
sdk-reference/**): describe, don't explain. Tables of params, signatures, return values, one minimal example per item. Reference is the only quadrant where bloat is permitted, and only when needed for disambiguation. - Explanation (
core-concepts/,about/): why-shaped. Cross-link to tutorials/how-tos rather than repeating their content.
If the user asks for a doc and you can't pick a quadrant in one sentence, ask them.
When NOT to use this skill
- The user wants to write a single targeted doc page from scratch — write it directly.
- The user is debugging or fixing a typo — direct edit.
- The bifrost test stack is broken — fix that first; this skill cannot work without it.
- Net-new feature docs ARE in scope — see "Default behavior" at the top. (This used to be a carve-out. It no longer is.) The default no-mode run discovers undocumented routes via router-walk ∖ manifest, authors MDX + manifest entries + fixtures for each (fanning out with
Workflow), then captures in one loop and stamps the watermark forward. The individualdiff/bootstrap/fullmodes remain the surgical primitives, but you do not need to hand-author net-new pages before running — the default path does it. TheAuthoring new capturesprocedure below is the per-page recipe each fan-out agent follows.
Authoring new captures (manual)
When you've written a new MDX page and need a screenshot:
- Identify the route in
client/src/App.tsx. Confirm the route renders empty-state-free with mocked data. - Find the API endpoints the page calls.
grep -nE 'apiClient|useQuery' <component>then look at the route names. For each, write a fixture undergobifrost/fixtures/. - Add a manifest entry to
screenshots.yaml.mocks,actions,crop,callouts,fullPage,settle_msMUST be nested under acapture:key — NOT at the entry top level. The capture spec readsentry.capture.actions/effectiveMocks(entry)fromcapture; top-levelmocks/actionsare silently ignored, which pr
Content truncated.