diff --git a/.github/workflows/build-docs-map.yml b/.github/workflows/build-docs-map.yml new file mode 100644 index 000000000..c690afb42 --- /dev/null +++ b/.github/workflows/build-docs-map.yml @@ -0,0 +1,44 @@ +name: Build Docs Map + +on: + workflow_run: + workflows: ["Update Claude Code Documentation"] + types: [completed] + workflow_dispatch: + push: + branches: [main] + paths: + - 'scripts/build_docs_map.py' + - 'docs/**/*.md' + +permissions: + contents: write + +jobs: + build-map: + if: github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: main + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Build docs map + run: python scripts/build_docs_map.py + + - name: Commit if changed + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + if [[ -n "$(git status --porcelain docs/DOCS_MAP.md)" ]]; then + git add docs/DOCS_MAP.md + git commit -m "Update DOCS_MAP.md - $(date +'%Y-%m-%d')" + git push + else + echo "No changes to DOCS_MAP.md" + fi diff --git a/.gitignore b/.gitignore index 729571015..6179884fe 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ Thumbs.db .last_check claude-docs-helper.sh +# User-generated query outputs (created by /query feature) +/query/ + # Test files test_*.txt test_*.md diff --git a/CLAUDE.md b/CLAUDE.md index 4e2ca390a..d3cf4ca70 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,14 @@ When responding to /docs commands: 2. Read documentation files from the docs/ directory only 3. Use the manifest to know available topics +## For /query Command + +When responding to /query commands: +1. Invoke the `query-orchestrator` skill via the Skill tool +2. Follow the skill's 7-step procedure (parse → task ID → folder → template → batch dispatch → assemble → summary) +3. Subagents read from docs/ folder via DOCS_MAP.md +4. Outputs accumulate in ~/.claude-code-docs/query/ + ## Files to ultrathink about @install.sh @@ -20,3 +28,5 @@ When responding to /docs commands: @claude-docs-helper.md @scripts/ @.github/workflows/ +@docs/DOCS_MAP.md +@claude-files/ diff --git a/README.md b/README.md index 17725df8f..ede1a8d2b 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,19 @@ The changelog feature fetches the latest release notes directly from the officia /docs uninstall # Get commnd to remove claude-code-docs completely ``` +### Multi-question research with /query + +`/query` parses your input into sub-questions, dispatches research subagents in batches of 3 in parallel, and assembles a structured answer file. + +```bash +/query What is a hook? # single question +/query Explain hooks and MCP, then compare them # multi-part +/query 1. ... 2. ... 3. ... # explicit numbering +``` + +Each query produces a folder under `~/.claude-code-docs/query/QUERY-TASK--/` +containing the full structured answer with citations. Useful for non-trivial questions that span multiple docs. + ### Customize command name If you prefer a different command name (e.g., `/claude-docs` instead of `/docs`), you can easily customize it: diff --git a/claude-files/agents/query-researcher.md b/claude-files/agents/query-researcher.md new file mode 100644 index 000000000..b7375649f --- /dev/null +++ b/claude-files/agents/query-researcher.md @@ -0,0 +1,90 @@ +--- +name: query-researcher +description: Research a single sub-question by reading Claude Code documentation files and producing a structured answer file +tools: Read, Grep, Glob, Write, Bash +--- + +# Query Researcher + +You research ONE sub-question. You read the docs map, pick 2-5 relevant files, read them, then write a structured answer to a specific file path. + +## Input (provided in your prompt) + +The orchestrator gives you these fields: + +- `Task: ` — the parent task identifier +- `Query ID: [QUERY-N]` — your specific query slot +- `Question:` — the actual question text +- `Output file:` — exact path where you write the answer +- `Docs map:` — path to DOCS_MAP.md +- `Docs folder:` — path to the docs directory + +## Procedure + +### Step 1 — Pick relevant docs (max 5) + +Read the docs map with the Read tool. Match the question against entries via: + +- Title overlap +- Summary overlap +- Keyword overlap (each entry lists TF-IDF keywords) + +Prefer specific files over general ones (e.g., `hooks.md` over `overview.md` for a hooks question). If the question is broad with no specific match, pick 1 general + 2 specific. + +You may use Grep to find term-specific matches: + +```bash +grep -l "specific-term" ~/.claude-code-docs/docs/*.md | head -5 +``` + +### Step 2 — Read selected docs + +Use the Read tool on each selected file. **Hard cap: 5 files.** If a file you're reading references another that's clearly more relevant, swap rather than add. + +### Step 3 — Synthesize an answer + +Build an answer that: + +- Directly answers the question +- Cites which docs you used +- Quotes short relevant excerpts +- Is 200-500 words typical (longer only if necessary) +- Notes gaps or ambiguities when docs don't fully cover the question + +### Step 4 — Write the output file + +Use the Write tool to create the output file at the path provided in your input. Use this EXACT structure: + +```markdown +# Answer to [QUERY-N] + +**Question:** +**Task:** + +## Researched files + +- `docs/file1.md` — why relevant +- `docs/file2.md` — why relevant + +## Answer + + + +## Source excerpts + +> Short relevant quote from `file1.md` + +> Short relevant quote from `file2.md` + +## Notes + + +``` + +## Constraints + +- Read AT MOST 5 docs +- Write EXACTLY ONE output file (path given in input) +- Do NOT call other subagents (no Task tool) +- Do NOT fetch from the web (use only the local docs folder) +- If no docs match the question, write the output file with `## Answer\n_No matching documentation found for this question. Suggested related topics: ..._` diff --git a/claude-files/commands/query.md b/claude-files/commands/query.md new file mode 100644 index 000000000..10d3038ec --- /dev/null +++ b/claude-files/commands/query.md @@ -0,0 +1,10 @@ +--- +description: Research Claude Code documentation by batching multi-question queries to specialized subagents +argument-hint: +--- + +The user has invoked /query with the following input: + +$ARGUMENTS + +Use the Skill tool to invoke the `query-orchestrator` skill. Pass the user query above as the skill's argument. Follow the skill's instructions exactly. diff --git a/claude-files/skills/query-orchestrator/SKILL.md b/claude-files/skills/query-orchestrator/SKILL.md new file mode 100644 index 000000000..ce616b6a4 --- /dev/null +++ b/claude-files/skills/query-orchestrator/SKILL.md @@ -0,0 +1,164 @@ +--- +name: query-orchestrator +description: Use when handling /query slash command — parses multi-part questions, dispatches batched subagents to research docs, and assembles final answer +--- + +# Query Orchestrator + +You orchestrate research on Claude Code documentation when the user invokes `/query`. You decompose the user's input into sub-questions, dispatch a `query-researcher` subagent for each in batches of 3 parallel, and assemble all answers into a single output file. + +## Inputs + +The slash command passes the user's raw query as your argument. Examples: + +- "What are hooks?" (single question, N=1) +- "Explain hooks and MCP, and how to integrate them" (3 sub-questions) +- "1. ... 2. ... 3. ..." (explicit numbering) + +## Step-by-step procedure + +### Step 1 — Parse into sub-questions + +Identify each independent factual sub-question in the user's input. A sub-question is something a researcher could answer alone by reading docs. + +Rules: + +- One cohesive question → N = 1 +- Explicit numbering (1./2./3. or bullets) → follow numbering +- Independent parts joined by a coordinating conjunction (e.g., `and`, `or`) → split, but only if each part is independently answerable from docs +- Trim and normalize each sub-question to a clear standalone form + +Output internally: + +SUB_QUESTIONS = [ + "What are hooks?", + "What is MCP?", + "How to integrate hooks with MCP?" +] +N = 3 + +### Step 2 — Generate task ID + +- Take the first sub-question's most discriminative content word, skipping stopwords (`the`, `a`, `what`, `how`, `is`, `does`). +- Lowercase, ASCII-normalize, slugify. +- If no content word can be identified (e.g., "How does it work?"), use the literal keyword `query`. +- Append current epoch milliseconds via Bash: `date +%s%3N`. +- Format: `QUERY-TASK--`. +- Example: `QUERY-TASK-hooks-1715432100123`. + +### Step 3 — Create task folder + +Use the Bash tool: + + mkdir -p ~/.claude-code-docs/query/ + +### Step 4 — Write initial query.md + +Use the Write tool to create `~/.claude-code-docs/query//query.md` from this template (substitute placeholders): + + # Query Task: + + **Original user query:** + > + + **Created at:** + **Number of sub-questions:** + **Status:** in-progress + + --- + + ## [QUERY-1] — + + **Question:** + + **Answer:** + + _pending — researcher dispatched_ + + + --- + + ## [QUERY-2] — + + **Question:** + + **Answer:** + + _pending — researcher dispatched_ + + + --- + + + +`SHORT_TITLE_n` is a 3-5 word descriptor you derive from the sub-question (e.g., "What are hooks?" → "Hooks definition"). + +### Step 5 — Dispatch subagents in batches of 3 + +**CRITICAL:** All Task tool calls in one batch MUST be sent in a SINGLE message to execute in parallel. If you send them in separate messages they will execute sequentially. + +Batching table: + +| N | Batches | +|----|--------------| +| 1 | [1] | +| 2 | [2] | +| 3 | [3] | +| 4 | [3, 1] | +| 5 | [3, 2] | +| 6 | [3, 3] | +| 7 | [3, 3, 1] | +| 15 | [3, 3, 3, 3, 3] | + +General rule: `ceil(N/3)` batches; first floor(N/3) batches have 3 calls each; final batch has N mod 3 calls (or 3 if N is a multiple of 3). + +For each batch of up to 3 consecutive sub-questions: + +1. In a SINGLE message, issue up to 3 parallel Task tool calls. +2. Each Task call uses `subagent_type: query-researcher`. +3. Wait for ALL calls in the batch to return before starting the next batch. + +Each Task call prompt MUST contain these exact fields: + + Task: + Query ID: [QUERY-N] + Question: + Output file: ~/.claude-code-docs/query//QUERY-.md + Docs map: ~/.claude-code-docs/docs/DOCS_MAP.md + Docs folder: ~/.claude-code-docs/docs/ + +### Step 6 — Assemble answers into final query.md + +After ALL batches complete: + +1. Issue parallel Read calls for every `QUERY-N.md` (single message, N Read tool calls). +2. For each file, extract everything below the H1 header (`# Answer to [QUERY-N]`) — this is the answer body. +3. Build the complete final `query.md` in memory: header (TASK_ID, original query, timestamp, N, `Status: complete`), then for each [QUERY-N] the question text plus the extracted body (replacing the `_pending_` placeholder). +4. Single Write call overwrites `query.md` with the complete assembled content. + +If a `QUERY-N.md` is missing (subagent failed): + +- Insert: `_⚠️ Researcher did not complete this query. Re-run `/query` for just this question._` in place of the answer body. + +### Step 7 — Chat summary + +Output to chat: + + ✓ Query complete: ( questions) + + • [QUERY-1] + • [QUERY-2] + • ... + + Full details: ~/.claude-code-docs/query//query.md + +Keep each bullet to one line. Do not paste the full answers in chat. + +## Failure handling + +| Failure | Handling | +|---------|----------| +| `mkdir` fails | Abort with error message; do not dispatch subagents | +| DOCS_MAP.md missing | Tell user to re-run `~/.claude-code-docs/install.sh` | +| Subagent returns no file | Insert warning placeholder for that query; continue with others | +| Parsing yields N=0 | Ask user to rephrase the query | diff --git a/docs/DOCS_MAP.md b/docs/DOCS_MAP.md new file mode 100644 index 000000000..d165d4446 --- /dev/null +++ b/docs/DOCS_MAP.md @@ -0,0 +1,670 @@ +# Docs Map + +> Auto-generated by `scripts/build_docs_map.py` on 2026-05-12 02:50 UTC +> 131 files indexed. + +Used by the `/query` skill to identify relevant docs for a given question. +Each entry shows the file, its title, a short summary, and discriminative keywords. + +--- + +## Agent SDK + +### `agent-sdk__agent-loop.md` +**Title:** How the agent loop works +**Summary:** The Agent SDK lets you embed Claude Code's autonomous agent loop in your own applications. The SDK is a standalone package that gives you programmatic control over tools, permissions, cost limits, and... +**Keywords:** message-types, yields, loop, agent-sdk, sdk, typescript, turns, final + +### `agent-sdk__claude-code-features.md` +**Title:** Use Claude Code features in the SDK +**Summary:** The Agent SDK is built on the same foundation as Claude Code, which means your SDK agents have access to the same filesystem-based features: project instructions ( and rules), skills, hooks, and more. +**Keywords:** skills, sdk, agent, hooks, loads, callbacks, settingsource, agent-sdk + +### `agent-sdk__cost-tracking.md` +**Title:** Track cost and usage +**Summary:** The Claude Agent SDK provides detailed token usage information for each interaction with Claude. This guide explains how to properly track usage and understand cost reporting, especially when dealing ... +**Keywords:** per-step, cost, agent-sdk, cache, typescript, ttl, total, python + +### `agent-sdk__custom-tools.md` +**Title:** Give Claude custom tools +**Summary:** Custom tools extend the Agent SDK by letting you define your own functions that Claude can call during a conversation. Using the SDK's in-process MCP server, you can give Claude access to databases, e... +**Keywords:** handler, built-ins, weather, python, tool, agent-sdk, dict, typescript + +### `agent-sdk__file-checkpointing.md` +**Title:** Rewind file changes with checkpointing +**Summary:** File checkpointing tracks file modifications made through the Write, Edit, and NotebookEdit tools during an agent session, allowing you to rewind files to any previous state. +**Keywords:** checkpoint, rewind, uuids, checkpointing, uuid, utility, stream, restore + +### `agent-sdk__hooks.md` +**Title:** Intercept and control agent behavior with hooks +**Summary:** Hooks are callback functions that run your code in response to agent events, like a tool being called, a session starting, or execution stopping. With hooks, you can: +**Keywords:** yes, hook, callback, hooks, matcher, matchers, python, event + +### `agent-sdk__hosting.md` +**Title:** Hosting the Agent SDK +**Summary:** The Claude Agent SDK differs from traditional stateless LLM APIs in that it maintains conversational state and executes commands in a persistent environment. +**Keywords:** container, hosting, containers, sandbox, sdk, isolation, simulations, ephemeral + +### `agent-sdk__mcp.md` +**Title:** Connect to external tools with MCP +**Summary:** The Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources. With MCP, your agent can query databases, integrate with APIs like Slack and GitHub, a... +**Keywords:** server, mcp, sse, transport, connection, servers, database, stdio + +### `agent-sdk__migration-guide.md` +**Title:** Migrate to Claude Agent SDK +**Summary:** The Claude Code SDK has been renamed to the Claude Agent SDK and its documentation has been reorganized. This change reflects the SDK's broader capabilities for building AI agents beyond just coding t... +**Keywords:** sdk, migration, imports, package, changed, python, migrating, renamed + +### `agent-sdk__modifying-system-prompts.md` +**Title:** Modifying system prompts +**Summary:** System prompts define Claude's behavior, capabilities, and response style. The Claude Agent SDK provides three ways to customize system prompts: using output styles (persistent, file-based configurati... +**Keywords:** styles, preset, style, standards, append, guidelines, team-shared, system + +### `agent-sdk__observability.md` +**Title:** Observability with OpenTelemetry +**Summary:** When you run agents in production, you need visibility into what they did: +**Keywords:** span, telemetry, collector, traces, attributes, spans, opentelemetry, exports + +### `agent-sdk__overview.md` +**Title:** Agent SDK overview +**Summary:** The Claude Code SDK has been renamed to the Claude Agent SDK. If you're migrating from the old SDK, see the Migration Guide. +**Keywords:** sdk, agent, branding, agents, license, typescript, product, changelog + +### `agent-sdk__permissions.md` +**Title:** Configure permissions +**Summary:** The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what's allowed automatically, and the callback to handle everything else at ... +**Keywords:** deny, rules, approves, permission, approvals, mode, modes, declarative + +### `agent-sdk__plugins.md` +**Title:** Plugins in the SDK +**Summary:** Plugins allow you to extend Claude Code with custom functionality that can be shared across projects. Through the Agent SDK, you can programmatically load plugins from local directories to add custom ... +**Keywords:** plugins, plugin, slash, paths, specifications, skills, relative, loading + +### `agent-sdk__python.md` +**Title:** Agent SDK reference - Python +**Summary:** The Python SDK provides two ways to interact with Claude Code: +**Keywords:** identifier, description, type, hook, input, unique, union, parameters + +### `agent-sdk__quickstart.md` +**Title:** Quickstart +**Summary:** Use the Agent SDK to build an AI agent that reads your code, finds bugs, and fixes them, all without manual intervention. +**Keywords:** agent, bugs, sdk, buggy, python, aws, typescript, azure + +### `agent-sdk__secure-deployment.md` +**Title:** Securely deploying AI agents +**Summary:** Claude Code and the Agent SDK are powerful tools that can execute code, access files, and interact with external services on your behalf. +**Keywords:** proxy, kernel, gvisor, container, traffic, credentials, isolation, agent + +### `agent-sdk__sessions.md` +**Title:** Work with sessions +**Summary:** A session is the conversation history the SDK accumulates while your agent works. It contains your prompt, every tool call the agent made, every tool result, and every response. +**Keywords:** agent-sdk, python, typescript, resume, fork, capture, session, original + +### `agent-sdk__skills.md` +**Title:** Agent Skills in the SDK +**Summary:** Agent Skills extend Claude with specialized capabilities that Claude autonomously invokes when relevant. Skills are packaged as files containing instructions, descriptions, and optional supporting res... +**Keywords:** skills, skill, sdk, discovered, authoring, filesystem, invokes, loaded + +### `agent-sdk__slash-commands.md` +**Title:** Slash Commands in the SDK +**Summary:** Slash commands provide a way to control Claude Code sessions with special commands that start with . These commands can be sent through the SDK to perform actions like compacting context, listing cont... +**Keywords:** slash, sdk, commands, placeholders, legacy, designated, create, custom + +### `agent-sdk__streaming-output.md` +**Title:** Stream responses in real-time +**Summary:** By default, the Agent SDK yields complete objects after Claude finishes generating each response. To receive incremental updates as text and tool calls are generated, enable partial message streaming ... +**Keywords:** streaming, stream, chunks, incremental, text, partial, responses, real-time + +### `agent-sdk__streaming-vs-single-mode.md` +**Title:** Streaming Input +**Summary:** The Claude Agent SDK supports two distinct input modes for interacting with agents: +**Keywords:** input, streaming, operate, attachments, one-shot, experiences, lived, lambda + +### `agent-sdk__structured-outputs.md` +**Title:** Get structured output from agents +**Summary:** Structured outputs let you define the exact shape of data you want back from an agent. The agent can use any tools it needs to complete the task, and you still get validated JSON matching your schema ... +**Keywords:** schema, structured, pydantic, outputs, zod, validated, json, schemas + +### `agent-sdk__subagents.md` +**Title:** Subagents in the SDK +**Summary:** Subagents are separate agent instances that your main agent can spawn to handle focused subtasks. Use subagents to isolate context for focused subtasks, run multiple analyses in parallel, and apply sp... +**Keywords:** subagent, subagents, agent, filesystem-based, parent, main, defining, code-reviewer + +### `agent-sdk__todo-tracking.md` +**Title:** Todo Lists +**Summary:** Todo tracking provides a structured way to manage tasks and display progress to users. The Claude Agent SDK includes built-in todo functionality that helps organize complex workflows and keep users in... +**Keywords:** todo, todos, progression, non-trivial, progress, display, informed, predictable + +### `agent-sdk__tool-search.md` +**Title:** Scale to many tools with tool search +**Summary:** Tool search enables your agent to work with hundreds or thousands of tools by dynamically discovering and loading them on demand. +**Keywords:** search, definitions, tool, exceed, activates, loading, upfront, scale + +### `agent-sdk__typescript-v2-preview.md` +**Title:** TypeScript SDK V2 session API (deprecated) +**Summary:** The V2 session API functions , , and are deprecated and will be removed in a future release. Use the V1 API instead. +**Keywords:** multi-turn, generator, cleanup, math, typescriptlang, handbook, typescript-5-2, using-declarations-and-explicit-resource-management + +### `agent-sdk__typescript.md` +**Title:** Agent SDK reference - TypeScript +**Summary:** (no summary available) +**Keywords:** emitted, returns, sandbox, tool, description, name, type, parameters + +### `agent-sdk__user-input.md` +**Title:** Handle approvals and user input +**Summary:** While working on a task, Claude sometimes needs to check in with users. It might need permission before deleting files, or need to ask which database to use for a new project. +**Keywords:** callback, questions, clarifying, input, question, selections, array, choices + +## Weekly Updates + +### `whats-new__2026-w13.md` +**Title:** Week 13 · March 23–27, 2026 +**Summary:** Releases v2.1.83 → v2.1.85 6 features · March 23–27 +**Keywords:** auto-fix, interrupting, march, powershell, computer, auto, now, transcript + +### `whats-new__2026-w14.md` +**Title:** Week 14 · March 30 – April 3, 2026 +**Summary:** Releases v2.1.86 → v2.1.91 5 features · March 30 – April 3 +**Keywords:** powerup, computer, result-size, bin, april, march, apps, flicker + +### `whats-new__2026-w15.md` +**Title:** Week 15 · April 6–10, 2026 +**Summary:** Releases v2.1.92 → v2.1.101 4 features · April 6–10 +**Keywords:** autofix-pr, auto-fix, team-onboarding, now, ultraplan, mantle, monitor, april + +### `whats-new__2026-w16.md` +**Title:** Week 16 · April 13–17, 2026 +**Summary:** Releases v2.1.105 → v2.1.113 5 features · April 13–17 +**Keywords:** now, mobile, xhigh, ping, tui, effort, driving, push + +### `whats-new__2026-w17.md` +**Title:** Week 17 · April 20–24, 2026 +**Summary:** Releases v2.1.114 → v2.1.119 4 features · April 20–24 +**Keywords:** themes, theme, ultrareview, recap, redesigned, now, april, color + +### `whats-new__2026-w18.md` +**Title:** Week 18 · April 27 – May 1, 2026 +**Summary:** Releases v2.1.120 → v2.1.126 4 features · April 27 – May 1 +**Keywords:** now, picker, purge, net, prune, localhost, gateway, callback + +### `whats-new__2026-w19.md` +**Title:** Week 19 · May 4–8, 2026 +**Summary:** Releases v2.1.128 → v2.1.136 2 features · May 4–8 +**Keywords:** zip, head, now, unconditionally, archives, ctrl, worktrees, longer + +## General + +### `admin-setup.md` +**Title:** Set up Claude Code for your organization +**Summary:** Claude Code enforces organization policy through managed settings that take precedence over local developer configuration. +**Keywords:** managed, seat, posture, server-managed, registry, provider, compliance, policy + +### `agent-teams.md` +**Title:** Orchestrate teams of Claude Code sessions +**Summary:** Agent teams are experimental and disabled by default. Enable them by adding to your settings.json or environment. Agent teams have known limitations around session resumption, task coordination, and s... +**Keywords:** teammates, lead, teammate, coordination, teams, team, tmux, in-process + +### `agent-view.md` +**Title:** Manage multiple agents with agent view +**Summary:** Agent view, opened with , is one screen for all your background sessions: what's running, what needs your input, and what's done. +**Keywords:** peek, supervisor, attach, view, dispatch, row, agent, press + +### `agents.md` +**Title:** Run agents in parallel +**Summary:** Subagents, agent view, agent teams, and worktrees each parallelize work in a different way. The right one depends on whether you want to stay in each conversation yourself, hand tasks off and check ba... +**Keywords:** workers, subagents, worktrees, view, assign, teams, agent, coordinates + +### `amazon-bedrock.md` +**Title:** Claude Code on Amazon Bedrock +**Summary:** (no summary available) +**Keywords:** mantle, aws, bedrock, inference, profile, iam, model, sso + +### `analytics.md` +**Title:** Track team usage with analytics +**Summary:** Claude Code provides analytics dashboards to help organizations understand developer usage patterns, track contribution metrics, and measure how Claude Code impacts engineering velocity. +**Keywords:** metrics, contribution, prs, lines, analytics, adoption, dashboard, daily + +### `authentication.md` +**Title:** Authentication +**Summary:** Claude Code supports multiple authentication methods depending on your setup. Individual users can log in with a Claude.ai account, while teams can use Claude for Teams or Enterprise, the Claude Conso... +**Keywords:** teams, credentials, invite, console, log, invited, authentication, browser + +### `auto-mode-config.md` +**Title:** Configure auto mode +**Summary:** Auto mode lets Claude Code run without permission prompts by routing each tool call through a classifier that blocks anything irreversible, destructive, or aimed outside your environment. +**Keywords:** classifier, rules, buckets, trusted, intent, exceptions, soft, exfiltration + +### `best-practices.md` +**Title:** Best practices for Claude Code +**Summary:** Claude Code is an agentic coding environment. Unlike a chatbot that answers questions and waits, Claude Code can read your files, run commands, make changes, and autonomously work through problems whi... +**Keywords:** irrelevant, context, exploration, sometimes, something, interview, questions, unrelated + +### `champion-kit.md` +**Title:** Champion kit +**Summary:** This page is for individual engineers who are already using Claude Code and want to help their team adopt it. It covers what to share, how to answer the questions you will get, a thirty-day playbook, ... +**Keywords:** person, colleagues, champion, channel, people, answer, colleague, engineers + +### `changelog.md` +**Title:** Changelog +**Summary:** This page is generated from the CHANGELOG.md on GitHub. +**Keywords:** fixed, improved, now, added, vscode, anthropics, failing, showing + +### `channels-reference.md` +**Title:** Channels reference +**Summary:** Channels are in research preview and require Claude Code v2.1.80 or later. Team and Enterprise organizations must explicitly enable them. +**Keywords:** channel, relay, reply, verdict, constructor, sender, two-way, channels + +### `channels.md` +**Title:** Push events into a running session with channels +**Summary:** Channels are in research preview and require Claude Code v2.1.80 or later. They require Anthropic authentication through claude. +**Keywords:** channels, bot, channel, fakechat, telegram, discord, imessage, replies + +### `checkpointing.md` +**Title:** Checkpointing +**Summary:** Claude Code automatically tracks Claude's file edits as you work, allowing you to quickly undo changes and rewind to previous states if anything gets off track. +**Keywords:** checkpoints, summarize, rewind, undo, revert, restore, knowing, compress + +### `chrome.md` +**Title:** Use Claude Code with Chrome (beta) +**Summary:** Claude Code integrates with the Claude in Chrome browser extension to give you browser automation capabilities from the CLI or the VS Code extension. +**Keywords:** chrome, extension, browser, navigates, reconnect, messaging, filling, multi-site + +### `claude-code-on-the-web.md` +**Title:** Use Claude Code on the web +**Summary:** Claude Code on the web is in research preview for Pro, Max, and Team users, and for Enterprise users with premium seats or Chat + Claude Code seats. +**Keywords:** cloud, auto-fix, github, repo, pre-installed, hashicorp, docker, net + +### `claude-directory.md` +**Title:** Explore the .claude directory +**Summary:** Claude Code reads instructions, settings, skills, subagents, and memory from your project directory and from in your home directory. +**Keywords:** global, per-session, delete, memory, project, transcripts, explorer, recall + +### `claude-platform-on-aws.md` +**Title:** Claude Code on Claude Platform on AWS +**Summary:** } /> +**Keywords:** aws, workspace, iam, sigv4, platform, credentials, sso, gateway + +### `cli-reference.md` +**Title:** CLI reference +**Summary:** You can start sessions, pipe content, resume conversations, and manage updates with these commands: +**Keywords:** print, overrides, flag, mode, flags, space-separated, session, append + +### `code-review.md` +**Title:** Code Review +**Summary:** Code Review is in research preview, available for Team and Enterprise subscriptions. It is not available for organizations with Zero Data Retention enabled. +**Keywords:** review, severity, reviews, comment, findings, nit, finding, comments + +### `commands.md` +**Title:** Commands +**Summary:** Commands control Claude Code from inside a session. They provide a quick way to switch models, manage permissions, clear context, run a workflow, and more. +**Keywords:** alias, wizard, color, opens, picker, argument, arrows, free + +### `common-workflows.md` +**Title:** Common workflows +**Summary:** This page collects short recipes for everyday development. For higher-level guidance on prompting and context management, see Best practices. +**Keywords:** suppose, tips, image, refactoring, prs, everyday, recipes, images + +### `communications-kit.md` +**Title:** Communications kit +**Summary:** This page is for administrators and engineering leads rolling Claude Code out to a team. It provides copy-ready launch announcements, a tips-and-tricks drip campaign, and one-line FAQ responses for th... +**Keywords:** announcement, announcements, faq, communications, drip, campaign, launch-day, flaky + +### `computer-use.md` +**Title:** Let Claude use your computer from the CLI +**Summary:** {/ plan-availability: feature=computer-use plans=pro,max /} +**Keywords:** computer, apps, screen, lock, simulator, macos, app, screenshots + +### `context-window.md` +**Title:** Explore the context window +**Summary:** Claude Code's context window holds everything Claude knows about your session: your instructions, the files it reads, its own responses, and content that never appears in your terminal. +**Keywords:** re-injected, timeline, representative, oldest, compaction, project-root, path-scoped, window + +### `costs.md` +**Title:** Manage costs effectively +**Summary:** Claude Code charges by API token consumption. For subscription plan pricing (Pro, Max, Team, Enterprise), see claude.com/pricing. +**Keywords:** tpm, costs, workspace, tokens, teams, token, per, spend + +### `data-usage.md` +**Title:** Data usage +**Summary:** Consumer users (Free, Pro, and Max plans): We give you the choice to allow your data to be used to improve future Claude models. +**Keywords:** data, encryption, retention, rating, partner, transit, surveys, train + +### `debug-your-config.md` +**Title:** Debug your configuration +**Summary:** When Claude ignores an instruction or a feature you configured doesn't appear, the cause is usually that the file didn't load, it loaded from a different location than you expected, or another file ov... +**Keywords:** hook, cause, hooks, never, loaded, doesn, standalone, load + +### `deep-links.md` +**Title:** Launch sessions from links +**Summary:** A deep link is a URL that opens Claude Code in a new terminal window. The URL can carry a working directory and a prompt to pre-fill. +**Keywords:** link, runbook, deep, handler, opens, url, slug, clone + +### `desktop-quickstart.md` +**Title:** Get started with the desktop app +**Summary:** The desktop app gives you Claude Code with a graphical interface built for running multiple sessions side by side: a sidebar for managing parallel work, a drag-and-drop layout with an integrated termi... +**Keywords:** desktop, click, app, button, arrange, diff, dropdown, cowork + +### `desktop-scheduled-tasks.md` +**Title:** Schedule recurring tasks in Claude Code Desktop +**Summary:** Scheduled tasks start a new session automatically at a time and frequency you choose. Use them for recurring work like daily code reviews, dependency update checks, or morning briefings that pull from... +**Keywords:** scheduled, schedule, task, computer, desktop, missed, routines, daily + +### `desktop.md` +**Title:** Use Claude Code Desktop +**Summary:** The Claude Desktop app has three tabs: Chat for conversations, Cowork for Dispatch and longer agentic work, and Code for software development. This page is the reference for the Code tab. +**Keywords:** pane, diff, preview, toolbar, cmd, app, arrange, auto-merge + +### `devcontainer.md` +**Title:** Development containers +**Summary:** A development container, or dev container, lets you define an identical, isolated environment that every engineer on your team can run. +**Keywords:** container, dev, codespaces, dockerfile, mount, containers, volume, rebuild + +### `discover-plugins.md` +**Title:** Discover and install prebuilt plugins through marketplaces +**Summary:** Plugins extend Claude Code with skills, agents, hooks, and MCP servers. Plugin marketplaces are catalogs that help you discover and install these extensions without building them yourself. +**Keywords:** marketplaces, plugins, marketplace, plugin, official, catalog, install, intelligence + +### `env-vars.md` +**Title:** Environment variables +**Summary:** Claude Code supports the following environment variables to control its behavior. Set them in your shell before launching , or configure them in [](/en/settings#available-settings) under the key to ap... +**Keywords:** override, disable, milliseconds, gateway, set, region, vertex, timeout + +### `errors.md` +**Title:** Error reference +**Summary:** This page lists runtime errors Claude Code displays and how to recover from each one, plus what to check when responses seem off without an error. +**Keywords:** errors, network, request, error, usually, retried, raise, stale + +### `fast-mode.md` +**Title:** Speed up responses with fast mode +**Summary:** Fast mode is in research preview. The feature, pricing, and availability may change based on feedback. +**Keywords:** fast, mode, speed, opus, mtok, cooldown, tradeoff, pricing + +### `features-overview.md` +**Title:** Extend Claude Code +**Summary:** Claude Code combines a model that reasons about your code with built-in tools for file operations, search, execution, and web access. The built-in tools cover most coding tasks. +**Keywords:** skill, skills, material, knowledge, loads, aspect, subagents, context + +### `fullscreen.md` +**Title:** Fullscreen rendering +**Summary:** Fullscreen rendering is an opt-in research preview and requires Claude Code v2.1.89 or later. Run to switch in your current conversation, or set on versions before v2.1.110. +**Keywords:** mouse, scroll, tmux, rendering, wheel, fullscreen, scrolling, iterm2 + +### `github-actions.md` +**Title:** Claude Code GitHub Actions +**Summary:** Claude Code GitHub Actions brings AI-powered automation to your GitHub workflow. With a simple mention in any PR or issue, Claude can analyze your code, create pull requests, implement features, and f... +**Keywords:** github, app, identity, secrets, actions, workload, oidc, repository + +### `github-enterprise-server.md` +**Title:** Claude Code with GitHub Enterprise Server +**Summary:** GitHub Enterprise Server support is available for Team and Enterprise plans. +**Keywords:** ghes, instance, marketplaces, github, contribution, admin, hostname, teleport + +### `gitlab-ci-cd.md` +**Title:** Claude Code GitLab CI/CD +**Summary:** Claude Code for GitLab CI/CD is currently in beta. Features and functionality may evolve as we refine the experience. +**Keywords:** gitlab, job, oidc, masked, mrs, iam, federation, bedrock + +### `glossary.md` +**Title:** Glossary +**Summary:** This glossary defines Claude Code terminology. Each entry links to the page where the concept is covered in depth. For model-level concepts like tokens, temperature, and RAG, see the platform glossary... +**Keywords:** learn, glossary, more, skills, agentic, auto, thinking, memory + +### `goal.md` +**Title:** Keep Claude working toward a goal +**Summary:** The command sets a completion condition and Claude keeps working toward it without you prompting each step. After each turn, a small fast model checks whether the condition holds. +**Keywords:** condition, goal, evaluator, met, turn, achieved, judges, evaluation + +### `google-vertex-ai.md` +**Title:** Claude Code on Google Vertex AI +**Summary:** (no summary available) +**Keywords:** vertex, garden, multi-region, gcp, wizard, models, model, region + +### `headless.md` +**Title:** Run Claude Code programmatically +**Summary:** The Agent SDK gives you the same tools, agent loop, and context management that power Claude Code. It's available as a CLI for scripts and CI/CD, or as Python and TypeScript packages for full programm... +**Keywords:** integer, bare, event, string, pipes, structured, scripted, stream + +### `hooks-guide.md` +**Title:** Automate workflows with hooks +**Summary:** Hooks are user-defined shell commands that execute at specific points in Claude Code's lifecycle. They provide deterministic control over Claude Code's behavior, ensuring certain actions always happen... +**Keywords:** hook, hooks, matcher, event, stderr, fires, exit, json + +### `hooks.md` +**Title:** Hooks reference +**Summary:** For a quickstart guide with examples, see Automate workflows with hooks. +**Keywords:** hook, hooks, fields, decision, field, matcher, json, addition + +### `how-claude-code-works.md` +**Title:** How Claude Code works +**Summary:** Claude Code is an agentic assistant that runs in your terminal. While it excels at coding, it can help with anything you can do from the command line: writing docs, running builds, searching files, re... +**Keywords:** agentic, loop, checkpoints, phases, learns, skills, undo, understand + +### `interactive-mode.md` +**Title:** Interactive mode +**Summary:** Keyboard shortcuts may vary by platform and terminal. In fullscreen rendering, press in the transcript viewer to see available shortcuts there. +**Keywords:** word, cursor, shortcut, inner, normal, meta, press, line + +### `jetbrains.md` +**Title:** JetBrains IDEs +**Summary:** Claude Code integrates with JetBrains IDEs through a dedicated plugin, providing features like interactive diff viewing, selection context sharing, and more. +**Keywords:** ide, jetbrains, ides, wsl, wsl2, networking, plugin, restart + +### `keybindings.md` +**Title:** Customize keyboard shortcuts +**Summary:** Customizable keyboard shortcuts require Claude Code v2.1.18 or later. Check your version with . +**Keywords:** ctrl, actions, unbound, shift, action, viewport, down, selection + +### `legal-and-compliance.md` +**Title:** Legal and compliance +**Summary:** Your use of Claude Code is subject to: +**Keywords:** baa, agreements, legal, commercial, zdr, customer, agreement, subject + +### `llm-gateway.md` +**Title:** LLM gateway configuration +**Summary:** LLM gateways provide a centralized proxy layer between Claude Code and model providers, often providing: +**Keywords:** litellm, gateway, pass-through, headers, endpoint, body, proxy, discovery + +### `mcp.md` +**Title:** Connect Claude Code to tools via MCP +**Summary:** (no summary available) +**Keywords:** connect, protocol, learn, tools, via, model, mcp, context + +### `memory.md` +**Title:** How Claude remembers your project +**Summary:** Each Claude Code session begins with a fresh context window. Two mechanisms carry knowledge across sessions: +**Keywords:** memory, instructions, auto, rules, files, subdirectories, loaded, import + +### `microsoft-foundry.md` +**Title:** Claude Code on Microsoft Foundry +**Summary:** (no summary available) +**Keywords:** microsoft, azure, foundry, rbac, resource, entra, portal, models + +### `model-config.md` +**Title:** Model configuration +**Summary:** For the setting in Claude Code, you can configure either: +**Keywords:** opus, model, effort, sonnet, thinking, picker, reasoning, ids + +### `monitoring-usage.md` +**Title:** Monitoring +**Summary:** Track Claude Code usage, costs, and tool activity across your organization by exporting telemetry data through OpenTelemetry (OTel). +**Keywords:** attributes, counter, event, monotonically, metrics, iso, ordering, increasing + +### `network-config.md` +**Title:** Enterprise network configuration +**Summary:** Claude Code supports various enterprise network and security configurations through environment variables. This includes routing traffic through corporate proxy servers, trusting custom Certificate Au... +**Keywords:** certificate, proxy, mozilla, mtls, certificates, authorities, mutual, authentication + +### `output-styles.md` +**Title:** Output styles +**Summary:** Output styles change how Claude responds, not what Claude knows. They modify the system prompt to set role, tone, and output format while keeping core capabilities like running scripts, reading and wr... +**Keywords:** styles, style, output, software, engineering, explanatory, system, tone + +### `overview.md` +**Title:** Claude Code overview +**Summary:** Claude Code is an AI-powered coding assistant that helps you build features, fix bugs, and automate development tasks. It understands your entire codebase and can work across multiple files and tools ... +**Keywords:** desktop, cmd, kick, powershell, installations, automate, ios, windows + +### `permission-modes.md` +**Title:** Choose a permission mode +**Summary:** When Claude wants to edit a file, run a shell command, or make a network request, it pauses and asks you to approve the action. Permission modes control how often that pause happens. +**Keywords:** classifier, auto, mode, plan, protected, cycle, meets, action + +### `permissions.md` +**Title:** Configure permissions +**Summary:** Claude Code supports fine-grained permissions so that you can specify exactly what the agent is allowed to do and what it cannot. +**Keywords:** rule, rules, matches, compound, deny, managed, symlink, permission + +### `platforms.md` +**Title:** Platforms and integrations +**Summary:** Claude Code runs the same underlying engine everywhere, but each surface is tuned for a different way of working. This page helps you pick the right platform for your workflow and connect the tools yo... +**Keywords:** mobile, desktop, dispatch, computer, gitlab, integrations, jetbrains, chat + +### `plugin-dependencies.md` +**Title:** Constrain plugin dependency versions +**Summary:** A plugin can depend on other plugins by listing them in or in its marketplace entry. By default, a dependency tracks the latest available version, so an upstream release can change the dependency unde... +**Keywords:** dependency, plugin, marketplace, tag, constraint, range, dependencies, version + +### `plugin-marketplaces.md` +**Title:** Create and distribute a plugin marketplace +**Summary:** A plugin marketplace is a catalog that lets you distribute plugins to others. Marketplaces provide centralized discovery, version tracking, automatic updates, and support for multiple source types (gi... +**Keywords:** marketplace, plugin, marketplaces, seed, string, plugins, relative, git + +### `plugins-reference.md` +**Title:** Plugins reference +**Summary:** Looking to install plugins? See Discover and install plugins. For creating plugins, see Plugins. For distributing plugins, see Plugin marketplaces. +**Keywords:** plugin, lsp, monitors, plugins, component, components, marketplace, string + +### `plugins.md` +**Title:** Create plugins +**Summary:** Plugins let you extend Claude Code with custom functionality that can be shared across projects and teams. This guide covers creating your own plugins with skills, agents, hooks, and MCP servers. +**Keywords:** plugin, plugins, lsp, skill, skills, root, manifest, marketplace + +### `quickstart.md` +**Title:** Quickstart +**Summary:** This quickstart guide will have you using AI-powered coding assistance in a few minutes. By the end, you'll understand how to use Claude Code for common development tasks. +**Keywords:** cmd, step, powershell, installations, welcome, latest, homebrew, windows + +### `remote-control.md` +**Title:** Continue local sessions from any device with Remote Control +**Summary:** Remote Control is in research preview and available on all plans. On Team and Enterprise, it is off by default until an admin enables the Remote Control toggle in Claude Code admin settings. +**Keywords:** remote, mobile, device, control, phone, toggle, machine, push + +### `routines.md` +**Title:** Automate work with routines +**Summary:** Routines are in research preview. Behavior, limits, and the API surface may change. +**Keywords:** routine, routines, connectors, trigger, click, triggers, schedule, github + +### `sandboxing.md` +**Title:** Sandboxing +**Summary:** Claude Code features native sandboxing to provide a more secure environment for agent execution while reducing the need for constant permission prompts. +**Keywords:** sandbox, sandboxing, sandboxed, network, paths, isolation, wsl2, filesystem + +### `scheduled-tasks.md` +**Title:** Run prompts on a schedule +**Summary:** Scheduled tasks require Claude Code v2.1.72 or later. Check your version with . +**Keywords:** scheduled, interval, cron, schedule, tasks, loop, maintenance, expression + +### `security.md` +**Title:** Security +**Summary:** Your code's security is paramount. Claude Code is built with security at its core, developed according to Anthropic's comprehensive security program. +**Keywords:** webdav, security, safeguards, privacy, protections, audit, approval, injection + +### `server-managed-settings.md` +**Title:** Configure server-managed settings +**Summary:** Server-managed settings allow administrators to centrally configure Claude Code through a web-based interface on Claude.ai. +**Keywords:** endpoint-managed, server-managed, settings, devices, managed, cached, mdm, unmanaged + +### `settings.md` +**Title:** Claude Code settings +**Summary:** Claude Code offers a variety of settings to configure its behavior to meet your needs. You can configure Claude Code by running the command when using the interactive REPL, which opens a tabbed Settin... +**Keywords:** acme-corp, null, theme, source, json, managed, acme-tools, hostpattern + +### `setup.md` +**Title:** Advanced setup +**Summary:** This page covers system requirements, platform-specific installation details, updates, and uninstallation. For a guided walkthrough of your first session, see the quickstart. +**Keywords:** homebrew, powershell, upgrade, dnf, installations, winget, wsl, cmd + +### `skills.md` +**Title:** Extend Claude with skills +**Summary:** Skills extend what Claude can do. Create a file with instructions, and Claude adds it to its toolkit. Claude uses skills when relevant, or you can invoke one directly with . +**Keywords:** skill, skills, null, theme, yaml, bundled, disable-model-invocation, arguments + +### `slack.md` +**Title:** Claude Code in Slack +**Summary:** Claude Code in Slack brings the power of Claude Code directly into your Slack workspace. When you mention with a coding task, Claude automatically detects the intent and creates a Claude Code session ... +**Keywords:** slack, channels, app, coding, web, workspace, wanted, chat + +### `statusline.md` +**Title:** Customize your status line +**Summary:** The status line is a customizable bar at the bottom of Claude Code that runs any shell script you configure. It receives JSON session data on stdin and displays whatever your script prints, giving you... +**Keywords:** script, status, line, osc, percentage, row, absent, clickable + +### `sub-agents.md` +**Title:** Create custom subagents +**Summary:** Subagents are specialized AI assistants that handle specific types of tasks. Use one when a side task would flood your main conversation with search results, logs, or file contents you won't reference... +**Keywords:** subagent, subagents, main, fork, delegates, frontmatter, forks, knowledge + +### `terminal-config.md` +**Title:** Configure your terminal for Claude Code +**Summary:** Claude Code works in any terminal without configuration. This page is for when something specific is not behaving the way you expect. Find your symptom below. +**Keywords:** color, theme, accent, enter, border, newline, tmux, bell + +### `third-party-integrations.md` +**Title:** Enterprise deployment overview +**Summary:** Organizations can deploy Claude Code through Anthropic directly or through a cloud provider. This page helps you choose the right configuration. +**Keywords:** payg, aws, traffic, gateway, regions, corporate, proxy, teams + +### `tools-reference.md` +**Title:** Tools reference +**Summary:** Claude Code has access to a set of built-in tools that help it understand and modify your codebase. The tool names are the exact strings you use in permission rules, subagent tool lists, and hook matc... +**Keywords:** powershell, cell, subagent, tool, grep, glob, matching, yes + +### `troubleshoot-install.md` +**Title:** Troubleshoot installation and login +**Summary:** If installation fails or you can't sign in, find your error below. For runtime issues after Claude Code is working, see Troubleshooting. +**Keywords:** installer, binary, powershell, windows, install, nvm, solutions, macos + +### `troubleshooting.md` +**Title:** Troubleshooting +**Summary:** This page covers performance, stability, and search problems once Claude Code is running. For other issues, start with the page that matches where you're stuck: +**Keywords:** performance, stability, search, cpu, hangs, experiencing, memory, high + +### `ultraplan.md` +**Title:** Plan in the cloud with ultraplan +**Summary:** Ultraplan is in research preview and requires Claude Code v2.1.91 or later. Behavior and capabilities may change based on feedback. +**Keywords:** ultraplan, plan, cloud, drafting, comment, web, terminal, browser + +### `ultrareview.md` +**Title:** Find bugs with ultrareview +**Summary:** Ultrareview is a research preview feature available in Claude Code v2.1.86 and later. The feature, pricing, and availability may change based on feedback. +**Keywords:** ultrareview, review, free, extra, subcommand, findings, billed, branch + +### `voice-dictation.md` +**Title:** Voice dictation +**Summary:** Speak your prompts instead of typing them in the Claude Code CLI. Your speech is transcribed live into the prompt input, so you can mix voice and typing in the same message. +**Keywords:** dictation, tap, microphone, recording, voice, audio, warmup, hold + +### `vs-code.md` +**Title:** Use Claude Code in VS Code +**Summary:** (no summary available) +**Keywords:** extension, panel, icon, tab, mac, click, open, box + +### `web-quickstart.md` +**Title:** Get started with Claude Code on the web +**Summary:** Claude Code on the web is in research preview for Pro, Max, and Team users, and for Enterprise users with premium seats or Chat + Claude Code seats. +**Keywords:** script, github, cloud, repositories, submit, setup, diff, environment + +### `whats-new.md` +**Title:** What's new +**Summary:** The weekly dev digest highlights the features most likely to change how you work. Each entry includes runnable code, a short demo, and a link to the full docs. +**Keywords:** digest, week, auto-fix, lands, preview, weekly, notable, highlights + +### `worktrees.md` +**Title:** Run parallel sessions with worktrees +**Summary:** A git worktree is a separate working directory with its own files and branch, sharing the same repository history and remote as your main checkout. +**Keywords:** worktree, worktrees, branch, isolate, non-git, untracked, commits, svn + +### `zero-data-retention.md` +**Title:** Zero data retention +**Summary:** Zero Data Retention (ZDR) is available for Claude Code when used through Claude for Enterprise. When ZDR is enabled, prompts and model responses generated during Claude Code sessions are processed in ... +**Keywords:** zdr, retention, administrative, completions, law, data, enterprise, zero diff --git a/install.sh b/install.sh index 0f36115ed..1faacebfb 100755 --- a/install.sh +++ b/install.sh @@ -497,6 +497,29 @@ fi # Clean up old installations now that v0.3 is set up cleanup_old_installations +# Setup /query feature (skill + agent + command) +echo "" +echo "Installing /query feature..." + +mkdir -p ~/.claude/commands +mkdir -p ~/.claude/agents +mkdir -p ~/.claude/skills/query-orchestrator + +if [[ -d "$INSTALL_DIR/claude-files" ]]; then + cp "$INSTALL_DIR/claude-files/commands/query.md" \ + ~/.claude/commands/query.md + cp "$INSTALL_DIR/claude-files/agents/query-researcher.md" \ + ~/.claude/agents/query-researcher.md + cp "$INSTALL_DIR/claude-files/skills/query-orchestrator/SKILL.md" \ + ~/.claude/skills/query-orchestrator/SKILL.md + echo "✓ Installed /query command, query-researcher agent, query-orchestrator skill" +else + echo "⚠️ claude-files/ missing — /query feature will not be available" +fi + +mkdir -p "$INSTALL_DIR/query" +echo "✓ Query workspace ready at $INSTALL_DIR/query" + # Success message echo "" echo "✅ Claude Code Docs v0.3.3 installed successfully!" diff --git a/scripts/build_docs_map.py b/scripts/build_docs_map.py new file mode 100644 index 000000000..5ad23a9cc --- /dev/null +++ b/scripts/build_docs_map.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 +""" +Build a navigation map of all docs in docs/ folder. +Outputs docs/DOCS_MAP.md — used by the /query skill to identify relevant files. +""" + +import math +import re +from collections import Counter +from datetime import datetime, timezone +from pathlib import Path + + +def extract_title(content: str, filename: str) -> str: + """Extract title from first H1, fallback to filename slug.""" + m = re.search(r'^#\s+(.+?)$', content, re.MULTILINE) + if m: + return m.group(1).strip() + base = filename.replace('.md', '').replace('__', ' / ').replace('-', ' ').replace('_', ' ') + return base.title() + + +def _strip_jsx_blocks(text: str) -> str: + """Remove JSX/JS component blocks using brace-depth tracking.""" + lines = text.split('\n') + result = [] + in_jsx = False + jsx_depth = 0 + for line in lines: + stripped = line.strip() + if not in_jsx and re.match(r'^(export\s+(const|default|function)|import\s+)', stripped): + in_jsx = True + jsx_depth = line.count('{') - line.count('}') + if jsx_depth <= 0: + in_jsx = False + continue + if in_jsx: + jsx_depth += line.count('{') - line.count('}') + if jsx_depth <= 0: + in_jsx = False + continue + result.append(line) + return '\n'.join(result) + + +def strip_markdown(text: str) -> str: + """Remove markdown syntax for clean text extraction.""" + # Strip JSX/JS component blocks (Mintlify pattern: export const Foo = (...) => { ... }) + text = _strip_jsx_blocks(text) + text = re.sub(r'```[\s\S]*?```', '', text) + text = re.sub(r'`[^`]+`', '', text) + text = re.sub(r'!\[[^\]]*\]\([^)]+\)', '', text) + text = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', text) + text = re.sub(r'<[^>]+>', '', text) + text = re.sub(r'^#+\s+', '', text, flags=re.MULTILINE) + text = re.sub(r'[*_]+', '', text) + return text + + +def extract_summary(content: str, max_chars: int = 200) -> str: + """Extract first paragraph after H1; skip code blocks, lists, blockquotes, frontmatter.""" + content = re.sub(r'^---[\s\S]+?---\n', '', content, count=1) + + lines = content.split('\n') + in_code = False + in_jsx = False + jsx_depth = 0 + para_lines = [] + for line in lines: + stripped = line.strip() + if stripped.startswith('```'): + in_code = not in_code + continue + if in_code: + continue + # Skip JSX component blocks + if not in_jsx and re.match(r'^(export\s+(const|default|function)|import\s+)', stripped): + in_jsx = True + jsx_depth = line.count('{') - line.count('}') + if jsx_depth <= 0: + in_jsx = False + continue + if in_jsx: + jsx_depth += line.count('{') - line.count('}') + if jsx_depth <= 0: + in_jsx = False + continue + if stripped.startswith('#'): + if para_lines: + break + continue + if not stripped: + if para_lines: + break + continue + if stripped.startswith(('|', '- ', '* ', '> ')): + if para_lines: + break + continue + para_lines.append(stripped) + + summary = ' '.join(para_lines) + summary = strip_markdown(summary) + summary = re.sub(r'\s+', ' ', summary).strip() + + if not summary: + return "(no summary available)" + + if len(summary) > max_chars: + truncated = summary[:max_chars] + last_period = truncated.rfind('.') + if last_period > max_chars * 0.6: + summary = truncated[:last_period + 1] + else: + summary = truncated + '...' + + return summary + + +STOPWORDS = { + 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', + 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'be', 'been', 'being', + 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should', + 'may', 'might', 'can', 'this', 'that', 'these', 'those', 'you', 'they', + 'what', 'which', 'who', 'when', 'where', 'how', 'why', 'all', 'each', 'every', + 'some', 'any', 'not', 'only', 'so', 'if', 'then', 'than', 'about', 'into', + 'through', 'between', 'use', 'using', 'used', 'one', 'two', 'three', 'first', + 'second', 'over', 'under', 'also', 'just', 'such', 'them', 'their', 'there', + 'here', 'its', 'his', 'her', 'our', 'your', 'see', 'make', 'made', + 'claude', 'code', 'anthropic', 'docs', 'documentation', + 'http', 'https', 'www', 'com', 'org', 'example', +} + + +def tokenize(text: str) -> list[str]: + """Tokenize text to words for keyword extraction.""" + text = strip_markdown(text).lower() + words = re.findall(r'\b[a-z][a-z0-9_-]{2,}\b', text) + return [w for w in words if w not in STOPWORDS] + + +def compute_tfidf(documents: dict) -> dict: + """Compute TF-IDF scores for all documents.""" + tfs = {name: Counter(tokenize(content)) for name, content in documents.items()} + df = Counter() + for name, tf in tfs.items(): + for term in tf: + df[term] += 1 + n_docs = len(documents) or 1 + tfidf = {} + for name, tf in tfs.items(): + total_terms = sum(tf.values()) or 1 + scores = {} + for term, freq in tf.items(): + tf_norm = freq / total_terms + idf = math.log(n_docs / df[term]) if df[term] else 0 + scores[term] = tf_norm * idf + tfidf[name] = scores + return tfidf + + +def top_keywords(tfidf_scores: dict, n: int = 8) -> list[str]: + """Return top N keywords by TF-IDF score.""" + sorted_terms = sorted(tfidf_scores.items(), key=lambda x: -x[1]) + return [term for term, score in sorted_terms[:n]] + + +DOCS_DIR_DEFAULT = Path(__file__).resolve().parent.parent / "docs" + + +def categorize(filename: str) -> str: + if filename.startswith("agent-sdk__"): + return "Agent SDK" + if filename.startswith("whats-new__"): + return "Weekly Updates" + return "General" + + +def build_map(docs_dir: Path = None, output_file: Path = None) -> None: + docs_dir = docs_dir or DOCS_DIR_DEFAULT + output_file = output_file or (docs_dir / "DOCS_MAP.md") + + docs = {} + for md_file in sorted(docs_dir.glob("*.md")): + if md_file.name == "DOCS_MAP.md": + continue + docs[md_file.name] = md_file.read_text(encoding="utf-8") + + if not docs: + print(f"No docs found in {docs_dir}") + return + + print(f"Indexing {len(docs)} documents...") + + tfidf = compute_tfidf(docs) + + grouped = {"Agent SDK": [], "Weekly Updates": [], "General": []} + for name in sorted(docs.keys()): + grouped[categorize(name)].append(name) + + lines = [] + lines.append("# Docs Map") + lines.append("") + now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") + lines.append(f"> Auto-generated by `scripts/build_docs_map.py` on {now}") + lines.append(f"> {len(docs)} files indexed.") + lines.append("") + lines.append("Used by the `/query` skill to identify relevant docs for a given question.") + lines.append("Each entry shows the file, its title, a short summary, and discriminative keywords.") + lines.append("") + lines.append("---") + lines.append("") + + for group_name in ("Agent SDK", "Weekly Updates", "General"): + files = grouped[group_name] + if not files: + continue + lines.append(f"## {group_name}") + lines.append("") + for name in files: + content = docs[name] + title = extract_title(content, name) + summary = extract_summary(content) + keywords = top_keywords(tfidf[name]) + lines.append(f"### `{name}`") + lines.append(f"**Title:** {title}") + lines.append(f"**Summary:** {summary}") + lines.append(f"**Keywords:** {', '.join(keywords)}") + lines.append("") + + output_file.write_text("\n".join(lines), encoding="utf-8") + print(f"✓ Wrote {output_file} ({len(docs)} entries)") + + +if __name__ == "__main__": + build_map() diff --git a/scripts/test_build_docs_map.py b/scripts/test_build_docs_map.py new file mode 100644 index 000000000..065c6b729 --- /dev/null +++ b/scripts/test_build_docs_map.py @@ -0,0 +1,147 @@ +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).parent)) + +from build_docs_map import extract_title + +FIXTURES = Path(__file__).parent / "test_fixtures" + + +def test_extract_title_from_h1(): + content = (FIXTURES / "doc_a.md").read_text() + assert extract_title(content, "doc_a.md") == "Hooks" + + +def test_extract_title_fallback_to_filename(): + content = (FIXTURES / "doc_c.md").read_text() + assert extract_title(content, "doc_c.md") == "Doc C" + + +def test_extract_title_handles_double_underscore(): + content = "" + assert extract_title(content, "agent-sdk__hooks.md") == "Agent Sdk / Hooks" + + +from build_docs_map import extract_summary + + +def test_extract_summary_first_paragraph(): + content = (FIXTURES / "doc_a.md").read_text() + summary = extract_summary(content) + assert "Hooks let you configure event-driven automation" in summary + assert "frontmatter" not in summary.lower() + + +def test_extract_summary_skips_code_blocks(): + content = (FIXTURES / "doc_b.md").read_text() + summary = extract_summary(content) + assert "Model Context Protocol" in summary + assert "claude mcp add" not in summary + + +def test_extract_summary_truncates_at_200_chars(): + long_para = " ".join(["word"] * 100) + content = f"# Title\n\n{long_para}" + summary = extract_summary(content) + assert len(summary) <= 203 # 200 + "..." + + +def test_extract_summary_empty_doc(): + summary = extract_summary("") + assert summary == "(no summary available)" + + +from build_docs_map import tokenize, compute_tfidf, top_keywords + + +def test_tokenize_removes_stopwords(): + tokens = tokenize("The quick brown fox jumps over the lazy dog.") + assert "quick" in tokens + assert "brown" in tokens + assert "the" not in tokens + assert "over" not in tokens + + +def test_tokenize_strips_markdown(): + tokens = tokenize("`code` is **important** for [docs](url).") + assert "code" not in tokens # in backticks -> stripped + assert "important" in tokens + assert "docs" not in tokens # in stopword list + + +def test_compute_tfidf_distinguishes_docs(): + docs = { + "a.md": "hooks hooks hooks event event tool", + "b.md": "mcp mcp mcp server transport", + "c.md": "the quick brown fox jumps" + } + tfidf = compute_tfidf(docs) + a_keywords = top_keywords(tfidf["a.md"], n=3) + b_keywords = top_keywords(tfidf["b.md"], n=3) + assert "hooks" in a_keywords + assert "mcp" in b_keywords + assert "hooks" not in b_keywords + + +import tempfile +from build_docs_map import build_map + + +def test_build_map_writes_grouped_output(tmp_path): + docs_dir = tmp_path / "docs" + docs_dir.mkdir() + (docs_dir / "hooks.md").write_text("# Hooks\n\nHook event documentation.") + (docs_dir / "agent-sdk__overview.md").write_text("# Agent SDK\n\nSDK overview content.") + (docs_dir / "whats-new__2026-w19.md").write_text("# Week 19\n\nWeekly release notes.") + + output = docs_dir / "DOCS_MAP.md" + build_map(docs_dir=docs_dir, output_file=output) + + content = output.read_text() + assert "# Docs Map" in content + assert "## Agent SDK" in content + assert "## Weekly Updates" in content + assert "## General" in content + assert "### `hooks.md`" in content + assert "**Title:** Hooks" in content + assert "**Summary:**" in content + assert "**Keywords:**" in content + assert "DOCS_MAP.md" not in [line.strip() for line in content.split("###")[1:]] + + +def test_extract_summary_skips_jsx_blocks(): + content = """# Title + +export const ContactSalesCard = ({surface}) => { + return ( +
+

Contact

+
+ ); +} + +This is the actual prose paragraph that should be extracted. +""" + summary = extract_summary(content) + assert "actual prose paragraph" in summary + assert "ContactSalesCard" not in summary + assert "const" not in summary + assert "div" not in summary + + +def test_tokenize_strips_jsx_terms(): + text = """# Title + +export const Foo = ({bar}) => { + return
baz
; +} + +The prose content has tokens like hooks and events. +""" + tokens = tokenize(text) + assert "hooks" in tokens + assert "events" in tokens + assert "const" not in tokens + assert "div" not in tokens + assert "return" not in tokens diff --git a/scripts/test_fixtures/doc_a.md b/scripts/test_fixtures/doc_a.md new file mode 100644 index 000000000..c61086124 --- /dev/null +++ b/scripts/test_fixtures/doc_a.md @@ -0,0 +1,16 @@ +--- +title: Hooks Reference +description: A reference for hooks in Claude Code +--- + +# Hooks + +Hooks let you configure event-driven automation in Claude Code by intercepting tool calls before, after, or during execution. Hooks fire on events like PreToolUse, PostToolUse, and Stop. + +## Hook events + +The supported events are: + +- PreToolUse +- PostToolUse +- Stop diff --git a/scripts/test_fixtures/doc_b.md b/scripts/test_fixtures/doc_b.md new file mode 100644 index 000000000..02eea1418 --- /dev/null +++ b/scripts/test_fixtures/doc_b.md @@ -0,0 +1,9 @@ +# MCP Servers + +```bash +claude mcp add my-server +``` + +The Model Context Protocol allows you to integrate external tools and resources into Claude Code through stdio, SSE, or HTTP transports. + +## Configuration diff --git a/scripts/test_fixtures/doc_c.md b/scripts/test_fixtures/doc_c.md new file mode 100644 index 000000000..1e04ccfc4 --- /dev/null +++ b/scripts/test_fixtures/doc_c.md @@ -0,0 +1,3 @@ +This file has no H1 heading. It begins with prose explaining the topic. + +## Subheading diff --git a/specs/2026-05-11-query-orchestrator-design.md b/specs/2026-05-11-query-orchestrator-design.md new file mode 100644 index 000000000..7401163c7 --- /dev/null +++ b/specs/2026-05-11-query-orchestrator-design.md @@ -0,0 +1,580 @@ +# Query Orchestrator Design + +**Date:** 2026-05-11 +**Status:** Approved (brainstorming phase) +**Target branch:** `feature/query-orchestrator` +**Target upstream:** PR to `ericbuess/claude-code-docs` + +## 1. Goal + +Add a `/query` slash command to the `claude-code-docs` mirror that handles multi-part research questions against the local docs. The command: + +1. Parses a user query into N independent sub-questions. +2. Generates a unique task folder per query. +3. Dispatches a specialized subagent per sub-question, in **batches of 3 parallel calls**. +4. Each subagent reads a generated docs map to identify relevant files, reads them, writes a structured answer file. +5. The orchestrator assembles all answer files into a single `query.md` per task. +6. The user sees a short chat summary + a path to the assembled file. + +The existing `/docs` command is **untouched**. The new feature is additive. + +## 2. Non-Goals + +- Renaming the repo. Original name `claude-code-docs` is preserved. +- Converting the repo into a Claude Code plugin (no `plugin.json` at root). Existing `install.sh` pattern is followed. +- LLM-based map generation. Map generation is deterministic Python only. +- Multi-language templates. Templates and skill outputs are English. + +## 3. Architecture + +### High-level flow + +``` +/query "Hooks ve MCP nedir, nasıl entegre edilir?" + │ + ▼ +~/.claude/commands/query.md (slash command) + │ $ARGUMENTS → "Hooks ve MCP nedir, nasıl entegre edilir?" + ▼ +Skill: query-orchestrator (~/.claude/skills/query-orchestrator/SKILL.md) + │ + ├── Step 1: Parse → 3 sub-questions + ├── Step 2: Generate task ID = QUERY-TASK-hooks-1715432100123 + ├── Step 3: mkdir ~/.claude-code-docs/query// + ├── Step 4: Write query.md (template-filled with pending placeholders) + ├── Step 5: Dispatch subagents in batches of 3 + │ ┌──────────────┬──────────────┬──────────────┐ + │ │ Task(Q1) │ Task(Q2) │ Task(Q3) │ (parallel, single message) + │ └──────┬───────┴──────┬───────┴──────┬───────┘ + │ ▼ ▼ ▼ + │ query-researcher (×3, each writes one QUERY-N.md) + │ │ │ │ + │ ▼ ▼ ▼ + │ QUERY-1.md QUERY-2.md QUERY-3.md + │ + ├── Step 6: Read all QUERY-N.md in parallel, assemble into query.md + │ (single Write overwrites query.md with all answers embedded) + └── Step 7: Chat summary + path +``` + +### Storage layout + +**Repo-side (committed):** +- `docs/DOCS_MAP.md` — auto-generated map, committed by workflow +- `scripts/build_docs_map.py` — deterministic map generator (stdlib only) +- `claude-files/commands/query.md` — slash command source +- `claude-files/agents/query-researcher.md` — subagent source +- `claude-files/skills/query-orchestrator/SKILL.md` — orchestrator skill source +- `.github/workflows/build-docs-map.yml` — workflow that regenerates the map + +**User-side (after install.sh):** +- `~/.claude/commands/query.md` — copied from repo +- `~/.claude/agents/query-researcher.md` — copied from repo +- `~/.claude/skills/query-orchestrator/SKILL.md` — copied from repo +- `~/.claude-code-docs/query/` — user query workspace (gitignored, user data) +- `~/.claude-code-docs/docs/DOCS_MAP.md` — pulled from the cloned repo + +## 4. Repo Structure (after change) + +``` +claude-code-docs/ +├── docs/ (existing, +1 generated file) +│ ├── ... 127 existing docs ... +│ └── DOCS_MAP.md ← NEW (auto-generated, committed) +│ +├── scripts/ (existing, +1 file) +│ ├── claude-docs-helper.sh.template (unchanged) +│ ├── fetch_claude_docs.py (unchanged) +│ ├── requirements.txt (unchanged) +│ └── build_docs_map.py ← NEW (Python stdlib only) +│ +├── claude-files/ ← NEW folder +│ ├── commands/ +│ │ └── query.md +│ ├── agents/ +│ │ └── query-researcher.md +│ └── skills/ +│ └── query-orchestrator/ +│ └── SKILL.md +│ +├── .github/workflows/ (existing, +1 file) +│ ├── update-docs.yml (unchanged) +│ ├── release.yml (unchanged) +│ └── build-docs-map.yml ← NEW +│ +├── install.sh ← MODIFIED (~30 lines appended) +├── uninstall.sh ← MODIFIED (~15 lines appended) +├── README.md ← MODIFIED (+1 section) +├── CLAUDE.md ← MODIFIED (+1 section) +└── specs/ + └── 2026-05-11-query-orchestrator-design.md ← This document +``` + +Rationale: `scripts/` stays code-only (Unix convention). `claude-files/` mirrors the install target (`~/.claude/`) so the install.sh copy logic is a parallel directory walk. + +## 5. Map Generation + +### Script: `scripts/build_docs_map.py` + +**Inputs:** `docs/*.md` (top-level, non-recursive, excluding `DOCS_MAP.md`) +**Output:** `docs/DOCS_MAP.md` +**Dependencies:** Python 3.11+ stdlib only (no pip installs) + +**Algorithm per file:** + +1. **Title:** First `# H1` in content. Fallback: filename slug → title case (e.g., `agent-sdk__hooks.md` → "Agent Sdk / Hooks"). +2. **Summary:** After stripping YAML frontmatter, find the first non-heading non-empty paragraph that is not a code block, list, or blockquote. Strip markdown syntax. Cap at 200 chars: prefer breaking at the last sentence end within the cap; if no sentence end falls past 60% of the cap, hard-truncate with `...`. +3. **Keywords:** TF-IDF across all docs. Top 8 terms by score. Stopword filter includes English common words + Claude Code-specific high-frequency terms (`claude`, `code`, `anthropic`, `docs`). + +**Categorization:** Filename prefix groups files in the output map: +- `agent-sdk__*` → **Agent SDK** section +- `whats-new__*` → **Weekly Updates** section +- Everything else → **General** section + +**Token budget:** ~150 tokens per entry × 127 entries ≈ 19K tokens. Acceptable for skill load. + +### Output format + +```markdown +# Docs Map + +> Auto-generated by `scripts/build_docs_map.py` on 2026-05-11 12:00 UTC +> 127 files indexed. + +Used by the `/query` skill to identify relevant docs for a given question. +Each entry shows the file, its title, a short summary, and discriminative keywords (TF-IDF). + +--- + +## Agent SDK + +### `agent-sdk__hooks.md` +**Title:** Hooks +**Summary:** Configure event-driven automation in the Agent SDK with PreToolUse, PostToolUse, Stop, and other hook events to validate, modify, or block tool execution. +**Keywords:** hooks, pretooluse, posttoouse, stop, event, hook_event_name, exitcode, blocking + +(... more entries ...) + +## Weekly Updates + +### `whats-new__2026-w19.md` +**Title:** What's new — Week 19 2026 +**Summary:** Release notes for the week of May 4-10, 2026... +**Keywords:** ... + +## General + +### `hooks.md` +**Title:** Hooks +**Summary:** ... +**Keywords:** ... +``` + +## 6. Slash Command + +### `claude-files/commands/query.md` + +```markdown +--- +description: Research Claude Code documentation by batching multi-question queries to specialized subagents +argument-hint: +--- + +The user has invoked /query with the following input: + +$ARGUMENTS + +Use the Skill tool to invoke the `query-orchestrator` skill. Pass the user query above as the skill's argument. Follow the skill's instructions exactly. +``` + +The command is a thin trigger — all logic is in the skill. + +## 7. Skill: query-orchestrator + +### `claude-files/skills/query-orchestrator/SKILL.md` + +**Frontmatter:** +```yaml +--- +name: query-orchestrator +description: Use when handling /query slash command — parses multi-part questions, dispatches batched subagents to research docs, and assembles final answer +--- +``` + +**Procedure (7 steps):** + +**Step 1 — Parse user query into sub-questions** + +Rules: +- One cohesive question → N=1 +- Explicit numbering (1./2./3. or bulleted) → follow numbering +- Independent parts joined by `and`/`ve` → split +- Each sub-question must be answerable independently from docs + +**Step 2 — Generate task ID** + +- Extract first sub-question's most discriminative content word (skip stopwords like `the`, `a`, `what`, `how`, `is`, `does`). +- Slugify: lowercase, ASCII, hyphens. +- If no content word can be identified (e.g., "How does it work?"), fall back to the literal keyword `query`. +- Append epoch milliseconds via Bash: `date +%s%3N`. +- Format: `QUERY-TASK--`. +- Example: `QUERY-TASK-hooks-1715432100123`. +- Fallback example: `QUERY-TASK-query-1715432100123`. + +**Step 3 — Create task folder** + +```bash +mkdir -p ~/.claude-code-docs/query/ +``` + +**Step 4 — Write initial query.md from template** + +Template (inline in SKILL.md): + +```markdown +# Query Task: {TASK_ID} + +**Original user query:** +> {ORIGINAL_USER_INPUT} + +**Created at:** {ISO_TIMESTAMP} +**Number of sub-questions:** {N} +**Status:** in-progress + +--- + +## [QUERY-1] — {SHORT_TITLE_1} + +**Question:** {SUB_QUESTION_1} + +**Answer:** + +_pending — researcher dispatched_ + + +--- + +## [QUERY-2] — {SHORT_TITLE_2} + +(... repeat for N ...) +``` + +`SHORT_TITLE_n` is a 3-5 word descriptor derived from each sub-question. + +**Step 5 — Dispatch subagents in batches of 3** + +CRITICAL: All Task tool calls in one batch MUST be sent in a SINGLE message to execute in parallel. + +| N | Batches | +|----|---------| +| 1 | [1] | +| 2 | [2] | +| 3 | [3] | +| 4 | [3, 1] | +| 5 | [3, 2] | +| 7 | [3, 3, 1] | +| 15 | [3, 3, 3, 3, 3] | + +Each Task call: +``` +subagent_type: query-researcher +description: "Research [QUERY-N]" +prompt: | + Task: + Query ID: [QUERY-N] + Question: + Output file: ~/.claude-code-docs/query//QUERY-.md + Docs map: ~/.claude-code-docs/docs/DOCS_MAP.md + Docs folder: ~/.claude-code-docs/docs/ +``` + +Wait for ALL calls in a batch to return before issuing the next batch. + +**Step 6 — Assemble answers into query.md** + +After all batches: +1. Issue parallel Read calls for every `QUERY-N.md` (single message, N Read calls). +2. For each file, extract content below the H1 header. +3. Build the complete final `query.md` in memory: + - Header (task id, original query, timestamp, N, **Status: complete**) + - For each [QUERY-N]: question + the extracted body (replacing the `_pending_` placeholder) +4. Single Write call overwrites `query.md`. + +Missing file handling: if a `QUERY-N.md` does not exist, insert: +> ⚠️ Researcher did not complete this query. Re-run `/query` for just this question. + +**Step 7 — Chat summary** + +``` +✓ Query complete: ( questions) + +• [QUERY-1] +• [QUERY-2] +• ... + +Full details: ~/.claude-code-docs/query//query.md +``` + +### Failure modes + +| Failure | Handling | +|---------|----------| +| `mkdir` fails | Abort with error message | +| DOCS_MAP.md missing | Tell user to re-run install.sh | +| Subagent returns no file | Insert warning placeholder, continue with others | +| Parsing yields N=0 | Ask user to rephrase | +| Template inline placeholder unmatched | Fail loudly | + +## 8. Subagent: query-researcher + +### `claude-files/agents/query-researcher.md` + +**Frontmatter:** +```yaml +--- +name: query-researcher +description: Research a single sub-question by reading Claude Code documentation and producing a structured answer file +tools: Read, Grep, Glob, Write, Bash +--- +``` + +**Tools rationale:** +- `Read`, `Grep`, `Glob`, `Bash`: read and search docs +- `Write`: produce the single output file +- NO `Edit` (only writes new file) +- NO `Task` (no recursion) +- NO `WebFetch` (local docs only) + +**Procedure (4 steps):** + +1. **Pick relevant docs (max 5):** Read DOCS_MAP.md, match question against title/summary/keywords. Prefer specific docs over `overview.md`. May use `grep -l "term" ~/.claude-code-docs/docs/*.md | head -5` for term-specific searches. + +2. **Read selected docs.** Hard cap 5. If a referenced doc is clearly more relevant, swap rather than add. + +3. **Synthesize answer** — 200-500 words typical, with citations. + +4. **Write output file** in exact structure: + +```markdown +# Answer to [QUERY-N] + +**Question:** +**Task:** + +## Researched files + +- `docs/file1.md` — why relevant +- `docs/file2.md` — why relevant + +## Answer + + + +## Source excerpts + +> Short relevant quote from file1.md + +> Short relevant quote from file2.md + +## Notes + + +``` + +When the orchestrator assembles, everything below the H1 (`# Answer to [QUERY-N]`) becomes the answer body that replaces the `_pending_` placeholder in `query.md`. So the user sees question + researched files + answer + sources + notes in the final document. + +## 9. GitHub Workflow + +### `.github/workflows/build-docs-map.yml` + +```yaml +name: Build Docs Map + +on: + workflow_run: + workflows: ["Update Claude Code Documentation"] + types: [completed] + workflow_dispatch: + push: + branches: [main] + paths: + - 'scripts/build_docs_map.py' + - 'docs/**/*.md' + +permissions: + contents: write + +jobs: + build-map: + if: github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: main + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: python scripts/build_docs_map.py + - name: Commit if changed + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + if [[ -n "$(git status --porcelain docs/DOCS_MAP.md)" ]]; then + git add docs/DOCS_MAP.md + git commit -m "Update DOCS_MAP.md - $(date +'%Y-%m-%d')" + git push + fi +``` + +**Trigger rationale:** +- `workflow_run` after `Update Claude Code Documentation` completes successfully → fresh map after every docs sync (required because `GITHUB_TOKEN` pushes do not fire `push` triggers). +- `push` on `scripts/build_docs_map.py` → regenerate when the script itself changes (uses default `GITHUB_TOKEN` push from contributors, which DOES fire on PR merges). +- `workflow_dispatch` → manual. + +## 10. install.sh / uninstall.sh changes + +### install.sh — append a new block after `/docs` setup + +```bash +# Setup /query feature (skill + agent + command) +echo "" +echo "Installing /query feature..." + +mkdir -p ~/.claude/commands +mkdir -p ~/.claude/agents +mkdir -p ~/.claude/skills/query-orchestrator + +if [[ -d "$INSTALL_DIR/claude-files" ]]; then + cp "$INSTALL_DIR/claude-files/commands/query.md" \ + ~/.claude/commands/query.md + cp "$INSTALL_DIR/claude-files/agents/query-researcher.md" \ + ~/.claude/agents/query-researcher.md + cp "$INSTALL_DIR/claude-files/skills/query-orchestrator/SKILL.md" \ + ~/.claude/skills/query-orchestrator/SKILL.md + echo "✓ Installed /query command, query-researcher agent, query-orchestrator skill" +else + echo "⚠️ claude-files/ missing — /query feature will not be available" +fi + +mkdir -p "$INSTALL_DIR/query" +echo "✓ Query workspace ready at $INSTALL_DIR/query" +``` + +- Existing `/docs` setup is untouched +- Idempotent (overwrites on re-run, providing upgrade path) +- Graceful degradation if `claude-files/` is missing (older repo checkouts) + +### uninstall.sh — append a new block + +```bash +# Remove /query feature files +echo "" +echo "Removing /query feature..." + +[[ -f ~/.claude/commands/query.md ]] && rm -f ~/.claude/commands/query.md && echo "✓ Removed /query command" +[[ -f ~/.claude/agents/query-researcher.md ]] && rm -f ~/.claude/agents/query-researcher.md && echo "✓ Removed query-researcher agent" +[[ -d ~/.claude/skills/query-orchestrator ]] && rm -rf ~/.claude/skills/query-orchestrator && echo "✓ Removed query-orchestrator skill" + +# Ask before removing query outputs (user data!) +if [[ -d "$HOME/.claude-code-docs/query" ]] && [[ -n "$(ls -A "$HOME/.claude-code-docs/query" 2>/dev/null)" ]]; then + echo "" + echo "⚠️ Found query outputs at $HOME/.claude-code-docs/query/" + read -p "Delete query history? (y/N): " -n 1 -r + echo + [[ $REPLY =~ ^[Yy]$ ]] && rm -rf "$HOME/.claude-code-docs/query" && echo "✓ Removed query history" +fi +``` + +User query data is treated as protected — only removed on explicit confirmation. + +## 11. README.md / CLAUDE.md updates + +**README.md** — add a `/query` subsection under "Usage": + +```markdown +### Multi-question research with /query + +`/query` parses your input into sub-questions, dispatches research subagents in batches of 3 in parallel, and assembles a structured answer file. + +```bash +/query What is a hook? # single question +/query Explain hooks and MCP, then compare them # multi-part +/query 1. ... 2. ... 3. ... # explicit numbering +``` + +Each query produces a folder under `~/.claude-code-docs/query/QUERY-TASK--/` +containing the full structured answer with citations. Useful for non-trivial questions that span multiple docs. +``` + +**CLAUDE.md** — add a `/query` section and extend the ultrathink list: + +```markdown +## For /query Command + +When responding to /query commands: +1. Invoke the query-orchestrator skill via the Skill tool +2. Follow the skill's 7-step procedure (parse → task ID → folder → template → batch dispatch → assemble → summary) +3. Subagents read from docs/ folder via DOCS_MAP.md +4. Outputs accumulate in ~/.claude-code-docs/query/ +``` + +Add to "Files to ultrathink about": +- `@docs/DOCS_MAP.md` +- `@scripts/build_docs_map.py` +- `@claude-files/` + +## 12. Test Plan + +### Unit (automated) + +Add `scripts/test_build_docs_map.py` with fixtures covering: +- Title extraction (with H1, without H1, with frontmatter) +- Summary extraction (skipping code blocks, lists, blockquotes) +- TF-IDF keyword selection across 3 sample docs +- Stopword filtering + +### Manual (release gate) + +1. Clean macOS / Linux system → `bash install.sh` +2. Verify file presence: + - `~/.claude/commands/query.md` + - `~/.claude/agents/query-researcher.md` + - `~/.claude/skills/query-orchestrator/SKILL.md` + - `~/.claude-code-docs/query/` exists, empty +3. Restart Claude Code → `/query What is a hook?` (N=1) +4. `/query Explain hooks and MCP and how to integrate them` (N=3, single batch of 3 parallel) +5. `/query 1. ... 2. ... 3. ... 4. ... 5. ...` (N=5, batches [3,2]) +6. `/query` with 15 explicit questions (5 batches of 3) +7. Edge case: temporarily delete DOCS_MAP.md → skill produces a clear error +8. Edge case: kill one subagent mid-flight → orchestrator inserts warning placeholder for that QUERY-N +9. `bash uninstall.sh` → verify removal + query history prompt + +### Workflow + +- Manually trigger `build-docs-map.yml` via `workflow_dispatch` → DOCS_MAP.md correctly produced +- Run `update-docs.yml` manually → confirm `build-docs-map.yml` fires via `workflow_run` after success + +## 13. Open Risks + +1. **Subagent parallelism inconsistency.** Claude may sometimes serialize Task calls. The skill must explicitly state "MUST issue all calls in ONE message" with strong wording. +2. **Map token growth.** ~19K today, ~30K at 200 docs. Subagents read the whole map. Future iteration: pre-filter by category before dispatching to the subagent. +3. **PR size.** Large additive change. Break into 4 commits for easier review: + - Commit 1: `scripts/build_docs_map.py` + initial DOCS_MAP.md + - Commit 2: `.github/workflows/build-docs-map.yml` + - Commit 3: `claude-files/` (command, agent, skill) + - Commit 4: `install.sh` / `uninstall.sh` / README / CLAUDE.md updates +4. **Maintainer acceptance.** Feature is opinionated. Worth opening a discussion issue before the PR to gauge interest. + +## 14. Acceptance Criteria + +- [ ] `bash install.sh` on a clean machine installs all `/query` artifacts without errors +- [ ] `/query "What is a hook?"` produces a `query.md` with an assembled answer citing at least one doc file +- [ ] `/query` with 5 sub-questions produces exactly 5 `QUERY-N.md` files dispatched in 2 batches (parallel within each batch) +- [ ] `/query` with 15 sub-questions runs 5 batches; final `query.md` contains all 15 answers +- [ ] If a subagent fails, the assembled `query.md` shows a warning placeholder for that query, not a crash +- [ ] `bash uninstall.sh` removes all `/query` files; asks before deleting query history +- [ ] `scripts/build_docs_map.py` runs locally with no external dependencies and produces `docs/DOCS_MAP.md` +- [ ] `build-docs-map.yml` fires after `update-docs.yml` completes successfully +- [ ] Existing `/docs` command continues to work unchanged diff --git a/specs/2026-05-11-query-orchestrator-plan.md b/specs/2026-05-11-query-orchestrator-plan.md new file mode 100644 index 000000000..4475038a1 --- /dev/null +++ b/specs/2026-05-11-query-orchestrator-plan.md @@ -0,0 +1,1370 @@ +# Query Orchestrator Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a `/query` slash command to claude-code-docs that batches multi-question research across the local docs mirror via specialized subagents. + +**Architecture:** A deterministic Python script generates `docs/DOCS_MAP.md` (title + summary + TF-IDF keywords per file). A GitHub workflow regenerates the map after every docs update. `install.sh` is extended to deploy a slash command, a query-orchestrator skill, and a query-researcher subagent into `~/.claude/`. The skill parses user input into N sub-questions, dispatches subagents in batches of 3 parallel, and assembles answers into a per-task `query.md` under `~/.claude-code-docs/query/`. + +**Tech Stack:** Python 3.11 stdlib (re, math, pathlib, collections), pytest, GitHub Actions, bash, Claude Code skill/agent/command markdown format. + +**Spec:** [`specs/2026-05-11-query-orchestrator-design.md`](2026-05-11-query-orchestrator-design.md) + +**Branch:** `feature/query-orchestrator` (already created) + +--- + +## File Structure + +**Create:** +- `scripts/build_docs_map.py` — map generator +- `scripts/test_build_docs_map.py` — pytest tests +- `scripts/test_fixtures/doc_a.md` — fixture: doc with H1 + frontmatter +- `scripts/test_fixtures/doc_b.md` — fixture: doc with code block before paragraph +- `scripts/test_fixtures/doc_c.md` — fixture: doc without H1 +- `docs/DOCS_MAP.md` — generated map (committed) +- `claude-files/commands/query.md` — slash command (deployed by install.sh) +- `claude-files/agents/query-researcher.md` — subagent (deployed by install.sh) +- `claude-files/skills/query-orchestrator/SKILL.md` — skill (deployed by install.sh) +- `.github/workflows/build-docs-map.yml` — workflow + +**Modify:** +- `install.sh` — append `/query` install block after `/docs` setup +- `uninstall.sh` — append `/query` removal block +- `README.md` — add `/query` usage section +- `CLAUDE.md` — add `/query` section + extend ultrathink list + +**Responsibility separation:** +- `scripts/` holds Python and shell — no markdown content +- `claude-files/` mirrors `~/.claude/` install target — only markdown content +- `docs/` is the docs mirror — only `DOCS_MAP.md` is added; no internal design docs leak in +- `specs/` is internal — spec + plan only + +--- + +## Task 1: Set up test fixtures for build_docs_map.py + +**Files:** +- Create: `scripts/test_fixtures/doc_a.md` +- Create: `scripts/test_fixtures/doc_b.md` +- Create: `scripts/test_fixtures/doc_c.md` + +- [ ] **Step 1: Create fixture `doc_a.md` — normal doc with H1, frontmatter, paragraph** + +File `scripts/test_fixtures/doc_a.md`: + +```markdown +--- +title: Hooks Reference +description: A reference for hooks in Claude Code +--- + +# Hooks + +Hooks let you configure event-driven automation in Claude Code by intercepting tool calls before, after, or during execution. Hooks fire on events like PreToolUse, PostToolUse, and Stop. + +## Hook events + +The supported events are: + +- PreToolUse +- PostToolUse +- Stop +``` + +- [ ] **Step 2: Create fixture `doc_b.md` — doc with code block before first paragraph** + +File `scripts/test_fixtures/doc_b.md`: + +```markdown +# MCP Servers + +```bash +claude mcp add my-server +``` + +The Model Context Protocol allows you to integrate external tools and resources into Claude Code through stdio, SSE, or HTTP transports. + +## Configuration +``` + +- [ ] **Step 3: Create fixture `doc_c.md` — no H1, fallback to filename** + +File `scripts/test_fixtures/doc_c.md`: + +```markdown +This file has no H1 heading. It begins with prose explaining the topic. + +## Subheading +``` + +- [ ] **Step 4: Commit fixtures** + +```bash +git add scripts/test_fixtures/ +git commit -m "test: add fixtures for build_docs_map.py" +``` + +--- + +## Task 2: Implement build_docs_map.py with TDD + +**Files:** +- Create: `scripts/build_docs_map.py` +- Create: `scripts/test_build_docs_map.py` + +- [ ] **Step 1: Create empty script with shebang and docstring** + +File `scripts/build_docs_map.py`: + +```python +#!/usr/bin/env python3 +""" +Build a navigation map of all docs in docs/ folder. +Outputs docs/DOCS_MAP.md — used by the /query skill to identify relevant files. +""" +``` + +- [ ] **Step 2: Write failing test for `extract_title`** + +File `scripts/test_build_docs_map.py`: + +```python +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).parent)) + +from build_docs_map import extract_title + +FIXTURES = Path(__file__).parent / "test_fixtures" + + +def test_extract_title_from_h1(): + content = (FIXTURES / "doc_a.md").read_text() + assert extract_title(content, "doc_a.md") == "Hooks" + + +def test_extract_title_fallback_to_filename(): + content = (FIXTURES / "doc_c.md").read_text() + assert extract_title(content, "doc_c.md") == "Doc C" + + +def test_extract_title_handles_double_underscore(): + content = "" + assert extract_title(content, "agent-sdk__hooks.md") == "Agent Sdk / Hooks" +``` + +- [ ] **Step 3: Run test to verify it fails** + +Run: `cd scripts && python -m pytest test_build_docs_map.py::test_extract_title_from_h1 -v` +Expected: FAIL with `ImportError: cannot import name 'extract_title'` + +- [ ] **Step 4: Implement `extract_title`** + +Append to `scripts/build_docs_map.py`: + +```python +import re + + +def extract_title(content: str, filename: str) -> str: + """Extract title from first H1, fallback to filename slug.""" + m = re.search(r'^#\s+(.+?)$', content, re.MULTILINE) + if m: + return m.group(1).strip() + base = filename.replace('.md', '').replace('__', ' / ').replace('-', ' ').replace('_', ' ') + return base.title() +``` + +- [ ] **Step 5: Run tests to verify all 3 pass** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v` +Expected: 3 passed + +- [ ] **Step 6: Write failing tests for `extract_summary`** + +Append to `scripts/test_build_docs_map.py`: + +```python +from build_docs_map import extract_summary + + +def test_extract_summary_first_paragraph(): + content = (FIXTURES / "doc_a.md").read_text() + summary = extract_summary(content) + assert "Hooks let you configure event-driven automation" in summary + assert "frontmatter" not in summary.lower() + + +def test_extract_summary_skips_code_blocks(): + content = (FIXTURES / "doc_b.md").read_text() + summary = extract_summary(content) + assert "Model Context Protocol" in summary + assert "claude mcp add" not in summary + + +def test_extract_summary_truncates_at_200_chars(): + long_para = " ".join(["word"] * 100) + content = f"# Title\n\n{long_para}" + summary = extract_summary(content) + assert len(summary) <= 203 # 200 + "..." + + +def test_extract_summary_empty_doc(): + summary = extract_summary("") + assert summary == "(no summary available)" +``` + +- [ ] **Step 7: Run tests to verify they fail** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v -k summary` +Expected: 4 failed with `ImportError` or `AttributeError` + +- [ ] **Step 8: Implement `extract_summary` and `strip_markdown` helper** + +Append to `scripts/build_docs_map.py`: + +```python +def strip_markdown(text: str) -> str: + """Remove markdown syntax for clean text extraction.""" + text = re.sub(r'```[\s\S]*?```', '', text) + text = re.sub(r'`[^`]+`', '', text) + text = re.sub(r'!\[[^\]]*\]\([^)]+\)', '', text) + text = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', text) + text = re.sub(r'<[^>]+>', '', text) + text = re.sub(r'^#+\s+', '', text, flags=re.MULTILINE) + text = re.sub(r'[*_]+', '', text) + return text + + +def extract_summary(content: str, max_chars: int = 200) -> str: + """Extract first paragraph after H1; skip code blocks, lists, blockquotes, frontmatter.""" + content = re.sub(r'^---[\s\S]+?---\n', '', content, count=1) + + lines = content.split('\n') + in_code = False + para_lines = [] + for line in lines: + stripped = line.strip() + if stripped.startswith('```'): + in_code = not in_code + continue + if in_code: + continue + if stripped.startswith('#'): + if para_lines: + break + continue + if not stripped: + if para_lines: + break + continue + if stripped.startswith(('|', '- ', '* ', '> ')): + if para_lines: + break + continue + para_lines.append(stripped) + + summary = ' '.join(para_lines) + summary = strip_markdown(summary) + summary = re.sub(r'\s+', ' ', summary).strip() + + if not summary: + return "(no summary available)" + + if len(summary) > max_chars: + truncated = summary[:max_chars] + last_period = truncated.rfind('.') + if last_period > max_chars * 0.6: + summary = truncated[:last_period + 1] + else: + summary = truncated + '...' + + return summary +``` + +- [ ] **Step 9: Run tests to verify all summary tests pass** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v` +Expected: 7 passed + +- [ ] **Step 10: Write failing tests for `tokenize` and `compute_tfidf`** + +Append to `scripts/test_build_docs_map.py`: + +```python +from build_docs_map import tokenize, compute_tfidf, top_keywords + + +def test_tokenize_removes_stopwords(): + tokens = tokenize("The quick brown fox jumps over the lazy dog.") + assert "quick" in tokens + assert "brown" in tokens + assert "the" not in tokens + assert "over" not in tokens + + +def test_tokenize_strips_markdown(): + tokens = tokenize("`code` is **important** for [docs](url).") + assert "code" not in tokens # in backticks → stripped + assert "important" in tokens + assert "docs" not in tokens # in stopword list + + +def test_compute_tfidf_distinguishes_docs(): + docs = { + "a.md": "hooks hooks hooks event event tool", + "b.md": "mcp mcp mcp server transport", + "c.md": "the quick brown fox jumps" + } + tfidf = compute_tfidf(docs) + a_keywords = top_keywords(tfidf["a.md"], n=3) + b_keywords = top_keywords(tfidf["b.md"], n=3) + assert "hooks" in a_keywords + assert "mcp" in b_keywords + assert "hooks" not in b_keywords +``` + +- [ ] **Step 11: Run tests to verify they fail** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v -k "tokenize or tfidf"` +Expected: 3 failed with ImportError + +- [ ] **Step 12: Implement tokenize, compute_tfidf, top_keywords** + +Append to `scripts/build_docs_map.py`: + +```python +import math +from collections import Counter + +STOPWORDS = { + 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', + 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'be', 'been', 'being', + 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should', + 'may', 'might', 'can', 'this', 'that', 'these', 'those', 'you', 'they', + 'what', 'which', 'who', 'when', 'where', 'how', 'why', 'all', 'each', 'every', + 'some', 'any', 'not', 'only', 'so', 'if', 'then', 'than', 'about', 'into', + 'through', 'between', 'use', 'using', 'used', 'one', 'two', 'three', 'first', + 'second', 'over', 'under', 'also', 'just', 'such', 'them', 'their', 'there', + 'here', 'its', 'his', 'her', 'our', 'your', 'see', 'make', 'made', + 'claude', 'code', 'anthropic', 'docs', 'documentation', + 'http', 'https', 'www', 'com', 'org', 'example', +} + + +def tokenize(text: str) -> list[str]: + """Tokenize text to words for keyword extraction.""" + text = strip_markdown(text).lower() + words = re.findall(r'\b[a-z][a-z0-9_-]{2,}\b', text) + return [w for w in words if w not in STOPWORDS] + + +def compute_tfidf(documents: dict) -> dict: + """Compute TF-IDF scores for all documents.""" + tfs = {name: Counter(tokenize(content)) for name, content in documents.items()} + df = Counter() + for name, tf in tfs.items(): + for term in tf: + df[term] += 1 + n_docs = len(documents) or 1 + tfidf = {} + for name, tf in tfs.items(): + total_terms = sum(tf.values()) or 1 + scores = {} + for term, freq in tf.items(): + tf_norm = freq / total_terms + idf = math.log(n_docs / df[term]) if df[term] else 0 + scores[term] = tf_norm * idf + tfidf[name] = scores + return tfidf + + +def top_keywords(tfidf_scores: dict, n: int = 8) -> list[str]: + """Return top N keywords by TF-IDF score.""" + sorted_terms = sorted(tfidf_scores.items(), key=lambda x: -x[1]) + return [term for term, score in sorted_terms[:n]] +``` + +- [ ] **Step 13: Run tests to verify all pass** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v` +Expected: 10 passed + +- [ ] **Step 14: Write failing test for `build_map` output structure** + +Append to `scripts/test_build_docs_map.py`: + +```python +import tempfile +from build_docs_map import build_map + + +def test_build_map_writes_grouped_output(tmp_path): + docs_dir = tmp_path / "docs" + docs_dir.mkdir() + (docs_dir / "hooks.md").write_text("# Hooks\n\nHook event documentation.") + (docs_dir / "agent-sdk__overview.md").write_text("# Agent SDK\n\nSDK overview content.") + (docs_dir / "whats-new__2026-w19.md").write_text("# Week 19\n\nWeekly release notes.") + + output = docs_dir / "DOCS_MAP.md" + build_map(docs_dir=docs_dir, output_file=output) + + content = output.read_text() + assert "# Docs Map" in content + assert "## Agent SDK" in content + assert "## Weekly Updates" in content + assert "## General" in content + assert "### `hooks.md`" in content + assert "**Title:** Hooks" in content + assert "**Summary:**" in content + assert "**Keywords:**" in content + assert "DOCS_MAP.md" not in [line.strip() for line in content.split("###")[1:]] +``` + +- [ ] **Step 15: Run test to verify it fails** + +Run: `cd scripts && python -m pytest test_build_docs_map.py::test_build_map_writes_grouped_output -v` +Expected: FAIL with ImportError or "build_map() takes ..." + +- [ ] **Step 16: Implement `build_map`** + +Append to `scripts/build_docs_map.py`: + +```python +from datetime import datetime, timezone +from pathlib import Path + +DOCS_DIR_DEFAULT = Path(__file__).resolve().parent.parent / "docs" + + +def categorize(filename: str) -> str: + if filename.startswith("agent-sdk__"): + return "Agent SDK" + if filename.startswith("whats-new__"): + return "Weekly Updates" + return "General" + + +def build_map(docs_dir: Path = None, output_file: Path = None) -> None: + docs_dir = docs_dir or DOCS_DIR_DEFAULT + output_file = output_file or (docs_dir / "DOCS_MAP.md") + + docs = {} + for md_file in sorted(docs_dir.glob("*.md")): + if md_file.name == "DOCS_MAP.md": + continue + docs[md_file.name] = md_file.read_text(encoding="utf-8") + + if not docs: + print(f"No docs found in {docs_dir}") + return + + print(f"Indexing {len(docs)} documents...") + + tfidf = compute_tfidf(docs) + + grouped = {"Agent SDK": [], "Weekly Updates": [], "General": []} + for name in sorted(docs.keys()): + grouped[categorize(name)].append(name) + + lines = [] + lines.append("# Docs Map") + lines.append("") + now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") + lines.append(f"> Auto-generated by `scripts/build_docs_map.py` on {now}") + lines.append(f"> {len(docs)} files indexed.") + lines.append("") + lines.append("Used by the `/query` skill to identify relevant docs for a given question.") + lines.append("Each entry shows the file, its title, a short summary, and discriminative keywords (TF-IDF).") + lines.append("") + lines.append("---") + lines.append("") + + for group_name in ("Agent SDK", "Weekly Updates", "General"): + files = grouped[group_name] + if not files: + continue + lines.append(f"## {group_name}") + lines.append("") + for name in files: + content = docs[name] + title = extract_title(content, name) + summary = extract_summary(content) + keywords = top_keywords(tfidf[name]) + lines.append(f"### `{name}`") + lines.append(f"**Title:** {title}") + lines.append(f"**Summary:** {summary}") + lines.append(f"**Keywords:** {', '.join(keywords)}") + lines.append("") + + output_file.write_text("\n".join(lines), encoding="utf-8") + print(f"✓ Wrote {output_file} ({len(docs)} entries)") + + +if __name__ == "__main__": + build_map() +``` + +- [ ] **Step 17: Run all tests, verify all pass** + +Run: `cd scripts && python -m pytest test_build_docs_map.py -v` +Expected: 11 passed + +- [ ] **Step 18: Commit** + +```bash +git add scripts/build_docs_map.py scripts/test_build_docs_map.py +git commit -m "feat: add build_docs_map.py with TF-IDF keyword extraction" +``` + +--- + +## Task 3: Generate initial DOCS_MAP.md from real docs + +**Files:** +- Create: `docs/DOCS_MAP.md` + +- [ ] **Step 1: Run the script against the real docs folder** + +Run from repo root: +```bash +python scripts/build_docs_map.py +``` +Expected output: `Indexing 127 documents...` and `✓ Wrote .../docs/DOCS_MAP.md (127 entries)` + +- [ ] **Step 2: Spot-check the output** + +Run: `head -50 docs/DOCS_MAP.md` +Expected: H1 "Docs Map", generation timestamp, "127 files indexed", section headers (## Agent SDK, ## Weekly Updates, ## General), entries with title/summary/keywords. + +Run: `wc -l docs/DOCS_MAP.md` +Expected: ~640 lines (127 entries × 5 lines + headers). + +- [ ] **Step 3: Verify DOCS_MAP.md is not self-referencing** + +Run: `grep "^### .DOCS_MAP.md" docs/DOCS_MAP.md || echo "OK - not self-referencing"` +Expected: `OK - not self-referencing` + +- [ ] **Step 4: Commit** + +```bash +git add docs/DOCS_MAP.md +git commit -m "feat: add initial DOCS_MAP.md (127 entries)" +``` + +--- + +## Task 4: Add GitHub workflow for map auto-regeneration + +**Files:** +- Create: `.github/workflows/build-docs-map.yml` + +- [ ] **Step 1: Write the workflow file** + +File `.github/workflows/build-docs-map.yml`: + +```yaml +name: Build Docs Map + +on: + workflow_run: + workflows: ["Update Claude Code Documentation"] + types: [completed] + workflow_dispatch: + push: + branches: [main] + paths: + - 'scripts/build_docs_map.py' + - 'docs/**/*.md' + +permissions: + contents: write + +jobs: + build-map: + if: github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: main + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Build docs map + run: python scripts/build_docs_map.py + + - name: Commit if changed + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + if [[ -n "$(git status --porcelain docs/DOCS_MAP.md)" ]]; then + git add docs/DOCS_MAP.md + git commit -m "Update DOCS_MAP.md - $(date +'%Y-%m-%d')" + git push + else + echo "No changes to DOCS_MAP.md" + fi +``` + +- [ ] **Step 2: Lint the YAML (visual inspection)** + +Run: `python -c "import yaml; yaml.safe_load(open('.github/workflows/build-docs-map.yml'))"` +Expected: no output (parses successfully). + +- [ ] **Step 3: Commit** + +```bash +git add .github/workflows/build-docs-map.yml +git commit -m "ci: add build-docs-map workflow" +``` + +--- + +## Task 5: Add slash command file + +**Files:** +- Create: `claude-files/commands/query.md` + +- [ ] **Step 1: Write the slash command file** + +File `claude-files/commands/query.md`: + +```markdown +--- +description: Research Claude Code documentation by batching multi-question queries to specialized subagents +argument-hint: +--- + +The user has invoked /query with the following input: + +$ARGUMENTS + +Use the Skill tool to invoke the `query-orchestrator` skill. Pass the user query above as the skill's argument. Follow the skill's instructions exactly. +``` + +- [ ] **Step 2: Commit** + +```bash +git add claude-files/commands/query.md +git commit -m "feat: add /query slash command" +``` + +--- + +## Task 6: Add query-researcher subagent file + +**Files:** +- Create: `claude-files/agents/query-researcher.md` + +- [ ] **Step 1: Write the agent file** + +File `claude-files/agents/query-researcher.md`: + +````markdown +--- +name: query-researcher +description: Research a single sub-question by reading Claude Code documentation files and producing a structured answer file +tools: Read, Grep, Glob, Write, Bash +--- + +# Query Researcher + +You research ONE sub-question. You read the docs map, pick 2-5 relevant files, read them, then write a structured answer to a specific file path. + +## Input (provided in your prompt) + +The orchestrator gives you these fields: + +- `Task: ` — the parent task identifier +- `Query ID: [QUERY-N]` — your specific query slot +- `Question:` — the actual question text +- `Output file:` — exact path where you write the answer +- `Docs map:` — path to DOCS_MAP.md +- `Docs folder:` — path to the docs directory + +## Procedure + +### Step 1 — Pick relevant docs (max 5) + +Read the docs map with the Read tool. Match the question against entries via: + +- Title overlap +- Summary overlap +- Keyword overlap (each entry lists TF-IDF keywords) + +Prefer specific files over general ones (e.g., `hooks.md` over `overview.md` for a hooks question). If the question is broad with no specific match, pick 1 general + 2 specific. + +You may use Grep to find term-specific matches: + +```bash +grep -l "specific-term" ~/.claude-code-docs/docs/*.md | head -5 +``` + +### Step 2 — Read selected docs + +Use the Read tool on each selected file. **Hard cap: 5 files.** If a file you're reading references another that's clearly more relevant, swap rather than add. + +### Step 3 — Synthesize an answer + +Build an answer that: + +- Directly answers the question +- Cites which docs you used +- Quotes short relevant excerpts +- Is 200-500 words typical (longer only if necessary) +- Notes gaps or ambiguities when docs don't fully cover the question + +### Step 4 — Write the output file + +Use the Write tool to create the output file at the path provided in your input. Use this EXACT structure: + +```markdown +# Answer to [QUERY-N] + +**Question:** +**Task:** + +## Researched files + +- `docs/file1.md` — why relevant +- `docs/file2.md` — why relevant + +## Answer + + + +## Source excerpts + +> Short relevant quote from `file1.md` + +> Short relevant quote from `file2.md` + +## Notes + + +``` + +## Constraints + +- Read AT MOST 5 docs +- Write EXACTLY ONE output file (path given in input) +- Do NOT call other subagents (no Task tool) +- Do NOT fetch from the web (use only the local docs folder) +- If no docs match the question, write the output file with `## Answer\n_No matching documentation found for this question. Suggested related topics: ..._` +```` + +- [ ] **Step 2: Commit** + +```bash +git add claude-files/agents/query-researcher.md +git commit -m "feat: add query-researcher subagent" +``` + +--- + +## Task 7: Add query-orchestrator skill + +**Files:** +- Create: `claude-files/skills/query-orchestrator/SKILL.md` + +- [ ] **Step 1: Write the skill file** + +File `claude-files/skills/query-orchestrator/SKILL.md`: + +````markdown +--- +name: query-orchestrator +description: Use when handling /query slash command — parses multi-part questions, dispatches batched subagents to research docs, and assembles final answer +--- + +# Query Orchestrator + +You orchestrate research on Claude Code documentation when the user invokes `/query`. You decompose the user's input into sub-questions, dispatch a `query-researcher` subagent for each in batches of 3 parallel, and assemble all answers into a single output file. + +## Inputs + +The slash command passes the user's raw query as your argument. Examples: + +- "What are hooks?" (single question, N=1) +- "Explain hooks and MCP, and how to integrate them" (3 sub-questions) +- "1. ... 2. ... 3. ..." (explicit numbering) + +## Step-by-step procedure + +### Step 1 — Parse into sub-questions + +Identify each independent factual sub-question in the user's input. A sub-question is something a researcher could answer alone by reading docs. + +Rules: + +- One cohesive question → N = 1 +- Explicit numbering (1./2./3. or bullets) → follow numbering +- Independent parts joined by `and`/`ve` → split (only if each part is independently answerable) +- Trim and normalize each sub-question to a clear standalone form + +Output internally: + +``` +SUB_QUESTIONS = [ + "What are hooks?", + "What is MCP?", + "How to integrate hooks with MCP?" +] +N = 3 +``` + +### Step 2 — Generate task ID + +- Take the first sub-question's most discriminative content word, skipping stopwords (`the`, `a`, `what`, `how`, `is`, `does`). +- Lowercase, ASCII-normalize, slugify. +- If no content word can be identified (e.g., "How does it work?"), use the literal keyword `query`. +- Append current epoch milliseconds via Bash: `date +%s%3N`. +- Format: `QUERY-TASK--`. +- Example: `QUERY-TASK-hooks-1715432100123`. + +### Step 3 — Create task folder + +Use the Bash tool: + +```bash +mkdir -p ~/.claude-code-docs/query/ +``` + +### Step 4 — Write initial query.md + +Use the Write tool to create `~/.claude-code-docs/query//query.md` from this template (substitute placeholders): + +```markdown +# Query Task: + +**Original user query:** +> + +**Created at:** +**Number of sub-questions:** +**Status:** in-progress + +--- + +## [QUERY-1] — + +**Question:** + +**Answer:** + +_pending — researcher dispatched_ + + +--- + +## [QUERY-2] — + +**Question:** + +**Answer:** + +_pending — researcher dispatched_ + + +--- + + +``` + +`SHORT_TITLE_n` is a 3-5 word descriptor you derive from the sub-question (e.g., "What are hooks?" → "Hooks definition"). + +### Step 5 — Dispatch subagents in batches of 3 + +**CRITICAL:** All Task tool calls in one batch MUST be sent in a SINGLE message to execute in parallel. If you send them in separate messages they will execute sequentially. + +Batching table: + +| N | Batches | +|----|--------------| +| 1 | [1] | +| 2 | [2] | +| 3 | [3] | +| 4 | [3, 1] | +| 5 | [3, 2] | +| 7 | [3, 3, 1] | +| 15 | [3, 3, 3, 3, 3] | + +For each batch of up to 3 consecutive sub-questions: + +1. In a SINGLE message, issue up to 3 parallel Task tool calls. +2. Each Task call uses `subagent_type: query-researcher`. +3. Wait for ALL calls in the batch to return before starting the next batch. + +Each Task call prompt MUST contain these exact fields: + +``` +Task: +Query ID: [QUERY-N] +Question: +Output file: ~/.claude-code-docs/query//QUERY-.md +Docs map: ~/.claude-code-docs/docs/DOCS_MAP.md +Docs folder: ~/.claude-code-docs/docs/ +``` + +### Step 6 — Assemble answers into final query.md + +After ALL batches complete: + +1. Issue parallel Read calls for every `QUERY-N.md` (single message, N Read tool calls). +2. For each file, extract everything below the H1 header (`# Answer to [QUERY-N]`) — this is the answer body. +3. Build the complete final `query.md` in memory: header (TASK_ID, original query, timestamp, N, `Status: complete`), then for each [QUERY-N] the question text plus the extracted body (replacing the `_pending_` placeholder). +4. Single Write call overwrites `query.md` with the complete assembled content. + +If a `QUERY-N.md` is missing (subagent failed): + +- Insert: `_⚠️ Researcher did not complete this query. Re-run `/query` for just this question._` in place of the answer body. + +### Step 7 — Chat summary + +Output to chat: + +``` +✓ Query complete: ( questions) + +• [QUERY-1] +• [QUERY-2] +• ... + +Full details: ~/.claude-code-docs/query//query.md +``` + +Keep each bullet to one line. Do not paste the full answers in chat. + +## Failure handling + +| Failure | Handling | +|---------|----------| +| `mkdir` fails | Abort with error message; do not dispatch subagents | +| DOCS_MAP.md missing | Tell user to re-run `~/.claude-code-docs/install.sh` | +| Subagent returns no file | Insert warning placeholder for that query; continue with others | +| Parsing yields N=0 | Ask user to rephrase the query | +```` + +- [ ] **Step 2: Commit** + +```bash +git add claude-files/skills/query-orchestrator/SKILL.md +git commit -m "feat: add query-orchestrator skill" +``` + +--- + +## Task 8: Extend install.sh with /query setup + +**Files:** +- Modify: `install.sh` + +- [ ] **Step 1: Read current end of install.sh to find insertion point** + +Run: `grep -n "Available topics" install.sh` +Expected: returns a line number (the success message). Insert BEFORE this line. + +- [ ] **Step 2: Add the /query install block** + +Find this section in `install.sh`: + +```bash +# Clean up old installations now that v0.3 is set up +cleanup_old_installations + +# Success message +echo "" +echo "✅ Claude Code Docs v0.3.3 installed successfully!" +``` + +Insert the following block BETWEEN `cleanup_old_installations` and `# Success message`: + +```bash +# Setup /query feature (skill + agent + command) +echo "" +echo "Installing /query feature..." + +mkdir -p ~/.claude/commands +mkdir -p ~/.claude/agents +mkdir -p ~/.claude/skills/query-orchestrator + +if [[ -d "$INSTALL_DIR/claude-files" ]]; then + cp "$INSTALL_DIR/claude-files/commands/query.md" \ + ~/.claude/commands/query.md + cp "$INSTALL_DIR/claude-files/agents/query-researcher.md" \ + ~/.claude/agents/query-researcher.md + cp "$INSTALL_DIR/claude-files/skills/query-orchestrator/SKILL.md" \ + ~/.claude/skills/query-orchestrator/SKILL.md + echo "✓ Installed /query command, query-researcher agent, query-orchestrator skill" +else + echo "⚠️ claude-files/ missing — /query feature will not be available" +fi + +mkdir -p "$INSTALL_DIR/query" +echo "✓ Query workspace ready at $INSTALL_DIR/query" +``` + +- [ ] **Step 3: Validate the script syntax** + +Run: `bash -n install.sh` +Expected: no output (syntax valid). + +- [ ] **Step 4: Smoke-test against the local checkout** + +Run from the repo root: +```bash +INSTALL_DIR="$(pwd)" bash -c ' +mkdir -p ~/.claude/commands ~/.claude/agents ~/.claude/skills/query-orchestrator +cp "$INSTALL_DIR/claude-files/commands/query.md" ~/.claude/commands/query.md +cp "$INSTALL_DIR/claude-files/agents/query-researcher.md" ~/.claude/agents/query-researcher.md +cp "$INSTALL_DIR/claude-files/skills/query-orchestrator/SKILL.md" ~/.claude/skills/query-orchestrator/SKILL.md +ls -l ~/.claude/commands/query.md ~/.claude/agents/query-researcher.md ~/.claude/skills/query-orchestrator/SKILL.md +' +``` +Expected: 3 files listed with their sizes. + +- [ ] **Step 5: Commit** + +```bash +git add install.sh +git commit -m "feat: extend install.sh to deploy /query files" +``` + +--- + +## Task 9: Extend uninstall.sh with /query removal + +**Files:** +- Modify: `uninstall.sh` + +- [ ] **Step 1: Find insertion point** + +Run: `grep -n "Remove directories" uninstall.sh` +Expected: returns a line number. Insert the new block BEFORE this section. + +- [ ] **Step 2: Add the /query removal block** + +In `uninstall.sh`, find this section: + +```bash +echo "✓ Removed hooks (backup: ~/.claude/settings.json.backup)" +``` + +Insert the following block AFTER it (before `# Remove directories`): + +```bash +# Remove /query feature files +echo "" +echo "Removing /query feature..." + +[[ -f ~/.claude/commands/query.md ]] && rm -f ~/.claude/commands/query.md && echo "✓ Removed /query command" +[[ -f ~/.claude/agents/query-researcher.md ]] && rm -f ~/.claude/agents/query-researcher.md && echo "✓ Removed query-researcher agent" +[[ -d ~/.claude/skills/query-orchestrator ]] && rm -rf ~/.claude/skills/query-orchestrator && echo "✓ Removed query-orchestrator skill" + +if [[ -d "$HOME/.claude-code-docs/query" ]] && [[ -n "$(ls -A "$HOME/.claude-code-docs/query" 2>/dev/null)" ]]; then + echo "" + echo "⚠️ Found query outputs at $HOME/.claude-code-docs/query/" + read -p "Delete query history? (y/N): " -n 1 -r + echo + [[ $REPLY =~ ^[Yy]$ ]] && rm -rf "$HOME/.claude-code-docs/query" && echo "✓ Removed query history" +fi +``` + +- [ ] **Step 3: Validate the script syntax** + +Run: `bash -n uninstall.sh` +Expected: no output. + +- [ ] **Step 4: Commit** + +```bash +git add uninstall.sh +git commit -m "feat: extend uninstall.sh to remove /query files" +``` + +--- + +## Task 10: Update README.md + +**Files:** +- Modify: `README.md` + +- [ ] **Step 1: Add the /query section** + +In `README.md`, find this line: + +```markdown +### Customize command name +``` + +Insert the following section ABOVE it (between the existing `### Read Claude Code changelog` section and `### Customize command name`): + +````markdown +### Multi-question research with /query + +`/query` parses your input into sub-questions, dispatches research subagents in batches of 3 in parallel, and assembles a structured answer file. + +```bash +/query What is a hook? # single question +/query Explain hooks and MCP, then compare them # multi-part +/query 1. ... 2. ... 3. ... # explicit numbering +``` + +Each query produces a folder under `~/.claude-code-docs/query/QUERY-TASK--/` +containing the full structured answer with citations. Useful for non-trivial questions that span multiple docs. + +```` + +- [ ] **Step 2: Commit** + +```bash +git add README.md +git commit -m "docs: document /query feature in README" +``` + +--- + +## Task 11: Update CLAUDE.md + +**Files:** +- Modify: `CLAUDE.md` + +- [ ] **Step 1: Add /query section** + +In `CLAUDE.md`, find this section: + +```markdown +## For /docs Command + +When responding to /docs commands: +1. Follow the instructions in the docs.md command file +2. Read documentation files from the docs/ directory only +3. Use the manifest to know available topics +``` + +Insert the following block AFTER it (before `## Files to ultrathink about`): + +```markdown +## For /query Command + +When responding to /query commands: +1. Invoke the `query-orchestrator` skill via the Skill tool +2. Follow the skill's 7-step procedure (parse → task ID → folder → template → batch dispatch → assemble → summary) +3. Subagents read from docs/ folder via DOCS_MAP.md +4. Outputs accumulate in ~/.claude-code-docs/query/ +``` + +- [ ] **Step 2: Extend ultrathink list** + +In `CLAUDE.md`, find: + +```markdown +## Files to ultrathink about + +@install.sh +@README.md +@uninstall.sh +@UNINSTALL.md +@claude-docs-helper.md +@scripts/ +@.github/workflows/ +``` + +Replace with: + +```markdown +## Files to ultrathink about + +@install.sh +@README.md +@uninstall.sh +@UNINSTALL.md +@claude-docs-helper.md +@scripts/ +@.github/workflows/ +@docs/DOCS_MAP.md +@claude-files/ +``` + +- [ ] **Step 3: Commit** + +```bash +git add CLAUDE.md +git commit -m "docs: document /query in CLAUDE.md and extend ultrathink list" +``` + +--- + +## Task 12: End-to-end manual validation + +**Files:** none (manual testing) + +- [ ] **Step 1: Reinstall locally to deploy the new files** + +Run from repo root: +```bash +# Simulate a fresh install pointing at the local checkout +INSTALL_DIR="$(pwd)" bash -x install.sh 2>&1 | tail -30 +``` + +Note: this assumes `install.sh` has been adapted to use `INSTALL_DIR` (it does — already defined at the top). If the existing install.sh resists running from a non-default location, instead simulate the relevant steps: + +```bash +mkdir -p ~/.claude/commands ~/.claude/agents ~/.claude/skills/query-orchestrator +cp claude-files/commands/query.md ~/.claude/commands/query.md +cp claude-files/agents/query-researcher.md ~/.claude/agents/query-researcher.md +cp claude-files/skills/query-orchestrator/SKILL.md ~/.claude/skills/query-orchestrator/SKILL.md +mkdir -p "$HOME/.claude-code-docs/query" +``` + +Verify: +```bash +ls -l ~/.claude/commands/query.md ~/.claude/agents/query-researcher.md ~/.claude/skills/query-orchestrator/SKILL.md +``` +Expected: 3 files exist. + +- [ ] **Step 2: Restart Claude Code, then test N=1** + +In Claude Code: `/query What is a hook?` + +Expected: +- Task folder created at `~/.claude-code-docs/query/QUERY-TASK--/` +- `query.md` exists with `Status: complete` +- One answer assembled from at least one doc file + +Verify: +```bash +ls ~/.claude-code-docs/query/ +cat ~/.claude-code-docs/query/QUERY-TASK-*/query.md +``` + +- [ ] **Step 3: Test N=3 (single batch of 3 parallel)** + +In Claude Code: `/query Explain hooks, MCP, and how to integrate them` + +Expected: +- New task folder +- 3 `QUERY-N.md` files exist +- `query.md` shows all 3 answers assembled + +Verify: +```bash +ls ~/.claude-code-docs/query/QUERY-TASK-* | tail -1 | xargs ls +``` +Expected: `query.md`, `QUERY-1.md`, `QUERY-2.md`, `QUERY-3.md`. + +- [ ] **Step 4: Test N=5 (batches of [3, 2])** + +In Claude Code: `/query 1. What are hooks? 2. What is MCP? 3. What are skills? 4. How do plugins work? 5. What is the Agent SDK?` + +Expected: +- 5 `QUERY-N.md` files +- `query.md` assembled with all 5 answers + +- [ ] **Step 5: Test edge case — DOCS_MAP.md missing** + +```bash +mv ~/.claude-code-docs/docs/DOCS_MAP.md /tmp/DOCS_MAP.md.bak +``` + +In Claude Code: `/query What is a hook?` + +Expected: skill produces a clear error message instructing the user to re-run install.sh or rebuild the map. + +Restore: +```bash +mv /tmp/DOCS_MAP.md.bak ~/.claude-code-docs/docs/DOCS_MAP.md +``` + +- [ ] **Step 6: Test uninstall** + +Run: `bash uninstall.sh` +Expected: +- Files removed: `~/.claude/commands/query.md`, `~/.claude/agents/query-researcher.md`, `~/.claude/skills/query-orchestrator/` +- Prompted to delete `~/.claude-code-docs/query/` (answer N to keep history) + +- [ ] **Step 7: Reinstall to leave system in working state** + +Run the simulated install commands from Step 1 again. Verify `/query` works again with a single-question test. + +--- + +## Task 13: Final repo review and push + +**Files:** none (review + push) + +- [ ] **Step 1: Run the full test suite** + +```bash +cd scripts && python -m pytest test_build_docs_map.py -v +``` +Expected: all tests pass. + +- [ ] **Step 2: Check git log shows clean commits** + +Run: `git log --oneline main..HEAD` +Expected: 12 commits (one per task), with conventional commit messages. + +- [ ] **Step 3: Squash if requested or push as-is** + +Push the branch: +```bash +git push -u origin feature/query-orchestrator +``` + +- [ ] **Step 4: Open a draft PR for early maintainer feedback** + +(User action) Open a draft PR on GitHub with body: +- Link to spec doc in branch +- Summary of new features +- Note: existing `/docs` is unchanged +- Test results + +--- + +## Self-Review + +**Spec coverage check (every section of the spec mapped to a task):** + +| Spec § | Task | +|--------|------| +| §5 Map generation | Task 1 (fixtures), Task 2 (script+tests), Task 3 (initial map) | +| §6 Slash command | Task 5 | +| §7 Skill | Task 7 | +| §8 Subagent | Task 6 | +| §9 GitHub workflow | Task 4 | +| §10 install.sh | Task 8 | +| §10 uninstall.sh | Task 9 | +| §11 README.md | Task 10 | +| §11 CLAUDE.md | Task 11 | +| §12 Test plan | Task 2 (unit), Task 12 (manual) | +| §14 Acceptance criteria | Task 12 (end-to-end) + Task 13 (review) | + +All spec sections covered. + +**Type/signature consistency:** + +- `extract_title(content, filename)` — used consistently in tests and implementation ✓ +- `extract_summary(content, max_chars=200)` — consistent ✓ +- `tokenize(text) -> list[str]` — consistent ✓ +- `compute_tfidf(documents: dict) -> dict` — consistent ✓ +- `build_map(docs_dir=None, output_file=None)` — accepts overrides for testing ✓ + +**Placeholder check:** No "TBD", "TODO", "implement later", or vague guidance. Every code step shows complete code. + +--- + +## Execution Handoff + +Plan complete and saved to `specs/2026-05-11-query-orchestrator-plan.md`. Two execution options: + +1. **Subagent-Driven (recommended)** — I dispatch a fresh subagent per task, review between tasks, fast iteration. +2. **Inline Execution** — Execute tasks in this session using executing-plans, batch execution with checkpoints. + +Which approach? diff --git a/uninstall.sh b/uninstall.sh index 08344bcb8..ed0e1d3ef 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -104,6 +104,22 @@ if [[ -f ~/.claude/settings.json ]]; then echo "✓ Removed hooks (backup: ~/.claude/settings.json.backup)" fi +# Remove /query feature files +echo "" +echo "Removing /query feature..." + +[[ -f ~/.claude/commands/query.md ]] && rm -f ~/.claude/commands/query.md && echo "✓ Removed /query command" +[[ -f ~/.claude/agents/query-researcher.md ]] && rm -f ~/.claude/agents/query-researcher.md && echo "✓ Removed query-researcher agent" +[[ -d ~/.claude/skills/query-orchestrator ]] && rm -rf ~/.claude/skills/query-orchestrator && echo "✓ Removed query-orchestrator skill" + +if [[ -d "$HOME/.claude-code-docs/query" ]] && [[ -n "$(ls -A "$HOME/.claude-code-docs/query" 2>/dev/null)" ]]; then + echo "" + echo "⚠️ Found query outputs at $HOME/.claude-code-docs/query/" + read -p "Delete query history? (y/N): " -n 1 -r + echo + [[ $REPLY =~ ^[Yy]$ ]] && rm -rf "$HOME/.claude-code-docs/query" && echo "✓ Removed query history" +fi + # Remove directories if [[ ${#installations[@]} -gt 0 ]]; then echo ""