You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(cli): codemap rename alias for homonym-safe renames (#166)
* feat(cli): add codemap rename alias for homonym-safe renames
`define_in` on rename-preview shipped in #165; this adds the thin
`codemap rename` → `apply rename-preview` alias with positional
ergonomics and plan doc for the scoped-rename slice.
* fix(cli): preserve missing --params operand in rename alias
Align with --define-in/--in-file/--kind: pass bare --params through so
apply reports the real missing-argument error instead of accepting {}.
* fix(cli): harden rename alias parsing and docs
Return rename-local errors for missing scoped-flag operands, extract
old/new regardless of apply-flag order, reject stray positionals, and
align README/roadmap/architecture/skill with the shipped alias.
* fix(cli): polish rename alias edge cases and docs
Support equals-form scoped flags, reject partial old/new at the alias
layer, add changeset and glossary/rule coverage, delete shipped plan.
* fix(cli): improve stray-arg error after complete rename params
Report unexpected positionals when old/new are already bound via --params;
align glossary shorthand with full rename flag surface.
* test(cli): cover stray positional after rename --params
* fix(cli): preserve state on trailing bare --params in rename
Only early-return bare --params when it is the sole rename arg; otherwise
keep merged params, positionals, and apply flags. Delegate incomplete
old/new to apply when applyTail still carries --params.
* fix(cli): reject flag tokens as --params operands in rename
Mirror query/apply parser guard: when --params is not followed by a
value token, treat it as bare trailing --params instead of parsing
the next flag as k=v input.
* fix(cli): strip redundant bare --params from rename rewrite
When old/new are already serialized, drop no-op trailing --params
tokens so apply argv stays parseable (e.g. before --dry-run).
* fix(cli): reject flag tokens as scoped-flag operands in rename
Align --define-in, --in-file, and --kind with --params: a following
flag is not a valid operand value.
* fix(cli): harden rename alias flag parsing and help guards
Treat --params followed by apply flags as bare passthrough, whitelist
apply flags in splitPassthrough so symbol names like --help stay
positional, and only show rename help when it is the sole argument.
* fix(cli): reject flag tokens as --commit/--max-passes operands
Rename alias and apply parser no longer pair value-taking apply flags
with a following flag, so `rename a b --commit --dry-run` preserves
dry-run semantics end-to-end.
* docs(cli): use generic paths in rename alias examples
Replace dogfood bench fixture paths in README and rename --help with
consumer-facing placeholder paths.
Copy file name to clipboardExpand all lines: docs/architecture.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -160,13 +160,13 @@ Three **mutually exclusive** CLI entry shapes; all converge on `applyDiffPayload
160
160
161
161
**Bundled diff-shape recipes** (emit the row contract; inspect with `codemap query --recipe <id> --format diff-json`): `rename-preview` (includes member/namespaced JSX via `jsx_elements`), `migrate-import-source`, `replace-marker-kind` (`auto_fixable: true`); `stale-imports`, `migrate-deprecated`, `deprecated-usages`, `add-jsdoc-deprecated`, `migrate-jsx-prop` (`auto_fixable: false` — writes need `--force` unless allowlisted). Pair read `deprecated-symbols` with `migrate-deprecated` + `deprecated-usages`; `find-jsx-usages` with `migrate-jsx-prop`. Golden map: [`testing-coverage.md`](./testing-coverage.md).
162
162
163
-
**Homonym-safe rename:** optional `define_in=<definition file_path>` on `rename-preview` anchors `target_symbols` and binding-resolved call/JSX sites (distinct from `in_file`, which only filters output row paths). Bare `old`/`new` still unions every same-named symbol.
163
+
**Homonym-safe rename:** optional `define_in=<definition file_path>` on `rename-preview` anchors `target_symbols` and binding-resolved call/JSX sites (distinct from `in_file`, which only filters output row paths). Bare `old`/`new` still unions every same-named symbol. CLI shorthand: `codemap rename <old> <new> [--define-in <file_path>] [--in-file <prefix>] [--kind <k>]` → `apply rename-preview` (thin alias — same recipe + policy gates; see `codemap rename --help`).
164
164
165
165
**Policy** (`src/application/apply-policy.ts`, recipe mode only): non-`auto_fixable` recipes reject writes unless `--force` / MCP `force: true`. `apply.autoApplyRecipes` in user config is an allowlist of recipe ids that may run without TTY `--yes` on non-interactive CLI (MCP/HTTP still require `yes: true` for writes). `--rows` / `apply_rows` / `--diff-input` bypass both gates — separate trust boundary for agent-supplied hunks.
166
166
167
167
**Discover → preview → apply** (agent loop): `query_recipe` / `query --recipe <id> --format diff-json` (or audit baseline `added` rows) → `apply` with `dry_run: true` → `apply` with `yes: true` (+ `force: true` when required). Per-row `actions[].command` on `--json` query output renders a copy-paste shell line (`renderRecipeActionCommands`).
168
168
169
-
**Non-goals on the apply path** (Moat A preserved): no curated write verbs (`codemap rename`, …); no severity / verdict engine on rows; no JS execution at apply time; no Path A AST apply engine; no cross-file transactional rollback. Rejected alternatives + revisit triggers: [synthesis §7](./research/codemap-richer-index-synthesis-2026-05.md#7-rejected-items-with-trigger-conditions) (`organize-imports`, Path A AST apply, trust tiers, …).
169
+
**Non-goals on the apply path** (Moat A preserved): no curated write verbs with new semantics (`codemap fix deprecated`, …); **`codemap rename`** is a thin alias to `apply rename-preview` (same recipe + policy gates as outcome aliases → `query --recipe`). No severity / verdict engine on rows; no JS execution at apply time; no Path A AST apply engine; no cross-file transactional rollback. Rejected alternatives + revisit triggers: [synthesis §7](./research/codemap-richer-index-synthesis-2026-05.md#7-rejected-items-with-trigger-conditions) (`organize-imports`, Path A AST apply, trust tiers, …).
170
170
171
171
**Show / snippet wiring:** **`src/cli/show-snippet-args.ts`** (shared argv parser) + **`src/cli/show-snippet-render.ts`** (shared terminal/JSON error helpers) + **`src/cli/cmd-show.ts`** + **`src/cli/cmd-snippet.ts`** — sibling CLI verbs sharing the same parser shape (`<name>` or **`--query '<field:value …>'`** + **`--with-fts`** + `--kind` + `--in <path>` + `--json`; show adds **`--print-sql`**) and the pure engines **`src/application/show-engine.ts`** (exact lookup + envelope builders), **`src/application/search-query-parser.ts`** + **`src/application/search-engine.ts`** (field-qualified search → parameterized SQL on `symbols`, optional `source_fts` join), and **`src/application/show-search-mode.ts`** (shared parse/normalize + FTS resolution + **`executeShowLookup`** + **`formatShowSearchSqlForQuery`** for CLI/MCP/HTTP). Exact lookup: `findSymbolsByName({db, name, kind?, inPath?})`. Query lookup: `searchSymbols({db, parsed, withFts?})`. Snippet FS read: `readSymbolSource({match, projectRoot, indexedContentHash?})` + `getIndexedContentHash(db, filePath)`. **`buildShowResult`** + **`buildSnippetResult`** envelope builders — same engines the MCP show/snippet tools call. Both verbs return the same `{matches, disambiguation?, warning?}` envelope — single match → `{matches: [{...}]}`; multi-match adds `{n, by_kind, files, hint}`; optional **`warning`** when FTS was requested but `source_fts` is empty. Snippet matches add `source` / `stale` / `missing` fields (additive — no shape divergence). **`--in <path>`** and **`path:`** inside **`--query`** normalize through `toProjectRelative(projectRoot, p)` (from **`src/application/validate-engine.ts`**). Stale-file behavior on `snippet`: `hashContent` (from **`src/hash.ts`**) compares on-disk content against `files.content_hash`; mismatch sets `stale: true` but source IS still returned. MCP tools `show` and `snippet` register parallel to the CLI surface (see [§ MCP wiring](#cli-usage)).
Top-level CLI verbs that thin-wrap `query --recipe <id>`: `dead-code` → `untested-and-dead`, `deprecated` → `deprecated-symbols`, `boundaries` → `boundary-violations`, `hotspots` → `fan-in`, `coverage-gaps` → `worst-covered-exports`. Every `query` flag passes through (`--json`, `--format`, `--ci`, `--summary`, `--changed-since`, `--group-by`, `--params`, `--save-baseline`, `--baseline`). Mapping lives in `src/cli/aliases.ts` (`OUTCOME_ALIASES`). Capped at 5 to avoid alias-sprawl — promote a sixth only when the recipe becomes a headline outcome. Moat-A clean: the alias is a one-line rewrite, not a new primitive; the recipe IS the SQL.
396
+
Top-level CLI verbs that thin-wrap `query --recipe <id>`: `dead-code` → `untested-and-dead`, `deprecated` → `deprecated-symbols`, `boundaries` → `boundary-violations`, `hotspots` → `fan-in`, `coverage-gaps` → `worst-covered-exports`. Every `query` flag passes through (`--json`, `--format`, `--ci`, `--summary`, `--changed-since`, `--group-by`, `--params`, `--save-baseline`, `--baseline`). Mapping lives in `src/cli/aliases.ts` (`OUTCOME_ALIASES`). Capped at 5 to avoid alias-sprawl — promote a sixth only when the recipe becomes a headline outcome. Moat-A clean: the alias is a one-line rewrite, not a new primitive; the recipe IS the SQL.**Write alias (distinct):**`codemap rename` thin-wraps `apply rename-preview` (not `query --recipe`) — mapping in `src/cli/rename-alias.ts`; same Moat-A rule (no new write semantics).
0 commit comments