@colbymchenry/codegraph-darwin-x64 1.0.0 → 1.1.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.
- package/lib/dist/bin/codegraph.js +258 -17
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/bin/fatal-handler.d.ts +20 -0
- package/lib/dist/bin/fatal-handler.d.ts.map +1 -0
- package/lib/dist/bin/fatal-handler.js +118 -0
- package/lib/dist/bin/fatal-handler.js.map +1 -0
- package/lib/dist/db/index.d.ts +22 -1
- package/lib/dist/db/index.d.ts.map +1 -1
- package/lib/dist/db/index.js +46 -1
- package/lib/dist/db/index.js.map +1 -1
- package/lib/dist/db/queries.d.ts +14 -0
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +25 -0
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/directory.d.ts +58 -0
- package/lib/dist/directory.d.ts.map +1 -1
- package/lib/dist/directory.js +165 -0
- package/lib/dist/directory.js.map +1 -1
- package/lib/dist/extraction/grammars.d.ts +11 -3
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +14 -5
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +202 -32
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.js +47 -2
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
- package/lib/dist/extraction/languages/csharp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/csharp.js +20 -0
- package/lib/dist/extraction/languages/csharp.js.map +1 -1
- package/lib/dist/extraction/languages/dart.d.ts.map +1 -1
- package/lib/dist/extraction/languages/dart.js +22 -0
- package/lib/dist/extraction/languages/dart.js.map +1 -1
- package/lib/dist/extraction/languages/java.d.ts.map +1 -1
- package/lib/dist/extraction/languages/java.js +213 -9
- package/lib/dist/extraction/languages/java.js.map +1 -1
- package/lib/dist/extraction/languages/kotlin.d.ts.map +1 -1
- package/lib/dist/extraction/languages/kotlin.js +51 -0
- package/lib/dist/extraction/languages/kotlin.js.map +1 -1
- package/lib/dist/extraction/languages/scala.d.ts.map +1 -1
- package/lib/dist/extraction/languages/scala.js +19 -9
- package/lib/dist/extraction/languages/scala.js.map +1 -1
- package/lib/dist/extraction/parse-worker.js +4 -1
- package/lib/dist/extraction/parse-worker.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts +13 -0
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.d.ts +119 -0
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +890 -11
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/index.d.ts +33 -0
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +68 -7
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +33 -56
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/instructions-template.d.ts +3 -3
- package/lib/dist/installer/instructions-template.d.ts.map +1 -1
- package/lib/dist/installer/instructions-template.js +4 -4
- package/lib/dist/installer/targets/claude.d.ts +18 -12
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +78 -6
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/installer/targets/shared.d.ts +12 -2
- package/lib/dist/installer/targets/shared.d.ts.map +1 -1
- package/lib/dist/installer/targets/shared.js +13 -12
- package/lib/dist/installer/targets/shared.js.map +1 -1
- package/lib/dist/installer/targets/types.d.ts +7 -0
- package/lib/dist/installer/targets/types.d.ts.map +1 -1
- package/lib/dist/mcp/daemon-manager.d.ts +42 -0
- package/lib/dist/mcp/daemon-manager.d.ts.map +1 -0
- package/lib/dist/mcp/daemon-manager.js +129 -0
- package/lib/dist/mcp/daemon-manager.js.map +1 -0
- package/lib/dist/mcp/daemon-registry.d.ts +47 -0
- package/lib/dist/mcp/daemon-registry.d.ts.map +1 -0
- package/lib/dist/mcp/daemon-registry.js +229 -0
- package/lib/dist/mcp/daemon-registry.js.map +1 -0
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +5 -0
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/engine.d.ts.map +1 -1
- package/lib/dist/mcp/engine.js +8 -0
- package/lib/dist/mcp/engine.js.map +1 -1
- package/lib/dist/mcp/index.d.ts +1 -0
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +13 -0
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/liveness-watchdog.d.ts +18 -0
- package/lib/dist/mcp/liveness-watchdog.d.ts.map +1 -0
- package/lib/dist/mcp/liveness-watchdog.js +207 -0
- package/lib/dist/mcp/liveness-watchdog.js.map +1 -0
- package/lib/dist/mcp/server-instructions.d.ts +18 -14
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +57 -52
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/session.d.ts.map +1 -1
- package/lib/dist/mcp/session.js +23 -18
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +51 -1
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +585 -151
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/project-config.d.ts +19 -0
- package/lib/dist/project-config.d.ts.map +1 -0
- package/lib/dist/project-config.js +180 -0
- package/lib/dist/project-config.js.map +1 -0
- package/lib/dist/reasoning/config.d.ts +45 -0
- package/lib/dist/reasoning/config.d.ts.map +1 -0
- package/lib/dist/reasoning/config.js +171 -0
- package/lib/dist/reasoning/config.js.map +1 -0
- package/lib/dist/reasoning/credentials.d.ts +5 -0
- package/lib/dist/reasoning/credentials.d.ts.map +1 -0
- package/lib/dist/reasoning/credentials.js +83 -0
- package/lib/dist/reasoning/credentials.js.map +1 -0
- package/lib/dist/reasoning/login.d.ts +21 -0
- package/lib/dist/reasoning/login.d.ts.map +1 -0
- package/lib/dist/reasoning/login.js +85 -0
- package/lib/dist/reasoning/login.js.map +1 -0
- package/lib/dist/reasoning/reasoner.d.ts +43 -0
- package/lib/dist/reasoning/reasoner.d.ts.map +1 -0
- package/lib/dist/reasoning/reasoner.js +308 -0
- package/lib/dist/reasoning/reasoner.js.map +1 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +33 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.js +352 -0
- package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -0
- package/lib/dist/resolution/callback-synthesizer.d.ts +6 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.js +1109 -1
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
- package/lib/dist/resolution/frameworks/goframe.d.ts +41 -0
- package/lib/dist/resolution/frameworks/goframe.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/goframe.js +112 -0
- package/lib/dist/resolution/frameworks/goframe.js.map +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/index.js +5 -1
- package/lib/dist/resolution/frameworks/index.js.map +1 -1
- package/lib/dist/resolution/frameworks/react.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/react.js +17 -60
- package/lib/dist/resolution/frameworks/react.js.map +1 -1
- package/lib/dist/resolution/goframe-synthesizer.d.ts +28 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.js +158 -0
- package/lib/dist/resolution/goframe-synthesizer.js.map +1 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/import-resolver.js +56 -0
- package/lib/dist/resolution/import-resolver.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +48 -8
- package/lib/dist/resolution/name-matcher.js.map +1 -1
- package/lib/dist/resolution/strip-comments.d.ts +1 -1
- package/lib/dist/resolution/strip-comments.d.ts.map +1 -1
- package/lib/dist/resolution/strip-comments.js +2 -0
- package/lib/dist/resolution/strip-comments.js.map +1 -1
- package/lib/dist/sync/watcher.d.ts +68 -1
- package/lib/dist/sync/watcher.d.ts.map +1 -1
- package/lib/dist/sync/watcher.js +212 -14
- package/lib/dist/sync/watcher.js.map +1 -1
- package/lib/dist/telemetry/index.d.ts +0 -3
- package/lib/dist/telemetry/index.d.ts.map +1 -1
- package/lib/dist/telemetry/index.js +4 -7
- package/lib/dist/telemetry/index.js.map +1 -1
- package/lib/dist/upgrade/index.d.ts.map +1 -1
- package/lib/dist/upgrade/index.js +40 -4
- package/lib/dist/upgrade/index.js.map +1 -1
- package/lib/dist/utils.d.ts +14 -1
- package/lib/dist/utils.d.ts.map +1 -1
- package/lib/dist/utils.js +20 -2
- package/lib/dist/utils.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +2 -2
- package/package.json +1 -1
|
@@ -65,6 +65,7 @@ const worktree_1 = require("../sync/worktree");
|
|
|
65
65
|
const shimmer_progress_1 = require("../ui/shimmer-progress");
|
|
66
66
|
const glyphs_1 = require("../ui/glyphs");
|
|
67
67
|
const node_version_check_1 = require("./node-version-check");
|
|
68
|
+
const fatal_handler_1 = require("./fatal-handler");
|
|
68
69
|
const wasm_runtime_flags_1 = require("../extraction/wasm-runtime-flags");
|
|
69
70
|
const extraction_version_1 = require("../extraction/extraction-version");
|
|
70
71
|
const telemetry_1 = require("../telemetry");
|
|
@@ -118,6 +119,12 @@ if (nodeMajor < node_version_check_1.MIN_NODE_MAJOR) {
|
|
|
118
119
|
// passes the flag. Must run before any grammar (in the parse worker, which
|
|
119
120
|
// inherits this process's flags) is compiled. See ../extraction/wasm-runtime-flags.
|
|
120
121
|
(0, wasm_runtime_flags_1.relaunchWithWasmRuntimeFlagsIfNeeded)(__filename);
|
|
122
|
+
// Last-resort fatal handlers: log a bounded line and exit non-zero. A fault
|
|
123
|
+
// that reaches here escaped every boundary, so the process is in an undefined
|
|
124
|
+
// state — keeping it alive is what let the detached MCP daemon orphan and pin a
|
|
125
|
+
// CPU core with no recovery (#799, #850). Installed before the command branch
|
|
126
|
+
// so it also covers a synchronous throw during startup. See ./fatal-handler.
|
|
127
|
+
(0, fatal_handler_1.installFatalHandlers)();
|
|
121
128
|
// Check if running with no arguments - run installer
|
|
122
129
|
if (process.argv.length === 2) {
|
|
123
130
|
Promise.resolve().then(() => __importStar(require('../installer'))).then(({ runInstaller }) => runInstaller()).catch((err) => {
|
|
@@ -129,16 +136,21 @@ else {
|
|
|
129
136
|
// Normal CLI flow
|
|
130
137
|
main();
|
|
131
138
|
}
|
|
132
|
-
process.on('uncaughtException', (error) => {
|
|
133
|
-
console.error('[CodeGraph] Uncaught exception:', error);
|
|
134
|
-
});
|
|
135
|
-
process.on('unhandledRejection', (reason) => {
|
|
136
|
-
console.error('[CodeGraph] Unhandled rejection:', reason);
|
|
137
|
-
});
|
|
138
139
|
function main() {
|
|
139
140
|
const program = new commander_1.Command();
|
|
140
141
|
// Version from package.json
|
|
141
142
|
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
143
|
+
// Make the version trivial to reach. commander's `.version()` (below) wires up
|
|
144
|
+
// `--version` and `-V`; intercept the spellings it can't — lowercase `-v` and
|
|
145
|
+
// single-dash `-version` — before any parsing. (commander's version short flag
|
|
146
|
+
// is the capital `-V`, and its parser rejects a multi-character single-dash
|
|
147
|
+
// flag.) The bare `codegraph version` subcommand is registered further down so
|
|
148
|
+
// the affordance also shows up in `codegraph --help`.
|
|
149
|
+
const firstArg = process.argv[2];
|
|
150
|
+
if (firstArg === '-v' || firstArg === '-version') {
|
|
151
|
+
console.log(packageJson.version);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
142
154
|
// =============================================================================
|
|
143
155
|
// ANSI Color Helpers (avoid chalk ESM issues)
|
|
144
156
|
// =============================================================================
|
|
@@ -432,12 +444,24 @@ function main() {
|
|
|
432
444
|
.command('init [path]')
|
|
433
445
|
.description('Initialize CodeGraph in a project directory and build the initial index')
|
|
434
446
|
.option('-i, --index', 'Deprecated: indexing now runs by default; flag accepted for backward compatibility')
|
|
447
|
+
.option('-f, --force', 'Initialize even if the path looks like your home directory or a filesystem root')
|
|
435
448
|
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
436
449
|
.action(async (pathArg, options) => {
|
|
437
450
|
const projectPath = path.resolve(pathArg || process.cwd());
|
|
438
451
|
const clack = await importESM('@clack/prompts');
|
|
439
452
|
clack.intro('Initializing CodeGraph');
|
|
440
453
|
try {
|
|
454
|
+
// Refuse to index your home directory / a filesystem root — it pulls in
|
|
455
|
+
// caches, other projects, and your whole tree (a multi-GB index + watcher
|
|
456
|
+
// churn, and on pre-1.0 macOS a machine-crashing fd blowup, #845).
|
|
457
|
+
const unsafe = (0, directory_1.unsafeIndexRootReason)(projectPath);
|
|
458
|
+
if (unsafe && !options.force) {
|
|
459
|
+
clack.log.error(`Refusing to initialize in ${projectPath} — it looks like ${unsafe}.`);
|
|
460
|
+
clack.log.info('Run this inside a specific project directory, or pass --force if you really mean to index everything under it.');
|
|
461
|
+
clack.outro('');
|
|
462
|
+
process.exitCode = 1;
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
441
465
|
if ((0, directory_1.isInitialized)(projectPath)) {
|
|
442
466
|
clack.log.warn(`Already initialized in ${projectPath}`);
|
|
443
467
|
clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update');
|
|
@@ -543,13 +567,20 @@ function main() {
|
|
|
543
567
|
*/
|
|
544
568
|
program
|
|
545
569
|
.command('index [path]')
|
|
546
|
-
.description('
|
|
547
|
-
.option('-f, --force', '
|
|
570
|
+
.description('Rebuild the full index from scratch (same result as a fresh init)')
|
|
571
|
+
.option('-f, --force', 'Index even if the path looks like your home directory or a filesystem root')
|
|
548
572
|
.option('-q, --quiet', 'Suppress progress output')
|
|
549
573
|
.option('-v, --verbose', 'Show detailed worker lifecycle and memory info')
|
|
550
574
|
.action(async (pathArg, options) => {
|
|
551
575
|
const projectPath = resolveProjectPath(pathArg);
|
|
552
576
|
try {
|
|
577
|
+
// Don't (re)index your home directory / a filesystem root (#845). --force
|
|
578
|
+
// doubles as the override.
|
|
579
|
+
const unsafe = (0, directory_1.unsafeIndexRootReason)(projectPath);
|
|
580
|
+
if (unsafe && !options.force) {
|
|
581
|
+
error(`Refusing to index ${projectPath} — it looks like ${unsafe}. Pass --force to override.`);
|
|
582
|
+
process.exit(1);
|
|
583
|
+
}
|
|
553
584
|
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
554
585
|
error(`CodeGraph not initialized in ${projectPath}`);
|
|
555
586
|
info('Run "codegraph init" first');
|
|
@@ -558,9 +589,9 @@ function main() {
|
|
|
558
589
|
const { default: CodeGraph } = await loadCodeGraph();
|
|
559
590
|
const cg = await CodeGraph.open(projectPath);
|
|
560
591
|
if (options.quiet) {
|
|
561
|
-
// Quiet mode: no UI, just run
|
|
562
|
-
|
|
563
|
-
|
|
592
|
+
// Quiet mode: no UI, just run. `index` is a full re-index, so clear the
|
|
593
|
+
// existing graph and rebuild from scratch (see the note below — #874).
|
|
594
|
+
cg.clear();
|
|
564
595
|
const result = await cg.indexAll();
|
|
565
596
|
if (!result.success)
|
|
566
597
|
process.exit(1);
|
|
@@ -569,10 +600,12 @@ function main() {
|
|
|
569
600
|
}
|
|
570
601
|
const clack = await importESM('@clack/prompts');
|
|
571
602
|
clack.intro('Indexing project');
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
603
|
+
// `index` is a FULL re-index: clear the existing graph and rebuild it from
|
|
604
|
+
// scratch so the result is identical to a fresh `init`. Without the clear,
|
|
605
|
+
// indexAll() skips every unchanged file by its content hash and reports
|
|
606
|
+
// "0 nodes, 0 edges" against the already-populated graph — which reads as
|
|
607
|
+
// "index wiped my index" (#874). For fast incremental updates use `sync`.
|
|
608
|
+
cg.clear();
|
|
576
609
|
let result;
|
|
577
610
|
if (options.verbose) {
|
|
578
611
|
result = await cg.indexAll({
|
|
@@ -800,7 +833,7 @@ function main() {
|
|
|
800
833
|
if (reindexRecommended) {
|
|
801
834
|
const builtWith = buildInfo.version ? `v${buildInfo.version.replace(/^v/, '')}` : 'an earlier version';
|
|
802
835
|
warn(`Index was built by ${builtWith}; re-index to pick up this engine's improvements.`);
|
|
803
|
-
info('Run "codegraph index
|
|
836
|
+
info('Run "codegraph index" (full rebuild) or "codegraph sync"');
|
|
804
837
|
console.log();
|
|
805
838
|
}
|
|
806
839
|
cg.destroy();
|
|
@@ -913,6 +946,104 @@ function main() {
|
|
|
913
946
|
process.exit(1);
|
|
914
947
|
}
|
|
915
948
|
});
|
|
949
|
+
/**
|
|
950
|
+
* codegraph prompt-hook (hidden)
|
|
951
|
+
*
|
|
952
|
+
* A Claude Code `UserPromptSubmit` hook entry point. Reads `{prompt, cwd}` JSON
|
|
953
|
+
* on stdin; for a structural/flow/impact prompt it runs `codegraph_explore` on
|
|
954
|
+
* the indexed project and prints the result to stdout, which Claude injects into
|
|
955
|
+
* the agent's context — so the agent's reflex grep/read has nothing left to find
|
|
956
|
+
* and reliably uses CodeGraph (the adoption problem). Installed by the installer
|
|
957
|
+
* into Claude's settings.json (opt-in, default-yes).
|
|
958
|
+
*
|
|
959
|
+
* LOAD-BEARING: this must NEVER break the user's prompt. Every failure path —
|
|
960
|
+
* kill-switch, non-structural prompt, no index, engine error — exits 0 with no
|
|
961
|
+
* output. The only effect is additive context when it can confidently provide it.
|
|
962
|
+
*/
|
|
963
|
+
program
|
|
964
|
+
.command('prompt-hook', { hidden: true })
|
|
965
|
+
.description('Claude UserPromptSubmit hook: inject CodeGraph context for structural prompts (reads {prompt,cwd} JSON on stdin)')
|
|
966
|
+
.action(async () => {
|
|
967
|
+
try {
|
|
968
|
+
// Kill-switch: lets a user disable the nudge without uninstalling /
|
|
969
|
+
// editing settings.json (CI, low-power machines, personal preference).
|
|
970
|
+
if (process.env.CODEGRAPH_NO_PROMPT_HOOK === '1' || process.env.CODEGRAPH_PROMPT_HOOK === '0')
|
|
971
|
+
return;
|
|
972
|
+
if (process.stdin.isTTY)
|
|
973
|
+
return; // invoked by hand, no piped payload
|
|
974
|
+
const raw = await new Promise((resolve) => {
|
|
975
|
+
let data = '';
|
|
976
|
+
process.stdin.setEncoding('utf8');
|
|
977
|
+
process.stdin.on('data', (c) => { data += c; });
|
|
978
|
+
process.stdin.on('end', () => resolve(data));
|
|
979
|
+
process.stdin.on('error', () => resolve(data));
|
|
980
|
+
});
|
|
981
|
+
let input = {};
|
|
982
|
+
try {
|
|
983
|
+
input = JSON.parse(raw);
|
|
984
|
+
}
|
|
985
|
+
catch {
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
const prompt = String(input.prompt || '');
|
|
989
|
+
// Gate: only structural / flow / impact / where-how prompts get context.
|
|
990
|
+
// A cheap regex keeps every other prompt ("fix this typo") a zero-cost
|
|
991
|
+
// no-op so we never add latency where there's no structural answer to give.
|
|
992
|
+
const STRUCTURAL = /\b(how|where|trace|flow|path|reach(?:es|ed)?|call(?:s|ed|er|ers|ee)?|depend|impact|affect|wired?|connect|implement|architect|structure|breaks?|what calls|why does)\b/i;
|
|
993
|
+
if (!prompt || !STRUCTURAL.test(prompt))
|
|
994
|
+
return;
|
|
995
|
+
// Decide what to inject, shaped by WHERE the index(es) are: the nearest
|
|
996
|
+
// indexed ancestor of cwd, or — when cwd is an un-indexed workspace root
|
|
997
|
+
// whose indexed project(s) live in sub-dirs (the monorepo case, #964) —
|
|
998
|
+
// the sub-project the prompt points at, plus a `projectPath` nudge for any
|
|
999
|
+
// others. Without the down-scan the hook injected nothing at a monorepo
|
|
1000
|
+
// root (it only walked up), so the validated adoption lever never fired
|
|
1001
|
+
// exactly where the agent most needs it.
|
|
1002
|
+
const plan = (0, directory_1.planFrontload)(String(input.cwd || process.cwd()), prompt);
|
|
1003
|
+
if (!plan.exploreRoot && plan.nudgeProjects.length === 0)
|
|
1004
|
+
return; // nothing reachable — the agent's normal tools apply
|
|
1005
|
+
// A "pass projectPath" line for indexed sub-projects we did NOT front-load.
|
|
1006
|
+
// Follow-up codegraph_explore calls against a sub-project (cwd isn't its
|
|
1007
|
+
// index root) need an explicit projectPath, so spell it out.
|
|
1008
|
+
const nudge = (projects, lead) => `${lead}\n${projects.map((p) => ` - projectPath: "${p}"`).join('\n')}\n`;
|
|
1009
|
+
if (plan.exploreRoot) {
|
|
1010
|
+
const { default: CodeGraph } = await loadCodeGraph();
|
|
1011
|
+
const cg = await CodeGraph.open(plan.exploreRoot);
|
|
1012
|
+
try {
|
|
1013
|
+
const { ToolHandler } = await Promise.resolve().then(() => __importStar(require('../mcp/tools')));
|
|
1014
|
+
const handler = new ToolHandler(cg);
|
|
1015
|
+
const result = await handler.execute('codegraph_explore', { query: prompt });
|
|
1016
|
+
const text = result.content[0]?.text ?? '';
|
|
1017
|
+
if (!result.isError && text.trim()) {
|
|
1018
|
+
// Cap the injection so a large-repo explore can't flood the prompt.
|
|
1019
|
+
const MAX = 16000;
|
|
1020
|
+
const body = text.length > MAX ? `${text.slice(0, MAX)}\n…(truncated; call codegraph_explore for the rest)` : text;
|
|
1021
|
+
// For a front-loaded SUB-project, a follow-up explore needs its path.
|
|
1022
|
+
const more = plan.viaSubScan
|
|
1023
|
+
? `call codegraph_explore with projectPath: "${plan.exploreRoot}" for more`
|
|
1024
|
+
: 'call codegraph_explore for more';
|
|
1025
|
+
const others = plan.nudgeProjects.length
|
|
1026
|
+
? `\n${nudge(plan.nudgeProjects, 'Other indexed projects in this workspace — pass projectPath to query them:')}`
|
|
1027
|
+
: '';
|
|
1028
|
+
process.stdout.write(`<codegraph_context note="Structural context from CodeGraph for this prompt — treat returned source as already read; ${more}.">\n${body}${others}\n</codegraph_context>\n`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
finally {
|
|
1032
|
+
cg.destroy();
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
// Several indexed sub-projects, none a clear match — don't guess; tell
|
|
1037
|
+
// the agent they exist and how to query one.
|
|
1038
|
+
process.stdout.write(`<codegraph_context note="CodeGraph is available for this workspace's indexed sub-projects — query one by passing projectPath to codegraph_explore.">\n` +
|
|
1039
|
+
nudge(plan.nudgeProjects, "This workspace's CodeGraph indexes live in sub-projects. To use CodeGraph, call codegraph_explore with the projectPath of the relevant one:") +
|
|
1040
|
+
`</codegraph_context>\n`);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
catch {
|
|
1044
|
+
// Degradable by contract: never surface an error to the prompt pipeline.
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
916
1047
|
/**
|
|
917
1048
|
* codegraph node <name>
|
|
918
1049
|
*
|
|
@@ -1081,6 +1212,24 @@ function main() {
|
|
|
1081
1212
|
process.exit(1);
|
|
1082
1213
|
}
|
|
1083
1214
|
});
|
|
1215
|
+
/**
|
|
1216
|
+
* Normalize a user-supplied file path to the project-relative, forward-slash
|
|
1217
|
+
* form CodeGraph stores in the index. Accepts an absolute path, a `./`-prefixed
|
|
1218
|
+
* path, or Windows back-slashes; an empty string when the input is blank. Used
|
|
1219
|
+
* by `codegraph affected` so `./src/x.ts`, `/abs/repo/src/x.ts`, and
|
|
1220
|
+
* `src/x.ts` all match the same indexed file. (#825)
|
|
1221
|
+
*/
|
|
1222
|
+
function normalizeIndexPath(filePath, projectPath) {
|
|
1223
|
+
let f = filePath.trim();
|
|
1224
|
+
if (!f)
|
|
1225
|
+
return '';
|
|
1226
|
+
if (path.isAbsolute(f))
|
|
1227
|
+
f = path.relative(projectPath, f);
|
|
1228
|
+
// Collapse `.`/`..` segments, then force forward slashes and drop a leading
|
|
1229
|
+
// `./` (path.normalize already strips it on POSIX; explicit for Windows).
|
|
1230
|
+
f = path.normalize(f).replace(/\\/g, '/').replace(/^\.\//, '');
|
|
1231
|
+
return f;
|
|
1232
|
+
}
|
|
1084
1233
|
/**
|
|
1085
1234
|
* Convert glob pattern to regex
|
|
1086
1235
|
*/
|
|
@@ -1143,11 +1292,66 @@ function main() {
|
|
|
1143
1292
|
};
|
|
1144
1293
|
renderNode(root, '', true, 0);
|
|
1145
1294
|
}
|
|
1295
|
+
/**
|
|
1296
|
+
* codegraph daemon — interactive manager for the background daemons. Arrow keys
|
|
1297
|
+
* to pick one (the current project's daemon floats to the top, auto-selected),
|
|
1298
|
+
* enter to stop it. Falls back to a plain list when output isn't a TTY.
|
|
1299
|
+
*/
|
|
1300
|
+
program
|
|
1301
|
+
.command('daemon')
|
|
1302
|
+
.aliases(['daemons'])
|
|
1303
|
+
.description('Manage running CodeGraph background daemons — pick one and press enter to stop it')
|
|
1304
|
+
.action(async () => {
|
|
1305
|
+
const { listDaemons, stopDaemonAt, stopAllDaemons } = await Promise.resolve().then(() => __importStar(require('../mcp/daemon-registry')));
|
|
1306
|
+
const { runDaemonPicker } = await Promise.resolve().then(() => __importStar(require('../mcp/daemon-manager')));
|
|
1307
|
+
const daemons = listDaemons();
|
|
1308
|
+
if (daemons.length === 0) {
|
|
1309
|
+
info('No CodeGraph daemons running.');
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
// No TTY (piped / CI / non-interactive) — can't do arrow-key selection, so
|
|
1313
|
+
// just print what's running instead of crashing on a prompt with no input.
|
|
1314
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
1315
|
+
for (const d of daemons) {
|
|
1316
|
+
console.log(`pid ${d.pid} v${d.version} up ${formatDuration(Date.now() - d.startedAt)} ${d.root}`);
|
|
1317
|
+
}
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
// The current project's daemon floats to the top and is pre-selected.
|
|
1321
|
+
let cwdRoot = null;
|
|
1322
|
+
const found = (0, directory_1.findNearestCodeGraphRoot)(process.cwd());
|
|
1323
|
+
if (found) {
|
|
1324
|
+
try {
|
|
1325
|
+
cwdRoot = fs.realpathSync(found);
|
|
1326
|
+
}
|
|
1327
|
+
catch {
|
|
1328
|
+
cwdRoot = found;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
const clack = await importESM('@clack/prompts');
|
|
1332
|
+
clack.intro('CodeGraph daemons');
|
|
1333
|
+
await runDaemonPicker({
|
|
1334
|
+
list: listDaemons,
|
|
1335
|
+
stop: stopDaemonAt,
|
|
1336
|
+
stopAll: stopAllDaemons,
|
|
1337
|
+
cwdRoot,
|
|
1338
|
+
now: () => Date.now(),
|
|
1339
|
+
select: (opts) => clack.select(opts),
|
|
1340
|
+
isCancel: (v) => clack.isCancel(v),
|
|
1341
|
+
note: (m) => clack.log.success(m),
|
|
1342
|
+
done: (m) => clack.outro(m),
|
|
1343
|
+
});
|
|
1344
|
+
});
|
|
1146
1345
|
/**
|
|
1147
1346
|
* codegraph serve
|
|
1148
1347
|
*/
|
|
1149
1348
|
program
|
|
1150
|
-
|
|
1349
|
+
// Hidden from `--help`: this is the stdio entry point an AI agent launches
|
|
1350
|
+
// for itself (the installer wires `args: ['serve','--mcp']` into every
|
|
1351
|
+
// agent's MCP config), not a command a human runs. It still works when
|
|
1352
|
+
// invoked — hiding only removes it from the listing. See the interactive-TTY
|
|
1353
|
+
// guard below, which explains this to anyone who runs it by hand.
|
|
1354
|
+
.command('serve', { hidden: true })
|
|
1151
1355
|
.description('Start CodeGraph as an MCP server for AI assistants')
|
|
1152
1356
|
.option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
|
|
1153
1357
|
.option('--mcp', 'Run as MCP server (stdio transport)')
|
|
@@ -1161,6 +1365,22 @@ function main() {
|
|
|
1161
1365
|
}
|
|
1162
1366
|
try {
|
|
1163
1367
|
if (options.mcp) {
|
|
1368
|
+
// `serve --mcp` is the stdio MCP server an AI agent launches for itself,
|
|
1369
|
+
// not a command to run by hand. A human in a terminal would otherwise
|
|
1370
|
+
// see it hang waiting for JSON-RPC on stdin, which reads as broken. If
|
|
1371
|
+
// stdin is an interactive TTY, explain instead of hanging. The agent's
|
|
1372
|
+
// pipe and the detached daemon both have a non-TTY stdin, so this only
|
|
1373
|
+
// ever fires for a person who typed it.
|
|
1374
|
+
if (process.stdin.isTTY && !process.env.CODEGRAPH_DAEMON_INTERNAL) {
|
|
1375
|
+
console.error(chalk.bold('\nCodeGraph MCP server\n'));
|
|
1376
|
+
console.error("This is the MCP server your AI agent (Claude Code, Cursor, Codex, opencode, …)");
|
|
1377
|
+
console.error("starts automatically — you don't run it yourself.");
|
|
1378
|
+
console.error(`\nIt's already wired up by ${chalk.cyan('codegraph install')}. To check on things:`);
|
|
1379
|
+
console.error(` ${chalk.cyan('codegraph status')} ${chalk.dim('— is this project indexed and healthy?')}`);
|
|
1380
|
+
console.error(` ${chalk.cyan('codegraph daemon')} ${chalk.dim('— list or stop background MCP servers')}`);
|
|
1381
|
+
console.error(chalk.dim('\n(Running it directly only does something when an MCP client drives it over stdin.)'));
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1164
1384
|
// Start MCP server - it handles initialization lazily based on rootUri from client
|
|
1165
1385
|
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
1166
1386
|
const server = new MCPServer(projectPath);
|
|
@@ -1493,6 +1713,13 @@ function main() {
|
|
|
1493
1713
|
const stdinFiles = stdinData.split('\n').map(f => f.trim()).filter(Boolean);
|
|
1494
1714
|
changedFiles.push(...stdinFiles);
|
|
1495
1715
|
}
|
|
1716
|
+
// Normalize inputs to the project-relative, forward-slash form the index
|
|
1717
|
+
// stores. Without this, `affected ./src/x.ts`, an absolute path (what a
|
|
1718
|
+
// wrapping script often passes), or a Windows back-slash path silently
|
|
1719
|
+
// matches nothing and reports 0 affected tests. (#825)
|
|
1720
|
+
changedFiles = changedFiles
|
|
1721
|
+
.map((f) => normalizeIndexPath(f, projectPath))
|
|
1722
|
+
.filter(Boolean);
|
|
1496
1723
|
if (changedFiles.length === 0) {
|
|
1497
1724
|
if (!options.quiet)
|
|
1498
1725
|
info('No files provided. Use file arguments or --stdin.');
|
|
@@ -1748,6 +1975,20 @@ function main() {
|
|
|
1748
1975
|
});
|
|
1749
1976
|
process.exit(code);
|
|
1750
1977
|
});
|
|
1978
|
+
/**
|
|
1979
|
+
* codegraph version
|
|
1980
|
+
*
|
|
1981
|
+
* The bare-noun form of `--version`. commander already provides `--version`
|
|
1982
|
+
* and `-V`, and the `-v` / `-version` spellings are intercepted before parse
|
|
1983
|
+
* (see top of main). This subcommand makes `codegraph version` work and lists
|
|
1984
|
+
* the version affordance in `codegraph --help`.
|
|
1985
|
+
*/
|
|
1986
|
+
program
|
|
1987
|
+
.command('version')
|
|
1988
|
+
.description('Print the installed CodeGraph version (also: -v, --version)')
|
|
1989
|
+
.action(() => {
|
|
1990
|
+
console.log(packageJson.version);
|
|
1991
|
+
});
|
|
1751
1992
|
// Parse and run
|
|
1752
1993
|
program.parse();
|
|
1753
1994
|
} // end main()
|