name: cqs-plan
description: Task planning with scout data + task-type templates. Produces implementation checklists.
disable-model-invocation: false
argument-hint: ""
Plan
Generate an implementation plan by combining cqs scout output with a task-type template.
Process
- Classify the task into one of the templates below based on the description.
- Run scout:
cqs scout "<task description>" --json 2>/dev/null(no-qflag on subcommands) - Run targeted lookups from the template's checklist — scout alone misses structural touchpoints (clap structs, dispatch arms, skill files).
- Produce a plan listing every file to change, what to change, and why. Be specific about struct fields, function signatures, and match arms.
Arguments
$ARGUMENTS— task description (required)
Templates
Add/Replace a CLI Flag
When: Adding a new flag, renaming a flag, changing a flag's type (bool → enum).
Checklist:
src/cli/definitions.rs—Commandsenum variant. Add/modify#[arg]field (often via a shared*Argsstruct insrc/cli/args.rs). If enum-typed, define withclap::ValueEnum.src/cli/dispatch.rs—run_with()/run_with_dispatch()match arm. Update destructuring andcmd_<name>()call.src/cli/commands/<group>/<name>.rs(groups: search/, graph/, review/, index/, io/, infra/, eval/, train/) — flag flows into the*_corefn's typed*Args; update branching there, not just the CLI adapter.- Daemon surface: if the flag affects core behavior, the daemon
dispatch_*handler insrc/cli/batch/handlers/must forward it too — CLI and daemon are parallel surfaces, wire both in the same PR. Parity tests live insrc/cli/batch/handlers/dispatch_tests.rs. src/store/*.rs/src/lib.rs— Usually NO changes. Only if flag affects query behavior.- Tests:
tests/<name>_test.rs— add case for new value. Update tests using old flag name. .claude/skills/cqs/SKILL.md— update the command's flag table.README.md— update examples if the command is featured.- Verify callers:
cqs callers cmd_<name> --json
Patterns:
- Output format flags:
#[arg(long, value_enum, default_value_t)] - Display functions:
display_<name>_text(),display_<name>_json() - JSON output:
serde_json::to_string_prettyon#[derive(Serialize)]structs
Add a New CLI Command
When: Adding an entirely new cqs <command>.
Checklist (command-core pattern — the NEW-COMMAND RULE, see CONTRIBUTING):
src/cli/commands/<group>/<name>.rs— New file in the right group (search/, graph/, review/, index/, io/, infra/). Implement ONE surface-agnostic<name>_core(...)taking a typed Deserialize<Name>Argsand returning a Serialize<Name>Output.cmd_<name>()is a thin CLI adapter over the core.src/cli/commands/<group>/mod.rs— Addmod <name>;and re-exportcmd_<name>(+ the core for the daemon).src/cli/definitions.rs— Add variant toCommandsenum with args (shared*Argsstructs live insrc/cli/args.rs).src/cli/dispatch.rs— Add match arm callingcmd_<name>().- Daemon surface in the same PR:
dispatch_<name>adapter insrc/cli/batch/handlers/(thin wrapper: parse wire request into<Name>Args, call the core). Add a CLI==daemon parity test insrc/cli/batch/handlers/dispatch_tests.rs. src/lib.rsorsrc/<module>.rs— Library function if logic is non-trivial. Keep CLI layer thin.- Tests:
tests/<name>_test.rs— integration tests usingTestStoreorassert_cmd. .claude/skills/cqs/SKILL.md— add the command to the dispatcher reference (and acqs-<name>skill only if the workflow warrants it)..claude/skills/cqs-bootstrap/SKILL.md— Add to portable skills list / command reference.CLAUDE.md— Add to "Key commands" list.README.md— Add to command reference.CONTRIBUTING.md— Update Architecture Overview if adding new source files.
Patterns:
- Command files are ~50-150 lines. Store/library calls, then display.
- JSON output with
--jsonflag; text output via a display fn the daemon can reuse. - Tracing span at core entry:
let _span = tracing::info_span!("<name>_core").entered();
Fix a Bug
When: Something produces wrong results, panics, or misbehaves.
Checklist:
- Reproduce: Understand the exact failure mode. Get input → actual → expected.
- Locate:
cqs scout "<bug description>"to find relevant code. - Trace callers:
cqs callers <function> --json— who calls the buggy code? Are callers also affected? - Check tests:
cqs test-map <function> --json— do tests exist? Do they cover the failing case? - Fix: Minimal change in the library layer, not the CLI layer.
- Add test: Regression test that would have caught this bug.
- Check impact:
cqs impact <function> --json— did the fix change behavior for other callers?
Patterns:
- Fix in
src/*.rs(library), test intests/*.rsor inline#[cfg(test)]. - Use
tracing::warn!for recoverable errors,bail!for unrecoverable. - Never
.unwrap()in library code.?ormatch+tracing::warn!.
Add Language Support
When: Adding a new programming language to the parser.
Checklist:
Cargo.toml— Add tree-sitter grammar dependency (optional).src/language/mod.rs— Add to thedefine_languages!macro invocation.src/language/languages.rs— Add the language'sLanguageDefblock (grammar wiring, extensions, extract/post-process hooks). Per-language files no longer exist — everything lives in this one file.src/language/queries/<lang>.chunks.scm+<lang>.calls.scm(+.types.scmif type deps apply) — tree-sitter queries live as standalone.scmfiles, not inline strings.Cargo.tomlfeatures — Addlang-<name>feature, add todefaultandlang-all.- Tests:
tests/fixtures/<lang>/— sample files. Parser tests intests/parser_test.rs. tests/eval_test.rsandtests/model_eval.rs— Add match arms.
Patterns:
- One-liner in
define_languages!handles registration. - Chunk query captures must use the parser's known capture names (see
src/parser/chunk.rs): function, struct, class, enum, trait, interface, const, ... - Call query uses
@calleecapture.
Add ChunkType Variant
When: Adding a new chunk type (e.g., Extension, Protocol, Alias).
Checklist:
src/language/mod.rs— Add variant to thedefine_chunk_types!invocation (ChunkType lives here now). Classify it sois_callable()/is_code()derive correctly — a round-trip test enforces consistency.src/nl/mod.rs— Add natural language label for the variant (used in embedding text).src/language/queries/<lang>.chunks.scm— Add capture using the new variant name.src/parser/chunk.rs— Add to the capture-name map if using a new capture name.src/cli/commands/index/stats.rs— Variant appears automatically viaChunkTypeiteration.- Tests: Parser tests for each language using the new variant. Verify
cqs searchreturns results with correct type. ROADMAP.md— Update ChunkType Variant Status table.
Patterns:
is_callable()returns true for Function, Method, Macro — most others return false.Displayuses lowercase singular (e.g., "type_alias").FromStraccepts both snake_case and spaces.- Container extraction uses
capture_typesto decide what's a container vs leaf.
Add Injection Rule
When: Adding multi-grammar parsing (e.g., HTML→JS, PHP→HTML, Svelte→CSS).
Checklist:
src/language/languages.rs(host language's block) — AddInjectionRuleto the host's injection rules. Specifyparent_node,content_node,target_language, and optionaldetect_languagecallback.src/language/languages.rs(target language's block) — Ensure the target'sLanguageDefexists and parses correctly in isolation.src/parser/injection.rs— Usually NO changes. Only if new detection logic is needed (e.g.,detect_script_language,detect_heredoc_language).- Tests:
tests/fixtures/<host>/— sample file with embedded content. Verify chunks from both host and injected language appear. - Verify depth limit: recursive injections (PHP→HTML→JS) must respect depth limit (default 3).
ROADMAP.md— Update Multi-Grammar Parsing section.
Patterns:
content_scoped_linesprevents container-spans-file problem in recursive injection.detect_languagecallbacks inspect attributes (e.g.,lang="ts",type="module").set_included_ranges()for byte-range isolation of injected content.
Performance Optimization
When: Improving speed or reducing resource usage for a specific operation.
Checklist:
- Benchmark before:
cargo benchor manual timing withtime cqs <command>. Record baseline. - Profile:
cqs scout "<bottleneck description>"to find hot path.cqs callersto trace the call chain. - Identify approach: Lazy loading, caching, reduced allocations, parallel iteration, candidate pruning.
- Implement: Minimal change. Prefer data structure changes over algorithmic rewrites.
- Benchmark after: Same benchmark as step 1. Quantify improvement.
- Regression test: Ensure correctness is preserved — same inputs produce same outputs.
- Check callers:
cqs impact <function> --json— did the optimization change the API surface?
Patterns:
- HNSW candidate fetch: load only
(id, embedding)for scoring, full content for top-k. - Rayon
par_iterfor embarrassingly parallel work. Check for shared mutable state first. tracing::info_span!around hot paths for flame graph visibility.
Audit Finding Fix
When: Fixing an issue identified during a code audit (from docs/audit-triage.md).
Checklist:
- Read triage entry: Get priority, category, description, and affected code from
docs/audit-triage.md. - Locate:
cqs scout "<finding description>"— verify the issue still exists (may have been fixed since audit). - Assess scope:
cqs impact <function> --json— how many callers are affected? - Fix: Follow the triage entry's suggested approach if provided.
- Add test: Cover the specific scenario from the finding.
- Update triage: Mark entry as fixed in
docs/audit-triage.mdwith PR reference. - Check related findings: Same category may have related issues — fix together if trivial.
Patterns:
- P1 findings: fix immediately, standalone PR.
- P2-P3: batch by category into single PR.
- P4: fix opportunistically when touching nearby code.
Add Tree-Sitter Grammar
When: Adding a new tree-sitter grammar dependency (new language or replacing a grammar).
Checklist:
Cargo.toml— Add grammar crate as optional dependency. Prefer crates.io; use git dep withrevpin if unpublished.build.rs— Usually NO changes (grammars self-register viatree-sitter-languagecrate).src/language/<lang>.rs— Wire grammar viatree_sitter_<lang>::LANGUAGEortree_sitter_<lang>::language().Cargo.tomlfeatures — Add tolang-<name>feature gate. Add todefaultandlang-all.- Verify compatibility: grammar must target tree-sitter
>=0.24, <0.27(current range). Check grammar'sCargo.toml. - Tests:
cargo test --features lang-<name>— parser produces expected chunks. - If forked: document fork reason in
Cargo.tomlcomment. Track upstream for eventual switch.
Patterns:
- Git deps need
revpin, notbranch— branches break reproducibility. - Some grammars export
LANGUAGE(static), otherslanguage()(function). Check their API. - Monolithic grammars (Razor, VB.NET) don't need injection — they parse everything in one pass.
Schema Migration
When: Bumping the SQLite schema version (adding tables, columns, or changing data layout).
Checklist:
src/store/helpers/mod.rs— BumpCURRENT_SCHEMA_VERSIONconstant.src/store/migrations.rs— Addasync fn migrate_vN_to_vM()with ALTER TABLE / CREATE TABLE statements.src/store/migrations.rs— Register it in theMIGRATIONStable as(N, M, |c| Box::pin(migrate_vN_to_vM(c))).src/store/mod.rs— Updateopen()if new tables need initialization or if Store fields changed.src/schema.sqlmust reflect the new layout (its header states the version).src/store/*.rs— Update queries that read/write affected tables.- Tests: Migration test with a v(N-1) database → verify v(N) upgrade succeeds and data is preserved.
PROJECT_CONTINUITY.md— Update schema version in Architecture section.
Patterns:
- Migrations must be idempotent —
IF NOT EXISTS,IF NOT COLUMNguards. - We use a metadata table for schema_version, not PRAGMA user_version.
- Test with a real old-version database if available (copy from
.cqs/before upgrading). cqs migrateskill handles user-facing migration workflow.
Refactor / Extract
When: Moving code, splitting files, extracting shared helpers.
Checklist:
- Find all call sites:
cqs callers <function> --jsonfor each function being moved. - Check similar code:
cqs similar <function> --jsonto find duplicates to consolidate. - Plan visibility:
pub(crate)for cross-module,pubfor public API, private for same-module. - Move tests with code:
#[cfg(test)] mod testsworks in submodules. - Update imports: Each file needs its own
usestatements — they don't carry across modules. - Verify callers compile: After moving, all callers must update their
usepaths. CONTRIBUTING.md— Update Architecture Overview for structural changes.
Patterns:
impl Fooblocks can live in separate files (Rust allows multiple).- Trait method imports don't carry over to submodule files.
- Use
pub(crate)for types/constants shared across submodules.
Output Format
Present the plan as:
## Plan: <task summary>
### Files to Change
1. **<file>** — <what and why>
- <specific change with code snippet>
### Tests
- <test file>: <what to test>
### Not Changed (verified)
- <file>: <why no changes needed>
When Not to Use
- Trivial changes (typos, single-line fixes) — just do it
- Pure research — use
cqs gatherorcqs scoutdirectly - Running an audit — use
/auditskill (but audit finding fixes have a template above)