-
Notifications
You must be signed in to change notification settings - Fork 34
Feature/docs updater workflow #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
csoceanu
wants to merge
17
commits into
ambient-code:main
Choose a base branch
from
csoceanu:feature/docs-updater-workflow
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
58d985f
feat: add docs-updater workflow
csoceanu cda3c73
fix: improve discovery and generation skills based on test feedback
csoceanu f7cf227
fix: improve indexing based on test feedback
csoceanu 2e4ad13
fix: show diff to user after applying updates
csoceanu 4df8789
fix: improve indexing guidance and index-assisted discovery
csoceanu 333f569
fix: enforce AskUserQuestion after setup, explain indexing clearly
csoceanu dab1eb7
fix: strengthen systemPrompt to enforce controller skill compliance
csoceanu 03f880c
fix: raise indexing threshold to 10+ folders, improve description
csoceanu 2b2299b
refactor: make /index a command, remove slash notation from phases
csoceanu d93174b
fix: require per-file SHA256 hashes in index manifest
csoceanu 6a25f5e
fix: mention /index command in startup greeting
csoceanu 44dbc69
fix: integrate /index into capabilities list in greeting
csoceanu 50dcd46
fix: remove format limitations and inconsistencies across all files
csoceanu ceddc2d
fix: final consistency pass across all files
csoceanu 4fa511e
fix: add language to code block for markdown linting
csoceanu c8437fb
fix: address CodeRabbit review feedback
csoceanu 592bdf1
fix: add language tag to second unlabeled code block in PR skill
csoceanu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "Docs Updater", | ||
| "description": "Analyze code changes and update documentation. Discovers affected doc files, generates conservative format-aware updates, and opens a docs PR. Works with any text-based doc format. Optional semantic indexing for large repos.", | ||
| "systemPrompt": "You are a documentation update assistant that analyzes code changes and keeps documentation in sync.\n\nCRITICAL: Before doing ANYTHING else, read and follow the controller skill at .claude/skills/controller/SKILL.md. The controller defines the workflow phases, the setup procedure, and how to recommend next steps. You MUST follow its instructions exactly — including using AskUserQuestion (not plain text) for all user decisions. Do NOT skip the controller or improvise your own flow.\n\nWORKSPACE NAVIGATION:\nStandard file locations (from workflow root):\n- Skills: .claude/skills/*/SKILL.md\n- Outputs: artifacts/docs-updater/\n\nTool selection rules:\n- Use Read for: Known paths, standard files, files you just created\n- Use Glob for: Discovery (finding multiple files by pattern)\n- Use Grep for: Content search\n\nNever glob for standard files:\n✅ DO: Read .ambient/ambient.json\n❌ DON'T: Glob **/ambient.json", | ||
| "startupPrompt": "Greet the user and introduce yourself as a documentation update assistant. Explain that you can analyze code changes (from a PR, branch diff, or local changes) to discover which documentation files need updating, generate conservative format-aware updates, and open a docs PR. Include /index in the list of capabilities — it builds semantic indexes for docs (whether in a separate repo or a folder alongside the code) so future runs are faster, use fewer tokens, and can catch conceptual matches that keyword grep would miss. Note that /index is only recommended when the docs have many folders — for smaller docs the default grep-based discovery works well. Ask the user how they'd like to provide the code changes — a PR URL, branch name, or local diff." | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # /index - Build semantic indexes for documentation | ||
|
|
||
| ## Purpose | ||
|
|
||
| Build a semantic summary of each documentation folder so future discovery | ||
| runs can skip irrelevant folders instead of grepping all files. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Access to the documentation location (repo or subfolder) | ||
| - Write permissions to create `.doc-index/` in the docs location | ||
|
|
||
| ## When to use | ||
|
|
||
| - The docs location has many folders and you plan to run the workflow | ||
| multiple times | ||
| - You want faster discovery in future sessions | ||
|
|
||
| ## Important | ||
|
|
||
| Indexes are only worth building if you commit and push them. Without | ||
| that, they're lost when the session ends and the next run starts from | ||
| scratch. | ||
|
|
||
| ## Process | ||
|
|
||
| 1. Ask the user where the documentation lives: | ||
| - Same repo, subfolder (ask which folder) | ||
| - Separate repo (ask for URL or local path) | ||
| 2. Check if `.doc-index/manifest.json` already exists | ||
| - If yes: for each folder in the manifest, compute SHA256 hashes of | ||
| all doc files and compare against the hashes stored in the manifest. | ||
| Only rebuild folders where at least one file hash differs. Report | ||
| which folders are up-to-date and which need rebuilding | ||
| - If no: build indexes for all folders from scratch | ||
| 3. Scan the docs location for folders containing documentation files | ||
| - Add any newly discovered folders (not present in the manifest) to | ||
| the rebuild list | ||
| - Remove entries for folders that no longer exist | ||
| 4. For folders with subfolders, create sub-indexes per subfolder | ||
| 5. Dispatch a subagent to build the indexes | ||
| 6. Generate a semantic summary for each folder covering: what it | ||
| documents, what code changes would affect it, key technical concepts | ||
| 7. Write indexes to `.doc-index/` and update `manifest.json`. The | ||
| manifest MUST store per-file SHA256 hashes (not just file counts) | ||
| so that future runs can detect exactly which folders changed: | ||
|
|
||
| ```json | ||
| { | ||
| "version": "1.0", | ||
| "updated": "<ISO 8601>", | ||
| "folders": { | ||
| "<folder-name>": { | ||
| "built": "<ISO 8601>", | ||
| "doc_hashes": { | ||
| "<folder>/<file>.md": "<sha256>", | ||
| "<folder>/<file2>.md": "<sha256>" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| 8. Ask where to commit the indexes (current branch or main) | ||
|
|
||
| ## Output | ||
|
|
||
| - `.doc-index/manifest.json` — metadata with per-file SHA256 hashes | ||
| - `.doc-index/<folder-name>.index.md` — semantic summary per folder | ||
132 changes: 132 additions & 0 deletions
132
workflows/docs-updater/.claude/skills/controller/SKILL.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| --- | ||
| name: controller | ||
| description: Top-level workflow controller that manages phase transitions for documentation updates. | ||
| --- | ||
|
|
||
| # Docs Updater Workflow Controller | ||
|
|
||
| You are the workflow controller. Your job is to manage the docs-updater workflow | ||
| by executing phases and handling transitions between them. | ||
|
|
||
| ## Phases | ||
|
|
||
| 1. **Setup** (automatic, first interaction) | ||
| Establish the code change source (diff) and the documentation repo location. | ||
|
|
||
| 2. **Review** — the `discovery` skill then the `generation` skill in preview mode. | ||
| Discover which doc files need updates and show proposed changes. | ||
|
|
||
| 3. **Update** — the `generation` skill in apply mode. | ||
| Apply the accepted changes to documentation files. | ||
|
|
||
| 4. **Open PR** — the `pr` skill. | ||
| Push changes and create a draft pull request for the documentation updates. | ||
|
|
||
| Phases can be skipped or reordered at the user's discretion. | ||
|
|
||
| Note: The `/index` command is available separately for building semantic | ||
| indexes. It is not a phase managed by this controller — the user can run | ||
| it independently at any time. | ||
|
|
||
| ## Setup Procedure | ||
|
|
||
| Before any phase can run, you must establish two things. Run this setup | ||
| automatically on the first user interaction. | ||
|
|
||
| ### Step 1: Determine the code change source | ||
|
|
||
| Ask the user via `AskUserQuestion` how they want to provide the code changes: | ||
|
|
||
| - **PR URL** — Use `gh pr diff <url>` to obtain the diff | ||
| - **Branch comparison** — Use `git diff <base>...<head>` to obtain the diff | ||
| - **Local uncommitted changes** — Use `git diff` to obtain the diff | ||
|
|
||
| Obtain the diff and keep it in context. If the diff is empty, tell the user | ||
| and stop. | ||
|
|
||
| ### Step 2: Determine the docs repo location | ||
|
|
||
| Ask the user via `AskUserQuestion` where the documentation lives: | ||
|
|
||
| - **Same repo, subfolder** — User provides the subfolder path (e.g., `docs/`) | ||
| - **Separate repo** — User provides a repo URL or local path; clone it if needed | ||
| - **Current directory** — Documentation is in the current working directory | ||
|
|
||
| Navigate to the docs location and record the path. All subsequent skills | ||
| operate relative to this docs root. | ||
|
|
||
| ### Step 3: Confirm setup and ask for next step | ||
|
|
||
| Summarize the setup to the user: | ||
| - Code change source and diff size (number of files changed) | ||
| - Docs location and number of doc files found | ||
|
|
||
| Then **you MUST use `AskUserQuestion`** to present the next step options. | ||
| Do NOT use a plain text question — `AskUserQuestion` triggers platform | ||
| notifications so the user knows you need input. Plain text questions do | ||
| not create these signals and the user may not see them. | ||
|
|
||
| ## How to Execute a Phase | ||
|
|
||
| 1. **Announce** the phase to the user before doing anything else. | ||
| 2. **Run** the skill for the current phase. | ||
| 3. When the skill completes, present the results and use "Recommending Next | ||
| Steps" below to offer options. | ||
| 4. **Use `AskUserQuestion` to get the user's decision.** Present the | ||
| recommended next step and alternatives as options. Do NOT continue until the | ||
| user responds. This is a hard gate — the `AskUserQuestion` tool triggers | ||
| platform notifications so the user knows you need their input. Plain-text | ||
| questions do not create these signals. | ||
|
|
||
| ## Recommending Next Steps | ||
|
|
||
| After each phase completes, present the user with **options** — not just one | ||
| next step. | ||
|
|
||
| ### Typical Flow | ||
|
|
||
| ```text | ||
| setup → review → (user selects files) → update → pr | ||
| ``` | ||
|
|
||
| ### What to Recommend | ||
|
|
||
| **After Setup — present these options via `AskUserQuestion`:** | ||
| - Review (recommended) — discover affected doc files | ||
| - If the docs location has 10+ folders and no `.doc-index/` exists, | ||
| mention that the user can run `/index` first to build semantic indexes | ||
| for faster discovery in future runs | ||
|
|
||
| **After Review:** | ||
| - Recommend Update to apply the proposed changes | ||
| - Offer to adjust the file selection first | ||
|
|
||
| **After Update:** | ||
| - Recommend Open PR to submit the changes | ||
| - Offer to stop here if the user handles PRs manually | ||
|
|
||
| **After PR:** | ||
| - The workflow is complete. Summarize what was done. | ||
|
|
||
| ## Passing Context to Skills | ||
|
|
||
| When invoking skills, provide the following context: | ||
|
|
||
| - **Discovery skill**: The diff content and the docs root path | ||
| - **Generation skill**: The diff content, the docs root path, and the list of | ||
| selected files from the discovery phase. Specify the mode: preview for | ||
| Review, apply for Update | ||
| - **PR skill**: Invoke after changes are written to disk. Use branch prefix | ||
| `docs/` and conventional commit format `docs(scope): description` | ||
|
|
||
| ## Rules | ||
|
|
||
| - **Never auto-advance.** Always use `AskUserQuestion` and wait for the user's | ||
| response between phases. This is the single most important rule. If you | ||
| proceed to another phase without the user's explicit go-ahead, the workflow | ||
| is broken. | ||
| - **Recommendations come from this file, not from skills.** Skills report | ||
| findings; this controller decides what to recommend next. | ||
| - **Track which directory you are in.** The code and docs may live in | ||
| separate repos or in the same repo (e.g., a `docs/` subfolder). Always | ||
| know which location you are in before running commands. |
157 changes: 157 additions & 0 deletions
157
workflows/docs-updater/.claude/skills/discovery/SKILL.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| --- | ||
| name: discovery | ||
| description: Find documentation files that need updates based on code changes. Default mode uses identifier matching and grep. Optional semantic indexing for large repos. | ||
| --- | ||
|
|
||
| # Documentation Discovery | ||
|
|
||
| Given a code diff and a docs repository, identify which documentation files | ||
| need updating based on the code changes. | ||
|
|
||
| ## Modes | ||
|
|
||
| - **Discovery mode** (default): Find files that need updating using identifier | ||
| matching and grep — no setup required, works immediately | ||
| - **Index-assisted mode**: If semantic indexes exist (`.doc-index/`), use them | ||
| for faster discovery on large repos | ||
|
|
||
| Index building is handled by the `/index` command, not this skill. | ||
|
|
||
| ## Discovery Process (Default — No Indexes) | ||
|
|
||
| Follow these steps in order. Do not skip steps. | ||
|
|
||
| ### Step 1: Receive the diff and changed file list | ||
|
|
||
| Use the diff provided by the controller. Record the list of changed files: | ||
|
|
||
| ```bash | ||
| git diff --name-only <base>...<head> | ||
| ``` | ||
|
|
||
| If no changes can be identified, stop and report. | ||
|
|
||
| ### Step 2: Build the identifier checklist | ||
|
|
||
| Go through **every** changed file in the diff. For each file, extract | ||
| identifiers from the modified lines (lines starting with `+` or `-`) and | ||
| from diff hunk headers (`@@` lines). | ||
|
|
||
| Identifiers to extract: | ||
| - Function and method names | ||
| - Class and type names | ||
| - CLI flag names and configuration keys | ||
| - API endpoint paths | ||
| - Constants and variable names that appear in public interfaces | ||
|
|
||
| Use the most specific form of each identifier. Full function names, CLI | ||
| flags, and config keys are good — they match only relevant docs. Avoid | ||
| short generic words that would match hundreds of unrelated files. | ||
|
|
||
| Write them as a numbered checklist — one entry per changed file, with all | ||
| identifiers from that file. **Do not skip files.** Every changed file gets | ||
| an entry. This checklist is your contract — you will search docs for every | ||
| identifier on it. | ||
|
|
||
| ### Step 3: Discover documentation files | ||
|
|
||
| Find all text-based documentation files in the docs location: | ||
|
|
||
| ```bash | ||
| find {docs_root} -type f \( -name "*.md" -o -name "*.adoc" -o -name "*.rst" \ | ||
| -o -name "*.txt" -o -name "*.html" -o -name "*.yaml" -o -name "*.yml" \) \ | ||
| ! -path "*/.git/*" ! -path "*/.doc-index/*" ! -path "*/node_modules/*" | ||
| ``` | ||
|
|
||
| If the location has no documentation files, produce zero findings and stop. | ||
|
|
||
| ### Step 4: Search docs for every identifier | ||
|
|
||
| Write a shell script that greps for each identifier across the documentation | ||
| files. Run it in a single Bash call: | ||
|
|
||
| ```bash | ||
| for id in "identifier1" "identifier2" "identifier3"; do | ||
| matches=$(grep -rFl "$id" {docs_root} --include="*.md" --include="*.adoc" --include="*.rst" --include="*.txt" --include="*.html" --include="*.yaml" --include="*.yml" 2>/dev/null) | ||
| if [ -n "$matches" ]; then | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| echo "MATCH: $id -> $matches" | ||
| fi | ||
| done | ||
| ``` | ||
|
|
||
| Include **every** identifier from the checklist. No identifiers are skipped. | ||
|
|
||
| From the output, collect all matched doc files into a candidate list. | ||
|
|
||
| Exclude from the candidate list: | ||
| - Documentation files already modified in the same diff — those are being | ||
| actively updated | ||
| - Auto-generated files — look for markers like "DO NOT EDIT", "generated by", | ||
| or "auto-generated" in the first few lines of the file, or check if a | ||
| generator script in the repo produces these files | ||
|
|
||
| ### Step 5: Evaluate candidates (two passes) | ||
|
|
||
| **Pass 1 — Quick scan.** For each candidate doc file from step 4, view | ||
| only the lines that matched (use `grep -n` to see them in context). Based | ||
| on the matching lines alone, decide whether the doc might be stale: | ||
|
|
||
| ```text | ||
| - path/to/doc.md → possibly stale (describes behavior that changed) | ||
| - path/to/other.md → not stale (mentions identifier in passing) | ||
| - path/to/another.md → not stale (changelog entry, historical) | ||
| ``` | ||
|
|
||
| Every candidate must have a verdict. Do not skip candidates. | ||
|
|
||
| **Pass 2 — Deep read.** For each candidate marked "possibly stale" in | ||
| pass 1, read the relevant sections of the file alongside the corresponding | ||
| part of the diff. Confirm whether the doc is actually stale. | ||
|
|
||
| When evaluating: | ||
| - **Only flag docs whose content is now incorrect.** A doc that mentions | ||
| an identifier is not stale if the described behavior is unchanged. | ||
| - **Do not flag changelog entries or release notes** that describe past | ||
| releases — historical entries are not stale. | ||
| - **Do not flag docs about a different component** that happens to share | ||
| an identifier name. | ||
|
|
||
| ### Step 6: Present results | ||
|
|
||
| For each confirmed stale doc, present to the user: | ||
|
|
||
| - File path | ||
| - What is stale and why (reference the specific code change) | ||
| - What should be updated | ||
|
|
||
| Use `AskUserQuestion` to let the user confirm or modify the selection. | ||
| Present files as options the user can accept or reject individually. | ||
|
|
||
| ## Index-Assisted Discovery (Optional — For Large Repos) | ||
|
|
||
| If `.doc-index/` exists in the docs location, use it for faster discovery. | ||
|
|
||
| ### How it works | ||
|
|
||
| 1. Read all `{docs_root}/.doc-index/*.index.md` files | ||
| 2. Read the code diff | ||
| 3. For each index, determine: would documentation in this area become | ||
| incorrect based on this diff? Use the "Code Changes That Would Require | ||
| Documentation Updates" and "Key Technical Concepts" sections to decide | ||
| 4. Only folders that pass this check proceed — the rest are skipped entirely | ||
| 5. For the relevant folders, use the "Files Summary" section of the index | ||
| to identify which specific files are likely affected — do NOT read all | ||
| files in the folder. Only read the files whose summary suggests they | ||
| document the changed behavior | ||
| 6. Present results to the user (same as Step 6 of the default mode) | ||
|
|
||
| ### When to suggest indexing | ||
|
|
||
| After completing discovery in default mode, if the docs location has 10+ | ||
| folders, suggest running the `/index` command to build indexes and | ||
| committing them to speed up future runs. | ||
|
|
||
| ## Output | ||
|
|
||
| Return the list of selected file paths (confirmed by the user) to the | ||
| controller for the generation phase. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.