Skip to content

Commit 002ef7b

Browse files
committed
docs(plans): draft targeted-read-cli (codemap show)
One-step CLI verb for 'where is this symbol' — codemap show <symbol> returns file_path:line_start-line_end + signature. Pure ergonomic affordance over SELECT … FROM symbols WHERE name = ?; no schema change. Plan covers surface (show + --all + --kind + --in flags), wiring (cmd-show.ts + show-engine.ts mirroring cmd-context/cmd-validate), MCP integration via the plan §35 pattern, and a 4-commit tracer-bullet sequence (~half day). 5 open questions worth a grill round before code: MCP tool registration, multiple-match UX (error vs list), exact vs fuzzy matching, file-scope filter, snippet-sibling timing. Status: design pass; not yet implemented.
1 parent abee731 commit 002ef7b

2 files changed

Lines changed: 139 additions & 1 deletion

File tree

docs/plans/targeted-read-cli.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
## Plan — `targeted-read-cli`
2+
3+
> One-step CLI verb for "tell me where this symbol is" — `codemap show <symbol>` returns `file_path:line_start-line_end` + `signature` for the symbol(s) matching the name. Pure ergonomic affordance over `SELECT … FROM symbols WHERE name = ?`; agents stop having to compose SQL for trivial precise-read questions.
4+
>
5+
> Adopted from [`docs/roadmap.md` § Backlog](../roadmap.md#backlog) ("Targeted-read CLI"). Builds on the symbols table that's been there since v0; no schema changes.
6+
7+
**Status:** Open — design pass; not yet implemented.
8+
**Cross-refs:** [`docs/architecture.md` § CLI usage](../architecture.md#cli-usage) (`show` becomes a sibling of `query` / `audit` / `mcp`); the existing `query` recipe surface is unaffected.
9+
10+
---
11+
12+
## 1. Goal
13+
14+
Today an agent that wants to find the `runQueryCmd` symbol composes:
15+
16+
```bash
17+
codemap query --json "SELECT name, file_path, line_start, line_end, signature FROM symbols WHERE name = 'runQueryCmd'"
18+
```
19+
20+
After v1:
21+
22+
```bash
23+
codemap show runQueryCmd
24+
# → src/cli/cmd-query.ts:521-606 export async function runQueryCmd(opts: …): Promise<void>
25+
```
26+
27+
The wins:
28+
29+
- **Tokens.** ~25-token CLI invocation vs ~80-token SQL. Multiplies across a session where the agent does this hundreds of times.
30+
- **Agent affordance.** "Find this name" is the most common precise-read question agents ask; making it a one-step CLI removes a derivation step.
31+
- **Composability stays.** `--json` returns the same row shape; agents that already know SQL can keep using `query` for cases `show` doesn't cover.
32+
33+
## 2. Surface
34+
35+
```text
36+
codemap show <name> [--json] [--all] [--kind <kind>]
37+
```
38+
39+
| Flag | Default | Behavior |
40+
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
41+
| `<name>` | required | Exact symbol name (case-sensitive). Maps to `WHERE name = '<name>'`. |
42+
| `--json` | off | Emit the JSON envelope (array of row objects). Without it, terminal-friendly `path:line-line signature` per row. |
43+
| `--all` | off | Show every match. Default: error if more than one match (forces the agent to disambiguate via `--kind` or by being more specific). |
44+
| `--kind <kind>` | unset | Filter by `kind` column (`function`, `class`, `interface`, `const`, `type`, etc.). Useful when overloaded names exist. |
45+
46+
**Output (terminal, single match):**
47+
48+
```
49+
src/cli/cmd-query.ts:521-606
50+
export async function runQueryCmd(opts: { … }): Promise<void>
51+
```
52+
53+
**Output (terminal, multiple matches with `--all`):**
54+
55+
```
56+
src/cli/cmd-query.ts:521-606
57+
export async function runQueryCmd(opts: { … }): Promise<void>
58+
59+
src/cli/cmd-query.test.ts:42-58
60+
function runQueryCmd(stub) { … }
61+
```
62+
63+
**Output (`--json`):**
64+
65+
```json
66+
[
67+
{
68+
"name": "runQueryCmd",
69+
"kind": "function",
70+
"file_path": "src/cli/cmd-query.ts",
71+
"line_start": 521,
72+
"line_end": 606,
73+
"signature": "export async function runQueryCmd(opts: { … }): Promise<void>"
74+
}
75+
]
76+
```
77+
78+
Same row shape as `SELECT name, kind, file_path, line_start, line_end, signature FROM symbols WHERE name = ?` — preserves the [plan § 4 uniformity](./agent-transports-NOTE.md) contract: any tool that's a thin wrapper over a CLI verb returns the verb's `--json` shape verbatim.
79+
80+
**Errors:**
81+
82+
- Unknown name → `{"error": "no symbol named '<name>'"}` on stdout (`--json`) or stderr otherwise; exit 1.
83+
- Multiple matches without `--all` or `--kind``{"error": "<n> symbols named '<name>'; use --all to list them or --kind to narrow"}`.
84+
85+
## 3. Why one verb, not two
86+
87+
The roadmap entry hedged `codemap show <symbol> / codemap snippet <name>`. Two verbs would imply two return shapes — but both end up returning the same data (path + line range + signature). One verb (`show`) is enough; the optional `--all` / `--kind` flags cover the disambiguation cases that might have justified a second verb. If a real consumer later asks for "the actual code body" (file content sliced to line_start-line_end), that's a different feature (`codemap snippet` returns text content, not metadata) and can ship as a sibling later — but defer until asked.
88+
89+
## 4. Wiring
90+
91+
Mirrors the `cmd-context.ts` / `cmd-validate.ts` shape (small CLI verb that calls a pure engine helper):
92+
93+
- **`src/cli/cmd-show.ts`** — argv parser, help text, terminal-mode renderer, `runShowCmd` orchestrator
94+
- **`src/application/show-engine.ts`** — pure `findSymbolsByName({db, name, kind?})` returning `SymbolMatch[]`
95+
- **`src/cli/main.ts`** dispatch entry for `rest[0] === "show"`
96+
- **`src/cli/bootstrap.ts`** — add `"show"` to the `validateIndexModeArgs` known-verbs list + help text
97+
98+
Reuses the `symbols` table directly — no new column, no new index (the existing `idx_symbols_name` already covers the lookup).
99+
100+
## 5. MCP integration
101+
102+
The MCP server (PR #35) auto-inherits via the same pattern as `audit` / `context` / `validate` — register a `show` tool that calls `findSymbolsByName` and returns the JSON envelope. Per Q-1 below.
103+
104+
## 6. Tracer-bullet sequence
105+
106+
1. **Engine**`src/application/show-engine.ts` with `findSymbolsByName` + tests (returns rows for a name, optional kind filter, empty array for unknown). Pure; no CLI dependency.
107+
2. **CLI verb**`src/cli/cmd-show.ts` (parser, help, terminal renderer, JSON renderer, error UX) wired into `main.ts` + `bootstrap.ts`. Tests cover `--help` / unknown-name / multiple-match-error / `--all` / `--kind` / `--json`.
108+
3. **MCP tool**`show({name, kind?, all?})` registered in `mcp-server.ts`; in-process SDK test.
109+
4. **Docs + agents**`architecture.md § Show wiring`, glossary entry, README CLI block, rule + skill across `.agents/` and `templates/agents/` (Rule 10), patch changeset, plan deletion (Rule 2).
110+
111+
Estimated total: ~half day across 4 commits.
112+
113+
## 7. Open questions
114+
115+
### Settled
116+
117+
_None yet — see § 8 for the grill round before code._
118+
119+
### Still open
120+
121+
- **Q-1. MCP `show` tool — separate from `query`?** Three options: (a) Ship `show` as a dedicated MCP tool (parallels CLI 1:1); (b) Skip MCP — agents call `query` with the SQL directly (one fewer tool to discover); (c) Add `show` only as a tool description hint, no separate registration. Bias toward (a) — uniform with how every other CLI verb maps to an MCP tool, plus the discoverability win is real (the tool listing teaches the agent `show` exists).
122+
- **Q-2. Multiple matches — error or list-with-confirm?** Current proposal: error unless `--all` is set. Alternative: always list, prefix the first row with a "(N matches; use --kind to narrow)" hint. Bias toward "error by default" — agents that get a list back on a `name=foo` query may pick the wrong row; an explicit error forces them to add `--kind` or `--all`.
123+
- **Q-3. Exact-match only or substring/regex?** Current proposal: `name = ?` exact match. Alternative: `name LIKE '%<name>%'` for fuzzy ("agent searches for `runQuery` and gets `runQueryCmd`"). Bias toward exact — fuzzy is what `query` is for; `show` is the precise read.
124+
- **Q-4. Should `show` accept a file scope (`--in <path>`)?** Use case: same name in multiple files, agent knows which file. Could be `codemap show foo --in src/cli/cmd-query.ts`. Bias toward yes — cheap to add (just `AND file_path LIKE ?`) and the alternative is making the agent write SQL.
125+
- **Q-5. Snippet sibling now or later?** `codemap snippet <name>` would slice the actual file content at `line_start..line_end` and return code text. Bias toward later — different feature (touches FS read, encoding, syntax-highlight question), ship `show` first.
126+
127+
## 8. Non-goals (v1)
128+
129+
- **Snippet output** (actual code text) — sibling feature; defer until a consumer asks.
130+
- **Cross-symbol resolution** (e.g. `codemap show MyClass.method`) — not what the symbols table indexes today; would need a new lookup path. Use `query` with `parent_name = 'MyClass'` for now.
131+
- **Fuzzy matching**`query` already covers this with `LIKE` patterns.
132+
- **Output sorting controls** — current default ORDER BY `file_path ASC, line_start ASC`. If a consumer wants different, use `query`.
133+
134+
## 9. References
135+
136+
- Roadmap entry: [`docs/roadmap.md` § Backlog](../roadmap.md#backlog).
137+
- Symbols table shape: [`docs/architecture.md` § Schema](../architecture.md#schema).
138+
- Doc lifecycle: this file follows the **Plan** type per [`docs/README.md` § Document Lifecycle](../README.md#document-lifecycle)**delete on ship**, lift the canonical bits into `architecture.md` per Rule 2.

docs/roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Codemap stays a structural-index primitive that other tools can consume. Out of
3939
- [ ] **`codemap audit --base <ref>`** (v1.x) — worktree+reindex snapshot strategy. v1 shipped `--baseline <prefix>` / `--<delta>-baseline <name>` (B.6 reuse) — see [`architecture.md` § Audit wiring](./architecture.md#cli-usage). v1.x adds `--base <ref>` for "audit against an arbitrary ref I haven't pre-baselined" (defers worktree spawn + cache decision until a real consumer asks).
4040
- [ ] **`codemap audit` verdict + thresholds** (v1.x) — `verdict: "pass" | "warn" | "fail"` driven by `codemap.config.audit.deltas[<key>].{added_max, action}`. Triggers: two consumers ship `jq`-based threshold scripts with similar shapes, OR one consumer asks with a concrete config sketch. Until then, raw deltas + consumer-side `jq` is the CI exit-code idiom.
4141
- [ ] **`codemap serve` (HTTP API, v1.x)** — same tool taxonomy + output shape as `codemap mcp` (shipped in v1), exposed over `POST /tool/{name}` with loopback default and optional `--token`. Defer until a concrete non-MCP consumer asks; design points are reserved in [`architecture.md` § MCP wiring](./architecture.md#cli-usage) so HTTP inherits them when its turn comes.
42-
- [ ] **Targeted-read CLI**`codemap show <symbol>` / `codemap snippet <name>` returns `file_path:line_start-line_end` + `signature` for one symbol. Same data as `SELECT … FROM symbols WHERE name = ?`, but a one-step CLI keeps agents from composing SQL for trivial precise reads
42+
- [ ] **Targeted-read CLI**`codemap show <symbol>` returns `file_path:line_start-line_end` + `signature` for the symbol(s) matching the name; `--all` / `--kind` / `--in <path>` for disambiguation. Plan: [`plans/targeted-read-cli.md`](./plans/targeted-read-cli.md). Pure ergonomic affordance over `SELECT … FROM symbols WHERE name = ?` — no schema change. Snippet sibling (actual code text) deferred until asked.
4343
- [ ] **Watch mode** for dev — `node:fs.watch` recursive + `--files` re-index loop; Linux `recursive` requires Node 19.1+
4444
- [ ] **Monorepo / workspace awareness** — discover workspaces from `pnpm-workspace.yaml` / `package.json` and index per-workspace dependency graphs
4545
- [ ] **Cross-agent handoff artifact**_speculative_; layered prefix/delta JSON written on session-stop, read on session-start. Complementary to indexing rather than core to it; revisit if user demand emerges

0 commit comments

Comments
 (0)