@aroman22/codegraph-vba-darwin-arm64 1.5.2 → 1.6.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.
- package/bin/codegraph +5 -0
- package/lib/dist/bin/codegraph.d.ts +1 -1
- package/lib/dist/bin/codegraph.d.ts.map +1 -1
- package/lib/dist/bin/codegraph.js +307 -81
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/bin/command-supervision.d.ts +38 -1
- package/lib/dist/bin/command-supervision.d.ts.map +1 -1
- package/lib/dist/bin/command-supervision.js +22 -3
- package/lib/dist/bin/command-supervision.js.map +1 -1
- package/lib/dist/db/index.d.ts +84 -5
- package/lib/dist/db/index.d.ts.map +1 -1
- package/lib/dist/db/index.js +209 -12
- package/lib/dist/db/index.js.map +1 -1
- package/lib/dist/db/migrations.d.ts +1 -1
- package/lib/dist/db/migrations.d.ts.map +1 -1
- package/lib/dist/db/migrations.js +80 -3
- package/lib/dist/db/migrations.js.map +1 -1
- package/lib/dist/db/queries.d.ts +116 -4
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +294 -7
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/db/schema.sql +43 -1
- package/lib/dist/db/wal-valve.d.ts +106 -0
- package/lib/dist/db/wal-valve.d.ts.map +1 -0
- package/lib/dist/db/wal-valve.js +208 -0
- package/lib/dist/db/wal-valve.js.map +1 -0
- package/lib/dist/directory.d.ts +9 -5
- package/lib/dist/directory.d.ts.map +1 -1
- package/lib/dist/directory.js +210 -19
- package/lib/dist/directory.js.map +1 -1
- package/lib/dist/extraction/cfml-extractor.d.ts +107 -0
- package/lib/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/cfml-extractor.js +494 -0
- package/lib/dist/extraction/cfml-extractor.js.map +1 -0
- package/lib/dist/extraction/grammars.d.ts +25 -1
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +177 -23
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +47 -2
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +568 -51
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/languages/arkts.d.ts +3 -0
- package/lib/dist/extraction/languages/arkts.d.ts.map +1 -0
- package/lib/dist/extraction/languages/arkts.js +127 -0
- package/lib/dist/extraction/languages/arkts.js.map +1 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts +98 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.js +563 -1
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
- package/lib/dist/extraction/languages/cfquery.d.ts +12 -0
- package/lib/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfquery.js +28 -0
- package/lib/dist/extraction/languages/cfquery.js.map +1 -0
- package/lib/dist/extraction/languages/cfscript.d.ts +3 -0
- package/lib/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfscript.js +73 -0
- package/lib/dist/extraction/languages/cfscript.js.map +1 -0
- package/lib/dist/extraction/languages/cobol.d.ts +33 -0
- package/lib/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cobol.js +499 -0
- package/lib/dist/extraction/languages/cobol.js.map +1 -0
- package/lib/dist/extraction/languages/erlang.d.ts +3 -0
- package/lib/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/lib/dist/extraction/languages/erlang.js +350 -0
- package/lib/dist/extraction/languages/erlang.js.map +1 -0
- package/lib/dist/extraction/languages/index.d.ts.map +1 -1
- package/lib/dist/extraction/languages/index.js +18 -0
- package/lib/dist/extraction/languages/index.js.map +1 -1
- package/lib/dist/extraction/languages/nix.d.ts +3 -0
- package/lib/dist/extraction/languages/nix.d.ts.map +1 -0
- package/lib/dist/extraction/languages/nix.js +294 -0
- package/lib/dist/extraction/languages/nix.js.map +1 -0
- package/lib/dist/extraction/languages/solidity.d.ts +3 -0
- package/lib/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/lib/dist/extraction/languages/solidity.js +293 -0
- package/lib/dist/extraction/languages/solidity.js.map +1 -0
- package/lib/dist/extraction/languages/terraform.d.ts +3 -0
- package/lib/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/lib/dist/extraction/languages/terraform.js +641 -0
- package/lib/dist/extraction/languages/terraform.js.map +1 -0
- package/lib/dist/extraction/languages/vbnet.d.ts +11 -0
- package/lib/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/lib/dist/extraction/languages/vbnet.js +141 -0
- package/lib/dist/extraction/languages/vbnet.js.map +1 -0
- package/lib/dist/extraction/mybatis-extractor.d.ts +30 -10
- package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/mybatis-extractor.js +140 -38
- package/lib/dist/extraction/mybatis-extractor.js.map +1 -1
- package/lib/dist/extraction/parse-pool.d.ts +28 -1
- package/lib/dist/extraction/parse-pool.d.ts.map +1 -1
- package/lib/dist/extraction/parse-pool.js +76 -7
- package/lib/dist/extraction/parse-pool.js.map +1 -1
- package/lib/dist/extraction/parse-worker.js +11 -4
- package/lib/dist/extraction/parse-worker.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.js +1 -0
- package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts +20 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.d.ts +60 -1
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +905 -20
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/extraction/vba/call-sweep.d.ts +3 -0
- package/lib/dist/extraction/vba/call-sweep.d.ts.map +1 -0
- package/lib/dist/extraction/vba/call-sweep.js +206 -0
- package/lib/dist/extraction/vba/call-sweep.js.map +1 -0
- package/lib/dist/extraction/vba/calls.d.ts +55 -0
- package/lib/dist/extraction/vba/calls.d.ts.map +1 -0
- package/lib/dist/extraction/vba/calls.js +439 -0
- package/lib/dist/extraction/vba/calls.js.map +1 -0
- package/lib/dist/extraction/vba/constants.d.ts +42 -0
- package/lib/dist/extraction/vba/constants.d.ts.map +1 -0
- package/lib/dist/extraction/vba/constants.js +112 -0
- package/lib/dist/extraction/vba/constants.js.map +1 -0
- package/lib/dist/extraction/vba/context.d.ts +175 -0
- package/lib/dist/extraction/vba/context.d.ts.map +1 -0
- package/lib/dist/extraction/vba/context.js +268 -0
- package/lib/dist/extraction/vba/context.js.map +1 -0
- package/lib/dist/extraction/vba/controls.d.ts +24 -0
- package/lib/dist/extraction/vba/controls.d.ts.map +1 -0
- package/lib/dist/extraction/vba/controls.js +89 -0
- package/lib/dist/extraction/vba/controls.js.map +1 -0
- package/lib/dist/extraction/vba/declarations.d.ts +3 -0
- package/lib/dist/extraction/vba/declarations.d.ts.map +1 -0
- package/lib/dist/extraction/vba/declarations.js +154 -0
- package/lib/dist/extraction/vba/declarations.js.map +1 -0
- package/lib/dist/extraction/vba/dims.d.ts +3 -0
- package/lib/dist/extraction/vba/dims.d.ts.map +1 -0
- package/lib/dist/extraction/vba/dims.js +186 -0
- package/lib/dist/extraction/vba/dims.js.map +1 -0
- package/lib/dist/extraction/vba/docmd.d.ts +16 -0
- package/lib/dist/extraction/vba/docmd.d.ts.map +1 -0
- package/lib/dist/extraction/vba/docmd.js +179 -0
- package/lib/dist/extraction/vba/docmd.js.map +1 -0
- package/lib/dist/extraction/vba/enums-consts.d.ts +15 -0
- package/lib/dist/extraction/vba/enums-consts.d.ts.map +1 -0
- package/lib/dist/extraction/vba/enums-consts.js +178 -0
- package/lib/dist/extraction/vba/enums-consts.js.map +1 -0
- package/lib/dist/extraction/vba/implements.d.ts +3 -0
- package/lib/dist/extraction/vba/implements.d.ts.map +1 -0
- package/lib/dist/extraction/vba/implements.js +52 -0
- package/lib/dist/extraction/vba/implements.js.map +1 -0
- package/lib/dist/extraction/vba/procedures.d.ts +3 -0
- package/lib/dist/extraction/vba/procedures.d.ts.map +1 -0
- package/lib/dist/extraction/vba/procedures.js +239 -0
- package/lib/dist/extraction/vba/procedures.js.map +1 -0
- package/lib/dist/extraction/vba/sql-wrapper.d.ts +17 -0
- package/lib/dist/extraction/vba/sql-wrapper.d.ts.map +1 -0
- package/lib/dist/extraction/vba/sql-wrapper.js +212 -0
- package/lib/dist/extraction/vba/sql-wrapper.js.map +1 -0
- package/lib/dist/extraction/vba/tempvars.d.ts +10 -0
- package/lib/dist/extraction/vba/tempvars.d.ts.map +1 -0
- package/lib/dist/extraction/vba/tempvars.js +138 -0
- package/lib/dist/extraction/vba/tempvars.js.map +1 -0
- package/lib/dist/extraction/vba/text-utils.d.ts +73 -0
- package/lib/dist/extraction/vba/text-utils.d.ts.map +1 -0
- package/lib/dist/extraction/vba/text-utils.js +195 -0
- package/lib/dist/extraction/vba/text-utils.js.map +1 -0
- package/lib/dist/extraction/vba-extractor.d.ts +3 -951
- package/lib/dist/extraction/vba-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vba-extractor.js +46 -2934
- package/lib/dist/extraction/vba-extractor.js.map +1 -1
- package/lib/dist/extraction/vba-preprocess.d.ts +1 -1
- package/lib/dist/extraction/vba-preprocess.d.ts.map +1 -1
- package/lib/dist/extraction/vba-preprocess.js +300 -88
- package/lib/dist/extraction/vba-preprocess.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/lib/dist/graph/traversal.d.ts.map +1 -1
- package/lib/dist/graph/traversal.js +76 -17
- package/lib/dist/graph/traversal.js.map +1 -1
- package/lib/dist/index.d.ts +81 -1
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +460 -10
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts +42 -0
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +97 -2
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/mcp/daemon.d.ts +35 -3
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +101 -9
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.js +2 -1
- package/lib/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/lib/dist/mcp/early-ppid.d.ts +26 -0
- package/lib/dist/mcp/early-ppid.d.ts.map +1 -0
- package/lib/dist/mcp/early-ppid.js +29 -0
- package/lib/dist/mcp/early-ppid.js.map +1 -0
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +29 -4
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/liveness-watchdog.d.ts +18 -1
- package/lib/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/lib/dist/mcp/liveness-watchdog.js +73 -13
- package/lib/dist/mcp/liveness-watchdog.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +30 -4
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/query-pool.d.ts +14 -0
- package/lib/dist/mcp/query-pool.d.ts.map +1 -1
- package/lib/dist/mcp/query-pool.js +18 -0
- package/lib/dist/mcp/query-pool.js.map +1 -1
- package/lib/dist/mcp/session.d.ts +14 -0
- package/lib/dist/mcp/session.d.ts.map +1 -1
- package/lib/dist/mcp/session.js +28 -1
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/startup-handshake.d.ts +44 -0
- package/lib/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/lib/dist/mcp/startup-handshake.js +73 -0
- package/lib/dist/mcp/startup-handshake.js.map +1 -0
- package/lib/dist/mcp/tools.d.ts +22 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +289 -23
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/mcp/transport.d.ts.map +1 -1
- package/lib/dist/mcp/transport.js +18 -0
- package/lib/dist/mcp/transport.js.map +1 -1
- package/lib/dist/project-config.d.ts +44 -0
- package/lib/dist/project-config.d.ts.map +1 -1
- package/lib/dist/project-config.js +151 -2
- package/lib/dist/project-config.js.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.js +170 -146
- package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.js +1109 -97
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
- package/lib/dist/resolution/cooperative-yield.d.ts +32 -0
- package/lib/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/lib/dist/resolution/cooperative-yield.js +42 -0
- package/lib/dist/resolution/cooperative-yield.js.map +1 -0
- package/lib/dist/resolution/frameworks/cics.d.ts +20 -0
- package/lib/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/cics.js +90 -0
- package/lib/dist/resolution/frameworks/cics.js.map +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/index.js +6 -0
- package/lib/dist/resolution/frameworks/index.js.map +1 -1
- package/lib/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/java.js +14 -6
- package/lib/dist/resolution/frameworks/java.js.map +1 -1
- package/lib/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/lib/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/terraform.js +277 -0
- package/lib/dist/resolution/frameworks/terraform.js.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/goframe-synthesizer.js +8 -3
- package/lib/dist/resolution/goframe-synthesizer.js.map +1 -1
- package/lib/dist/resolution/import-resolver.d.ts +7 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/import-resolver.js +129 -4
- package/lib/dist/resolution/import-resolver.js.map +1 -1
- package/lib/dist/resolution/index.d.ts +64 -2
- package/lib/dist/resolution/index.d.ts.map +1 -1
- package/lib/dist/resolution/index.js +476 -58
- package/lib/dist/resolution/index.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts +22 -3
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +613 -39
- 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 +49 -0
- package/lib/dist/resolution/strip-comments.js.map +1 -1
- package/lib/dist/resolution/types.d.ts +29 -0
- package/lib/dist/resolution/types.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.d.ts +10 -0
- package/lib/dist/resolution/workspace-packages.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.js +142 -4
- package/lib/dist/resolution/workspace-packages.js.map +1 -1
- package/lib/dist/search/identifier-segments.d.ts +60 -0
- package/lib/dist/search/identifier-segments.d.ts.map +1 -0
- package/lib/dist/search/identifier-segments.js +176 -0
- package/lib/dist/search/identifier-segments.js.map +1 -0
- package/lib/dist/sync/git-hooks.d.ts.map +1 -1
- package/lib/dist/sync/git-hooks.js +2 -0
- package/lib/dist/sync/git-hooks.js.map +1 -1
- package/lib/dist/sync/watcher.d.ts +10 -5
- package/lib/dist/sync/watcher.d.ts.map +1 -1
- package/lib/dist/sync/watcher.js +51 -14
- package/lib/dist/sync/watcher.js.map +1 -1
- package/lib/dist/sync/worktree.d.ts +9 -0
- package/lib/dist/sync/worktree.d.ts.map +1 -1
- package/lib/dist/sync/worktree.js +45 -0
- package/lib/dist/sync/worktree.js.map +1 -1
- package/lib/dist/types.d.ts +25 -2
- package/lib/dist/types.d.ts.map +1 -1
- package/lib/dist/types.js +10 -0
- package/lib/dist/types.js.map +1 -1
- package/lib/dist/upgrade/index.d.ts +34 -2
- package/lib/dist/upgrade/index.d.ts.map +1 -1
- package/lib/dist/upgrade/index.js +164 -15
- package/lib/dist/upgrade/index.js.map +1 -1
- package/lib/dist/upgrade/remove-binary.d.ts +87 -0
- package/lib/dist/upgrade/remove-binary.d.ts.map +1 -0
- package/lib/dist/upgrade/remove-binary.js +289 -0
- package/lib/dist/upgrade/remove-binary.js.map +1 -0
- package/lib/dist/upgrade/update-check.d.ts +92 -0
- package/lib/dist/upgrade/update-check.d.ts.map +1 -0
- package/lib/dist/upgrade/update-check.js +258 -0
- package/lib/dist/upgrade/update-check.js.map +1 -0
- package/lib/node_modules/.modules.yaml +1 -1
- package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/lib/dist/reasoning/config.d.ts +0 -45
- package/lib/dist/reasoning/config.d.ts.map +0 -1
- package/lib/dist/reasoning/config.js +0 -171
- package/lib/dist/reasoning/config.js.map +0 -1
- package/lib/dist/reasoning/credentials.d.ts +0 -5
- package/lib/dist/reasoning/credentials.d.ts.map +0 -1
- package/lib/dist/reasoning/credentials.js +0 -83
- package/lib/dist/reasoning/credentials.js.map +0 -1
- package/lib/dist/reasoning/login.d.ts +0 -21
- package/lib/dist/reasoning/login.d.ts.map +0 -1
- package/lib/dist/reasoning/login.js +0 -85
- package/lib/dist/reasoning/login.js.map +0 -1
- package/lib/dist/reasoning/reasoner.d.ts +0 -43
- package/lib/dist/reasoning/reasoner.d.ts.map +0 -1
- package/lib/dist/reasoning/reasoner.js +0 -308
- package/lib/dist/reasoning/reasoner.js.map +0 -1
package/lib/dist/mcp/tools.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.ToolHandler = exports.tools = exports.PathRefusalError = exports.NotIndexedError = void 0;
|
|
9
|
+
exports.normalizeQuerySpelling = normalizeQuerySpelling;
|
|
9
10
|
exports.getExploreBudget = getExploreBudget;
|
|
10
11
|
exports.getExploreOutputBudget = getExploreOutputBudget;
|
|
11
12
|
exports.formatStaleBanner = formatStaleBanner;
|
|
@@ -25,6 +26,7 @@ const fs_1 = require("fs");
|
|
|
25
26
|
const utils_1 = require("../utils");
|
|
26
27
|
const generated_detection_1 = require("../extraction/generated-detection");
|
|
27
28
|
const dynamic_boundaries_1 = require("./dynamic-boundaries");
|
|
29
|
+
const update_check_1 = require("../upgrade/update-check");
|
|
28
30
|
/**
|
|
29
31
|
* An expected, recoverable "codegraph can't serve this" condition — most
|
|
30
32
|
* importantly a project with no index. The dispatch catch converts these to
|
|
@@ -85,6 +87,32 @@ function lastQualifierPart(symbol) {
|
|
|
85
87
|
const parts = symbol.split(/::|[./]/).filter((p) => p.length > 0);
|
|
86
88
|
return parts[parts.length - 1] ?? symbol;
|
|
87
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Normalize Erlang-native symbol spellings in an explore query into the shapes
|
|
92
|
+
* the rest of the pipeline already understands. Agents working Erlang code
|
|
93
|
+
* name symbols the way the language spells them — `mod:fn/3`, `init/2` — and
|
|
94
|
+
* those tokens previously died in both consumers: the flow-builder's token
|
|
95
|
+
* filter rejects `:` and `/arity` outright, and the search-side field parser
|
|
96
|
+
* eats `mod:fn` as an unknown `field:value`. Measured on cowboy: the agent
|
|
97
|
+
* named `cowboy_stream_h:request_process/3` in two queries, got no body back
|
|
98
|
+
* either time, and fell back to Read.
|
|
99
|
+
*
|
|
100
|
+
* - `fn/3` → `fn` (arity tail after an identifier; a path segment like
|
|
101
|
+
* `src/2fa` doesn't match because the tail must be all digits)
|
|
102
|
+
* - `mod:fn` → `mod.fn` (exactly one colon between identifiers, so it rides
|
|
103
|
+
* the existing Class.method qualified handling; `::`, URLs, drive letters,
|
|
104
|
+
* and times don't match, and the query language's own field prefixes —
|
|
105
|
+
* kind:/lang:/language:/path:/name: — are left alone)
|
|
106
|
+
*
|
|
107
|
+
* Safe cross-language: Lua's `t:m` spelling maps to the same `t.m` its
|
|
108
|
+
* qualified names use, and no other supported spelling contains a bare
|
|
109
|
+
* single-colon identifier pair.
|
|
110
|
+
*/
|
|
111
|
+
function normalizeQuerySpelling(query) {
|
|
112
|
+
return query
|
|
113
|
+
.replace(/\b([A-Za-z_][\w@]*)\/(\d{1,3})(?=$|[\s,()[\]/])/g, '$1')
|
|
114
|
+
.replace(/(^|[\s,()[\]])(?!(?:kind|lang|language|path|name):)([a-z_][\w@]*):([A-Za-z_][\w@]*)(?=$|[\s,()[\]])/g, '$1$2.$3');
|
|
115
|
+
}
|
|
88
116
|
/**
|
|
89
117
|
* Calculate the recommended number of codegraph_explore calls based on project size.
|
|
90
118
|
* Larger codebases need more exploration calls to cover their surface area,
|
|
@@ -274,10 +302,15 @@ function numberSourceLines(slice, firstLineNumber) {
|
|
|
274
302
|
* extension) stop blowing every header up to H1–H4. The path is bold + a code
|
|
275
303
|
* span so it still reads as a header, and the leading ``**` `` stays a UNIQUE,
|
|
276
304
|
* greppable marker — no other explore line begins with it — that the explore
|
|
277
|
-
* truncation boundary (`handleExplore`)
|
|
278
|
-
* (`reasoning/reasoner.ts`) both key off to cut on whole file sections.
|
|
305
|
+
* truncation boundary (`handleExplore`) keys off to cut on whole file sections.
|
|
279
306
|
*/
|
|
280
307
|
const FILE_SECTION_PREFIX = '**`';
|
|
308
|
+
// Placeholder for codegraph_explore's "Found N symbols across M files." line.
|
|
309
|
+
// The honest N/M can only be known after the final truncation drops trailing
|
|
310
|
+
// sections (#1046), so the header is emitted as this sentinel and substituted
|
|
311
|
+
// at the very end. This bracketed token never occurs in rendered source or a
|
|
312
|
+
// file path, so the final string-replace can't collide.
|
|
313
|
+
const SUMMARY_SENTINEL = '[[codegraph-explore-summary]]';
|
|
281
314
|
function fileSectionHeader(filePath, suffix) {
|
|
282
315
|
return suffix
|
|
283
316
|
? `${FILE_SECTION_PREFIX}${filePath}\`** — ${suffix}`
|
|
@@ -1202,15 +1235,20 @@ class ToolHandler {
|
|
|
1202
1235
|
return await this.handleStatus(args);
|
|
1203
1236
|
}
|
|
1204
1237
|
// Read tools: off-load the CPU-heavy dispatch to the worker pool when one
|
|
1205
|
-
// is attached
|
|
1206
|
-
//
|
|
1207
|
-
//
|
|
1208
|
-
//
|
|
1209
|
-
//
|
|
1210
|
-
//
|
|
1211
|
-
//
|
|
1212
|
-
//
|
|
1213
|
-
|
|
1238
|
+
// is attached, healthy, AND has finished its first cold start (daemon
|
|
1239
|
+
// mode), so the daemon's single event loop stays free for the MCP
|
|
1240
|
+
// transport under concurrent load — otherwise N concurrent explores
|
|
1241
|
+
// serialize AND starve the transport until the whole batch drains
|
|
1242
|
+
// (clients then time out). Before the first worker is warm, calls run
|
|
1243
|
+
// in-process: a call queued behind a cold start sat invisible until the
|
|
1244
|
+
// 45s busy backstop — the daemon's first tool call stalling for however
|
|
1245
|
+
// long a worker spawn takes on a loaded machine (the #662 flake). With
|
|
1246
|
+
// no pool (direct mode) or a degraded one, dispatch runs in-process
|
|
1247
|
+
// exactly as before. Either way the result flows through the
|
|
1248
|
+
// cross-cutting notices — worktree-index mismatch (#155) and per-file
|
|
1249
|
+
// staleness (#403) — which need the watched MAIN instance and so are
|
|
1250
|
+
// always applied here, never in the worker.
|
|
1251
|
+
const result = (this.queryPool && this.queryPool.healthy && this.queryPool.ready)
|
|
1214
1252
|
? await this.queryPool.run(toolName, args)
|
|
1215
1253
|
: await this.executeReadTool(toolName, args);
|
|
1216
1254
|
const withWorktree = this.withWorktreeNotice(result, args.projectPath);
|
|
@@ -1654,7 +1692,7 @@ class ToolHandler {
|
|
|
1654
1692
|
// names (Class.method / Class::method) — the agent's most precise input,
|
|
1655
1693
|
// resolved exactly by findAllSymbols. (The old strip mangled Class.method
|
|
1656
1694
|
// into Class, throwing the method away.)
|
|
1657
|
-
const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro)$/i;
|
|
1695
|
+
const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro|erl|hrl)$/i;
|
|
1658
1696
|
const tokens = [...new Set(query.split(/[\s,()[\]]+/)
|
|
1659
1697
|
.map((t) => t.replace(FILE_EXT, '').trim())
|
|
1660
1698
|
.filter((t) => t.length >= 3 && /^[A-Za-z_$][\w$]*(?:(?:::|\.)[\w$]+)*$/.test(t)))].slice(0, 16);
|
|
@@ -1716,13 +1754,19 @@ class ToolHandler {
|
|
|
1716
1754
|
}
|
|
1717
1755
|
// Same token, non-callable synth endpoints (capped, precision-gated on an
|
|
1718
1756
|
// actual heuristic edge so plain config constants never qualify).
|
|
1757
|
+
// Per-token sub-cap so one token's many endpoints (10 nix option writes
|
|
1758
|
+
// of `programs.git.enable` across test configs) can't fill the pool
|
|
1759
|
+
// before later tokens (`home.file`) get a slot.
|
|
1719
1760
|
if (dynNamed.size < 12) {
|
|
1761
|
+
let tokenDyn = 0;
|
|
1720
1762
|
for (const n of hits) {
|
|
1721
1763
|
if (CALLABLE.has(n.kind) || !DYN_KINDS.has(n.kind) || dynNamed.has(n.id))
|
|
1722
1764
|
continue;
|
|
1723
|
-
if (hasHeuristicEdge(n.id))
|
|
1765
|
+
if (hasHeuristicEdge(n.id)) {
|
|
1724
1766
|
dynNamed.set(n.id, n);
|
|
1725
|
-
|
|
1767
|
+
tokenDyn++;
|
|
1768
|
+
}
|
|
1769
|
+
if (dynNamed.size >= 12 || tokenDyn >= 4)
|
|
1726
1770
|
break;
|
|
1727
1771
|
}
|
|
1728
1772
|
}
|
|
@@ -2353,9 +2397,12 @@ class ToolHandler {
|
|
|
2353
2397
|
* tax on small projects while earning its keep on large ones.
|
|
2354
2398
|
*/
|
|
2355
2399
|
async handleExplore(args) {
|
|
2356
|
-
const
|
|
2357
|
-
if (typeof
|
|
2358
|
-
return
|
|
2400
|
+
const rawQuery = this.validateString(args.query, 'query');
|
|
2401
|
+
if (typeof rawQuery !== 'string')
|
|
2402
|
+
return rawQuery;
|
|
2403
|
+
// One normalization point so the flow-builder, relevance search, and
|
|
2404
|
+
// ranking all see the same canonical spelling (Erlang `mod:fn/arity`).
|
|
2405
|
+
const query = normalizeQuerySpelling(rawQuery);
|
|
2359
2406
|
const cg = this.getCodeGraph(args.projectPath);
|
|
2360
2407
|
const projectRoot = cg.getProjectRoot();
|
|
2361
2408
|
// Resolve adaptive output budget from project size. Falls back to the
|
|
@@ -2429,11 +2476,24 @@ class ToolHandler {
|
|
|
2429
2476
|
// trace endpoint picker uses) and inject it as an entry, so every symbol the
|
|
2430
2477
|
// agent explicitly named is in the subgraph and its file is scored.
|
|
2431
2478
|
const namedSeedIds = new Set();
|
|
2479
|
+
// The subset of named seeds that earns the named-FIRST sort tier. We still
|
|
2480
|
+
// SEED every ≤3-def name (so RWR / flow ranking is unchanged), but only the
|
|
2481
|
+
// most-substantive def is tiered — a bare name's unrelated namesakes (Go's
|
|
2482
|
+
// `NewClient` = real client + test fake + xds pool) must not fill the tier
|
|
2483
|
+
// and crowd out the real answer file (grpc's `dialoptions.go`). Corroborated
|
|
2484
|
+
// overloads (the query also named the type) all earn it. (#1064)
|
|
2485
|
+
const tierSeedIds = new Set();
|
|
2432
2486
|
{
|
|
2433
|
-
const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro)$/i;
|
|
2487
|
+
const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro|erl|hrl)$/i;
|
|
2434
2488
|
const CALLABLE = new Set(['method', 'function', 'component', 'constructor']);
|
|
2435
2489
|
const isTestPath = (p) => /(^|\/)(tests?|specs?|__tests__|testdata|mocks?|fixtures?)\//i.test(p) || /\.(test|spec)\.[a-z]+$/i.test(p);
|
|
2436
2490
|
const bodyLines = (n) => Math.max(0, (n.endLine ?? n.startLine) - n.startLine);
|
|
2491
|
+
const callerCount = (n) => { try {
|
|
2492
|
+
return cg.getCallers(n.id).length;
|
|
2493
|
+
}
|
|
2494
|
+
catch {
|
|
2495
|
+
return 0;
|
|
2496
|
+
} };
|
|
2437
2497
|
const tokens = [...new Set(query.split(/[\s,()[\]]+/)
|
|
2438
2498
|
.map((t) => t.replace(FILE_EXT, '').trim())
|
|
2439
2499
|
.filter((t) => t.length >= 3 && /^[A-Za-z_$][\w$]*(?:(?:::|\.)[\w$]+)*$/.test(t)))].slice(0, 16);
|
|
@@ -2451,6 +2511,38 @@ class ToolHandler {
|
|
|
2451
2511
|
const lc = ct.toLowerCase();
|
|
2452
2512
|
return n.filePath.toLowerCase().includes(lc) || n.qualifiedName.toLowerCase().includes(lc);
|
|
2453
2513
|
});
|
|
2514
|
+
// NL-stopword guard: this seeding treats every token as "a symbol the
|
|
2515
|
+
// agent named", but explore also takes natural-language questions, whose
|
|
2516
|
+
// ordinary English words collide with real callables — "…check the latest
|
|
2517
|
+
// version…" exact-matched a lone `check()` method, which then earned the
|
|
2518
|
+
// named-FIRST sort tier and displaced the corroborated answer files from
|
|
2519
|
+
// the whole render budget (the agent fell back to Read). A shape-precise
|
|
2520
|
+
// token (camelCase, PascalCase, snake_case, qualified) is an unambiguous
|
|
2521
|
+
// symbol reference and seeds unconditionally; a BARE lowercase word seeds
|
|
2522
|
+
// only where the query corroborates the file — another query token is
|
|
2523
|
+
// itself a symbol defined in that same file (the "check drain fire"
|
|
2524
|
+
// sibling-bag case), which an incidental English-word collision never is.
|
|
2525
|
+
const lcTokens = new Set(tokens.map((x) => x.toLowerCase()));
|
|
2526
|
+
const isPreciseToken = (x) => /[._$]|::|\//.test(x) || /[a-z][A-Z]/.test(x) || /^[A-Z]/.test(x);
|
|
2527
|
+
const fileNameSets = new Map();
|
|
2528
|
+
const coNamedInFile = (t, fp) => {
|
|
2529
|
+
let names = fileNameSets.get(fp);
|
|
2530
|
+
if (!names) {
|
|
2531
|
+
names = new Set();
|
|
2532
|
+
try {
|
|
2533
|
+
for (const n of cg.getNodesInFile(fp))
|
|
2534
|
+
names.add(n.name.toLowerCase());
|
|
2535
|
+
}
|
|
2536
|
+
catch { /* unreadable file entry — treat as uncorroborated */ }
|
|
2537
|
+
fileNameSets.set(fp, names);
|
|
2538
|
+
}
|
|
2539
|
+
const self = t.toLowerCase();
|
|
2540
|
+
for (const o of lcTokens) {
|
|
2541
|
+
if (o !== self && names.has(o))
|
|
2542
|
+
return true;
|
|
2543
|
+
}
|
|
2544
|
+
return false;
|
|
2545
|
+
};
|
|
2454
2546
|
for (const t of tokens) {
|
|
2455
2547
|
// Enumerate ALL defs of a bare token via the direct index, not FTS — a
|
|
2456
2548
|
// 50+-overload name (tokio `poll`) ranks the wanted def (`Harness::poll`)
|
|
@@ -2459,9 +2551,17 @@ class ToolHandler {
|
|
|
2459
2551
|
// codegraph_node's findSymbolMatches.) Qualified tokens keep findAllSymbols.
|
|
2460
2552
|
const isQual = /[.\/]|::/.test(t);
|
|
2461
2553
|
const raw = isQual ? this.findAllSymbols(cg, t).nodes : cg.getNodesByName(t);
|
|
2462
|
-
|
|
2554
|
+
let cands = raw
|
|
2463
2555
|
.filter((n) => CALLABLE.has(n.kind) && !isTestPath(n.filePath))
|
|
2464
2556
|
.sort((a, b) => (bodyLines(b) > 1 ? 1 : 0) - (bodyLines(a) > 1 ? 1 : 0) || bodyLines(b) - bodyLines(a));
|
|
2557
|
+
// Bare lowercase words only seed defs their query-siblings corroborate
|
|
2558
|
+
// (see the NL-stopword guard above). Filtering CANDS (not picks) applies
|
|
2559
|
+
// the guard uniformly to both branches below, including the >3-def
|
|
2560
|
+
// single-pick fallback — an uncorroborated bare `run` must not tier its
|
|
2561
|
+
// most-substantive namesake any more than a 1-def `check` may.
|
|
2562
|
+
if (!isPreciseToken(t)) {
|
|
2563
|
+
cands = cands.filter((n) => coNamedInFile(t, n.filePath));
|
|
2564
|
+
}
|
|
2465
2565
|
// A specific name (<=3 defs) injects all its defs. An overloaded name
|
|
2466
2566
|
// (`validate` = 10, `request` = 44) would flood the subgraph, so inject
|
|
2467
2567
|
// only: the overloads whose file/class the query ALSO names (the agent
|
|
@@ -2469,12 +2569,23 @@ class ToolHandler {
|
|
|
2469
2569
|
// capped; else fall back to the single most-substantive def. This is the
|
|
2470
2570
|
// explore-side mirror of codegraph_node's overload disambiguation.
|
|
2471
2571
|
let picks;
|
|
2572
|
+
let tierPicks; // subset that earns the named-first tier (#1064)
|
|
2472
2573
|
if (cands.length <= 3) {
|
|
2473
2574
|
picks = cands;
|
|
2575
|
+
// Centrality de-noise: tier the most-substantive def PLUS any co-named
|
|
2576
|
+
// def of comparable centrality (a real overload/wrapper — excalidraw's
|
|
2577
|
+
// `mutateElement` lives in mutateElement.ts, App.tsx AND Scene.ts, all
|
|
2578
|
+
// within ~2x callers). EXCLUDE a vastly-less-central namesake (Go's
|
|
2579
|
+
// `NewClient`: real client 492 callers vs xds-pool 11, test-fake 3 →
|
|
2580
|
+
// ratio <0.025) so it doesn't fill the tier and crowd out the answer.
|
|
2581
|
+
const counts = new Map(cands.map((c) => [c.id, callerCount(c)]));
|
|
2582
|
+
const maxCallers = Math.max(1, ...counts.values());
|
|
2583
|
+
tierPicks = cands.filter((c, i) => i === 0 || (counts.get(c.id) ?? 0) >= maxCallers * 0.25);
|
|
2474
2584
|
}
|
|
2475
2585
|
else {
|
|
2476
2586
|
const ctx = cands.filter(inNamedContext);
|
|
2477
2587
|
picks = ctx.length > 0 ? ctx.slice(0, 4) : cands.slice(0, 1);
|
|
2588
|
+
tierPicks = picks; // corroborated overloads (or the single fallback) all earn it
|
|
2478
2589
|
}
|
|
2479
2590
|
for (const n of picks) {
|
|
2480
2591
|
if (!subgraph.nodes.has(n.id))
|
|
@@ -2486,6 +2597,8 @@ class ToolHandler {
|
|
|
2486
2597
|
// so a named symbol FTS already gathered never sorted to the top.)
|
|
2487
2598
|
namedSeedIds.add(n.id);
|
|
2488
2599
|
}
|
|
2600
|
+
for (const n of tierPicks)
|
|
2601
|
+
tierSeedIds.add(n.id);
|
|
2489
2602
|
}
|
|
2490
2603
|
}
|
|
2491
2604
|
// Step 2: Group nodes by file, score by relevance
|
|
@@ -2499,6 +2612,46 @@ class ToolHandler {
|
|
|
2499
2612
|
if (entryNodeIds.has(edge.target))
|
|
2500
2613
|
connectedToEntry.add(edge.source);
|
|
2501
2614
|
}
|
|
2615
|
+
// CHANGE SURFACE (#1064): a named method's signature types — its parameter
|
|
2616
|
+
// and return types — are part of what you'd edit to "add a parameter to X",
|
|
2617
|
+
// yet they can be lexically dissimilar to the query ("add a parameter to
|
|
2618
|
+
// NewClient" shares no words with `dialoptions.go`, which defines NewClient's
|
|
2619
|
+
// `DialOption`) and sit a hop away. COLLECT them here from each named-seed
|
|
2620
|
+
// callable's outgoing signature edges (full graph — the type is often not in
|
|
2621
|
+
// the subgraph); the decision to surface one is DEFERRED to the buried-rescue
|
|
2622
|
+
// pass below, which fires only when the type's file would otherwise be
|
|
2623
|
+
// dropped — so a well-connected type (excalidraw's element types, Alamofire's
|
|
2624
|
+
// `DataRequest` on a flow query) is left to rank on its own and never
|
|
2625
|
+
// displaces a flow-central file. Bounded: only the few named seeds, only the
|
|
2626
|
+
// types in their signatures.
|
|
2627
|
+
const CALLABLE_KINDS = new Set(['method', 'function', 'component', 'constructor']);
|
|
2628
|
+
const TYPE_KINDS = new Set(['class', 'struct', 'interface', 'trait', 'protocol', 'enum', 'type_alias']);
|
|
2629
|
+
const SIG_EDGE = new Set(['references', 'type_of', 'returns']);
|
|
2630
|
+
const changeSurfaceCandidates = [];
|
|
2631
|
+
const seenChangeSurface = new Set();
|
|
2632
|
+
for (const seedId of tierSeedIds) {
|
|
2633
|
+
const seedNode = subgraph.nodes.get(seedId);
|
|
2634
|
+
if (!seedNode || !CALLABLE_KINDS.has(seedNode.kind))
|
|
2635
|
+
continue;
|
|
2636
|
+
let outs = [];
|
|
2637
|
+
try {
|
|
2638
|
+
outs = cg.getOutgoingEdges(seedId);
|
|
2639
|
+
}
|
|
2640
|
+
catch {
|
|
2641
|
+
continue;
|
|
2642
|
+
}
|
|
2643
|
+
for (const e of outs) {
|
|
2644
|
+
if (!SIG_EDGE.has(e.kind))
|
|
2645
|
+
continue;
|
|
2646
|
+
const tgt = cg.getNode(e.target);
|
|
2647
|
+
if (!tgt || !TYPE_KINDS.has(tgt.kind) || namedSeedIds.has(tgt.id))
|
|
2648
|
+
continue;
|
|
2649
|
+
if (seenChangeSurface.has(tgt.id))
|
|
2650
|
+
continue;
|
|
2651
|
+
seenChangeSurface.add(tgt.id);
|
|
2652
|
+
changeSurfaceCandidates.push(tgt);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2502
2655
|
for (const node of subgraph.nodes.values()) {
|
|
2503
2656
|
// Skip import/export nodes — they add noise without information
|
|
2504
2657
|
if (node.kind === 'import' || node.kind === 'export')
|
|
@@ -2618,6 +2771,36 @@ class ToolHandler {
|
|
|
2618
2771
|
if (n)
|
|
2619
2772
|
entryFiles.add(n.filePath);
|
|
2620
2773
|
}
|
|
2774
|
+
// Buried-rescue pass (#1064): surface a named method's signature type ONLY
|
|
2775
|
+
// when its file is genuinely buried — near-zero graph mass AND not lexically
|
|
2776
|
+
// matched. That is the invisible case (grpc's `DialOption` → `dialoptions.go`,
|
|
2777
|
+
// g≈0, 0 term hits): reachable but ranked nowhere, so the agent greps. A
|
|
2778
|
+
// well-connected type file (excalidraw element types, Alamofire `DataRequest`)
|
|
2779
|
+
// is NOT buried and is left alone — rescuing it would displace a flow-central
|
|
2780
|
+
// file (App.tsx, Validation.swift). Buried is judged on the PRE-rescue graph,
|
|
2781
|
+
// so injecting the type below can't make it look connected. A rescued file is
|
|
2782
|
+
// injected (so it renders), force-kept (gate + relevantFiles), and tiered.
|
|
2783
|
+
const changeSurfaceFiles = new Set();
|
|
2784
|
+
for (const t of changeSurfaceCandidates) {
|
|
2785
|
+
const fp = t.filePath;
|
|
2786
|
+
const buried = (fileGraphScore.get(fp) ?? 0) < maxGraph * 0.06
|
|
2787
|
+
&& (fileTermHits.get(fp) ?? 0) < 2;
|
|
2788
|
+
if (!buried)
|
|
2789
|
+
continue;
|
|
2790
|
+
changeSurfaceFiles.add(fp);
|
|
2791
|
+
if (!subgraph.nodes.has(t.id))
|
|
2792
|
+
subgraph.nodes.set(t.id, t);
|
|
2793
|
+
let group = fileGroups.get(fp);
|
|
2794
|
+
if (!group) {
|
|
2795
|
+
group = { nodes: [], score: 0 };
|
|
2796
|
+
fileGroups.set(fp, group);
|
|
2797
|
+
}
|
|
2798
|
+
if (!group.nodes.some((n) => n.id === t.id))
|
|
2799
|
+
group.nodes.push(t);
|
|
2800
|
+
group.score = Math.max(group.score, 45);
|
|
2801
|
+
if (!relevantFiles.some(([f]) => f === fp))
|
|
2802
|
+
relevantFiles.push([fp, group]);
|
|
2803
|
+
}
|
|
2621
2804
|
// Relevance gate (so the generous budget is a CEILING, not a target): keep a
|
|
2622
2805
|
// file only if it is STRUCTURALLY relevant by ANY of:
|
|
2623
2806
|
// - graph score within a fraction of the top (it's on/near the flow), OR
|
|
@@ -2634,6 +2817,7 @@ class ToolHandler {
|
|
|
2634
2817
|
const gated = relevantFiles.filter(([fp]) => (fileGraphScore.get(fp) ?? 0) >= maxGraph * 0.06
|
|
2635
2818
|
|| centralFiles.has(fp)
|
|
2636
2819
|
|| entryFiles.has(fp)
|
|
2820
|
+
|| changeSurfaceFiles.has(fp)
|
|
2637
2821
|
|| (fileTermHits.get(fp) ?? 0) >= 2);
|
|
2638
2822
|
if (gated.length >= 2)
|
|
2639
2823
|
relevantFiles = gated;
|
|
@@ -2648,11 +2832,16 @@ class ToolHandler {
|
|
|
2648
2832
|
// in other files (`Validation.swift`), falls outside the budget, and the
|
|
2649
2833
|
// agent Reads it. The named file is the answer — rank it at the top.
|
|
2650
2834
|
const namedSeedFiles = new Set();
|
|
2651
|
-
for (const id of
|
|
2835
|
+
for (const id of tierSeedIds) {
|
|
2652
2836
|
const n = subgraph.nodes.get(id);
|
|
2653
2837
|
if (n)
|
|
2654
2838
|
namedSeedFiles.add(n.filePath);
|
|
2655
2839
|
}
|
|
2840
|
+
// A rescued change-surface file (only the genuinely-buried ones — see the
|
|
2841
|
+
// buried-rescue pass) is the lexically-dissimilar answer; give it the named
|
|
2842
|
+
// tier so it isn't buried under files that merely share surface words (#1064).
|
|
2843
|
+
for (const fp of changeSurfaceFiles)
|
|
2844
|
+
namedSeedFiles.add(fp);
|
|
2656
2845
|
// Multi-term corroboration tier: a file that is BOTH (a) an entry/central file
|
|
2657
2846
|
// (a search root, named seed, or graph-central hub — i.e. structurally part of
|
|
2658
2847
|
// the answer) AND (b) matched by ≥2 DISTINCT query terms must not be buried by
|
|
@@ -2717,9 +2906,16 @@ class ToolHandler {
|
|
|
2717
2906
|
const lines = [
|
|
2718
2907
|
`**Exploration: ${query}**`,
|
|
2719
2908
|
'',
|
|
2720
|
-
|
|
2909
|
+
// Curated summary — filled in after the source loop (see below). We do NOT
|
|
2910
|
+
// report `subgraph.nodes.size` / `fileGroups.size` here: that's the raw
|
|
2911
|
+
// candidate gather, which a broad natural-language query inflates wildly
|
|
2912
|
+
// (260 symbols / 124 files on a 636-file repo) even though only a handful
|
|
2913
|
+
// render. Reporting the pool read as "260 results to wade through" when the
|
|
2914
|
+
// real, correctly-ranked answer is the few files below (#1046).
|
|
2915
|
+
'',
|
|
2721
2916
|
'',
|
|
2722
2917
|
];
|
|
2918
|
+
const summaryLineIdx = 2;
|
|
2723
2919
|
// Blast radius (always-on, compact): for the entry symbols, who depends on
|
|
2724
2920
|
// them + which tests cover them — locations only, no source — so the agent
|
|
2725
2921
|
// knows what to update/verify before editing without a separate call.
|
|
@@ -2821,6 +3017,9 @@ class ToolHandler {
|
|
|
2821
3017
|
lines.push('');
|
|
2822
3018
|
let totalChars = lines.join('\n').length;
|
|
2823
3019
|
let filesIncluded = 0;
|
|
3020
|
+
// Paths we actually render source for below. Drives the curated header count
|
|
3021
|
+
// (#1046) — it must reflect what we show, not the raw candidate gather.
|
|
3022
|
+
const renderedFilePaths = [];
|
|
2824
3023
|
let anyFileTrimmed = false;
|
|
2825
3024
|
for (const [filePath, group] of sortedFiles) {
|
|
2826
3025
|
if (filesIncluded >= maxFiles)
|
|
@@ -2972,6 +3171,7 @@ class ToolHandler {
|
|
|
2972
3171
|
: 'skeleton (signatures only — codegraph_explore a name for its full body; do NOT Read)';
|
|
2973
3172
|
lines.push(fileSectionHeader(filePath, `${names} · ${tag}`), '', '```' + lang, skel.join('\n'), '```', '');
|
|
2974
3173
|
totalChars += skel.join('\n').length + 120;
|
|
3174
|
+
renderedFilePaths.push(filePath);
|
|
2975
3175
|
filesIncluded++;
|
|
2976
3176
|
continue;
|
|
2977
3177
|
}
|
|
@@ -3018,6 +3218,7 @@ class ToolHandler {
|
|
|
3018
3218
|
}
|
|
3019
3219
|
lines.push(wholeHeader, '', '```' + lang, wholeSection, '```', '');
|
|
3020
3220
|
totalChars += wholeSection.length + 200;
|
|
3221
|
+
renderedFilePaths.push(filePath);
|
|
3021
3222
|
filesIncluded++;
|
|
3022
3223
|
continue;
|
|
3023
3224
|
}
|
|
@@ -3306,8 +3507,14 @@ class ToolHandler {
|
|
|
3306
3507
|
lines.push('```');
|
|
3307
3508
|
lines.push('');
|
|
3308
3509
|
totalChars += fileSection.length + 200;
|
|
3510
|
+
renderedFilePaths.push(filePath);
|
|
3309
3511
|
filesIncluded++;
|
|
3310
3512
|
}
|
|
3513
|
+
// The curated header count is computed from the files that SURVIVE the final
|
|
3514
|
+
// truncation (see end of method) — `filesIncluded` can over-count when the
|
|
3515
|
+
// hard ceiling drops trailing sections — so leave a sentinel here and fill it
|
|
3516
|
+
// in once the output is final.
|
|
3517
|
+
lines[summaryLineIdx] = SUMMARY_SENTINEL;
|
|
3311
3518
|
// Add remaining files as references (from both relevant and peripheral files).
|
|
3312
3519
|
// Small projects (per budget) skip this — the relevant story already fits
|
|
3313
3520
|
// in the source section, and a trailing pointer list is pure overhead.
|
|
@@ -3364,6 +3571,7 @@ class ToolHandler {
|
|
|
3364
3571
|
// externalize territory.
|
|
3365
3572
|
const output = flow.text + lines.join('\n');
|
|
3366
3573
|
const hardCeiling = Math.min(Math.round(budget.maxOutputChars * 1.5), 25000);
|
|
3574
|
+
let finalText;
|
|
3367
3575
|
if (output.length > hardCeiling) {
|
|
3368
3576
|
// Cut at a FILE-SECTION boundary (the last ``**` `` file header before the
|
|
3369
3577
|
// ceiling) so we drop whole trailing file-sections rather than slicing
|
|
@@ -3374,9 +3582,30 @@ class ToolHandler {
|
|
|
3374
3582
|
const lastSection = cut.lastIndexOf('\n' + FILE_SECTION_PREFIX);
|
|
3375
3583
|
const boundary = lastSection > hardCeiling * 0.5 ? lastSection : cut.lastIndexOf('\n');
|
|
3376
3584
|
const safe = boundary > 0 ? cut.slice(0, boundary) : cut;
|
|
3377
|
-
|
|
3585
|
+
finalText = safe + '\n\n... (output truncated to budget; the source above is complete and verbatim — treat it as already Read. For any area not covered, run another codegraph_explore with the specific names — do NOT Read these files.)';
|
|
3378
3586
|
}
|
|
3379
|
-
|
|
3587
|
+
else {
|
|
3588
|
+
finalText = output;
|
|
3589
|
+
}
|
|
3590
|
+
// Curated header (#1046): substitute the sentinel with the count of files
|
|
3591
|
+
// whose source SURVIVES in the final text — not `subgraph`/`fileGroups` (the
|
|
3592
|
+
// raw gather a broad query inflates) and not `filesIncluded` (which can
|
|
3593
|
+
// over-count when the ceiling above drops trailing sections). A file counts
|
|
3594
|
+
// only if its section header is still present; its relevant (non-import)
|
|
3595
|
+
// symbols are summed for N. Files we couldn't fit are still named under "Not
|
|
3596
|
+
// shown above" + the budget note, so nothing is silently dropped.
|
|
3597
|
+
const survivors = renderedFilePaths.filter((fp) => finalText.includes(`${FILE_SECTION_PREFIX}${fp}\``));
|
|
3598
|
+
const shownSymbols = survivors.reduce((sum, fp) => {
|
|
3599
|
+
const g = fileGroups.get(fp);
|
|
3600
|
+
if (!g)
|
|
3601
|
+
return sum;
|
|
3602
|
+
return sum + new Set(g.nodes.filter((n) => n.kind !== 'import' && n.kind !== 'export').map((n) => n.id)).size;
|
|
3603
|
+
}, 0);
|
|
3604
|
+
const summaryLine = survivors.length > 0
|
|
3605
|
+
? `Found ${shownSymbols} symbol${shownSymbols === 1 ? '' : 's'} across ${survivors.length} file${survivors.length === 1 ? '' : 's'}.`
|
|
3606
|
+
: `Found ${subgraph.nodes.size} symbol${subgraph.nodes.size === 1 ? '' : 's'} across ${fileGroups.size} file${fileGroups.size === 1 ? '' : 's'}.`;
|
|
3607
|
+
finalText = finalText.replace(SUMMARY_SENTINEL, summaryLine);
|
|
3608
|
+
return this.textResult(finalText);
|
|
3380
3609
|
}
|
|
3381
3610
|
/**
|
|
3382
3611
|
* Handle codegraph_node
|
|
@@ -3726,6 +3955,23 @@ class ToolHandler {
|
|
|
3726
3955
|
lines.push(`**Journal mode:** ⚠ ${journalMode || 'unknown'} — WAL not active, so reads ` +
|
|
3727
3956
|
`can block on a concurrent write (WAL appears unsupported on this filesystem)`);
|
|
3728
3957
|
}
|
|
3958
|
+
// A newer release exists (#1243) — status is where users and agents look
|
|
3959
|
+
// when something seems off, so surface the drift here too. Cheap memoized
|
|
3960
|
+
// cache read; absent entirely when up to date or opted out.
|
|
3961
|
+
const updateNotice = (0, update_check_1.getUpdateNotice)();
|
|
3962
|
+
if (updateNotice) {
|
|
3963
|
+
lines.push(`**Update available:** ${updateNotice}`);
|
|
3964
|
+
}
|
|
3965
|
+
// Non-zero at rest means a resolution pass was interrupted mid-run, so
|
|
3966
|
+
// some files' call/impact edges are missing until the next sync sweeps
|
|
3967
|
+
// the leftovers (#1187). Surface it — an agent trusting an incomplete
|
|
3968
|
+
// blast radius is worse than one that knows to re-sync.
|
|
3969
|
+
const pendingRefs = cg.getPendingReferenceCount();
|
|
3970
|
+
if (pendingRefs > 0) {
|
|
3971
|
+
lines.push(`**Pending resolution:** ⚠ ${pendingRefs} references from an interrupted ` +
|
|
3972
|
+
`index run — some caller/impact edges are missing until the next sync ` +
|
|
3973
|
+
`(any file change triggers it, or run \`codegraph sync\`)`);
|
|
3974
|
+
}
|
|
3729
3975
|
lines.push('', '**Nodes by Kind:**');
|
|
3730
3976
|
for (const [kind, count] of Object.entries(stats.nodesByKind)) {
|
|
3731
3977
|
if (count > 0) {
|
|
@@ -4039,6 +4285,26 @@ class ToolHandler {
|
|
|
4039
4285
|
* results across all matching symbols (e.g., multiple classes with an `execute` method).
|
|
4040
4286
|
*/
|
|
4041
4287
|
findAllSymbols(cg, symbol) {
|
|
4288
|
+
// Nix option paths: the declaration is stored as `options.<path>` and
|
|
4289
|
+
// config writes carry longer/quoted tails (`<path>."git/config".text`),
|
|
4290
|
+
// so a dotted option token (`xdg.configFile`, `launchd.user.agents`) has
|
|
4291
|
+
// no exact-name node and would degrade to bare-tail FTS soup — burying
|
|
4292
|
+
// the declaration hub the nix-option-path edges hang off. Resolve the
|
|
4293
|
+
// convention directly: declaration first, then the exact write, then a
|
|
4294
|
+
// capped prefix scan of write sites. Three index hits; non-nix graphs
|
|
4295
|
+
// fall straight through.
|
|
4296
|
+
if (/^[a-z][\w'-]*(?:\.[\w'-]+)+$/.test(symbol)) {
|
|
4297
|
+
const optionHits = [
|
|
4298
|
+
...cg.getNodesByName(`options.${symbol}`),
|
|
4299
|
+
...cg.getNodesByName(symbol),
|
|
4300
|
+
...cg.getNodesByNamePrefix(`${symbol}.`, 12),
|
|
4301
|
+
].filter((n) => n.language === 'nix');
|
|
4302
|
+
if (optionHits.length > 0) {
|
|
4303
|
+
const seen = new Set();
|
|
4304
|
+
const nodes = optionHits.filter((n) => !seen.has(n.id) && !!seen.add(n.id)).slice(0, 10);
|
|
4305
|
+
return { nodes, note: '' };
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4042
4308
|
let results = cg.searchNodes(symbol, { limit: 50 });
|
|
4043
4309
|
// Mirror the fallback in `findSymbol` for qualified queries — FTS
|
|
4044
4310
|
// strips colons, so a module-qualified lookup needs a second pass
|