-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbootstrap.ts
More file actions
230 lines (202 loc) · 8.89 KB
/
Copy pathbootstrap.ts
File metadata and controls
230 lines (202 loc) · 8.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import { resolve } from "node:path";
import { CODEMAP_VERSION } from "../version";
/**
* Printed for `codemap --help` / `-h` (must run before config or DB access).
*/
export function printCliUsage(): void {
console.log(`Usage: codemap [options] [command]
Index (default): update .codemap/index.db for the project root (\`--root\` or cwd).
codemap [--root DIR] [--config FILE] [--full]
codemap [--root DIR] [--config FILE] --files <paths...>
Query:
codemap query [--json] "<SQL>"
codemap query [--json] --recipe <id>
codemap query batch [--stdin | --file <path>] [--summary | --no-summary] [--changed-since <ref>] [--group-by <mode>] [--compact]
Outcome aliases (thin wrappers around \`query --recipe <id>\`; pass-through flags):
codemap dead-code # query --recipe untested-and-dead
codemap deprecated # query --recipe deprecated-symbols
codemap boundaries # query --recipe boundary-violations
codemap hotspots # query --recipe fan-in
codemap coverage-gaps # query --recipe worst-covered-exports
Validate (compare on-disk SHA-256 to indexed hash):
codemap validate [--json] [paths...]
Context (project snapshot envelope for any agent):
codemap context [--compact] [--for "<intent>"] [--include-snippets]
Audit (structural drift — baseline snapshots or git ref):
codemap audit [--baseline <prefix>] [--base <ref>] [--json] [--ci] ...
Agents:
codemap agents init [--force] [--interactive|-i] [--mcp] [--targets <ids>] [--link-mode symlink|copy] [--git-hooks] [--no-git-hooks]
codemap skill · codemap rule # live full markdown (pointer protocol)
PR comment renderer (audit/SARIF → markdown summary):
codemap pr-comment <file> [--shape audit|sarif] [--json] # - for stdin
MCP server (Model Context Protocol — for agent hosts):
codemap mcp # stdio JSON-RPC (19 tools; watcher default-ON)
# CLI parity: query batch, trace, explore, node, file, schema, symbols, context --include-snippets
HTTP server (for non-MCP consumers — CI scripts, curl, IDE plugins):
codemap serve [--host 127.0.0.1] [--port 7878] [--token <secret>] # watcher default-ON
Watch mode (long-running; keeps .codemap/index.db fresh on file edits):
codemap watch [--debounce 250] [--quiet]
codemap mcp · codemap serve # transport + watcher (default-ON since 2026-05)
codemap mcp --no-watch · CODEMAP_WATCH=0 # opt out for one-shot calls
Targeted reads (precise lookup by symbol name):
codemap show <name> [--kind <k>] [--in <path>] [--json] # metadata: file:line + signature
codemap snippet <name> [--kind <k>] [--in <path>] [--json] # source text from disk + stale flag
codemap file <path> [--compact] # per-file roll-up (MCP codemap://files twin)
codemap schema [--compact] # index DDL (MCP codemap://schema twin)
codemap symbols <name> [--in <path>] [--compact] # symbol lookup (MCP codemap://symbols twin)
Graph composers (MCP trace / explore / node twins):
codemap trace --from <sym> --to <sym> [--max-depth N] [--via <b>] [--budget-chars N] [--compact]
codemap explore <name>... [--depth N] [--kind <k>] [--budget-chars N] [--compact]
codemap node <name> [--kind <k>] [--in <path>] [--include-snippets] [--budget-chars N] [--compact]
Impact analysis (graph walk for refactor blast-radius):
codemap impact <target> [--direction up|down|both] [--depth N] [--via <b>] [--limit N] [--summary] [--json]
Affected tests (reverse dep walk → test files to run):
codemap affected [--stdin] [--changed-since <ref>] [--json] [<path>...]
Apply (substrate-shaped fix executor; diff-json row contract):
codemap apply <recipe-id> [--params k=v[,k=v]] [--dry-run] [--yes] [--json]
codemap apply --rows -|<file.json> codemap apply --diff-input <file>
codemap rename <old> <new> [--define-in <file_path>] [apply flags...] # alias → apply rename-preview
(see codemap apply --help for --force, --until-empty, --commit; codemap rename --help)
Coverage ingest (Istanbul JSON or LCOV from any test runner):
codemap ingest-coverage <path> [--json] # path = file or dir; format auto-detected
Other:
codemap unlock [--force] Remove stale cross-process index lock
codemap version
codemap --version, -V
Environment: CODEMAP_ROOT (same as --root), CODEMAP_STATE_DIR (same as --state-dir)
Options:
--full Full rebuild
--state-dir DIR State directory for codemap-managed files (default .codemap/ under root)
--performance Print per-phase timing breakdown + top-10 slowest files
(full rebuild only)
--help, -h Show this help
`);
}
export function printVersion(): void {
console.log(CODEMAP_VERSION);
}
/**
* Paths for `codemap --files <paths...>` when `rest[0] === "--files"`; otherwise `null`.
* Exits 1 on missing paths or flags where operands are required.
*/
export function parseIndexFilesArgs(rest: string[]): string[] | null {
if (rest[0] !== "--files") return null;
const files: string[] = [];
for (let i = 1; i < rest.length; i++) {
const a = rest[i];
if (a.startsWith("-")) {
console.error(`codemap: unexpected option "${a}" after --files`);
console.error("Run codemap --help for usage.");
process.exit(1);
}
files.push(a);
}
if (files.length === 0) {
console.error("codemap: --files requires at least one path");
console.error("Run codemap --help for usage.");
process.exit(1);
}
return files;
}
/**
* Reject unknown flags/args for index mode before config or DB access.
* Enforces `--files` as the first index option with at least one path.
*/
export function validateIndexModeArgs(rest: string[]): void {
if (rest.length === 0) return;
if (rest.includes("--files") && rest[0] !== "--files") {
console.error("codemap: --files must be the first index option");
console.error("Run codemap --help for usage.");
process.exit(1);
}
if (rest[0] === "query") return;
if (rest[0] === "validate") return;
if (rest[0] === "context") return;
if (rest[0] === "audit") return;
if (rest[0] === "mcp") return;
if (rest[0] === "serve") return;
if (rest[0] === "watch") return;
if (rest[0] === "show") return;
if (rest[0] === "snippet") return;
if (rest[0] === "impact") return;
if (rest[0] === "affected") return;
if (rest[0] === "apply") return;
if (rest[0] === "ingest-coverage") return;
if (rest[0] === "pr-comment") return;
if (rest[0] === "trace") return;
if (rest[0] === "explore") return;
if (rest[0] === "node") return;
if (rest[0] === "file") return;
if (rest[0] === "schema") return;
if (rest[0] === "symbols") return;
if (rest[0] === "unlock") return;
if (rest[0] === "agents") {
if (rest[1] === "init") return;
console.error(
`codemap: unknown agents command "${rest[1] ?? "(missing)"}". Expected: codemap agents init [--force] [--interactive|-i] [--mcp] [--targets <ids>] [--link-mode symlink|copy] [--git-hooks] [--no-git-hooks]`,
);
process.exit(1);
}
let i = 0;
while (i < rest.length) {
const a = rest[i];
if (a === "--full" || a === "--performance" || a === "--with-fts") {
i++;
continue;
}
if (a === "--files") {
i++;
const start = i;
while (i < rest.length && !rest[i].startsWith("-")) i++;
if (i === start) {
console.error("codemap: --files requires at least one path");
console.error("Run codemap --help for usage.");
process.exit(1);
}
continue;
}
if (a.startsWith("-")) {
console.error(`codemap: unknown option "${a}"`);
console.error("Run codemap --help for usage.");
process.exit(1);
}
console.error(`codemap: unexpected argument "${a}"`);
console.error("Run codemap --help for usage.");
process.exit(1);
}
}
export function parseBootstrapArgs(argv: string[]) {
const envRoot = process.env.CODEMAP_ROOT ?? process.env.CODEMAP_TEST_BENCH;
let root = envRoot ? resolve(envRoot) : undefined;
let configFile: string | undefined;
let stateDir: string | undefined;
let fts5Cli: boolean | undefined;
const rest: string[] = [];
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a === "--root" && argv[i + 1]) {
root = resolve(argv[++i]);
continue;
}
if (a === "--config" && argv[i + 1]) {
configFile = resolve(argv[++i]);
continue;
}
if (a === "--state-dir" && argv[i + 1]) {
stateDir = argv[++i];
continue;
}
// Bootstrap-level (config-resolve needs it); also pushed to `rest` so
// `validateIndexModeArgs` accepts it as a known flag.
if (a === "--with-fts") {
fts5Cli = true;
rest.push(a);
continue;
}
rest.push(a);
}
if (!root) root = process.cwd();
// --state-dir wins over CODEMAP_STATE_DIR (precedence per plan §D7).
if (!stateDir) stateDir = process.env.CODEMAP_STATE_DIR;
return { root, configFile, stateDir, fts5Cli, rest };
}