@cesarandreslopez/occ 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +17 -3
  2. package/dist/src/cli.d.ts +16 -0
  3. package/dist/src/cli.js +46 -4
  4. package/dist/src/cli.js.map +1 -1
  5. package/dist/src/code/build.d.ts +22 -0
  6. package/dist/src/code/build.js +47 -13
  7. package/dist/src/code/build.js.map +1 -1
  8. package/dist/src/code/cache.js +30 -1
  9. package/dist/src/code/cache.js.map +1 -1
  10. package/dist/src/code/check.js +46 -6
  11. package/dist/src/code/check.js.map +1 -1
  12. package/dist/src/code/command.js +96 -68
  13. package/dist/src/code/command.js.map +1 -1
  14. package/dist/src/code/context.d.ts +54 -0
  15. package/dist/src/code/context.js +67 -0
  16. package/dist/src/code/context.js.map +1 -0
  17. package/dist/src/code/diff.d.ts +12 -2
  18. package/dist/src/code/diff.js +15 -3
  19. package/dist/src/code/diff.js.map +1 -1
  20. package/dist/src/code/discover.d.ts +2 -2
  21. package/dist/src/code/discover.js +8 -10
  22. package/dist/src/code/discover.js.map +1 -1
  23. package/dist/src/code/focus.js +34 -26
  24. package/dist/src/code/focus.js.map +1 -1
  25. package/dist/src/code/incremental.js +1 -1
  26. package/dist/src/code/incremental.js.map +1 -1
  27. package/dist/src/code/index-io.js +10 -2
  28. package/dist/src/code/index-io.js.map +1 -1
  29. package/dist/src/code/isolated-chunk-runner.js +17 -2
  30. package/dist/src/code/isolated-chunk-runner.js.map +1 -1
  31. package/dist/src/code/isolated-runner.js +17 -3
  32. package/dist/src/code/isolated-runner.js.map +1 -1
  33. package/dist/src/code/isolated.js +32 -6
  34. package/dist/src/code/isolated.js.map +1 -1
  35. package/dist/src/code/languages.js +23 -3
  36. package/dist/src/code/languages.js.map +1 -1
  37. package/dist/src/code/map.d.ts +47 -0
  38. package/dist/src/code/map.js +155 -12
  39. package/dist/src/code/map.js.map +1 -1
  40. package/dist/src/code/parsers.js +115 -36
  41. package/dist/src/code/parsers.js.map +1 -1
  42. package/dist/src/code/preview.js +24 -22
  43. package/dist/src/code/preview.js.map +1 -1
  44. package/dist/src/code/query.js +0 -0
  45. package/dist/src/code/query.js.map +1 -1
  46. package/dist/src/code/search.d.ts +39 -0
  47. package/dist/src/code/search.js +154 -0
  48. package/dist/src/code/search.js.map +1 -0
  49. package/dist/src/code/session.d.ts +6 -2
  50. package/dist/src/code/session.js +12 -4
  51. package/dist/src/code/session.js.map +1 -1
  52. package/dist/src/code/slim.d.ts +2 -0
  53. package/dist/src/code/slim.js +16 -1
  54. package/dist/src/code/slim.js.map +1 -1
  55. package/dist/src/code/store.d.ts +23 -0
  56. package/dist/src/code/store.js +61 -6
  57. package/dist/src/code/store.js.map +1 -1
  58. package/dist/src/code/tree-sitter.d.ts +1 -0
  59. package/dist/src/code/tree-sitter.js +11 -10
  60. package/dist/src/code/tree-sitter.js.map +1 -1
  61. package/dist/src/code/types.d.ts +3 -0
  62. package/dist/src/code/types.js +2 -0
  63. package/dist/src/code/types.js.map +1 -1
  64. package/dist/src/doc/batch.d.ts +2 -0
  65. package/dist/src/doc/batch.js +3 -1
  66. package/dist/src/doc/batch.js.map +1 -1
  67. package/dist/src/doc/discover.js +2 -2
  68. package/dist/src/doc/discover.js.map +1 -1
  69. package/dist/src/doc/inspect-odt.js +3 -1
  70. package/dist/src/doc/inspect-odt.js.map +1 -1
  71. package/dist/src/doc/inspect-pdf.d.ts +6 -0
  72. package/dist/src/doc/inspect-pdf.js +11 -1
  73. package/dist/src/doc/inspect-pdf.js.map +1 -1
  74. package/dist/src/doc/inspect.js +2 -2
  75. package/dist/src/doc/inspect.js.map +1 -1
  76. package/dist/src/doc/types.d.ts +1 -0
  77. package/dist/src/doc/types.js +7 -0
  78. package/dist/src/doc/types.js.map +1 -1
  79. package/dist/src/git/api.d.ts +2 -1
  80. package/dist/src/git/api.js +15 -9
  81. package/dist/src/git/api.js.map +1 -1
  82. package/dist/src/git/client.js +5 -1
  83. package/dist/src/git/client.js.map +1 -1
  84. package/dist/src/git/output.js +2 -1
  85. package/dist/src/git/output.js.map +1 -1
  86. package/dist/src/git/parse.js +131 -2
  87. package/dist/src/git/parse.js.map +1 -1
  88. package/dist/src/git/types.d.ts +5 -5
  89. package/dist/src/health.d.ts +8 -0
  90. package/dist/src/health.js +12 -0
  91. package/dist/src/health.js.map +1 -1
  92. package/dist/src/index.d.ts +14 -6
  93. package/dist/src/index.js +9 -3
  94. package/dist/src/index.js.map +1 -1
  95. package/dist/src/inspect/xlsx-cells.js +4 -2
  96. package/dist/src/inspect/xlsx-cells.js.map +1 -1
  97. package/dist/src/markdown/convert.d.ts +9 -0
  98. package/dist/src/markdown/convert.js +23 -1
  99. package/dist/src/markdown/convert.js.map +1 -1
  100. package/dist/src/parsers/odf.js +4 -2
  101. package/dist/src/parsers/odf.js.map +1 -1
  102. package/dist/src/skills/command.d.ts +6 -0
  103. package/dist/src/skills/command.js +18 -3
  104. package/dist/src/skills/command.js.map +1 -1
  105. package/dist/src/slide/inspect-odp.js +3 -2
  106. package/dist/src/slide/inspect-odp.js.map +1 -1
  107. package/dist/src/slide/inspect-pptx.js +4 -3
  108. package/dist/src/slide/inspect-pptx.js.map +1 -1
  109. package/dist/src/stats.js +3 -1
  110. package/dist/src/stats.js.map +1 -1
  111. package/dist/src/structure/extract.js +16 -3
  112. package/dist/src/structure/extract.js.map +1 -1
  113. package/dist/src/utils.d.ts +7 -0
  114. package/dist/src/utils.js +19 -0
  115. package/dist/src/utils.js.map +1 -1
  116. package/dist/src/walker.js +15 -3
  117. package/dist/src/walker.js.map +1 -1
  118. package/dist/src/workspace/analyze.d.ts +3 -0
  119. package/dist/src/workspace/analyze.js +26 -15
  120. package/dist/src/workspace/analyze.js.map +1 -1
  121. package/dist/src/workspace/bundle.js +11 -3
  122. package/dist/src/workspace/bundle.js.map +1 -1
  123. package/dist/src/workspace/command.d.ts +6 -0
  124. package/dist/src/workspace/command.js +73 -44
  125. package/dist/src/workspace/command.js.map +1 -1
  126. package/dist/src/workspace/describe.js +22 -13
  127. package/dist/src/workspace/describe.js.map +1 -1
  128. package/dist/src/workspace/documents.d.ts +3 -0
  129. package/dist/src/workspace/documents.js +25 -14
  130. package/dist/src/workspace/documents.js.map +1 -1
  131. package/dist/src/workspace/prepare.js +3 -1
  132. package/dist/src/workspace/prepare.js.map +1 -1
  133. package/package.json +11 -11
  134. package/skills/occ/SKILL.md +2 -1
  135. package/skills/occ/reference/code.md +41 -1
@@ -20,6 +20,9 @@ function resolveWithinRepo(repoRoot, file) {
20
20
  }
21
21
  return { path: resolved, relativePath: relativePath.split(path.sep).join('/') };
22
22
  }
23
+ function stripBom(text) {
24
+ return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
25
+ }
23
26
  function languageForExtension(filePath) {
24
27
  const extension = path.extname(filePath).toLowerCase();
25
28
  switch (extension) {
@@ -98,7 +101,31 @@ function isMissingExecutable(error) {
98
101
  return error instanceof Error && 'code' in error && error.code === 'ENOENT';
99
102
  }
100
103
  function pythonDiagnostic(stderr) {
101
- const lineMatch = stderr.match(/line (\d+)/);
104
+ const encodingMatch = stderr.match(/OCC_ENCODING_ERROR:([\s\S]*)/);
105
+ if (encodingMatch) {
106
+ const detail = encodingMatch[1].trim();
107
+ return {
108
+ message: `Unsupported source encoding: ${detail || 'file is not valid UTF-8 and declares no encoding cookie'}`,
109
+ code: 'unsupported-encoding',
110
+ source: 'python',
111
+ severity: 'error',
112
+ };
113
+ }
114
+ const syntaxMatch = stderr.match(/OCC_SYNTAX_ERROR:(\d*):(\d*):([\s\S]*)/);
115
+ if (syntaxMatch) {
116
+ const line = syntaxMatch[1] ? Number(syntaxMatch[1]) : undefined;
117
+ const column = syntaxMatch[2] ? Number(syntaxMatch[2]) : undefined;
118
+ return {
119
+ message: syntaxMatch[3].trim() || 'Python syntax error',
120
+ line,
121
+ column,
122
+ source: 'python',
123
+ severity: 'error',
124
+ };
125
+ }
126
+ // Fallback for unexpected failure modes: anchor the line to a SyntaxError frame
127
+ // so the harness's own `File "<string>", line N` frame is never reported.
128
+ const lineMatch = stderr.match(/SyntaxError[\s\S]*?\bline (\d+)/) ?? stderr.match(/^\s*File .*, line (\d+)/m);
102
129
  const message = stderr
103
130
  .split(/\r?\n/)
104
131
  .map(line => line.trim())
@@ -112,11 +139,24 @@ function pythonDiagnostic(stderr) {
112
139
  };
113
140
  }
114
141
  async function checkPython(filePath) {
142
+ // Read via tokenize.open so the PEP 263 encoding cookie and a leading BOM are
143
+ // honored, then parse the decoded text. Encoding and syntax failures are
144
+ // reported through distinct markers so a non-UTF-8 file is not mistaken for a
145
+ // syntax error with a fabricated line number.
115
146
  const script = [
116
- 'import ast, pathlib, sys',
147
+ 'import ast, sys, tokenize',
117
148
  'path = sys.argv[1]',
118
- "source = pathlib.Path(path).read_text(encoding='utf8')",
119
- 'ast.parse(source, filename=path)',
149
+ 'try:',
150
+ ' with tokenize.open(path) as handle:',
151
+ ' source = handle.read()',
152
+ 'except (SyntaxError, ValueError, LookupError, UnicodeDecodeError) as exc:',
153
+ " sys.stderr.write('OCC_ENCODING_ERROR:' + str(exc))",
154
+ ' sys.exit(1)',
155
+ 'try:',
156
+ ' ast.parse(source, filename=path)',
157
+ 'except SyntaxError as exc:',
158
+ " sys.stderr.write('OCC_SYNTAX_ERROR:%s:%s:%s' % (exc.lineno or '', exc.offset or '', exc.msg or ''))",
159
+ ' sys.exit(1)',
120
160
  ].join('\n');
121
161
  try {
122
162
  await execFileAsync('python3', ['-c', script, filePath], { timeout: 5_000, maxBuffer: 1_000_000 });
@@ -178,7 +218,7 @@ export async function checkCodeSyntax(options) {
178
218
  let diagnostics = await checkPython(resolved.path);
179
219
  if (diagnostics === 'unsupported' && spec?.treeSitter) {
180
220
  // python3 isn't on PATH (e.g. Windows) — fall back to the vendored tree-sitter grammar.
181
- const content = await readFile(resolved.path, 'utf8');
221
+ const content = stripBom(await readFile(resolved.path, 'utf8'));
182
222
  diagnostics = await checkTreeSitter(spec.treeSitter.grammar, content);
183
223
  }
184
224
  if (diagnostics === 'unsupported') {
@@ -211,7 +251,7 @@ export async function checkCodeSyntax(options) {
211
251
  diagnostics: [],
212
252
  };
213
253
  }
214
- const content = await readFile(resolved.path, 'utf8');
254
+ const content = stripBom(await readFile(resolved.path, 'utf8'));
215
255
  const diagnostics = extension === '.vue'
216
256
  ? await checkVue(resolved.path, content)
217
257
  : ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'].includes(extension)
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/code/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/code/check.ts"],"names":[],"mappings":"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"}
@@ -3,13 +3,13 @@ import path from 'node:path';
3
3
  import { Option } from 'commander';
4
4
  import { z } from 'zod';
5
5
  import { buildCodebaseIndex } from './build.js';
6
- import { writeStream } from '../utils.js';
6
+ import { DEFAULT_EXCLUDE_DIRS, writeStream } from '../utils.js';
7
7
  import { parsePositiveInt } from '../cli-validation.js';
8
8
  import { checkCodeSyntax } from './check.js';
9
9
  import { analyzeCallChain, analyzeCallers, analyzeCalls, analyzeDeps, analyzeModuleCoupling, analyzeTree, createPayload, findByName, findByPattern, findByType, findContent, fusedSearch, } from './query.js';
10
10
  import { formatCodeDiff, formatCodeDiffJson, formatChains, formatClassTree, formatContentResults, formatDependencies, formatFusedResults, formatModuleCoupling, formatPayloadJson, formatRelationResults, formatSearchResults, renderRepoMap, } from './output.js';
11
11
  import { computeCodeDiff } from './diff.js';
12
- import { buildRepoMap } from './map.js';
12
+ import { buildRepoMap, stampRepoMapChanges, toRepoMapChangeContext, } from './map.js';
13
13
  import { readCodeSource } from './source.js';
14
14
  import { createTokenizer, resolveTokenizerName } from '../tokens.js';
15
15
  import { getGitDiffSummary, getGitFileHistory } from '../git/api.js';
@@ -52,6 +52,23 @@ const CodeCommandOptionsSchema = z
52
52
  function getOptions(command) {
53
53
  return CodeCommandOptionsSchema.parse(command.optsWithGlobals());
54
54
  }
55
+ /**
56
+ * Wrap a subcommand action so thrown validation/runtime errors print a clean
57
+ * `Error: <message>` line and set a non-zero exit code, matching the default
58
+ * scan command. parseAsync does not catch action-handler rejections, so each
59
+ * action opts in explicitly.
60
+ */
61
+ function runAction(handler) {
62
+ return async (...args) => {
63
+ try {
64
+ await handler(...args);
65
+ }
66
+ catch (error) {
67
+ await writeStream(process.stderr, `Error: ${error.message}\n`);
68
+ process.exitCode = 1;
69
+ }
70
+ };
71
+ }
55
72
  const FINDABLE_TYPES = [
56
73
  'file',
57
74
  'module',
@@ -85,6 +102,16 @@ function parseType(value) {
85
102
  }
86
103
  return result.data;
87
104
  }
105
+ /** Parse a CLI string option as a non-negative integer, returning fallback if undefined. */
106
+ function parseNonNegativeInt(value, fallback, label) {
107
+ if (!value)
108
+ return fallback;
109
+ const parsed = Number.parseInt(value, 10);
110
+ if (!Number.isFinite(parsed) || parsed < 0) {
111
+ throw new Error(`Invalid ${label}: "${value}"`);
112
+ }
113
+ return parsed;
114
+ }
88
115
  async function emit(output, options) {
89
116
  if (options.output) {
90
117
  await writeFile(options.output, output);
@@ -122,7 +149,7 @@ function resolveContentMode(value, fallback) {
122
149
  return fallback;
123
150
  return ContentModeSchema.parse(value);
124
151
  }
125
- function buildIndexOptions(options, fallbackContentMode) {
152
+ function buildIndexOptions(options, fallbackContentMode, forceContentMode) {
126
153
  const repoRoot = path.resolve(options.path ?? process.cwd());
127
154
  return {
128
155
  repoRoot,
@@ -132,7 +159,7 @@ function buildIndexOptions(options, fallbackContentMode) {
132
159
  .filter(Boolean),
133
160
  noGitignore: options.gitignore === false,
134
161
  ignorePatterns: options.ignorePattern,
135
- contentMode: resolveContentMode(options.contentMode, fallbackContentMode),
162
+ contentMode: forceContentMode ?? resolveContentMode(options.contentMode, fallbackContentMode),
136
163
  maxFileSizeBytes: options.maxFileSizeBytes
137
164
  ? parsePositiveInt(options.maxFileSizeBytes, 2_097_152, 'max file size')
138
165
  : undefined,
@@ -143,13 +170,24 @@ function buildIndexOptions(options, fallbackContentMode) {
143
170
  async function withIndex(options, fallbackContentMode = 'excerpt') {
144
171
  return buildCodebaseIndex(buildIndexOptions(options, fallbackContentMode));
145
172
  }
173
+ /**
174
+ * Build an index with content forced to "full" for commands whose search cannot
175
+ * run without full content. An explicit conflicting --content-mode is reported
176
+ * and overridden rather than silently producing an index that would fail.
177
+ */
178
+ async function withFullContentIndex(options, commandLabel) {
179
+ if (options.contentMode && options.contentMode !== 'full') {
180
+ await writeStream(process.stderr, `Warning: ${commandLabel} requires --content-mode full; ignoring "${options.contentMode}".\n`);
181
+ }
182
+ return buildCodebaseIndex(buildIndexOptions(options, 'full', 'full'));
183
+ }
146
184
  function addSharedOptions(command, extra = {}) {
147
185
  command
148
186
  .option('--path <repo-root>', 'repository root to analyze', process.cwd())
149
187
  .option('--format <type>', 'output format: tabular or json', 'tabular')
150
188
  .option('-o, --output <file>', 'write output to file')
151
189
  .option('--ci', 'ASCII-only output, no colors')
152
- .option('--exclude-dir <dirs>', 'directories to skip (comma-separated)', 'node_modules,.git,dist,vendor,build,coverage,target')
190
+ .option('--exclude-dir <dirs>', 'directories to skip (comma-separated)', DEFAULT_EXCLUDE_DIRS.join(','))
153
191
  .option('--no-gitignore', 'disable .gitignore respect')
154
192
  .option('--ignore-pattern <pattern>', 'gitignore-style pattern to ignore', collectOption, [])
155
193
  .option('--content-mode <mode>', 'indexed content mode: none, excerpt, or full')
@@ -184,7 +222,7 @@ export function registerCodeCommands(program) {
184
222
  'o200k_base',
185
223
  'cl100k_base',
186
224
  ]));
187
- diffCmd.action(async (_options, command) => {
225
+ diffCmd.action(runAction(async (_options, command) => {
188
226
  const options = getOptions(command);
189
227
  const tokenizerName = resolveTokenizerName(options.tokenizer);
190
228
  const tokenizer = await createTokenizer(tokenizerName);
@@ -199,10 +237,10 @@ export function registerCodeCommands(program) {
199
237
  });
200
238
  const output = options.format === 'json' ? formatCodeDiffJson(result) : formatCodeDiff(result, options.ci);
201
239
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
202
- });
240
+ }));
203
241
  const historyCmd = code.command('history <symbol>').description('Show git line history for a symbol');
204
242
  addSharedOptions(historyCmd, { includeFile: true, includeLimit: true, includeType: true });
205
- historyCmd.action(async (symbol, _options, command) => {
243
+ historyCmd.action(runAction(async (symbol, _options, command) => {
206
244
  const options = getOptions(command);
207
245
  const index = await withIndex(options, 'excerpt');
208
246
  const matches = findByName(index, symbol, parseType(options.type), options.file, 1);
@@ -221,13 +259,13 @@ export function registerCodeCommands(program) {
221
259
  ? JSON.stringify(result, null, 2)
222
260
  : result.entries.map(entry => `${entry.shortHash} ${entry.authorDate} ${entry.subject}`).join('\n') + '\n';
223
261
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
224
- });
262
+ }));
225
263
  // occ code index — build and emit the full codebase index
226
264
  const indexCmd = code
227
265
  .command('index')
228
266
  .description('Build the full codebase index (files, symbols, edges, capabilities)');
229
267
  addSharedOptions(indexCmd);
230
- indexCmd.action(async (_options, command) => {
268
+ indexCmd.action(runAction(async (_options, command) => {
231
269
  const options = getOptions(command);
232
270
  const index = await buildCodebaseIndex(buildIndexOptions(options, 'full'), event => {
233
271
  if (options.format !== 'json') {
@@ -241,10 +279,10 @@ export function registerCodeCommands(program) {
241
279
  ? JSON.stringify(index, null, 2)
242
280
  : `${index.files.length} files, ${index.nodes.length} nodes, ${index.edges.length} edges, ${Object.keys(index.capabilities).length} languages\n`;
243
281
  await emit(summary.endsWith('\n') ? summary : `${summary}\n`, options);
244
- });
282
+ }));
245
283
  const findName = find.command('name <name>').description('Find code elements by exact name');
246
284
  addSharedOptions(findName, { includeFile: true, includeLimit: true, includeType: true });
247
- findName.action(async (name, _options, command) => {
285
+ findName.action(runAction(async (name, _options, command) => {
248
286
  const options = getOptions(command);
249
287
  const index = await withIndex(options, 'excerpt');
250
288
  const results = findByName(index, name, parseType(options.type), options.file, parsePositiveInt(options.limit, 50, 'limit'));
@@ -253,10 +291,10 @@ export function registerCodeCommands(program) {
253
291
  ? formatPayloadJson(payload)
254
292
  : formatSearchResults(`Code Search: ${name}`, results, options.ci);
255
293
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
256
- });
294
+ }));
257
295
  const findPatternCmd = find.command('pattern <pattern>').description('Find code elements by substring pattern');
258
296
  addSharedOptions(findPatternCmd, { includeLimit: true, includeType: true });
259
- findPatternCmd.action(async (pattern, _options, command) => {
297
+ findPatternCmd.action(runAction(async (pattern, _options, command) => {
260
298
  const options = getOptions(command);
261
299
  const index = await withIndex(options, 'excerpt');
262
300
  const results = findByPattern(index, pattern, parseType(options.type), parsePositiveInt(options.limit, 50, 'limit'));
@@ -265,10 +303,10 @@ export function registerCodeCommands(program) {
265
303
  ? formatPayloadJson(payload)
266
304
  : formatSearchResults(`Code Pattern: ${pattern}`, results, options.ci);
267
305
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
268
- });
306
+ }));
269
307
  const findTypeCmd = find.command('type <nodeType>').description('List all nodes of a given type');
270
308
  addSharedOptions(findTypeCmd, { includeLimit: true });
271
- findTypeCmd.action(async (nodeType, _options, command) => {
309
+ findTypeCmd.action(runAction(async (nodeType, _options, command) => {
272
310
  const options = getOptions(command);
273
311
  const index = await withIndex(options, 'excerpt');
274
312
  const results = findByType(index, parseType(nodeType) ?? 'function', parsePositiveInt(options.limit, 50, 'limit'));
@@ -277,21 +315,21 @@ export function registerCodeCommands(program) {
277
315
  ? formatPayloadJson(payload)
278
316
  : formatSearchResults(`Code Type: ${nodeType}`, results, options.ci);
279
317
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
280
- });
318
+ }));
281
319
  const findContentCmd = find.command('content <text>').description('Search code content');
282
320
  addSharedOptions(findContentCmd, { includeLimit: true });
283
- findContentCmd.action(async (text, _options, command) => {
321
+ findContentCmd.action(runAction(async (text, _options, command) => {
284
322
  const options = getOptions(command);
285
- const index = await withIndex(options, 'full');
323
+ const index = await withFullContentIndex(options, 'find content');
286
324
  const results = findContent(index, text, parsePositiveInt(options.limit, 50, 'limit'));
287
325
  const payload = createPayload(index, { command: 'code.find.content', value: text }, results);
288
326
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatContentResults(results, options.ci);
289
327
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
290
- });
328
+ }));
291
329
  const sourceCmd = code.command('source [name]').description('Read one symbol body by node id or disambiguated name');
292
330
  addSharedOptions(sourceCmd, { includeFile: true, includeType: true });
293
331
  sourceCmd.option('--node-id <id>', 'exact node id from code map/find/index output');
294
- sourceCmd.action(async (name, _options, command) => {
332
+ sourceCmd.action(runAction(async (name, _options, command) => {
295
333
  const options = getOptions(command);
296
334
  if (options.nodeId && name) {
297
335
  throw new Error('Use either --node-id or a symbol name, not both.');
@@ -311,10 +349,10 @@ export function registerCodeCommands(program) {
311
349
  }
312
350
  const output = options.format === 'json' ? JSON.stringify(result, null, 2) : formatSourceResult(result);
313
351
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
314
- });
352
+ }));
315
353
  const checkCmd = code.command('check <file>').description('Check syntax for a source file without a language server');
316
354
  addSharedOptions(checkCmd);
317
- checkCmd.action(async (file, _options, command) => {
355
+ checkCmd.action(runAction(async (file, _options, command) => {
318
356
  const options = getOptions(command);
319
357
  const repoRoot = path.resolve(options.path ?? process.cwd());
320
358
  const result = await checkCodeSyntax({ repoRoot, file });
@@ -323,10 +361,10 @@ export function registerCodeCommands(program) {
323
361
  }
324
362
  const output = options.format === 'json' ? JSON.stringify(result, null, 2) : formatCheckResult(result);
325
363
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
326
- });
364
+ }));
327
365
  const analyzeCallsCmd = analyze.command('calls <functionName>').description('Show what a function calls');
328
366
  addSharedOptions(analyzeCallsCmd, { includeFile: true });
329
- analyzeCallsCmd.action(async (functionName, _options, command) => {
367
+ analyzeCallsCmd.action(runAction(async (functionName, _options, command) => {
330
368
  const options = getOptions(command);
331
369
  const index = await withIndex(options, 'excerpt');
332
370
  const results = analyzeCalls(index, functionName, options.file);
@@ -335,10 +373,10 @@ export function registerCodeCommands(program) {
335
373
  ? formatPayloadJson(payload)
336
374
  : formatRelationResults(`Outgoing Calls: ${functionName}`, 'Callee', results, options.ci);
337
375
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
338
- });
376
+ }));
339
377
  const analyzeCallersCmd = analyze.command('callers <functionName>').description('Show what calls a function');
340
378
  addSharedOptions(analyzeCallersCmd, { includeFile: true });
341
- analyzeCallersCmd.action(async (functionName, _options, command) => {
379
+ analyzeCallersCmd.action(runAction(async (functionName, _options, command) => {
342
380
  const options = getOptions(command);
343
381
  const index = await withIndex(options, 'excerpt');
344
382
  const results = analyzeCallers(index, functionName, options.file);
@@ -347,66 +385,74 @@ export function registerCodeCommands(program) {
347
385
  ? formatPayloadJson(payload)
348
386
  : formatRelationResults(`Incoming Calls: ${functionName}`, 'Caller', results, options.ci, 'from');
349
387
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
350
- });
388
+ }));
351
389
  const analyzeChainCmd = analyze
352
390
  .command('chain <fromFunction> <toFunction>')
353
391
  .description('Find call paths between two functions');
354
392
  addSharedOptions(analyzeChainCmd, { includeDepth: true });
355
- analyzeChainCmd.action(async (fromFunction, toFunction, _options, command) => {
393
+ analyzeChainCmd.action(runAction(async (fromFunction, toFunction, _options, command) => {
356
394
  const options = getOptions(command);
357
395
  const index = await withIndex(options, 'excerpt');
358
396
  const results = analyzeCallChain(index, fromFunction, toFunction, parsePositiveInt(options.depth, 5, 'depth'));
359
397
  const payload = createPayload(index, { command: 'code.analyze.chain', from: fromFunction, to: toFunction, depth: options.depth }, results);
360
398
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatChains(results, options.ci);
361
399
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
362
- });
400
+ }));
363
401
  const analyzeDepsCmd = analyze.command('deps <target>').description('Show module/file import relationships');
364
402
  addSharedOptions(analyzeDepsCmd);
365
- analyzeDepsCmd.action(async (target, _options, command) => {
403
+ analyzeDepsCmd.action(runAction(async (target, _options, command) => {
366
404
  const options = getOptions(command);
367
405
  const index = await withIndex(options, 'excerpt');
368
406
  const results = analyzeDeps(index, target);
369
407
  const payload = createPayload(index, { command: 'code.analyze.deps', value: target }, results);
370
408
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatDependencies(results, options.ci);
371
409
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
372
- });
410
+ }));
373
411
  const analyzeCouplingCmd = analyze.command('coupling <target>').description('Show module-level coupling metrics');
374
412
  addSharedOptions(analyzeCouplingCmd);
375
- analyzeCouplingCmd.action(async (target, _options, command) => {
413
+ analyzeCouplingCmd.action(runAction(async (target, _options, command) => {
376
414
  const options = getOptions(command);
377
415
  const index = await withIndex(options, 'excerpt');
378
416
  const results = analyzeModuleCoupling(index, target);
379
417
  const payload = createPayload(index, { command: 'code.analyze.coupling', value: target }, results);
380
418
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatModuleCoupling(results, options.ci);
381
419
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
382
- });
420
+ }));
383
421
  const analyzeTreeCmd = analyze
384
422
  .command('tree <className>')
385
423
  .description('Show class/interface inheritance relationships');
386
424
  addSharedOptions(analyzeTreeCmd, { includeFile: true });
387
- analyzeTreeCmd.action(async (className, _options, command) => {
425
+ analyzeTreeCmd.action(runAction(async (className, _options, command) => {
388
426
  const options = getOptions(command);
389
427
  const index = await withIndex(options, 'excerpt');
390
428
  const results = analyzeTree(index, className, options.file);
391
429
  const payload = createPayload(index, { command: 'code.analyze.tree', value: className, file: options.file }, results);
392
430
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatClassTree(results, options.ci);
393
431
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
394
- });
432
+ }));
395
433
  const findFusedCmd = find
396
434
  .command('fused <query>')
397
435
  .description('Fused search: combines name, pattern, and content search with rank fusion');
398
436
  addSharedOptions(findFusedCmd, { includeLimit: true });
399
437
  findFusedCmd.option('--weights <spec>', 'weights as name:N,pattern:N,content:N', 'name:3,pattern:2,content:1');
400
- findFusedCmd.action(async (query, _options, command) => {
438
+ findFusedCmd.action(runAction(async (query, _options, command) => {
401
439
  const options = getOptions(command);
402
440
  const weightsStr = options.weights ?? 'name:3,pattern:2,content:1';
403
441
  const weights = {};
404
442
  for (const pair of weightsStr.split(',')) {
405
443
  const [key, val] = pair.split(':');
406
- if (key && val)
407
- weights[key.trim()] = parseFloat(val);
444
+ const weightKey = key?.trim();
445
+ const weightValue = val?.trim();
446
+ if (!weightKey || !weightValue)
447
+ continue;
448
+ const parsed = z.number().finite().nonnegative().safeParse(Number(weightValue));
449
+ if (!parsed.success) {
450
+ throw new Error(`Invalid --weights value "${weightValue}" for "${weightKey}" (expected a non-negative number).`);
451
+ }
452
+ weights[weightKey] = parsed.data;
408
453
  }
409
- const index = await withIndex(options, (weights.content ?? 1) > 0 ? 'full' : 'excerpt');
454
+ const needsFull = (weights.content ?? 1) > 0;
455
+ const index = needsFull ? await withFullContentIndex(options, 'find fused') : await withIndex(options, 'excerpt');
410
456
  const results = fusedSearch(index, query, {
411
457
  weights: { name: weights.name, pattern: weights.pattern, content: weights.content },
412
458
  limit: parsePositiveInt(options.limit, 50, 'limit'),
@@ -414,7 +460,7 @@ export function registerCodeCommands(program) {
414
460
  const payload = createPayload(index, { command: 'code.find.fused', value: query, weights }, results);
415
461
  const output = options.format === 'json' ? formatPayloadJson(payload) : formatFusedResults(results, options.ci);
416
462
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
417
- });
463
+ }));
418
464
  registerRepoMapCommand(code, 'map', 'map', 'Token-budgeted, importance-ranked repo map (top symbol signatures per file)');
419
465
  registerRepoMapCommand(code, 'pack', 'pack', 'Token-budgeted, importance-ranked pack (file content, optionally compressed)');
420
466
  }
@@ -432,11 +478,11 @@ function registerRepoMapCommand(code, name, defaultMode, description) {
432
478
  cmd.addOption(new Option('--tokenizer <name>', 'token counter for the budget').choices(['heuristic', 'o200k_base', 'cl100k_base']));
433
479
  cmd.option('--query <text>', 'focus: boost files/symbols matching this text');
434
480
  cmd.option('--focus-path <path>', 'focus: boost this file/dir and its graph neighbors (repeatable)', collectOption, []);
435
- cmd.option('--focus-depth <n>', 'focus: graph-neighbor depth for --focus-path (default 1)');
481
+ cmd.option('--focus-depth <n>', 'focus: graph-neighbor depth for --focus-path (default 1, 0 = seeds only)');
436
482
  cmd.option('--changed-from <ref>', 'focus: boost files changed from this base ref');
437
483
  cmd.option('--changed-to <ref>', 'focus: compare changed files to this head ref');
438
484
  cmd.option('--staged', 'focus: use staged changes for --changed-from/--changed-to');
439
- cmd.action(async (_options, command) => {
485
+ cmd.action(runAction(async (_options, command) => {
440
486
  const options = getOptions(command);
441
487
  const mode = options.mode ?? defaultMode;
442
488
  const format = options.mapFormat ?? (options.format === 'json' ? 'json' : 'markdown');
@@ -447,8 +493,7 @@ function registerRepoMapCommand(code, name, defaultMode, description) {
447
493
  const index = await withIndex(options, mode === 'pack' ? 'full' : 'excerpt');
448
494
  const focusQuery = options.query?.trim();
449
495
  const focusPaths = (options.focusPath ?? []).map(value => value.trim()).filter(Boolean);
450
- const changedByPath = new Map();
451
- const changedFocusPaths = [];
496
+ let changeContext;
452
497
  if (options.changedFrom || options.changedTo || options.staged) {
453
498
  const summary = await getGitDiffSummary({
454
499
  repoRoot: index.repoRoot,
@@ -456,26 +501,14 @@ function registerRepoMapCommand(code, name, defaultMode, description) {
456
501
  head: options.changedTo,
457
502
  staged: options.staged,
458
503
  });
459
- const numstatByPath = new Map(summary.numstat.map(entry => [entry.path, entry]));
460
- for (const file of summary.files) {
461
- if (file.status === 'deleted')
462
- continue;
463
- const absolutePath = path.resolve(index.repoRoot, file.path);
464
- const numstat = numstatByPath.get(file.path);
465
- changedFocusPaths.push(absolutePath);
466
- changedByPath.set(absolutePath, {
467
- added: numstat?.added ?? 0,
468
- deleted: numstat?.deleted ?? 0,
469
- binary: file.binary === true || numstat?.binary === true,
470
- });
471
- }
504
+ changeContext = toRepoMapChangeContext(index.repoRoot, summary);
472
505
  }
473
- const allFocusPaths = [...new Set([...focusPaths, ...changedFocusPaths])];
506
+ const allFocusPaths = [...new Set([...focusPaths, ...(changeContext?.focusPaths ?? [])])];
474
507
  const focus = focusQuery || allFocusPaths.length > 0
475
508
  ? {
476
509
  query: focusQuery || undefined,
477
510
  paths: allFocusPaths,
478
- graphDepth: options.focusDepth ? parsePositiveInt(options.focusDepth, 1, 'focus depth') : undefined,
511
+ graphDepth: options.focusDepth ? parseNonNegativeInt(options.focusDepth, 1, 'focus depth') : undefined,
479
512
  }
480
513
  : undefined;
481
514
  const result = buildRepoMap(index, {
@@ -489,15 +522,10 @@ function registerRepoMapCommand(code, name, defaultMode, description) {
489
522
  focus,
490
523
  });
491
524
  result.tokenizer = tokenizerName;
492
- for (const entry of result.entries) {
493
- const churn = changedByPath.get(entry.path);
494
- if (!churn)
495
- continue;
496
- entry.changed = true;
497
- entry.churn = churn;
498
- }
525
+ if (changeContext)
526
+ stampRepoMapChanges(result, changeContext);
499
527
  const output = renderRepoMap(result);
500
528
  await emit(output.endsWith('\n') ? output : `${output}\n`, options);
501
- });
529
+ }));
502
530
  }
503
531
  //# sourceMappingURL=command.js.map