@aroman22/codegraph-vba-darwin-arm64 1.7.2 → 1.8.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/mcp/tools.d.ts +15 -1
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +228 -3
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/upgrade/index.d.ts.map +1 -1
- package/lib/dist/upgrade/index.js +6 -1
- package/lib/dist/upgrade/index.js.map +1 -1
- package/lib/node_modules/.modules.yaml +3 -2
- package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
- package/lib/package.json +3 -2
- package/package.json +1 -1
package/lib/dist/mcp/tools.d.ts
CHANGED
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
import type CodeGraph from '../index';
|
|
7
7
|
import type { QueryPool } from './query-pool';
|
|
8
8
|
import type { PendingFile } from '../sync';
|
|
9
|
+
import { spawnSync } from 'child_process';
|
|
10
|
+
/** Narrow subprocess seam for testing CLI-only MCP wrappers. */
|
|
11
|
+
export declare const cliProcess: {
|
|
12
|
+
spawnSync: typeof spawnSync;
|
|
13
|
+
};
|
|
9
14
|
/**
|
|
10
15
|
* An expected, recoverable "codegraph can't serve this" condition — most
|
|
11
16
|
* importantly a project with no index. The dispatch catch converts these to
|
|
@@ -252,7 +257,8 @@ export declare class ToolHandler {
|
|
|
252
257
|
/**
|
|
253
258
|
* Optional allowlist of exposed tools, parsed from the CODEGRAPH_MCP_TOOLS
|
|
254
259
|
* env var (comma-separated short names, e.g. "trace,search,node,context").
|
|
255
|
-
* Unset/empty →
|
|
260
|
+
* Unset/empty → legacy direct calls to read-only tools are allowed, while
|
|
261
|
+
* mutating lifecycle tools remain opt-in. Lets an operator (or an A/B harness)
|
|
256
262
|
* trim the tool surface without rebuilding the client config; the ablated
|
|
257
263
|
* tool is then truly absent from ListTools rather than merely denied on call.
|
|
258
264
|
* Matching is on the short form, so "node" and "codegraph_node" both work.
|
|
@@ -344,6 +350,12 @@ export declare class ToolHandler {
|
|
|
344
350
|
* Execute a tool by name
|
|
345
351
|
*/
|
|
346
352
|
execute(toolName: string, args: Record<string, unknown>): Promise<ToolResult>;
|
|
353
|
+
/** Run the CLI sync command and preserve its complete process output. */
|
|
354
|
+
private handleSync;
|
|
355
|
+
/** Resolve symlinks/junctions and enforce mutation-root boundaries. */
|
|
356
|
+
private validateMutationTarget;
|
|
357
|
+
/** Execute a mutating CodeGraph CLI command after enforcing its path allowlist. */
|
|
358
|
+
private executeMutatingTool;
|
|
347
359
|
/**
|
|
348
360
|
* Run a single read tool to completion and return its raw {@link ToolResult},
|
|
349
361
|
* classifying expected failures the same way {@link execute}'s catch does so
|
|
@@ -365,6 +377,8 @@ export declare class ToolHandler {
|
|
|
365
377
|
* NotIndexed/PathRefusal, which {@link executeReadTool} classifies.
|
|
366
378
|
*/
|
|
367
379
|
private dispatchTool;
|
|
380
|
+
/** Run the CLI-only query command and preserve its JSON stdout verbatim. */
|
|
381
|
+
private handleQuery;
|
|
368
382
|
/**
|
|
369
383
|
* Handle codegraph_search
|
|
370
384
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,SAAS,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAe9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,SAAS,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAe9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQ3C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM1C,gEAAgE;AAChE,eAAO,MAAM,UAAU;;CAAgB,CAAC;AAExC;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AAE7C;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AA+C9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0EAA0E;IAC1E,2BAA2B,EAAE,MAAM,CAAC;IACpC,2CAA2C;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,sBAAsB,EAAE,OAAO,CAAC;IAChC,sEAAsE;IACtE,yBAAyB,EAAE,OAAO,CAAC;IACnC,sDAAsD;IACtD,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAkG7E;AA6FD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAc9D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAa9D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAOlE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,kEAAkE;IAClE,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oFAAoF;IACpF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA4BD;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,EAAE,cAAc,EAsSjC,CAAC;AAmCF;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,cAAc,EAAE,CAOjD;AAeD;;;;;GAKG;AACH,qBAAa,WAAW;IA4BV,OAAO,CAAC,EAAE;IA1BtB,OAAO,CAAC,YAAY,CAAqC;IAGzD,OAAO,CAAC,kBAAkB,CAAuB;IAMjD,OAAO,CAAC,qBAAqB,CAAwD;IAUrF,OAAO,CAAC,WAAW,CAA8B;IAKjD,OAAO,CAAC,SAAS,CAA0B;gBAEvB,EAAE,EAAE,SAAS,GAAG,IAAI;IAExC;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAI1C;;OAEG;IACH,mBAAmB,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAIxC;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAI7C;;;;;;;;OAQG;YACW,gBAAgB;IA4B9B;;;OAGG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAIjD;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAQrB,6EAA6E;IAC7E,OAAO,CAAC,aAAa;IASrB;;;;;OAKG;IACH,QAAQ,IAAI,cAAc,EAAE;IAuE5B;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IA6EpB;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO;IAef;;OAEG;IACH,QAAQ,IAAI,IAAI;IAQhB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAgBtB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA6B3B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,mBAAmB;IA2F3B;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IA8FnF,yEAAyE;IACzE,OAAO,CAAC,UAAU;IAmClB,uEAAuE;IACvE,OAAO,CAAC,sBAAsB;IAwB9B,mFAAmF;IACnF,OAAO,CAAC,mBAAmB;IAuB3B;;;;;;;;;;;;OAYG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAkB3F;;;;;OAKG;YACW,YAAY;IAc1B,4EAA4E;YAC9D,WAAW;IAqCzB;;OAEG;YACW,YAAY;IAmC1B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA2BxB,qEAAqE;IACrE,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;YACW,aAAa;IAsE3B;;OAEG;YACW,aAAa;IAmE3B;;OAEG;YACW,YAAY;IA6D1B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAsFrB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,yBAAyB;IA4QjC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,sBAAsB;IA6C9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,0BAA0B;IAoElC;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IA2D1B;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IAoD/B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,qBAAqB;IAuD7B;;;;;;;;;;OAUG;YACW,aAAa;IAsrC3B;;OAEG;YACW,UAAU;IAoHxB;;;;;;;;;;;;OAYG;YACW,cAAc;IAkI5B,sFAAsF;YACxE,iBAAiB;IAkB/B;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IA8BnB;;OAEG;YACW,YAAY;IAyH1B;;OAEG;YACW,WAAW;IA2DzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,eAAe;IA4EvB;;;OAGG;IACH;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,aAAa;IAqCrB;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IA+CzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA0DtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,cAAc;IAgBtB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,YAAY;IA4BpB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,WAAW;CAMpB"}
|
package/lib/dist/mcp/tools.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Defines the tools exposed by the CodeGraph MCP server.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.ToolHandler = exports.tools = exports.PathRefusalError = exports.NotIndexedError = void 0;
|
|
8
|
+
exports.ToolHandler = exports.tools = exports.PathRefusalError = exports.NotIndexedError = exports.cliProcess = void 0;
|
|
9
9
|
exports.normalizeQuerySpelling = normalizeQuerySpelling;
|
|
10
10
|
exports.getExploreBudget = getExploreBudget;
|
|
11
11
|
exports.getExploreOutputBudget = getExploreOutputBudget;
|
|
@@ -23,10 +23,13 @@ const loadCodeGraph = () => require('../index').default;
|
|
|
23
23
|
const worktree_1 = require("../sync/worktree");
|
|
24
24
|
const query_utils_1 = require("../search/query-utils");
|
|
25
25
|
const fs_1 = require("fs");
|
|
26
|
+
const child_process_1 = require("child_process");
|
|
26
27
|
const utils_1 = require("../utils");
|
|
27
28
|
const generated_detection_1 = require("../extraction/generated-detection");
|
|
28
29
|
const dynamic_boundaries_1 = require("./dynamic-boundaries");
|
|
29
30
|
const update_check_1 = require("../upgrade/update-check");
|
|
31
|
+
/** Narrow subprocess seam for testing CLI-only MCP wrappers. */
|
|
32
|
+
exports.cliProcess = { spawnSync: child_process_1.spawnSync };
|
|
30
33
|
/**
|
|
31
34
|
* An expected, recoverable "codegraph can't serve this" condition — most
|
|
32
35
|
* importantly a project with no index. The dispatch catch converts these to
|
|
@@ -400,6 +403,35 @@ const READ_ONLY_ANNOTATIONS = {
|
|
|
400
403
|
* All tools support cross-project queries via the optional `projectPath` parameter.
|
|
401
404
|
*/
|
|
402
405
|
exports.tools = [
|
|
406
|
+
{
|
|
407
|
+
name: 'codegraph_query',
|
|
408
|
+
description: 'Run the canonical CodeGraph CLI symbol query and return its structured JSON output.',
|
|
409
|
+
inputSchema: {
|
|
410
|
+
type: 'object',
|
|
411
|
+
properties: {
|
|
412
|
+
query: {
|
|
413
|
+
type: 'string',
|
|
414
|
+
description: 'Symbol name or partial name to query',
|
|
415
|
+
},
|
|
416
|
+
path: {
|
|
417
|
+
type: 'string',
|
|
418
|
+
description: 'Validated project directory passed to the CLI; overrides projectPath when both are set. Defaults to the selected project root.',
|
|
419
|
+
},
|
|
420
|
+
limit: {
|
|
421
|
+
type: 'number',
|
|
422
|
+
description: 'Maximum results (default: 10)',
|
|
423
|
+
default: 10,
|
|
424
|
+
},
|
|
425
|
+
kind: {
|
|
426
|
+
type: 'string',
|
|
427
|
+
description: 'Filter by node kind',
|
|
428
|
+
},
|
|
429
|
+
projectPath: projectPathProperty,
|
|
430
|
+
},
|
|
431
|
+
required: ['query'],
|
|
432
|
+
},
|
|
433
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
434
|
+
},
|
|
403
435
|
{
|
|
404
436
|
name: 'codegraph_search',
|
|
405
437
|
description: 'Quick symbol search by name. Returns locations only (no code). Use codegraph_explore instead to get the actual source / understand an area in one call.',
|
|
@@ -564,6 +596,30 @@ exports.tools = [
|
|
|
564
596
|
},
|
|
565
597
|
annotations: READ_ONLY_ANNOTATIONS,
|
|
566
598
|
},
|
|
599
|
+
{
|
|
600
|
+
name: 'codegraph_sync',
|
|
601
|
+
description: 'Synchronize an existing CodeGraph index with filesystem changes.',
|
|
602
|
+
inputSchema: {
|
|
603
|
+
type: 'object',
|
|
604
|
+
properties: {
|
|
605
|
+
path: {
|
|
606
|
+
type: 'string',
|
|
607
|
+
description: 'Project or directory whose full CodeGraph index should be synchronized.',
|
|
608
|
+
},
|
|
609
|
+
quiet: {
|
|
610
|
+
type: 'boolean',
|
|
611
|
+
description: 'Suppress progress output.',
|
|
612
|
+
},
|
|
613
|
+
projectPath: projectPathProperty,
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
annotations: {
|
|
617
|
+
readOnlyHint: false,
|
|
618
|
+
destructiveHint: false,
|
|
619
|
+
idempotentHint: true,
|
|
620
|
+
openWorldHint: false,
|
|
621
|
+
},
|
|
622
|
+
},
|
|
567
623
|
{
|
|
568
624
|
name: 'codegraph_status',
|
|
569
625
|
description: 'Index health check (files / nodes / edges). Skip unless debugging.',
|
|
@@ -609,6 +665,37 @@ exports.tools = [
|
|
|
609
665
|
},
|
|
610
666
|
annotations: READ_ONLY_ANNOTATIONS,
|
|
611
667
|
},
|
|
668
|
+
{
|
|
669
|
+
name: 'codegraph_init',
|
|
670
|
+
description: 'Initialize and index a project by invoking the codegraph init CLI. This mutates the target project and is disabled unless explicitly enabled via CODEGRAPH_MCP_TOOLS.',
|
|
671
|
+
inputSchema: {
|
|
672
|
+
type: 'object',
|
|
673
|
+
properties: {
|
|
674
|
+
path: {
|
|
675
|
+
type: 'string',
|
|
676
|
+
description: 'Project directory to initialize and index.',
|
|
677
|
+
},
|
|
678
|
+
force: {
|
|
679
|
+
type: 'boolean',
|
|
680
|
+
description: 'Pass --force to allow initialization at a normally unsafe root.',
|
|
681
|
+
default: false,
|
|
682
|
+
},
|
|
683
|
+
verbose: {
|
|
684
|
+
type: 'boolean',
|
|
685
|
+
description: 'Pass --verbose to show detailed worker lifecycle and memory information.',
|
|
686
|
+
default: false,
|
|
687
|
+
},
|
|
688
|
+
projectPath: projectPathProperty,
|
|
689
|
+
},
|
|
690
|
+
required: ['path'],
|
|
691
|
+
},
|
|
692
|
+
annotations: {
|
|
693
|
+
readOnlyHint: false,
|
|
694
|
+
destructiveHint: true,
|
|
695
|
+
idempotentHint: false,
|
|
696
|
+
openWorldHint: false,
|
|
697
|
+
},
|
|
698
|
+
},
|
|
612
699
|
];
|
|
613
700
|
/**
|
|
614
701
|
* Return `defs` with `projectPath` marked `required` in each tool's inputSchema.
|
|
@@ -630,6 +717,10 @@ exports.tools = [
|
|
|
630
717
|
*/
|
|
631
718
|
function withRequiredProjectPath(defs) {
|
|
632
719
|
return defs.map((tool) => {
|
|
720
|
+
// Lifecycle tools operate on their own required `path`; they do not need a
|
|
721
|
+
// pre-opened default index, so their cross-project hint remains optional.
|
|
722
|
+
if (tool.annotations?.readOnlyHint === false && tool.inputSchema.required?.includes('path'))
|
|
723
|
+
return tool;
|
|
633
724
|
if (!tool.inputSchema.properties.projectPath)
|
|
634
725
|
return tool;
|
|
635
726
|
const required = tool.inputSchema.required ?? [];
|
|
@@ -784,7 +875,8 @@ class ToolHandler {
|
|
|
784
875
|
/**
|
|
785
876
|
* Optional allowlist of exposed tools, parsed from the CODEGRAPH_MCP_TOOLS
|
|
786
877
|
* env var (comma-separated short names, e.g. "trace,search,node,context").
|
|
787
|
-
* Unset/empty →
|
|
878
|
+
* Unset/empty → legacy direct calls to read-only tools are allowed, while
|
|
879
|
+
* mutating lifecycle tools remain opt-in. Lets an operator (or an A/B harness)
|
|
788
880
|
* trim the tool surface without rebuilding the client config; the ablated
|
|
789
881
|
* tool is then truly absent from ListTools rather than merely denied on call.
|
|
790
882
|
* Matching is on the short form, so "node" and "codegraph_node" both work.
|
|
@@ -800,7 +892,12 @@ class ToolHandler {
|
|
|
800
892
|
/** Whether a tool name passes the CODEGRAPH_MCP_TOOLS allowlist (if any). */
|
|
801
893
|
isToolAllowed(name) {
|
|
802
894
|
const allow = this.toolAllowlist();
|
|
803
|
-
|
|
895
|
+
const shortName = name.replace(/^codegraph_/, '');
|
|
896
|
+
if (allow)
|
|
897
|
+
return allow.has(shortName);
|
|
898
|
+
// Preserve backwards compatibility for direct read-only calls. Mutating
|
|
899
|
+
// lifecycle tools must be explicitly enabled even when tools/list is bypassed.
|
|
900
|
+
return shortName !== 'init' && shortName !== 'sync';
|
|
804
901
|
}
|
|
805
902
|
/**
|
|
806
903
|
* Get tool definitions with dynamic descriptions based on project size.
|
|
@@ -1226,6 +1323,9 @@ class ToolHandler {
|
|
|
1226
1323
|
if (typeof check === 'object' && check !== undefined)
|
|
1227
1324
|
return check;
|
|
1228
1325
|
}
|
|
1326
|
+
if (toolName === 'codegraph_init') {
|
|
1327
|
+
return this.executeMutatingTool('init', args);
|
|
1328
|
+
}
|
|
1229
1329
|
// codegraph_status reports watcher state (pending files, degraded mode,
|
|
1230
1330
|
// worktree warning) and embeds its own sections — it must run on the MAIN
|
|
1231
1331
|
// thread against the watched default instance, so it is NEVER off-loaded to
|
|
@@ -1234,6 +1334,9 @@ class ToolHandler {
|
|
|
1234
1334
|
if (toolName === 'codegraph_status') {
|
|
1235
1335
|
return await this.handleStatus(args);
|
|
1236
1336
|
}
|
|
1337
|
+
if (toolName === 'codegraph_sync') {
|
|
1338
|
+
return this.handleSync(args);
|
|
1339
|
+
}
|
|
1237
1340
|
// Read tools: off-load the CPU-heavy dispatch to the worker pool when one
|
|
1238
1341
|
// is attached, healthy, AND has finished its first cold start (daemon
|
|
1239
1342
|
// mode), so the daemon's single event loop stays free for the MCP
|
|
@@ -1270,6 +1373,91 @@ class ToolHandler {
|
|
|
1270
1373
|
'continue without codegraph for this task.');
|
|
1271
1374
|
}
|
|
1272
1375
|
}
|
|
1376
|
+
/** Run the CLI sync command and preserve its complete process output. */
|
|
1377
|
+
handleSync(args) {
|
|
1378
|
+
if (args.quiet !== undefined && typeof args.quiet !== 'boolean') {
|
|
1379
|
+
return this.errorResult('quiet must be a boolean');
|
|
1380
|
+
}
|
|
1381
|
+
const target = args.path ?? args.projectPath ?? this.cg?.getProjectRoot() ?? process.cwd();
|
|
1382
|
+
if (typeof target !== 'string')
|
|
1383
|
+
return this.errorResult('path must be a string');
|
|
1384
|
+
const resolvedTarget = this.validateMutationTarget(target);
|
|
1385
|
+
if (typeof resolvedTarget !== 'string')
|
|
1386
|
+
return resolvedTarget;
|
|
1387
|
+
const commandArgs = [(0, path_1.resolve)(__dirname, '../../dist/bin/codegraph.js'), 'sync', resolvedTarget];
|
|
1388
|
+
if (args.quiet === true)
|
|
1389
|
+
commandArgs.push('--quiet');
|
|
1390
|
+
const result = (0, child_process_1.spawnSync)(process.execPath, commandArgs, {
|
|
1391
|
+
encoding: 'utf8',
|
|
1392
|
+
windowsHide: true,
|
|
1393
|
+
});
|
|
1394
|
+
const stdout = result.stdout ?? '';
|
|
1395
|
+
const stderr = result.stderr ?? '';
|
|
1396
|
+
const output = [stdout, stderr].filter(Boolean).join(stdout && stderr ? '\n' : '');
|
|
1397
|
+
if (result.error) {
|
|
1398
|
+
return this.errorResult(`${result.error.message}${output ? `\n${output}` : ''}`);
|
|
1399
|
+
}
|
|
1400
|
+
if (result.status !== 0) {
|
|
1401
|
+
return {
|
|
1402
|
+
content: [{
|
|
1403
|
+
type: 'text',
|
|
1404
|
+
text: [output, `codegraph sync exited with code ${result.status}`].filter(Boolean).join('\n'),
|
|
1405
|
+
}],
|
|
1406
|
+
isError: true,
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
return this.textResult(output || 'codegraph sync exited with code 0');
|
|
1410
|
+
}
|
|
1411
|
+
/** Resolve symlinks/junctions and enforce mutation-root boundaries. */
|
|
1412
|
+
validateMutationTarget(target) {
|
|
1413
|
+
const canonicalize = (candidate) => {
|
|
1414
|
+
let existing = (0, path_1.resolve)(candidate);
|
|
1415
|
+
const missing = [];
|
|
1416
|
+
while (!(0, fs_1.existsSync)(existing)) {
|
|
1417
|
+
const parent = (0, path_1.resolve)(existing, '..');
|
|
1418
|
+
if (parent === existing)
|
|
1419
|
+
break;
|
|
1420
|
+
missing.unshift((0, path_1.basename)(existing));
|
|
1421
|
+
existing = parent;
|
|
1422
|
+
}
|
|
1423
|
+
return (0, path_1.resolve)(fs_1.realpathSync.native(existing), ...missing);
|
|
1424
|
+
};
|
|
1425
|
+
const resolvedTarget = canonicalize(target);
|
|
1426
|
+
const rawAllowlist = process.env.CODEGRAPH_MCP_ALLOWLIST?.trim();
|
|
1427
|
+
if (rawAllowlist && rawAllowlist !== '*') {
|
|
1428
|
+
const allowed = rawAllowlist.split(path_1.delimiter).map(entry => entry.trim()).filter(Boolean).some(entry => {
|
|
1429
|
+
const relativePath = (0, path_1.relative)(canonicalize(entry), resolvedTarget);
|
|
1430
|
+
return relativePath === '' || (!relativePath.startsWith('..') && !(0, path_1.isAbsolute)(relativePath));
|
|
1431
|
+
});
|
|
1432
|
+
if (!allowed)
|
|
1433
|
+
return this.errorResult(`Path is outside CODEGRAPH_MCP_ALLOWLIST: ${resolvedTarget}`);
|
|
1434
|
+
}
|
|
1435
|
+
return resolvedTarget;
|
|
1436
|
+
}
|
|
1437
|
+
/** Execute a mutating CodeGraph CLI command after enforcing its path allowlist. */
|
|
1438
|
+
executeMutatingTool(command, args) {
|
|
1439
|
+
const target = this.validateString(args.path, 'path');
|
|
1440
|
+
if (typeof target !== 'string')
|
|
1441
|
+
return target;
|
|
1442
|
+
const resolvedTarget = this.validateMutationTarget(target);
|
|
1443
|
+
if (typeof resolvedTarget !== 'string')
|
|
1444
|
+
return resolvedTarget;
|
|
1445
|
+
const adjacentCli = (0, path_1.resolve)(__dirname, '../bin/codegraph.js');
|
|
1446
|
+
const builtCli = (0, fs_1.existsSync)(adjacentCli) ? adjacentCli : (0, path_1.resolve)(__dirname, '../../dist/bin/codegraph.js');
|
|
1447
|
+
const cliArgs = [builtCli, command];
|
|
1448
|
+
if (args.force === true)
|
|
1449
|
+
cliArgs.push('--force');
|
|
1450
|
+
if (args.verbose === true)
|
|
1451
|
+
cliArgs.push('--verbose');
|
|
1452
|
+
cliArgs.push(resolvedTarget);
|
|
1453
|
+
const result = (0, child_process_1.spawnSync)(process.execPath, cliArgs, { encoding: 'utf8' });
|
|
1454
|
+
const output = [result.stdout, result.stderr].filter(Boolean).join('');
|
|
1455
|
+
const failed = result.status !== 0 || result.error !== undefined;
|
|
1456
|
+
return {
|
|
1457
|
+
content: [{ type: 'text', text: output || result.error?.message || `codegraph ${command} exited with status ${result.status}` }],
|
|
1458
|
+
isError: failed,
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1273
1461
|
/**
|
|
1274
1462
|
* Run a single read tool to completion and return its raw {@link ToolResult},
|
|
1275
1463
|
* classifying expected failures the same way {@link execute}'s catch does so
|
|
@@ -1307,6 +1495,7 @@ class ToolHandler {
|
|
|
1307
1495
|
*/
|
|
1308
1496
|
async dispatchTool(toolName, args) {
|
|
1309
1497
|
switch (toolName) {
|
|
1498
|
+
case 'codegraph_query': return await this.handleQuery(args);
|
|
1310
1499
|
case 'codegraph_search': return await this.handleSearch(args);
|
|
1311
1500
|
case 'codegraph_callers': return await this.handleCallers(args);
|
|
1312
1501
|
case 'codegraph_callees': return await this.handleCallees(args);
|
|
@@ -1317,6 +1506,42 @@ class ToolHandler {
|
|
|
1317
1506
|
default: return this.errorResult(`Unknown tool: ${toolName}`);
|
|
1318
1507
|
}
|
|
1319
1508
|
}
|
|
1509
|
+
/** Run the CLI-only query command and preserve its JSON stdout verbatim. */
|
|
1510
|
+
async handleQuery(args) {
|
|
1511
|
+
const query = this.validateString(args.query, 'query');
|
|
1512
|
+
if (typeof query !== 'string')
|
|
1513
|
+
return query;
|
|
1514
|
+
let projectPath;
|
|
1515
|
+
if (args.path !== undefined) {
|
|
1516
|
+
const explicitPath = this.validateString(args.path, 'path');
|
|
1517
|
+
if (typeof explicitPath !== 'string')
|
|
1518
|
+
return explicitPath;
|
|
1519
|
+
projectPath = explicitPath;
|
|
1520
|
+
const pathError = (0, utils_1.validateProjectPath)(projectPath);
|
|
1521
|
+
if (pathError)
|
|
1522
|
+
return this.errorResult(pathError);
|
|
1523
|
+
}
|
|
1524
|
+
else {
|
|
1525
|
+
projectPath = this.getCodeGraph(args.projectPath).getProjectRoot();
|
|
1526
|
+
}
|
|
1527
|
+
const limit = (0, utils_1.clamp)(Number(args.limit) || 10, 1, 100);
|
|
1528
|
+
const commandArgs = ['query', query, '-p', projectPath, '-l', String(limit)];
|
|
1529
|
+
if (args.kind !== undefined) {
|
|
1530
|
+
const kind = this.validateString(args.kind, 'kind');
|
|
1531
|
+
if (typeof kind !== 'string')
|
|
1532
|
+
return kind;
|
|
1533
|
+
commandArgs.push('-k', kind);
|
|
1534
|
+
}
|
|
1535
|
+
commandArgs.push('--json');
|
|
1536
|
+
const cliEntry = (0, path_1.resolve)(__dirname, '../bin/codegraph.js'); // Keep CLI and MCP on the same package version.
|
|
1537
|
+
const result = exports.cliProcess.spawnSync(process.execPath, [cliEntry, ...commandArgs], { encoding: 'utf8', timeout: 30_000 });
|
|
1538
|
+
if (result.error)
|
|
1539
|
+
return this.errorResult(`codegraph query failed: ${result.error.message}`);
|
|
1540
|
+
if (result.status !== 0) {
|
|
1541
|
+
return this.errorResult(`codegraph query failed: ${(result.stderr || '').trim() || `exit code ${result.status}`}`);
|
|
1542
|
+
}
|
|
1543
|
+
return this.textResult(result.stdout || '');
|
|
1544
|
+
}
|
|
1320
1545
|
/**
|
|
1321
1546
|
* Handle codegraph_search
|
|
1322
1547
|
*/
|