@lzehrung/codegraph 2.2.3 → 2.3.1

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 (82) hide show
  1. package/README.md +1 -1
  2. package/codegraph-skill/codegraph/SKILL.md +15 -7
  3. package/dist/agent/followUps.d.ts +1 -0
  4. package/dist/agent/followUps.d.ts.map +1 -1
  5. package/dist/agent/followUps.js +11 -0
  6. package/dist/agent/followUps.js.map +1 -1
  7. package/dist/agent/orient.d.ts.map +1 -1
  8. package/dist/agent/orient.js +3 -3
  9. package/dist/agent/orient.js.map +1 -1
  10. package/dist/bin/cli.js +358 -118
  11. package/dist/cli/affected.js +2 -2
  12. package/dist/cli/affected.js.map +1 -1
  13. package/dist/cli/chunk.d.ts.map +1 -1
  14. package/dist/cli/chunk.js +16 -6
  15. package/dist/cli/chunk.js.map +1 -1
  16. package/dist/cli/commandCatalog.d.ts +1 -1
  17. package/dist/cli/commandCatalog.d.ts.map +1 -1
  18. package/dist/cli/commandCatalog.js +15 -3
  19. package/dist/cli/commandCatalog.js.map +1 -1
  20. package/dist/cli/context.d.ts.map +1 -1
  21. package/dist/cli/context.js +1 -0
  22. package/dist/cli/context.js.map +1 -1
  23. package/dist/cli/explain.d.ts.map +1 -1
  24. package/dist/cli/explain.js +3 -0
  25. package/dist/cli/explain.js.map +1 -1
  26. package/dist/cli/graph.d.ts.map +1 -1
  27. package/dist/cli/graph.js +1 -1
  28. package/dist/cli/graph.js.map +1 -1
  29. package/dist/cli/graphQueries.d.ts.map +1 -1
  30. package/dist/cli/graphQueries.js +22 -14
  31. package/dist/cli/graphQueries.js.map +1 -1
  32. package/dist/cli/grep.js +2 -2
  33. package/dist/cli/grep.js.map +1 -1
  34. package/dist/cli/help.d.ts +5 -4
  35. package/dist/cli/help.d.ts.map +1 -1
  36. package/dist/cli/help.js +18 -7
  37. package/dist/cli/help.js.map +1 -1
  38. package/dist/cli/navigation.d.ts.map +1 -1
  39. package/dist/cli/navigation.js +19 -6
  40. package/dist/cli/navigation.js.map +1 -1
  41. package/dist/cli/options.d.ts +8 -0
  42. package/dist/cli/options.d.ts.map +1 -1
  43. package/dist/cli/options.js +43 -11
  44. package/dist/cli/options.js.map +1 -1
  45. package/dist/cli/progress.d.ts +1 -0
  46. package/dist/cli/progress.d.ts.map +1 -1
  47. package/dist/cli/progress.js +103 -30
  48. package/dist/cli/progress.js.map +1 -1
  49. package/dist/cli/rootPolicy.d.ts.map +1 -1
  50. package/dist/cli/rootPolicy.js +2 -4
  51. package/dist/cli/rootPolicy.js.map +1 -1
  52. package/dist/cli/server.d.ts.map +1 -1
  53. package/dist/cli/server.js +3 -2
  54. package/dist/cli/server.js.map +1 -1
  55. package/dist/cli/sql.d.ts.map +1 -1
  56. package/dist/cli/sql.js +2 -1
  57. package/dist/cli/sql.js.map +1 -1
  58. package/dist/cli/typeHierarchy.d.ts.map +1 -1
  59. package/dist/cli/typeHierarchy.js +12 -3
  60. package/dist/cli/typeHierarchy.js.map +1 -1
  61. package/dist/cli.d.ts.map +1 -1
  62. package/dist/cli.js +5 -1
  63. package/dist/cli.js.map +1 -1
  64. package/dist/graphs.d.ts +0 -1
  65. package/dist/graphs.d.ts.map +1 -1
  66. package/dist/graphs.js +0 -1
  67. package/dist/graphs.js.map +1 -1
  68. package/dist/indexer/build-cache/project-snapshot.js +26 -25
  69. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  70. package/dist/indexer.d.ts +3 -6
  71. package/dist/indexer.d.ts.map +1 -1
  72. package/dist/indexer.js +2 -9
  73. package/dist/indexer.js.map +1 -1
  74. package/dist/mcp/handlers.js +1 -1
  75. package/dist/mcp/handlers.js.map +1 -1
  76. package/dist/mcp/protocol.d.ts.map +1 -1
  77. package/dist/mcp/protocol.js +79 -1
  78. package/dist/mcp/protocol.js.map +1 -1
  79. package/dist/mcp/tools.js +1 -1
  80. package/dist/mcp/tools.js.map +1 -1
  81. package/docs/mcp.md +12 -10
  82. package/package.json +3 -3
package/dist/bin/cli.js CHANGED
@@ -432,6 +432,13 @@ function graphCommandSchema(positionals) {
432
432
  "--symbols-detailed-scope"
433
433
  ], positionals);
434
434
  }
435
+ function getCliCommandUsage(command) {
436
+ const usage = CLI_COMMAND_SCHEMAS.get(command)?.positionals.usage;
437
+ if (!usage) {
438
+ throw new Error(`No validation usage is defined for ${command}.`);
439
+ }
440
+ return usage;
441
+ }
435
442
  function allowedFlagsForSchema(schema) {
436
443
  return /* @__PURE__ */ new Set(["--help", "-h", "--version", "-v", "--debug", ...schema.flags ?? []]);
437
444
  }
@@ -692,7 +699,8 @@ var init_options = __esm({
692
699
  [
693
700
  "affected",
694
701
  commandSchema([...SHARED_BUILD_FLAGS, "--json", "--quiet", "--stdin"], [...SHARED_BUILD_OPTIONS, "--base", "--depth", "--filter", "--head"], {
695
- kind: "any"
702
+ kind: "any",
703
+ usage: "Usage: codegraph affected <file...> [--stdin] [--base <ref> --head <ref>] [--root <path>] [--depth <n>] [--filter <glob>] [--json | --quiet]"
696
704
  })
697
705
  ],
698
706
  [
@@ -716,7 +724,7 @@ var init_options = __esm({
716
724
  commandSchema([...JSON_OUTPUT_FLAGS, "--text"], ["--language", "--max-tokens", "--min-tokens"], {
717
725
  kind: "max",
718
726
  max: 1,
719
- usage: "Usage: codegraph chunk <file-path> [options]"
727
+ usage: "Usage: codegraph chunk <file-path> [--language <language>] [--min-tokens <n>] [--max-tokens <n>] [--text] [--json | --pretty]"
720
728
  })
721
729
  ],
722
730
  [
@@ -727,10 +735,10 @@ var init_options = __esm({
727
735
  ],
728
736
  [
729
737
  "deps",
730
- commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--depth"], {
738
+ commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS, "--all"], [...SHARED_BUILD_OPTIONS, "--depth"], {
731
739
  kind: "max",
732
740
  max: 1,
733
- usage: "Usage: codegraph deps <file> [--root <path>] [--depth <n>] [--json | --pretty]"
741
+ usage: "Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]"
734
742
  })
735
743
  ],
736
744
  [
@@ -813,7 +821,7 @@ var init_options = __esm({
813
821
  commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], SHARED_BUILD_OPTIONS, {
814
822
  kind: "max",
815
823
  max: 3,
816
- usage: "Usage: codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
824
+ usage: "Usage: codegraph goto <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]\n codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
817
825
  })
818
826
  ],
819
827
  ["graph", graphCommandSchema({ kind: "any" })],
@@ -832,7 +840,16 @@ var init_options = __esm({
832
840
  [
833
841
  "grep",
834
842
  commandSchema(["--ignore-case", "--json", "--pretty", "-i", "--no-gitignore"], ["--glob", "--ignore-glob", "--include-glob", "--max-hits", "--pattern", "--query", "--regex", "--root"], {
835
- kind: "any"
843
+ kind: "max",
844
+ max: 1,
845
+ // `handleGrepCommand` takes the pattern from --pattern, then --regex, then the
846
+ // positional, and --query is a separate syntax-tree mode. Present all three forms
847
+ // so a parse failure does not imply the positional regex is mandatory.
848
+ usage: [
849
+ "Usage: codegraph grep <regex> [--root <dir>] [--glob|--include-glob|--ignore-glob <glob>] [--ignore-case|-i] [--no-gitignore] [--max-hits <n>] [--json | --pretty]",
850
+ " codegraph grep --pattern|--regex <expr> [--root <dir>] [--glob|--include-glob|--ignore-glob <glob>] [--ignore-case|-i] [--no-gitignore] [--max-hits <n>] [--json | --pretty]",
851
+ " codegraph grep --query <tree-sitter-query> [--root <dir>] [--json | --pretty]"
852
+ ].join("\n")
836
853
  })
837
854
  ],
838
855
  [
@@ -872,7 +889,7 @@ var init_options = __esm({
872
889
  ], {
873
890
  kind: "max",
874
891
  max: 1,
875
- usage: "Usage: codegraph impact [project-root] [--provider git|github|raw] [options]"
892
+ usage: "Usage: codegraph impact [project-root] [--provider git|github|raw] [--depth <n>] [options] [--json | --pretty]"
876
893
  })
877
894
  ],
878
895
  [
@@ -947,7 +964,7 @@ var init_options = __esm({
947
964
  ], {
948
965
  kind: "max",
949
966
  max: 1,
950
- usage: "Usage: codegraph server <start|status|stop> [--root <path>]"
967
+ usage: "Usage: codegraph server <start|status|stop> [--root <path>] [--json | --pretty]"
951
968
  })
952
969
  ],
953
970
  [
@@ -974,10 +991,10 @@ var init_options = __esm({
974
991
  ],
975
992
  [
976
993
  "rdeps",
977
- commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--depth"], {
994
+ commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS, "--all"], [...SHARED_BUILD_OPTIONS, "--depth"], {
978
995
  kind: "max",
979
996
  max: 1,
980
- usage: "Usage: codegraph rdeps <file> [--root <path>] [--depth <n>] [--json | --pretty]"
997
+ usage: "Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]"
981
998
  })
982
999
  ],
983
1000
  [
@@ -985,7 +1002,7 @@ var init_options = __esm({
985
1002
  commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--col", "--column", "--file", "--line"], {
986
1003
  kind: "max",
987
1004
  max: 3,
988
- usage: "Usage: codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
1005
+ usage: "Usage: codegraph refs <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]\n codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]\n codegraph refs --file <file> [--line <line> --col <column>] [--root <path>] [--json | --pretty]"
989
1006
  })
990
1007
  ],
991
1008
  [
@@ -1095,7 +1112,7 @@ var init_options = __esm({
1095
1112
  commandSchema(["--json", "--pretty"], ["--db", "--query", "--sqlite"], {
1096
1113
  kind: "max",
1097
1114
  max: 2,
1098
- usage: 'Usage: codegraph sql <sqlite-path> "SELECT ..." [--json | --pretty] OR codegraph sql --db <sqlite path> --query "SELECT ..." [--json | --pretty]'
1115
+ usage: 'Usage: codegraph sql <sqlite-path> "SELECT ..." [--json | --pretty] OR codegraph sql --db <sqlite-path> --query "SELECT ..." [--json | --pretty]'
1099
1116
  })
1100
1117
  ],
1101
1118
  [
@@ -1148,16 +1165,14 @@ function resolveCliProgressPresentation(input) {
1148
1165
  if (input.stderrIsTTY) {
1149
1166
  return input.terminalSupportsControlSequences ? "interactive" : "log";
1150
1167
  }
1151
- if (input.policy === "always")
1152
- return "log";
1153
- return "off";
1168
+ return "log";
1154
1169
  }
1155
1170
  function createCliProgressDisplay(options) {
1156
1171
  if (options.presentation === "log")
1157
- return createLogProgressDisplay(options.write);
1158
- return createInteractiveProgressDisplay(options.write);
1172
+ return createLogProgressDisplay(options.write, options.delayMs);
1173
+ return createInteractiveProgressDisplay(options.write, options.delayMs);
1159
1174
  }
1160
- function createInteractiveProgressDisplay(write) {
1175
+ function createInteractiveProgressDisplay(write, delayMs = 0) {
1161
1176
  let active = false;
1162
1177
  let rendered = false;
1163
1178
  let frameIndex = 0;
@@ -1165,6 +1180,7 @@ function createInteractiveProgressDisplay(write) {
1165
1180
  let total = 0;
1166
1181
  let mode = "build";
1167
1182
  let interval;
1183
+ let delay;
1168
1184
  const clear = () => {
1169
1185
  if (!rendered)
1170
1186
  return;
@@ -1177,39 +1193,55 @@ function createInteractiveProgressDisplay(write) {
1177
1193
  const action = progressAction(mode);
1178
1194
  const frame = SPINNER_FRAMES[frameIndex % SPINNER_FRAMES.length];
1179
1195
  frameIndex += 1;
1180
- const count = total > 0 ? ` ${current}/${total} files` : "";
1196
+ const count = formatProgressCount(current, total);
1181
1197
  write(`${CLEAR_LINE}${action} project index... ${frame}${count}`);
1182
1198
  rendered = true;
1183
1199
  };
1184
1200
  const stopInterval = () => {
1185
- if (interval === void 0)
1186
- return;
1187
- clearInterval(interval);
1188
- interval = void 0;
1201
+ if (interval !== void 0) {
1202
+ clearInterval(interval);
1203
+ interval = void 0;
1204
+ }
1205
+ if (delay !== void 0) {
1206
+ clearTimeout(delay);
1207
+ delay = void 0;
1208
+ }
1189
1209
  };
1190
1210
  const start = (update) => {
1191
1211
  stopInterval();
1192
1212
  clear();
1193
1213
  active = true;
1214
+ rendered = false;
1194
1215
  frameIndex = 0;
1195
1216
  current = update.current;
1196
1217
  total = update.total;
1197
1218
  mode = update.mode ?? "build";
1198
- render();
1199
- interval = setInterval(render, REFRESH_INTERVAL_MS);
1200
- interval.unref();
1219
+ const beginRendering = () => {
1220
+ if (!active)
1221
+ return;
1222
+ render();
1223
+ interval = setInterval(render, REFRESH_INTERVAL_MS);
1224
+ interval.unref();
1225
+ };
1226
+ if (delayMs) {
1227
+ delay = setTimeout(beginRendering, delayMs);
1228
+ delay.unref();
1229
+ } else {
1230
+ beginRendering();
1231
+ }
1201
1232
  };
1202
1233
  const complete = (update) => {
1203
1234
  if (!active)
1204
1235
  return;
1205
1236
  active = false;
1206
1237
  stopInterval();
1238
+ if (!rendered)
1239
+ return;
1207
1240
  clear();
1208
1241
  const verb = progressCompleteVerb(mode);
1209
- const fileCount = update.total;
1210
- const files = fileCount === 1 ? "file" : "files";
1242
+ const fileCount = formatFileCount(update.total, "words");
1211
1243
  const elapsed = update.elapsedMs === void 0 ? "" : ` in ${formatDuration(update.elapsedMs)}`;
1212
- write(`${verb} project index: ${fileCount} ${files}${elapsed}.
1244
+ write(`${verb} project index: ${fileCount}${elapsed}.
1213
1245
  `);
1214
1246
  };
1215
1247
  return {
@@ -1239,37 +1271,92 @@ function createInteractiveProgressDisplay(write) {
1239
1271
  }
1240
1272
  };
1241
1273
  }
1242
- function createLogProgressDisplay(write) {
1274
+ function formatFileCount(count, zeroFormat = "numeric") {
1275
+ if (!count && zeroFormat === "words")
1276
+ return "no files";
1277
+ return `${count} file${count === 1 ? "" : "s"}`;
1278
+ }
1279
+ function formatProgressCount(current, total) {
1280
+ if (total > 0)
1281
+ return ` ${current}/${formatFileCount(total)}`;
1282
+ return ` ${formatFileCount(current)} processed`;
1283
+ }
1284
+ function createLogProgressDisplay(write, delayMs = 0) {
1243
1285
  let active = false;
1286
+ let rendered = false;
1287
+ let current = 0;
1288
+ let total = 0;
1244
1289
  let mode = "build";
1290
+ let delay;
1291
+ let heartbeat;
1292
+ const stopTimers = () => {
1293
+ if (delay !== void 0) {
1294
+ clearTimeout(delay);
1295
+ delay = void 0;
1296
+ }
1297
+ if (heartbeat !== void 0) {
1298
+ clearInterval(heartbeat);
1299
+ heartbeat = void 0;
1300
+ }
1301
+ };
1302
+ const renderStart = () => {
1303
+ if (!active || rendered)
1304
+ return;
1305
+ rendered = true;
1306
+ write(`[Progress] ${progressAction(mode)} project index.
1307
+ `);
1308
+ heartbeat = setInterval(() => {
1309
+ if (!active)
1310
+ return;
1311
+ write(`[Progress] ${progressAction(mode)} project index:${formatProgressCount(current, total)}.
1312
+ `);
1313
+ }, 1e3);
1314
+ heartbeat.unref();
1315
+ };
1316
+ const start = (update) => {
1317
+ stopTimers();
1318
+ active = true;
1319
+ rendered = false;
1320
+ current = update.current;
1321
+ total = update.total;
1322
+ mode = update.mode ?? "build";
1323
+ if (delayMs) {
1324
+ delay = setTimeout(renderStart, delayMs);
1325
+ delay.unref();
1326
+ } else {
1327
+ renderStart();
1328
+ }
1329
+ };
1245
1330
  return {
1246
1331
  update: (update) => {
1247
1332
  if (update.phase === "start") {
1248
- active = true;
1249
- mode = update.mode ?? "build";
1250
- const action = progressAction(mode);
1251
- write(`[Progress] ${action} project index.
1252
- `);
1333
+ start(update);
1253
1334
  return;
1254
1335
  }
1255
1336
  if (update.phase === "complete") {
1256
1337
  if (!active)
1257
1338
  return;
1258
1339
  active = false;
1340
+ stopTimers();
1341
+ if (!rendered)
1342
+ return;
1259
1343
  const verb = progressCompleteVerb(mode);
1260
1344
  const elapsed = update.elapsedMs === void 0 ? "" : ` in ${formatDuration(update.elapsedMs)}`;
1261
- write(`[Progress] ${verb} project index: ${update.total} files${elapsed}.
1345
+ write(`[Progress] ${verb} project index: ${formatFileCount(update.total, "words")}${elapsed}.
1262
1346
  `);
1263
1347
  return;
1264
1348
  }
1265
1349
  if (!active) {
1266
1350
  if (update.phase === "update")
1267
1351
  return;
1268
- active = true;
1352
+ start(update);
1269
1353
  }
1270
- const isComplete = update.current >= update.total;
1271
- if (update.current === 1 || isComplete || update.current % 100 === 0) {
1272
- write(`[Progress] ${update.current}/${update.total} files processed.
1354
+ current = update.current;
1355
+ total = update.total;
1356
+ mode = update.mode ?? mode;
1357
+ const isComplete = update.total > 0 && update.current >= update.total;
1358
+ if (rendered && (update.current === 1 || isComplete || update.current % 100 === 0)) {
1359
+ write(`[Progress] ${formatFileCount(update.current)} processed.
1273
1360
  `);
1274
1361
  }
1275
1362
  },
@@ -1277,6 +1364,7 @@ function createLogProgressDisplay(write) {
1277
1364
  },
1278
1365
  dispose: () => {
1279
1366
  active = false;
1367
+ stopTimers();
1280
1368
  }
1281
1369
  };
1282
1370
  }
@@ -1295,9 +1383,10 @@ function progressCompleteVerb(mode) {
1295
1383
  return "Checked";
1296
1384
  }
1297
1385
  function formatDuration(elapsedMs2) {
1298
- if (elapsedMs2 < 1e3)
1299
- return `${Math.max(0, Math.round(elapsedMs2))}ms`;
1300
- return `${(elapsedMs2 / 1e3).toFixed(1)}s`;
1386
+ const durationMs = Math.max(0, elapsedMs2);
1387
+ if (durationMs < 1e3)
1388
+ return `${Math.round(durationMs)}ms`;
1389
+ return `${(durationMs / 1e3).toFixed(1)}s`;
1301
1390
  }
1302
1391
  var REFRESH_INTERVAL_MS, CLEAR_LINE, SPINNER_FRAMES;
1303
1392
  var init_progress = __esm({
@@ -1519,7 +1608,8 @@ function createCliProgressHandler(policy) {
1519
1608
  context.progressDisplay?.dispose();
1520
1609
  const display = createCliProgressDisplay({
1521
1610
  presentation,
1522
- write: context.runtime.stderr
1611
+ write: context.runtime.stderr,
1612
+ ...policy === "auto" ? { delayMs: 1e3 } : {}
1523
1613
  });
1524
1614
  context.progressDisplay = display;
1525
1615
  return display.update;
@@ -50669,11 +50759,11 @@ function sameSymbolEdgeMultiset(expected, actual) {
50669
50759
  return false;
50670
50760
  const counts = /* @__PURE__ */ new Map();
50671
50761
  for (const edge of expected) {
50672
- const key = serializedSymbolEdge(edge);
50762
+ const key = symbolEdgeKey(edge);
50673
50763
  counts.set(key, (counts.get(key) ?? 0) + 1);
50674
50764
  }
50675
50765
  for (const edge of actual) {
50676
- const key = serializedSymbolEdge(edge);
50766
+ const key = symbolEdgeKey(edge);
50677
50767
  const remaining = counts.get(key);
50678
50768
  if (remaining === void 0)
50679
50769
  return false;
@@ -50684,27 +50774,30 @@ function sameSymbolEdgeMultiset(expected, actual) {
50684
50774
  }
50685
50775
  return !counts.size;
50686
50776
  }
50687
- function serializedSymbolEdge(edge) {
50688
- return JSON.stringify({
50689
- from: edge.from,
50690
- to: edge.to,
50691
- label: edge.label,
50692
- site: edge.site ? {
50693
- file: edge.site.file,
50694
- range: {
50695
- start: {
50696
- line: edge.site.range.start.line,
50697
- column: edge.site.range.start.column,
50698
- ...edge.site.range.start.index !== void 0 ? { index: edge.site.range.start.index } : {}
50699
- },
50700
- end: {
50701
- line: edge.site.range.end.line,
50702
- column: edge.site.range.end.column,
50703
- ...edge.site.range.end.index !== void 0 ? { index: edge.site.range.end.index } : {}
50704
- }
50705
- }
50706
- } : void 0
50707
- });
50777
+ function symbolEdgeKey(edge) {
50778
+ const from = lengthPrefixedSymbolEdgeField(edge.from);
50779
+ const to = lengthPrefixedSymbolEdgeField(edge.to);
50780
+ const label = edge.label === void 0 ? "u" : `s${lengthPrefixedSymbolEdgeField(edge.label)}`;
50781
+ if (!edge.site)
50782
+ return `f${from}t${to}l${label}s`;
50783
+ const { file: file2, range } = edge.site;
50784
+ const startIndex = range.start.index === void 0 ? "u" : `n${range.start.index}`;
50785
+ const endIndex = range.end.index === void 0 ? "u" : `n${range.end.index}`;
50786
+ return [
50787
+ `f${from}`,
50788
+ `t${to}`,
50789
+ `l${label}`,
50790
+ `s${lengthPrefixedSymbolEdgeField(file2)}`,
50791
+ `sl${range.start.line}`,
50792
+ `sc${range.start.column}`,
50793
+ `si${startIndex}`,
50794
+ `el${range.end.line}`,
50795
+ `ec${range.end.column}`,
50796
+ `ei${endIndex}`
50797
+ ].join("");
50798
+ }
50799
+ function lengthPrefixedSymbolEdgeField(value) {
50800
+ return `${value.length}:${value}`;
50708
50801
  }
50709
50802
  function normalizedSnapshotNativeMode(nativeMode) {
50710
50803
  if (nativeMode === void 0 || nativeMode === "auto")
@@ -55743,6 +55836,17 @@ function toolFollowUp(tool, arguments_ = {}, label) {
55743
55836
  ...label !== void 0 ? { label } : {}
55744
55837
  };
55745
55838
  }
55839
+ function dedupeAgentFollowUps(followUps) {
55840
+ const seen = /* @__PURE__ */ new Set();
55841
+ return followUps.filter((followUp) => {
55842
+ const serializedArguments = JSON.stringify(followUp.arguments);
55843
+ const key = `${followUp.tool.length}|${followUp.tool}${serializedArguments}`;
55844
+ if (seen.has(key))
55845
+ return false;
55846
+ seen.add(key);
55847
+ return true;
55848
+ });
55849
+ }
55746
55850
  function formatAgentFollowUpAsCli(followUp) {
55747
55851
  const args = followUp.arguments;
55748
55852
  switch (followUp.tool) {
@@ -60762,7 +60866,7 @@ async function handleSqlCommand(context) {
60762
60866
  const dbOpt = context.getOpt("--db") ?? context.getOpt("--sqlite") ?? context.positionals[0];
60763
60867
  const queryText = context.getOpt("--query") ?? context.positionals[1];
60764
60868
  if (!dbOpt || !queryText) {
60765
- context.writeStderrLine('Usage: sql <sqlite-path> "SELECT ..." OR sql --db <sqlite-path> --query "SELECT ..."');
60869
+ context.writeStderrLine(getCliCommandUsage("sql"));
60766
60870
  context.exit(2);
60767
60871
  }
60768
60872
  const dbPath = path60.isAbsolute(dbOpt) ? normalizePath(dbOpt) : normalizePath(resolveFilePathFromRoot(context.cwd(), dbOpt));
@@ -60775,6 +60879,7 @@ var init_sql2 = __esm({
60775
60879
  init_sqlite();
60776
60880
  init_paths();
60777
60881
  init_pretty();
60882
+ init_options();
60778
60883
  }
60779
60884
  });
60780
60885
 
@@ -60968,7 +61073,7 @@ function formatChunkSummary(chunks) {
60968
61073
  async function handleChunkCommand(context) {
60969
61074
  const inputFilePath = context.positionals[0];
60970
61075
  if (!inputFilePath) {
60971
- context.writeStderrLine("Usage: chunk <file-path> [options]");
61076
+ context.writeStderrLine(getCliCommandUsage("chunk"));
60972
61077
  context.writeStderrLine("Options:");
60973
61078
  context.writeStderrLine(" --min-tokens N Minimum tokens per chunk (default: 150)");
60974
61079
  context.writeStderrLine(" --max-tokens N Maximum tokens per chunk (default: 400)");
@@ -60976,16 +61081,25 @@ async function handleChunkCommand(context) {
60976
61081
  context.writeStderrLine(" --text Force text chunking mode");
60977
61082
  context.exit(2);
60978
61083
  }
61084
+ const languageOverride = context.getOpt("--language");
61085
+ if (languageOverride) {
61086
+ const languageId = normalizeChunkLanguageId(languageOverride);
61087
+ const isSupported = supportedChunkLanguageIds.has(languageId);
61088
+ if (!isSupported) {
61089
+ context.writeStderrLine(`Unsupported --language value "${languageId}". Supported languages: ${chunkLanguageHelp}.`);
61090
+ context.exit(2);
61091
+ }
61092
+ }
60979
61093
  try {
60980
61094
  const filePath = path61.resolve(context.cwd(), parseSourceLocationInput(inputFilePath).file);
60981
61095
  const source = await fsp33.readFile(filePath, "utf8");
60982
61096
  const ext = path61.extname(filePath).toLowerCase();
60983
- let languageId = context.getOpt("--language");
60984
- if (!languageId) {
61097
+ let languageId;
61098
+ if (!languageOverride) {
60985
61099
  const support = supportForFile(filePath);
60986
61100
  languageId = support ? normalizeChunkLanguageId(support.id) : chunkTextLanguageByExtension[ext] || "text";
60987
61101
  } else {
60988
- languageId = normalizeChunkLanguageId(languageId);
61102
+ languageId = normalizeChunkLanguageId(languageOverride);
60989
61103
  }
60990
61104
  const forceText = context.hasFlag("--text");
60991
61105
  const minTokensRaw = context.getOpt("--min-tokens");
@@ -61032,7 +61146,7 @@ async function handleChunkCommand(context) {
61032
61146
  exitWithError(context, error51, 1, "Chunking failed");
61033
61147
  }
61034
61148
  }
61035
- var chunkLanguageAliases2, chunkTextLanguageByExtension, chunkLanguageHelp;
61149
+ var chunkLanguageAliases2, chunkTextLanguageByExtension, supportedChunkLanguageIds, chunkLanguageHelp;
61036
61150
  var init_chunk = __esm({
61037
61151
  "dist/cli/chunk.js"() {
61038
61152
  "use strict";
@@ -61054,7 +61168,8 @@ var init_chunk = __esm({
61054
61168
  ".yaml": "yaml",
61055
61169
  ".yml": "yaml"
61056
61170
  };
61057
- chunkLanguageHelp = Array.from(/* @__PURE__ */ new Set([...Object.keys(LANG_CONFIGS).sort(), "vue", "svelte", "json", "yaml", "text"])).join(", ");
61171
+ supportedChunkLanguageIds = /* @__PURE__ */ new Set([...Object.keys(LANG_CONFIGS), "vue", "svelte", "json", "yaml", "text"]);
61172
+ chunkLanguageHelp = [...supportedChunkLanguageIds].sort().join(", ");
61058
61173
  }
61059
61174
  });
61060
61175
 
@@ -74864,11 +74979,12 @@ function suggestCliCommands(input, limit = 3) {
74864
74979
  function routeForCliIntent(input) {
74865
74980
  return INTENT_ROUTES.find((route) => route.pattern.test(input))?.command;
74866
74981
  }
74867
- function renderCliCommandList() {
74868
- const width = Math.max(...CLI_COMMAND_CATALOG.map((command) => command.name.length));
74869
- return CLI_COMMAND_CATALOG.map((command) => ` ${command.name.padEnd(width)} ${command.summary}`).join("\n");
74982
+ function renderCliCommandList(advanced = false) {
74983
+ const commands = advanced ? CLI_COMMAND_CATALOG : CLI_COMMAND_CATALOG.filter((command) => CORE_COMMAND_NAMES[command.name]);
74984
+ const width = Math.max(...commands.map((command) => command.name.length));
74985
+ return commands.map((command) => ` ${command.name.padEnd(width)} ${command.summary}`).join("\n");
74870
74986
  }
74871
- var CLI_COMMAND_CATALOG, commandByName, aliasToCommand, INTENT_ROUTES;
74987
+ var CLI_COMMAND_CATALOG, commandByName, aliasToCommand, INTENT_ROUTES, CORE_COMMAND_NAMES;
74872
74988
  var init_commandCatalog = __esm({
74873
74989
  "dist/cli/commandCatalog.js"() {
74874
74990
  "use strict";
@@ -74940,6 +75056,15 @@ var init_commandCatalog = __esm({
74940
75056
  { pattern: /^(configure|setup|agent)$/i, command: "codegraph install" },
74941
75057
  { pattern: /^(health|diagnose|check)$/i, command: "codegraph doctor" }
74942
75058
  ];
75059
+ CORE_COMMAND_NAMES = {
75060
+ doctor: true,
75061
+ orient: true,
75062
+ explore: true,
75063
+ search: true,
75064
+ file: true,
75065
+ deps: true,
75066
+ review: true
75067
+ };
74943
75068
  }
74944
75069
  });
74945
75070
 
@@ -75042,7 +75167,7 @@ function helpTextForCommand(command, positionals) {
75042
75167
  }
75043
75168
  return void 0;
75044
75169
  }
75045
- var CLI_TASK_HELP_TEXT, CLI_HELP_TEXT, LIFECYCLE_HELP_TEXT, AFFECTED_HELP_TEXT, INSTALL_HELP_TEXT, UNINSTALL_HELP_TEXT, SHARED_INDEX_OPTIONS_HELP, EXPLORE_HELP_TEXT, FILE_HELP_TEXT, SEARCH_HELP_TEXT, GOTO_HELP_TEXT, REFS_HELP_TEXT, GREP_HELP_TEXT, SQL_HELP_TEXT, SYMBOLS_HELP_TEXT, CALLERS_HELP_TEXT, CALLEES_HELP_TEXT, SUPERTYPES_HELP_TEXT, SUBTYPES_HELP_TEXT, IMPLEMENTATIONS_HELP_TEXT, RENAME_PREVIEW_HELP_TEXT, REFACTOR_PLAN_HELP_TEXT, ORIENT_HELP_TEXT, PACKET_HELP_TEXT, EXPLAIN_HELP_TEXT, ARTIFACT_HELP_TEXT, SERVER_HELP_TEXT, MCP_HELP_TEXT, MCP_SERVE_HELP_TEXT, DUPLICATES_HELP_TEXT, DRIFT_HELP_TEXT, VIEWER_HELP_TEXT, INDEX_HELP_TEXT, GRAPH_HELP_TEXT, REVIEW_HELP_TEXT, IMPACT_HELP_TEXT, INSPECT_HELP_TEXT, DEPS_HELP_TEXT, RDEPS_HELP_TEXT, PATH_HELP_TEXT, CYCLES_HELP_TEXT, HOTSPOTS_HELP_TEXT, UNRESOLVED_HELP_TEXT, LINKS_HELP_TEXT, APISURFACE_HELP_TEXT, GRAPH_DELTA_HELP_TEXT, DOCTOR_HELP_TEXT, CHUNK_HELP_TEXT, SKILL_HELP_TEXT, DUMPMOD_HELP_TEXT, VERSION_HELP_TEXT;
75170
+ var CLI_TASK_HELP_TEXT, CLI_HELP_TEXT, ADVANCED_HELP_TEXT, LIFECYCLE_HELP_TEXT, AFFECTED_HELP_TEXT, INSTALL_HELP_TEXT, UNINSTALL_HELP_TEXT, SHARED_INDEX_OPTIONS_HELP, EXPLORE_HELP_TEXT, FILE_HELP_TEXT, SEARCH_HELP_TEXT, GOTO_HELP_TEXT, REFS_HELP_TEXT, GREP_HELP_TEXT, SQL_HELP_TEXT, SYMBOLS_HELP_TEXT, CALLERS_HELP_TEXT, CALLEES_HELP_TEXT, SUPERTYPES_HELP_TEXT, SUBTYPES_HELP_TEXT, IMPLEMENTATIONS_HELP_TEXT, RENAME_PREVIEW_HELP_TEXT, REFACTOR_PLAN_HELP_TEXT, ORIENT_HELP_TEXT, PACKET_HELP_TEXT, EXPLAIN_HELP_TEXT, ARTIFACT_HELP_TEXT, SERVER_HELP_TEXT, MCP_HELP_TEXT, MCP_SERVE_HELP_TEXT, DUPLICATES_HELP_TEXT, DRIFT_HELP_TEXT, VIEWER_HELP_TEXT, INDEX_HELP_TEXT, GRAPH_HELP_TEXT, REVIEW_HELP_TEXT, IMPACT_HELP_TEXT, INSPECT_HELP_TEXT, DEPS_HELP_TEXT, RDEPS_HELP_TEXT, PATH_HELP_TEXT, CYCLES_HELP_TEXT, HOTSPOTS_HELP_TEXT, UNRESOLVED_HELP_TEXT, LINKS_HELP_TEXT, APISURFACE_HELP_TEXT, GRAPH_DELTA_HELP_TEXT, DOCTOR_HELP_TEXT, CHUNK_HELP_TEXT, SKILL_HELP_TEXT, DUMPMOD_HELP_TEXT, VERSION_HELP_TEXT;
75046
75171
  var init_help = __esm({
75047
75172
  "dist/cli/help.js"() {
75048
75173
  "use strict";
@@ -75069,9 +75194,11 @@ Start here:
75069
75194
 
75070
75195
  Usage: codegraph <command> [options] [path]
75071
75196
 
75072
- Commands:
75197
+ Core commands:
75073
75198
  ${renderCliCommandList()}
75074
75199
 
75200
+ For the complete catalog, run: codegraph help advanced
75201
+
75075
75202
  Graph Options:
75076
75203
  --fast-graph Use text import extraction for plain .js and .ts
75077
75204
  files. May miss multiline or complex patterns;
@@ -75170,6 +75297,11 @@ Examples:
75170
75297
  codegraph refactor-plan Service --rename RenamedService
75171
75298
  codegraph version
75172
75299
  codegraph -v
75300
+ `;
75301
+ ADVANCED_HELP_TEXT = `codegraph - Complete command catalog
75302
+
75303
+ Commands:
75304
+ ${renderCliCommandList(true)}
75173
75305
  `;
75174
75306
  LIFECYCLE_HELP_TEXT = `codegraph init/status/sync/uninit - Initialize, inspect, refresh, or remove project-local Codegraph state
75175
75307
 
@@ -75266,20 +75398,20 @@ ${SHARED_INDEX_OPTIONS_HELP}
75266
75398
  `;
75267
75399
  GOTO_HELP_TEXT = `codegraph goto - Go to a definition
75268
75400
 
75269
- Usage: codegraph goto <file>::<symbol> [--root <path>] [--json | --pretty]
75401
+ Usage: codegraph goto <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]
75270
75402
  codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]
75271
75403
 
75272
- A qualified symbol path resolves one definition without a location. A file-only target succeeds when the file defines one symbol; otherwise JSON returns bounded candidates. Search-result locations and portable symbol handles can be pasted directly.
75404
+ A qualified symbol path or portable symbol handle resolves one definition without a location. A file-only target succeeds when the file defines one symbol; otherwise JSON returns bounded candidates. Search-result locations and portable symbol handles can be pasted directly.
75273
75405
 
75274
75406
  ${SHARED_INDEX_OPTIONS_HELP}
75275
75407
  `;
75276
75408
  REFS_HELP_TEXT = `codegraph refs - Find semantic references
75277
75409
 
75278
- Usage: codegraph refs <file>::<symbol> [--root <path>] [--json | --pretty]
75410
+ Usage: codegraph refs <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]
75279
75411
  codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]
75280
75412
  codegraph refs --file <file> [--line <line> --col <column>] [--root <path>] [--json | --pretty]
75281
75413
 
75282
- A qualified symbol path finds references for one declaration without a location. A file-only target finds references for every symbol defined in that file. Search-result locations and portable symbol handles can be pasted directly.
75414
+ A qualified symbol path or portable symbol handle resolves one definition and reports references to it without a location. A file-only target finds references for every definition in the file.
75283
75415
 
75284
75416
  ${SHARED_INDEX_OPTIONS_HELP}
75285
75417
  `;
@@ -75635,7 +75767,9 @@ ${SHARED_INDEX_OPTIONS_HELP}
75635
75767
  `;
75636
75768
  DEPS_HELP_TEXT = `codegraph deps - List file dependencies
75637
75769
 
75638
- Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n>] [--json | --pretty]
75770
+ Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]
75771
+
75772
+ By default, outputs dependencies through depth 1. Use --depth for another finite output depth, or --all to include every depth.
75639
75773
 
75640
75774
  A qualified symbol path or portable symbol handle uses its declaring file for file-graph traversal. Use callees for symbol-level call relationships.
75641
75775
 
@@ -75643,7 +75777,9 @@ ${SHARED_INDEX_OPTIONS_HELP}
75643
75777
  `;
75644
75778
  RDEPS_HELP_TEXT = `codegraph rdeps - List reverse file dependencies
75645
75779
 
75646
- Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n>] [--json | --pretty]
75780
+ Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]
75781
+
75782
+ By default, outputs reverse dependencies through depth 1. Use --depth for another finite output depth, or --all to include every depth.
75647
75783
 
75648
75784
  A qualified symbol path or portable symbol handle uses its declaring file for file-graph traversal. Use callers for symbol-level call relationships.
75649
75785
 
@@ -81735,8 +81871,17 @@ async function handleTypeHierarchyCommand(command, context) {
81735
81871
  context.writeStderrLine(helpText2(command).trimEnd());
81736
81872
  context.exit(2);
81737
81873
  }
81874
+ let limit;
81875
+ let depth;
81876
+ try {
81877
+ limit = parseBoundedIntegerOption(context.getOpt("--limit"), "--limit", DEFAULT_HIERARCHY_LIMIT2, 0, MAX_HIERARCHY_LIMIT2);
81878
+ if (command !== "implementations") {
81879
+ depth = parseBoundedIntegerOption(context.getOpt("--depth"), "--depth", DEFAULT_HIERARCHY_DEPTH, 1, MAX_HIERARCHY_DEPTH2);
81880
+ }
81881
+ } catch (error51) {
81882
+ exitWithError(context, error51, 2);
81883
+ }
81738
81884
  try {
81739
- const limit = parseBoundedIntegerOption(context.getOpt("--limit"), "--limit", DEFAULT_HIERARCHY_LIMIT2, 0, MAX_HIERARCHY_LIMIT2);
81740
81885
  if (command === "implementations") {
81741
81886
  const response2 = await findImplementations2({
81742
81887
  root: context.root,
@@ -81747,7 +81892,6 @@ async function handleTypeHierarchyCommand(command, context) {
81747
81892
  writeResponse(context, response2, formatImplementationsResponse);
81748
81893
  return;
81749
81894
  }
81750
- const depth = parseBoundedIntegerOption(context.getOpt("--depth"), "--depth", DEFAULT_HIERARCHY_DEPTH, 1, MAX_HIERARCHY_DEPTH2);
81751
81895
  const request = {
81752
81896
  root: context.root,
81753
81897
  handle,
@@ -81853,6 +81997,9 @@ async function handleExplainCommand(context) {
81853
81997
  } else {
81854
81998
  context.writeStdoutLine(formatAgentExplanation(response));
81855
81999
  }
82000
+ if (response.target.kind === "not_found") {
82001
+ context.exit(1);
82002
+ }
81856
82003
  }
81857
82004
  var init_explain2 = __esm({
81858
82005
  "dist/cli/explain.js"() {
@@ -82140,10 +82287,10 @@ function buildFocusTargets(modules, packets, review) {
82140
82287
  kind: "hotspot",
82141
82288
  file: module2.file,
82142
82289
  why: `graph-central module: fan-in ${module2.fanIn}, fan-out ${module2.fanOut}, score ${module2.score}`,
82143
- followUps: [
82290
+ followUps: dedupeAgentFollowUps([
82144
82291
  toolFollowUp("packet_get", { target: packet.file }),
82145
82292
  toolFollowUp("packet_get", { target: module2.file })
82146
- ]
82293
+ ])
82147
82294
  });
82148
82295
  continue;
82149
82296
  }
@@ -98492,7 +98639,7 @@ var init_tools = __esm({
98492
98639
  limit: { type: "integer", minimum: 0, maximum: 50, default: 5 },
98493
98640
  maxPackets: { type: "integer", minimum: 0, maximum: 10, default: 3 },
98494
98641
  maxPaths: { type: "integer", minimum: 0, maximum: 10, default: 3 },
98495
- includeSource: { type: "boolean", default: true }
98642
+ includeSource: { type: "boolean", default: false }
98496
98643
  }, ["query"]),
98497
98644
  dispatch: { handler: "explore" }
98498
98645
  },
@@ -99107,7 +99254,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
99107
99254
  ...request.limit !== void 0 ? { limit: request.limit } : {},
99108
99255
  ...request.maxPackets !== void 0 ? { maxPackets: request.maxPackets } : {},
99109
99256
  ...request.maxPaths !== void 0 ? { maxPaths: request.maxPaths } : {},
99110
- ...request.includeSource !== void 0 ? { includeSource: request.includeSource } : {}
99257
+ includeSource: request.includeSource ?? false
99111
99258
  })),
99112
99259
  orient: async (request) => await withFreshness(async () => await orientCodegraphWithSession(session, {
99113
99260
  root,
@@ -102676,11 +102823,82 @@ function toToolResult(value) {
102676
102823
  content: [
102677
102824
  {
102678
102825
  type: "text",
102679
- text: JSON.stringify(value, null, 2)
102826
+ text: JSON.stringify(translateMcpFollowUps(value))
102680
102827
  }
102681
102828
  ]
102682
102829
  };
102683
102830
  }
102831
+ function translateMcpFollowUps(value) {
102832
+ if (Array.isArray(value))
102833
+ return translateFollowUpCollection(value);
102834
+ if (typeof value !== "object" || value === null)
102835
+ return value;
102836
+ const source = value;
102837
+ let translated;
102838
+ for (const [key, nestedValue] of Object.entries(source)) {
102839
+ const nestedTranslation = translateMcpFollowUps(nestedValue);
102840
+ if (nestedTranslation === nestedValue)
102841
+ continue;
102842
+ translated ??= { ...source };
102843
+ translated[key] = nestedTranslation;
102844
+ }
102845
+ return translateFollowUps(translated ?? source);
102846
+ }
102847
+ function translateFollowUpCollection(value) {
102848
+ let translated;
102849
+ for (const [index, entry] of value.entries()) {
102850
+ const entryTranslation = translateMcpFollowUps(entry);
102851
+ if (entryTranslation === entry) {
102852
+ if (translated !== void 0)
102853
+ translated.push(entry);
102854
+ continue;
102855
+ }
102856
+ translated ??= [...value.slice(0, index)];
102857
+ translated.push(entryTranslation);
102858
+ }
102859
+ return translated ?? value;
102860
+ }
102861
+ function translateFollowUps(value) {
102862
+ const followUps = value.followUps;
102863
+ if (!Array.isArray(followUps) || !followUps.every(isAgentFollowUp))
102864
+ return value;
102865
+ const translatedFollowUps = followUps.map(translateMcpFollowUp);
102866
+ if (translatedFollowUps.every((followUp, index) => followUp === followUps[index]))
102867
+ return value;
102868
+ return { ...value, followUps: translatedFollowUps };
102869
+ }
102870
+ function isAgentFollowUp(value) {
102871
+ return typeof value === "object" && value !== null && "tool" in value && typeof value.tool === "string" && "arguments" in value && typeof value.arguments === "object" && value.arguments !== null && !Array.isArray(value.arguments);
102872
+ }
102873
+ function translateMcpFollowUp(followUp) {
102874
+ if (followUp.tool === "chunk")
102875
+ return { ...followUp, tool: "get_file" };
102876
+ if (followUp.tool === "duplicates") {
102877
+ return {
102878
+ ...followUp,
102879
+ tool: "packet_get",
102880
+ arguments: { target: firstDuplicateFile(followUp.arguments) }
102881
+ };
102882
+ }
102883
+ if (followUp.tool === "explore" && followUp.arguments.includeSource === void 0) {
102884
+ return {
102885
+ ...followUp,
102886
+ arguments: { ...followUp.arguments, includeSource: true }
102887
+ };
102888
+ }
102889
+ if (followUp.tool === "impact" && followUp.arguments.provider === "git") {
102890
+ const arguments_ = { ...followUp.arguments };
102891
+ delete arguments_.provider;
102892
+ return { ...followUp, arguments: arguments_ };
102893
+ }
102894
+ return followUp;
102895
+ }
102896
+ function firstDuplicateFile(arguments_) {
102897
+ const files = arguments_.files;
102898
+ if (!Array.isArray(files))
102899
+ return ".";
102900
+ return files.find((file2) => typeof file2 === "string") ?? ".";
102901
+ }
102684
102902
  function toToolErrorResult(error51) {
102685
102903
  const message = errorMessage(error51).replace(/(?:[A-Za-z]:)?[/\\][^'"\n]*?(?=(?:[/\\][^'"\n]*)?['"]|$)/g, "<path>");
102686
102904
  return { isError: true, content: [{ type: "text", text: message }] };
@@ -103344,7 +103562,7 @@ import path86 from "node:path";
103344
103562
  async function handleServerCommand(context) {
103345
103563
  const command = context.positionals[0];
103346
103564
  if (!isServerCommand(command)) {
103347
- context.writeStderrLine("Usage: codegraph server <start|status|stop> [--root <path>]");
103565
+ context.writeStderrLine(getCliCommandUsage("server"));
103348
103566
  context.exit(2);
103349
103567
  }
103350
103568
  try {
@@ -104174,7 +104392,8 @@ var init_server2 = __esm({
104174
104392
  "--warmup",
104175
104393
  "--warmup-symbols",
104176
104394
  "--workers",
104177
- "--json"
104395
+ "--json",
104396
+ "--pretty"
104178
104397
  ],
104179
104398
  status: ["--json", "--pretty"],
104180
104399
  stop: []
@@ -104922,7 +105141,7 @@ async function handleGraphCommand(context) {
104922
105141
  ...cacheDir ? { cacheDir } : {},
104923
105142
  ...context.cacheLocation ? { cacheLocation: context.cacheLocation } : {}
104924
105143
  };
104925
- const stable = context.hasFlag("--stable");
105144
+ const stable = true;
104926
105145
  let format = "mermaid";
104927
105146
  if (context.hasFlag("--json")) {
104928
105147
  format = "json";
@@ -106844,7 +107063,7 @@ function formatGotoOutput(projectRootFs, output) {
106844
107063
  async function handleDumpmodCommand(context) {
106845
107064
  const [fileArg] = context.positionals;
106846
107065
  if (!fileArg) {
106847
- context.writeStderrLine("Usage: dumpmod <file>");
107066
+ context.writeStderrLine(getCliCommandUsage("dumpmod"));
106848
107067
  context.exit(2);
106849
107068
  }
106850
107069
  const resolvedFile = resolveCliProjectFile(context.projectRootFs, fileArg, "File");
@@ -106966,9 +107185,14 @@ function writePrettyReferences(context, result) {
106966
107185
  }
106967
107186
  }
106968
107187
  async function handleGotoCommand(context) {
106969
- const input = parseNavigationInput(context, false);
107188
+ let input;
107189
+ try {
107190
+ input = parseNavigationInput(context, false);
107191
+ } catch (error51) {
107192
+ exitWithError(context, error51, 2);
107193
+ }
106970
107194
  if (!input) {
106971
- context.writeStderrLine("Usage: goto <file>[:line[:column]] [line] [column]");
107195
+ context.writeStderrLine(getCliCommandUsage("goto"));
106972
107196
  context.exit(2);
106973
107197
  }
106974
107198
  const resolvedFile = resolveCliProjectFile(context.projectRootFs, input.file, "File");
@@ -107021,9 +107245,14 @@ async function handleGotoCommand(context) {
107021
107245
  context.exit(1);
107022
107246
  }
107023
107247
  async function handleRefsCommand(context) {
107024
- const input = parseNavigationInput(context, true);
107248
+ let input;
107249
+ try {
107250
+ input = parseNavigationInput(context, true);
107251
+ } catch (error51) {
107252
+ exitWithError(context, error51, 2);
107253
+ }
107025
107254
  if (!input) {
107026
- context.writeStderrLine("Usage: refs <file>[:line[:column]] [line] [column] OR refs --file <file> [--line <line> --col <column>]");
107255
+ context.writeStderrLine(getCliCommandUsage("refs"));
107027
107256
  context.exit(2);
107028
107257
  }
107029
107258
  const pretty = !context.hasFlag("--json");
@@ -107109,6 +107338,7 @@ var init_navigation3 = __esm({
107109
107338
  init_location2();
107110
107339
  init_projectFile();
107111
107340
  init_pretty();
107341
+ init_context();
107112
107342
  }
107113
107343
  });
107114
107344
 
@@ -107260,7 +107490,7 @@ async function handleGrepCommand(context) {
107260
107490
  exitWithError(context, error51, 2);
107261
107491
  }
107262
107492
  if ((querySource ? 1 : 0) + (patternSource ? 1 : 0) !== 1) {
107263
- context.writeStderrLine("Usage: grep <regex> [--root <dir>] OR grep --query '<tree-sitter query>' [--root <dir>]");
107493
+ context.writeStderrLine(getCliCommandUsage("grep"));
107264
107494
  context.exit(2);
107265
107495
  }
107266
107496
  if (querySource && maxHits !== void 0) {
@@ -108172,7 +108402,7 @@ function deletedPathsForChange2(change2) {
108172
108402
  async function buildAffectedReportFromContext(context) {
108173
108403
  const inputs = await collectChangedFileInputs(context);
108174
108404
  if (!inputs.files.length) {
108175
- throw new Error("Usage: codegraph affected <file...> [--stdin] [--base <ref> --head <ref>] [--root <path>]");
108405
+ throw new Error(getCliCommandUsage("affected"));
108176
108406
  }
108177
108407
  const normalizedChangedFiles = Array.from(new Set(inputs.files.map((input) => normalizeChangedFileInput(context.projectRootFs, input)))).sort();
108178
108408
  const normalizedDeletedFiles = Array.from(new Set(inputs.deletedFiles.map((input) => normalizeChangedFileInput(context.projectRootFs, input)))).sort();
@@ -108568,10 +108798,15 @@ async function loadGraph(context) {
108568
108798
  async function handleDepsCommand(context) {
108569
108799
  const [fileArg] = context.positionals;
108570
108800
  if (!fileArg) {
108571
- context.writeStderrLine(`Usage: ${context.command} <file|file::symbol|symbol:...> [--depth N] [--json]`);
108801
+ context.writeStderrLine(getCliCommandUsage(context.command));
108572
108802
  context.exit(2);
108573
108803
  }
108574
108804
  const depthRaw = context.getOpt("--depth");
108805
+ const all = context.hasFlag("--all");
108806
+ if (all && depthRaw !== void 0) {
108807
+ context.writeStderrLine("--all cannot be combined with --depth.");
108808
+ context.exit(2);
108809
+ }
108575
108810
  let depth;
108576
108811
  try {
108577
108812
  depth = parseOptionalNonNegativeIntegerOption(depthRaw, "--depth");
@@ -108648,18 +108883,21 @@ async function handleDepsCommand(context) {
108648
108883
  context.exit(1);
108649
108884
  }
108650
108885
  targetFile = matchedGraphNode;
108651
- const results = context.command === "deps" ? getDependencies(loaded.graph, targetFile, {
108652
- ...depth !== void 0 ? { depth } : {},
108653
- ...loaded.adjacency ? { adjacency: loaded.adjacency } : {}
108654
- }) : getReverseDependencies(loaded.graph, targetFile, {
108655
- ...depth !== void 0 ? { depth } : {},
108656
- ...loaded.adjacency ? { adjacency: loaded.adjacency } : {}
108657
- });
108886
+ const effectiveDepth = depth ?? 1;
108887
+ const traversalOptions = {
108888
+ ...loaded.adjacency ? { adjacency: loaded.adjacency } : {},
108889
+ ...json3 && !all ? { depth: effectiveDepth + 1 } : {}
108890
+ };
108891
+ const allResults = context.command === "deps" ? getDependencies(loaded.graph, targetFile, traversalOptions) : getReverseDependencies(loaded.graph, targetFile, traversalOptions);
108892
+ const results = all ? allResults : allResults.filter((result) => result.depth <= effectiveDepth);
108893
+ const truncated = results.length !== allResults.length;
108894
+ const omittedCount = allResults.length - results.length;
108658
108895
  if (json3) {
108659
- context.writeJSONLine(results);
108896
+ context.writeJSONLine({ items: results, truncated });
108660
108897
  return;
108661
108898
  }
108662
- context.writeStdoutLine(`${context.command === "deps" ? "Dependencies" : "Reverse dependencies"} for ${fileArg}:`);
108899
+ const depthDescription = all ? "all depths" : `depth ${effectiveDepth}`;
108900
+ context.writeStdoutLine(`${context.command === "deps" ? "Dependencies" : "Reverse dependencies"} for ${fileArg} (${depthDescription}; ${omittedCount} omitted):`);
108663
108901
  for (const result of results) {
108664
108902
  const rel = toProjectDisplayPath(context.projectRootFs, result.file);
108665
108903
  context.writeStdoutLine(`${" ".repeat(result.depth)} ${rel} (depth ${result.depth})`);
@@ -108668,7 +108906,7 @@ async function handleDepsCommand(context) {
108668
108906
  async function handlePathCommand(context) {
108669
108907
  const [fromArg, toArg] = context.positionals;
108670
108908
  if (!fromArg || !toArg) {
108671
- context.writeStderrLine("Usage: path <from-file> <to-file> [--json]");
108909
+ context.writeStderrLine(getCliCommandUsage("path"));
108672
108910
  context.exit(2);
108673
108911
  }
108674
108912
  const json3 = context.hasFlag("--json");
@@ -109932,10 +110170,7 @@ function resolveCliRootPolicy(input) {
109932
110170
  if (!isLegacyImpactRoot) {
109933
110171
  return {
109934
110172
  status: "error",
109935
- messages: [
109936
- `Unexpected positional argument for impact: ${impactRootArg}`,
109937
- "Usage: codegraph impact [project-root] [--provider git|github|raw] [options]"
109938
- ]
110173
+ messages: [`Unexpected positional argument for impact: ${impactRootArg}`, getCliCommandUsage("impact")]
109939
110174
  };
109940
110175
  }
109941
110176
  }
@@ -110028,6 +110263,7 @@ var init_rootPolicy = __esm({
110028
110263
  "dist/cli/rootPolicy.js"() {
110029
110264
  "use strict";
110030
110265
  init_paths();
110266
+ init_options();
110031
110267
  WINDOWS_DRIVE_QUALIFIED_PATTERN = /^[A-Za-z]:[\\/]/;
110032
110268
  WINDOWS_DRIVE_RELATIVE_ROOT_PATTERN = /^[\\/](?![\\/])/;
110033
110269
  }
@@ -110804,6 +111040,10 @@ async function runCliWithActiveRuntime(rawArgs) {
110804
111040
  writeStdoutLine(CLI_HELP_TEXT.trimEnd());
110805
111041
  return;
110806
111042
  }
111043
+ if (command === "advanced") {
111044
+ writeStdoutLine(ADVANCED_HELP_TEXT.trimEnd());
111045
+ return;
111046
+ }
110807
111047
  if (!isKnownCliCommand(command)) {
110808
111048
  writeStderrLine(`Unknown command "${command}".`);
110809
111049
  const suggestions = suggestCliCommands(command);