Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 85 additions & 9 deletions .claude/skills/docs-update/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,60 @@ Show the user a summary table of what was found:
| --- | ----- | ----------- | ------------- | ------------------------------------------- |
| #N | ... | Yes/No | ... | Document / Beta (skipped) / Not user-facing |

### Graduation catch-up scan

Run this scan whenever Step 5c detects a graduation event (a flag's `category` flipped away from `"beta"`, a flag was removed from `src/flags.ts`, or a route-level `isFlagEnabled("...")` guard was removed from `src/routes/router.ts`). Skip this section entirely if no graduation event was detected.

The standard 7-day window will not contain the PRs that built the feature — those PRs were correctly skipped as `Beta (skipped)` in earlier weekly runs, and the skill keeps no memory between runs. The graduation week is the only opportunity to recover them, reconstructed on demand from git history.

#### 1. Identify the graduating flag and its gated paths

The flag ID comes straight from the graduating PR's diff: a removed entry in `src/flags.ts` for flag-removal/category-flip, or the argument of the removed `isFlagEnabled("...")` call for router-guard removal.

Build the set of **path roots** the flag was gating by combining all of the following (deduplicate, expect 1–3 roots):

- **Feature-area mapping.** If the flag ID matches a feature area in `docs-config.json` (by name or description), use the file-mapping hints in Step 5 to derive directory roots — e.g. `dashboard` → `src/routes/Dashboard/`, `v2_editor` → `src/routes/v2/`.
- **Removed-guard call sites.** Every file in the graduating PR's diff where `isFlagEnabled("<flag>")` was removed contributes its containing directory.
- **Residual grep.** At the graduation commit, search the codebase for any remaining references to the flag ID (tests, comments, analytics metadata). Each match's directory is also a path root.

#### 2. Walk back to find the feature's actual start

Features are frequently built silently before a beta flag is added, so the flag's introduction date is a **floor, not a start**. Compute the earliest plausible start date:

```bash
GRAD_FLAG="<flag-id>"

# When was the flag itself introduced in src/flags.ts?
FLAG_ADDED_DATE=$(git log --reverse --format='%aI' -S "\"${GRAD_FLAG}\"" -- src/flags.ts | head -1 | cut -dT -f1)

# When was each path root first created? (Run once per path root.)
PATH_ROOT_DATE=$(git log --reverse --diff-filter=A --format='%aI' -- "<path-root>" | head -1 | cut -dT -f1)
```

`FEATURE_START_DATE` is the **earliest** of:

- The earliest `PATH_ROOT_DATE` across all path roots
- `FLAG_ADDED_DATE` minus 30 days (covers silent pre-flag development that didn't create a new directory)

Then apply a hard floor: never go earlier than 180 days before the graduation. PRs older than that rarely describe current behaviour and are better handled by a focused manual docs pass.

#### 3. Re-screen PRs in the extended window

Re-run Step 4's `gh pr list` with `--search "merged:>=${FEATURE_START_DATE} merged:<${SINCE_DATE}"` (the `<` excludes PRs already in the current window), then filter to PRs whose `files` list intersects the path roots from #1. Run the survivors through Step 5 with these adjustments:

- The graduating flag is no longer beta. In the per-PR diff scan (5b), drop its flag ID from the beta flag set. All other beta flags still apply.
- Skipped-by-label rules (`dependencies`, `chore`, `ci`) still apply as in Step 4.

Add the documentable PRs to the run's documentable set with status `Document (graduation catch-up)` in the screening table, marked as pre-dating the standard window.

#### 4. Volume cap

If the catch-up surfaces more than ~80 PRs, or spans more than 4 distinct feature areas, **stop expanding and degrade gracefully** — a single auto-generated PR cannot meaningfully document that much surface area:

- Keep only the 30 most recent PRs from the catch-up
- Add a prominent warning to the docs PR body: the graduating feature has a long history and a hand-curated docs migration is recommended
- The reviewer can re-run with a narrower `--since` and a focused feature-area filter once they've decided how to scope the migration

## Step 6: Fetch Current Documentation

Get the full recursive file tree of the docs repo so you can find the best home for every change — do not assume any single file is the right place:
Expand Down Expand Up @@ -283,13 +337,33 @@ Then either reuse an existing screenshot from `playwright-report/` or add `await

If running tests is impractical (no dev server, slow, or fails), skip screenshot capture — never block the docs update on it. Documentation without a screenshot is still valuable.

### 7b. Generate Updates
### 7b. Read the source code for graduating features

**Skip this sub-step entirely if the documentable set contains no graduation catch-up PRs.** For ordinary weekly updates, the E2E test grounding from 7a is sufficient.

When catch-up PRs are present, the diffs and commit messages are not a reliable source. Catch-up PRs span months; later PRs silently override earlier ones, labels get renamed, panels get restructured. **The current code is the only authoritative source for what the graduated feature looks like today.** Read the implementation directly before writing any docs:

1. **Entry-point components** — the route component(s) the feature lives in (e.g. `EditorV2.tsx`, `DashboardLayout.tsx`). These enumerate panels, toolbars, dialogs, and child components in their current shape.
2. **User-visible labels and copy** — JSX text, button labels, tooltip strings, dialog titles, error messages. A label that was renamed three times across the catch-up has only one current name; use that one.
3. **Manifests, registries, and config** — files like `nodes/index.ts`, `registry.ts`, or `manifest.ts` enumerate the feature's current capabilities and are the right source for "what does this feature support" sections.
4. **In-repo architecture notes** — `ARCHITECTURE.md`, `WINDOWS.md`, etc. at the path root. Use these for background understanding only; maintainer language tends to leak internals, so do not copy phrasing into user-facing docs.
5. **E2E tests** (covered in 7a) — for graduating features these are typically the most reliable source of the actual user flow, because they exercise the current shape, not whatever shape existed when each catch-up PR was written.

The goal is documentation that describes **how the feature works now**, not a commit-by-commit retelling of how it was built. PRs are timeline artifacts; the code is the spec.

### 7c. Generate Updates

For each user-facing PR and its affected feature areas, reason through:

1. **What changed?** Summarize the behavioral/UI change in plain terms, drawing on the PR diff, linked issues (Step 4a), and E2E test context (Step 7a).
1. **What changed?** Summarize the behavioral/UI change in plain terms, drawing on the PR diff, linked issues (Step 4a), and E2E test context (Step 7a). For graduating features, draw on the current code as read in Step 7b — _not_ a stitched-together summary of the catch-up PR diffs.
2. **Which file(s) should be updated?** Do not default to a single file. Consider every section of the docs. A single PR may warrant changes in more than one file (e.g., a new feature that affects both a core-concepts page and the UI overview). Ask: "Where would a user look for this?"
3. **Does a new page need to be created?** If a feature is substantial and has no existing home (e.g., secrets management, artifact visualization), create a new dedicated page in the most appropriate section.
3. **What's the right structure — edit, new page, or new section?** Default to the smallest unit that fits, and split larger only when the content actually justifies it:
- **Edit / add-section** — small features or refinements that fit naturally inside an existing page. Default for ordinary weekly updates.
- **Single new page** — a substantial feature with no existing home (e.g. secrets management, artifact visualization). Place it in the most appropriate existing sidebar category.
- **New sidebar category with multiple pages** — large graduations (e.g. a redesigned editor, a new run experience) often warrant their own top-level docs section. Trigger this option only when **at least 3 distinct sub-topics each need more than roughly half a page of content**. Plan a coordinated set of `new-page` changes plus a single `sidebar-update` registering them under a new category. Mirror an existing category's shape (depth, page count, naming patterns from e.g. `core-concepts/` or `user-guide/`); do not nest a new category more than one level deep.

When in doubt, consolidate. A single dense page is easier to review and maintain than three thin ones.

4. **What should the update say?** Write the updated markdown content.

**Writing guidelines:**
Expand Down Expand Up @@ -319,12 +393,14 @@ Produce a list of proposed changes, each with:
- `summary` — one-sentence description of the change (for the PR body)
- `content` — the full updated file content, or the new section markdown if `add-section`. For `new-asset`, set `content` to the absolute local path of the binary file to copy (e.g., `/tmp/docs-screenshots/foo.png`) — Step 8 will copy the file rather than writing its bytes.

**Mandatory pairing:** Every `new-page` change MUST be accompanied by a `sidebar-update` change in the same run. A new `.mdx` file that is not added to `sidebars.ts` will not appear in the documentation navigation, defeating the purpose of writing it. When you produce a `new-page` change:
**Mandatory pairing:** Every `new-page` change MUST be registered in `sidebars.ts` in the same run, otherwise the page is invisible in the docs navigation and the run was wasted. Emit exactly **one** `sidebar-update` change per run, containing the fully updated `sidebars.ts` with every new page from this run registered — multiple `sidebar-update` changes would conflict on commit.

Rules for the `sidebar-update`:

1. Read the current `sidebars.ts` content fetched in Step 6.
2. Determine the correct category and position for the new page based on its topic and the existing structure.
3. Produce a `sidebar-update` change that contains the full updated `sidebars.ts` with the new doc ID inserted. The doc ID is the path within `<docsPath>/` with the `.mdx`/`.md` extension stripped (e.g., a new file at `docs/core-concepts/artifacts.mdx` is registered as `'core-concepts/artifacts'`).
4. Preserve all existing entries, formatting, and ordering — only add the new entry.
- **Doc IDs** are the path within `<docsPath>/` with the `.mdx`/`.md` extension stripped (e.g. `docs/core-concepts/artifacts.mdx` → `'core-concepts/artifacts'`).
- **Placement.** A single new page goes into the most topically appropriate existing category. A coordinated set of pages from a graduation goes into a new top-level category, ordered overview-first then drill-down (do not nest more than one level deep).
- **Preserve everything else.** Add new entries only. Do not reorder, rename, or remove existing categories or pages.
- **Match existing shape.** Use the same entry shape (`type: 'category'`, `label`, `items`) as existing categories — do not introduce autogenerated, linked, or other sidebar shapes that the file does not already use.

If `--dry-run` was passed, print all proposed changes to the chat in full and stop here. Do not write any files or open any PRs.

Expand Down Expand Up @@ -352,7 +428,7 @@ Reject and skip any path containing `..` segments or that would resolve outside

**Pairing enforcement:** Before writing, verify that every `new-page` change has a matching `sidebar-update` change in the proposed change list. If a `new-page` is missing its sidebar entry, halt and report the error rather than committing — an unregistered page is invisible in the docs and would defeat the purpose of the run.

**Reference verification (final pre-commit check):** For every doc file you are about to write, scan its rendered content for image references (`![...](...)`, `<img src="...">`) and link references (`[...](...)`). For each reference, confirm the target exists either (a) already in the cloned repo, (b) in your `new-asset` change set in this same run, or (c) is a verified external URL from the source rules in Step 7b. If any reference fails this check, edit the content to remove the broken reference before writing — do not commit broken links.
**Reference verification (final pre-commit check):** For every doc file you are about to write, scan its rendered content for image references (`![...](...)`, `<img src="...">`) and link references (`[...](...)`). For each reference, confirm the target exists either (a) already in the cloned repo, (b) in your `new-asset` change set in this same run, or (c) is a verified external URL from the source rules in Step 7c. If any reference fails this check, edit the content to remove the broken reference before writing — do not commit broken links.

For each proposed change that passes validation:

Expand Down
Loading