homegraph 1.1.2 → 1.2.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/LICENSE +21 -21
- package/README.md +268 -243
- package/dist/arkts/ohos-api-index.d.ts +15 -0
- package/dist/arkts/ohos-api-index.d.ts.map +1 -0
- package/dist/arkts/ohos-api-index.js +190 -0
- package/dist/arkts/ohos-api-index.js.map +1 -0
- package/dist/arkts/ohos-sdk-input.d.ts +36 -0
- package/dist/arkts/ohos-sdk-input.d.ts.map +1 -0
- package/dist/arkts/ohos-sdk-input.js +214 -0
- package/dist/arkts/ohos-sdk-input.js.map +1 -0
- package/dist/bin/command-supervision.d.ts +12 -0
- package/dist/bin/command-supervision.d.ts.map +1 -0
- package/dist/bin/command-supervision.js +86 -0
- package/dist/bin/command-supervision.js.map +1 -0
- package/dist/bin/homegraph.d.ts +1 -1
- package/dist/bin/homegraph.js +971 -71
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/db/index.d.ts +20 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +39 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +58 -19
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +14 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +314 -143
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +172 -152
- package/dist/directory.d.ts +32 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +88 -5
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.d.ts +2 -0
- package/dist/extraction/arkts-batch-worker.d.ts.map +1 -0
- package/dist/extraction/arkts-batch-worker.js +28 -0
- package/dist/extraction/arkts-batch-worker.js.map +1 -0
- package/dist/extraction/context.d.ts +11 -0
- package/dist/extraction/context.d.ts.map +1 -1
- package/dist/extraction/context.js +20 -0
- package/dist/extraction/context.js.map +1 -1
- package/dist/extraction/index.d.ts +16 -2
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +619 -380
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts-state-decorators.d.ts +13 -0
- package/dist/extraction/languages/arkts-state-decorators.d.ts.map +1 -0
- package/dist/extraction/languages/arkts-state-decorators.js +26 -0
- package/dist/extraction/languages/arkts-state-decorators.js.map +1 -0
- package/dist/extraction/languages/arkts-viewtree.d.ts +4 -2
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.js +21 -6
- package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +98 -2
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1290 -61
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +56 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +198 -1
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/ohos-api-consumer.d.ts +34 -0
- package/dist/extraction/languages/ohos-api-consumer.d.ts.map +1 -0
- package/dist/extraction/languages/ohos-api-consumer.js +283 -0
- package/dist/extraction/languages/ohos-api-consumer.js.map +1 -0
- package/dist/extraction/parse-pool.d.ts +126 -0
- package/dist/extraction/parse-pool.d.ts.map +1 -0
- package/dist/extraction/parse-pool.js +319 -0
- package/dist/extraction/parse-pool.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +17 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +21 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +198 -27
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +76 -17
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -4
- package/dist/index.js.map +1 -1
- package/dist/installer/instructions-template.js +9 -9
- package/dist/installer/targets/shared.d.ts +5 -6
- package/dist/installer/targets/shared.d.ts.map +1 -1
- package/dist/installer/targets/shared.js +5 -6
- package/dist/installer/targets/shared.js.map +1 -1
- package/dist/mcp/daemon-paths.d.ts +30 -3
- package/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/dist/mcp/daemon-paths.js +50 -10
- package/dist/mcp/daemon-paths.js.map +1 -1
- package/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/dist/mcp/daemon-registry.js +7 -3
- package/dist/mcp/daemon-registry.js.map +1 -1
- package/dist/mcp/daemon.d.ts +48 -0
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +196 -32
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/engine.d.ts +17 -0
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +73 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +25 -43
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/liveness-watchdog.js +16 -16
- package/dist/mcp/ppid-watchdog.d.ts +18 -0
- package/dist/mcp/ppid-watchdog.d.ts.map +1 -1
- package/dist/mcp/ppid-watchdog.js +37 -0
- package/dist/mcp/ppid-watchdog.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +25 -0
- package/dist/mcp/query-cache.d.ts.map +1 -0
- package/dist/mcp/query-cache.js +191 -0
- package/dist/mcp/query-cache.js.map +1 -0
- package/dist/mcp/query-pool.d.ts +94 -0
- package/dist/mcp/query-pool.d.ts.map +1 -0
- package/dist/mcp/query-pool.js +297 -0
- package/dist/mcp/query-pool.js.map +1 -0
- package/dist/mcp/query-worker.d.ts +24 -0
- package/dist/mcp/query-worker.d.ts.map +1 -0
- package/dist/mcp/query-worker.js +87 -0
- package/dist/mcp/query-worker.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +5 -7
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +72 -74
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +94 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +877 -71
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-config.d.ts +20 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +42 -2
- package/dist/project-config.js.map +1 -1
- package/dist/reasoning/login.js +1 -1
- package/dist/reasoning/login.js.map +1 -1
- package/dist/reasoning/reasoner.js +32 -32
- package/dist/resolution/c-fnptr-synthesizer.d.ts +0 -28
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +765 -79
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +72 -11
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +32 -0
- package/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/dist/resolution/cooperative-yield.js +42 -0
- package/dist/resolution/cooperative-yield.js.map +1 -0
- package/dist/resolution/index.d.ts +11 -2
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +72 -4
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +22 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +317 -20
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/spec/config.d.ts +39 -0
- package/dist/spec/config.d.ts.map +1 -0
- package/dist/spec/config.js +304 -0
- package/dist/spec/config.js.map +1 -0
- package/dist/spec/db/commit-node.d.ts +23 -0
- package/dist/spec/db/commit-node.d.ts.map +1 -0
- package/dist/spec/db/commit-node.js +62 -0
- package/dist/spec/db/commit-node.js.map +1 -0
- package/dist/spec/db/fragment-node.d.ts +24 -0
- package/dist/spec/db/fragment-node.d.ts.map +1 -0
- package/dist/spec/db/fragment-node.js +128 -0
- package/dist/spec/db/fragment-node.js.map +1 -0
- package/dist/spec/db/fts.d.ts +74 -0
- package/dist/spec/db/fts.d.ts.map +1 -0
- package/dist/spec/db/fts.js +324 -0
- package/dist/spec/db/fts.js.map +1 -0
- package/dist/spec/db/index.d.ts +13 -0
- package/dist/spec/db/index.d.ts.map +1 -0
- package/dist/spec/db/index.js +50 -0
- package/dist/spec/db/index.js.map +1 -0
- package/dist/spec/db/relations.d.ts +55 -0
- package/dist/spec/db/relations.d.ts.map +1 -0
- package/dist/spec/db/relations.js +158 -0
- package/dist/spec/db/relations.js.map +1 -0
- package/dist/spec/db/schema.d.ts +33 -0
- package/dist/spec/db/schema.d.ts.map +1 -0
- package/dist/spec/db/schema.js +119 -0
- package/dist/spec/db/schema.js.map +1 -0
- package/dist/spec/db/schema.sql +117 -0
- package/dist/spec/db/spec-node.d.ts +41 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -0
- package/dist/spec/db/spec-node.js +114 -0
- package/dist/spec/db/spec-node.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +13 -0
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -0
- package/dist/spec/evolve/impact-locator.js +25 -0
- package/dist/spec/evolve/impact-locator.js.map +1 -0
- package/dist/spec/evolve/llm-client.d.ts +50 -0
- package/dist/spec/evolve/llm-client.d.ts.map +1 -0
- package/dist/spec/evolve/llm-client.js +176 -0
- package/dist/spec/evolve/llm-client.js.map +1 -0
- package/dist/spec/evolve/logic-checker.d.ts +12 -0
- package/dist/spec/evolve/logic-checker.d.ts.map +1 -0
- package/dist/spec/evolve/logic-checker.js +24 -0
- package/dist/spec/evolve/logic-checker.js.map +1 -0
- package/dist/spec/evolve/pipeline.d.ts +42 -0
- package/dist/spec/evolve/pipeline.d.ts.map +1 -0
- package/dist/spec/evolve/pipeline.js +567 -0
- package/dist/spec/evolve/pipeline.js.map +1 -0
- package/dist/spec/evolve/spec-rewriter.d.ts +42 -0
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -0
- package/dist/spec/evolve/spec-rewriter.js +230 -0
- package/dist/spec/evolve/spec-rewriter.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +155 -0
- package/dist/spec/graph/queries.d.ts.map +1 -0
- package/dist/spec/graph/queries.js +440 -0
- package/dist/spec/graph/queries.js.map +1 -0
- package/dist/spec/llm/client.d.ts +29 -0
- package/dist/spec/llm/client.d.ts.map +1 -0
- package/dist/spec/llm/client.js +123 -0
- package/dist/spec/llm/client.js.map +1 -0
- package/dist/spec/llm/index.d.ts +3 -0
- package/dist/spec/llm/index.d.ts.map +1 -0
- package/dist/spec/llm/index.js +11 -0
- package/dist/spec/llm/index.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +13 -0
- package/dist/spec/llm/prompts.d.ts.map +1 -0
- package/dist/spec/llm/prompts.js +75 -0
- package/dist/spec/llm/prompts.js.map +1 -0
- package/dist/spec/mining/diff-parser.d.ts +33 -0
- package/dist/spec/mining/diff-parser.d.ts.map +1 -0
- package/dist/spec/mining/diff-parser.js +166 -0
- package/dist/spec/mining/diff-parser.js.map +1 -0
- package/dist/spec/mining/git-scanner.d.ts +103 -0
- package/dist/spec/mining/git-scanner.d.ts.map +1 -0
- package/dist/spec/mining/git-scanner.js +307 -0
- package/dist/spec/mining/git-scanner.js.map +1 -0
- package/dist/spec/mining/pipeline.d.ts +53 -0
- package/dist/spec/mining/pipeline.d.ts.map +1 -0
- package/dist/spec/mining/pipeline.js +178 -0
- package/dist/spec/mining/pipeline.js.map +1 -0
- package/dist/spec/mining/scope-resolver.d.ts +45 -0
- package/dist/spec/mining/scope-resolver.d.ts.map +1 -0
- package/dist/spec/mining/scope-resolver.js +103 -0
- package/dist/spec/mining/scope-resolver.js.map +1 -0
- package/dist/spec/mining/spec-extractor.d.ts +69 -0
- package/dist/spec/mining/spec-extractor.d.ts.map +1 -0
- package/dist/spec/mining/spec-extractor.js +369 -0
- package/dist/spec/mining/spec-extractor.js.map +1 -0
- package/dist/spec/types.d.ts +149 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +15 -0
- package/dist/spec/types.js.map +1 -0
- package/dist/spec/utils.d.ts +167 -0
- package/dist/spec/utils.d.ts.map +1 -0
- package/dist/spec/utils.js +463 -0
- package/dist/spec/utils.js.map +1 -0
- package/dist/sync/worktree.d.ts +9 -0
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +40 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.d.ts +2 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.js +19 -2
- package/dist/ui/shimmer-progress.js.map +1 -1
- package/dist/upgrade/index.js +1 -1
- package/dist/upgrade/index.js.map +1 -1
- package/package.json +58 -57
- package/scripts/add-lang/bench.sh +60 -60
- package/scripts/add-lang/check-grammar.mjs +75 -75
- package/scripts/add-lang/dump-ast.mjs +103 -103
- package/scripts/add-lang/verify-extraction.mjs +70 -70
- package/scripts/agent-eval/ab-adoption.sh +91 -91
- package/scripts/agent-eval/ab-hook.sh +86 -86
- package/scripts/agent-eval/ab-impl.sh +78 -78
- package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
- package/scripts/agent-eval/ab-sufficiency.sh +78 -78
- package/scripts/agent-eval/arms-F.sh +21 -21
- package/scripts/agent-eval/arms-matrix.sh +37 -37
- package/scripts/agent-eval/audit.sh +68 -68
- package/scripts/agent-eval/bench-readme.sh +28 -28
- package/scripts/agent-eval/bench-why-repo.sh +22 -22
- package/scripts/agent-eval/block-read-hook.sh +19 -19
- package/scripts/agent-eval/hook-settings.json +15 -15
- package/scripts/agent-eval/itrun.sh +120 -120
- package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
- package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
- package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
- package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
- package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
- package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
- package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
- package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
- package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
- package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
- package/scripts/agent-eval/offload-eval-setup.sh +24 -24
- package/scripts/agent-eval/offload-eval-styles.sh +71 -71
- package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
- package/scripts/agent-eval/offload-eval.md +76 -76
- package/scripts/agent-eval/parse-arms.mjs +116 -116
- package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
- package/scripts/agent-eval/parse-run.mjs +45 -45
- package/scripts/agent-eval/parse-session.mjs +93 -93
- package/scripts/agent-eval/probe-context.mjs +21 -21
- package/scripts/agent-eval/probe-explore.mjs +40 -40
- package/scripts/agent-eval/probe-node.mjs +20 -20
- package/scripts/agent-eval/probe-sweep.mjs +119 -119
- package/scripts/agent-eval/probe-trace.mjs +20 -20
- package/scripts/agent-eval/redirect-read-hook.sh +38 -38
- package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
- package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
- package/scripts/agent-eval/run-agent.sh +34 -34
- package/scripts/agent-eval/run-all.sh +69 -69
- package/scripts/agent-eval/run-arms.sh +56 -56
- package/scripts/agent-eval/seq-matrix.mjs +137 -137
- package/scripts/build-bundle.sh +118 -118
- package/scripts/exp_boundary_eval/README.md +247 -0
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -0
- package/scripts/exp_boundary_eval/_test_stdin.py +8 -0
- package/scripts/exp_boundary_eval/_utils.py +1116 -0
- package/scripts/exp_boundary_eval/analyze.py +1313 -0
- package/scripts/exp_boundary_eval/data/agents.json +109 -0
- package/scripts/exp_boundary_eval/data/experiments.json +140 -0
- package/scripts/exp_boundary_eval/deveco_arm.py +519 -0
- package/scripts/exp_boundary_eval/run_all.py +378 -0
- package/scripts/exp_boundary_eval/run_one.py +165 -0
- package/scripts/exp_boundary_eval/run_session.py +158 -0
- package/scripts/exp_boundary_eval/setup.py +120 -0
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -0
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -0
- package/scripts/exp_boundary_eval/win_node_launcher.py +24 -0
- package/scripts/extract-release-notes.mjs +130 -130
- package/scripts/local-install.sh +41 -41
- package/scripts/npm-sdk.js +75 -75
- package/scripts/npm-shim.js +268 -246
- package/scripts/ohos-sdk-publish.mjs +133 -0
- package/scripts/pack-npm.sh +119 -119
- package/scripts/prepare-release.mjs +270 -270
- package/scripts/qa_eval/README.md +407 -404
- package/scripts/qa_eval/_test_deveco_probe.py +41 -41
- package/scripts/qa_eval/agent_runner.py +526 -526
- package/scripts/qa_eval/data/.gitignore +4 -4
- package/scripts/qa_eval/data/test-set.jsonl +2 -22
- package/scripts/qa_eval/eval_metrics.py +274 -233
- package/scripts/qa_eval/external_agent.py +976 -671
- package/scripts/qa_eval/llm_config.py +92 -92
- package/scripts/qa_eval/memory_monitor.py +132 -132
- package/scripts/qa_eval/my_answer_accuracy.py +187 -187
- package/scripts/qa_eval/requirements.txt +2 -2
- package/scripts/qa_eval/run_pipeline.py +804 -711
- package/scripts/qa_eval/stats_efficiency.py +279 -279
- package/scripts/qa_eval/stats_scores.py +207 -207
package/dist/db/queries.js
CHANGED
|
@@ -4,12 +4,48 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Prepared statements for CRUD operations on the knowledge graph.
|
|
6
6
|
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
7
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
41
|
exports.QueryBuilder = void 0;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
9
44
|
const utils_1 = require("../utils");
|
|
10
45
|
const query_utils_1 = require("../search/query-utils");
|
|
11
46
|
const query_parser_1 = require("../search/query-parser");
|
|
12
47
|
const generated_detection_1 = require("../extraction/generated-detection");
|
|
48
|
+
const arkts_1 = require("../extraction/languages/arkts");
|
|
13
49
|
/**
|
|
14
50
|
* Path-only heuristic for files that should not be candidates for
|
|
15
51
|
* "dominant file" detection: test/spec files and tool-generated files.
|
|
@@ -103,11 +139,49 @@ class QueryBuilder {
|
|
|
103
139
|
// Node cache for frequently accessed nodes (LRU-style, max 1000 entries)
|
|
104
140
|
nodeCache = new Map();
|
|
105
141
|
maxCacheSize = 1000;
|
|
142
|
+
/** Attached prebuilt OHOS API db (see arkts.ts). */
|
|
143
|
+
ohosApiDbPath = null;
|
|
106
144
|
// Prepared statements (lazily initialized)
|
|
107
145
|
stmts = {};
|
|
108
146
|
constructor(db) {
|
|
109
147
|
this.db = db;
|
|
110
148
|
}
|
|
149
|
+
/** Attach a versioned OHOS API db for federated symbol lookup. */
|
|
150
|
+
attachOhosApiDb(dbPath) {
|
|
151
|
+
if (dbPath === this.ohosApiDbPath)
|
|
152
|
+
return;
|
|
153
|
+
if (this.ohosApiDbPath) {
|
|
154
|
+
try {
|
|
155
|
+
this.db.exec('DETACH DATABASE ohos_api');
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
/* already detached */
|
|
159
|
+
}
|
|
160
|
+
this.ohosApiDbPath = null;
|
|
161
|
+
}
|
|
162
|
+
if (!dbPath)
|
|
163
|
+
return;
|
|
164
|
+
const resolved = path.resolve(dbPath);
|
|
165
|
+
if (!fs.existsSync(resolved)) {
|
|
166
|
+
throw new Error(`OHOS API db not found: ${resolved}`);
|
|
167
|
+
}
|
|
168
|
+
const escaped = resolved.replace(/'/g, "''");
|
|
169
|
+
this.db.exec(`ATTACH DATABASE '${escaped}' AS ohos_api`);
|
|
170
|
+
this.ohosApiDbPath = resolved;
|
|
171
|
+
this.stmts = {};
|
|
172
|
+
this.nodeCache.clear();
|
|
173
|
+
}
|
|
174
|
+
getOhosApiDbPath() {
|
|
175
|
+
return this.ohosApiDbPath;
|
|
176
|
+
}
|
|
177
|
+
hasOhosApiAttached() {
|
|
178
|
+
return this.ohosApiDbPath != null;
|
|
179
|
+
}
|
|
180
|
+
mapOhosApiNodeRow(row) {
|
|
181
|
+
const node = rowToNode(row);
|
|
182
|
+
node.filePath = (0, arkts_1.markOhosApiFilePath)(node.filePath);
|
|
183
|
+
return node;
|
|
184
|
+
}
|
|
111
185
|
/** Set the normalized project-name tokens used to down-weight non-discriminative
|
|
112
186
|
* query words in path scoring (#720). Called once when the project opens. */
|
|
113
187
|
setProjectNameTokens(tokens) {
|
|
@@ -125,20 +199,20 @@ class QueryBuilder {
|
|
|
125
199
|
*/
|
|
126
200
|
insertNode(node) {
|
|
127
201
|
if (!this.stmts.insertNode) {
|
|
128
|
-
this.stmts.insertNode = this.db.prepare(`
|
|
129
|
-
INSERT OR REPLACE INTO nodes (
|
|
130
|
-
id, kind, name, qualified_name, file_path, language,
|
|
131
|
-
start_line, end_line, start_column, end_column,
|
|
132
|
-
docstring, signature, visibility,
|
|
133
|
-
is_exported, is_async, is_static, is_abstract,
|
|
134
|
-
decorators, type_parameters, return_type, updated_at
|
|
135
|
-
) VALUES (
|
|
136
|
-
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
137
|
-
@startLine, @endLine, @startColumn, @endColumn,
|
|
138
|
-
@docstring, @signature, @visibility,
|
|
139
|
-
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
140
|
-
@decorators, @typeParameters, @returnType, @updatedAt
|
|
141
|
-
)
|
|
202
|
+
this.stmts.insertNode = this.db.prepare(`
|
|
203
|
+
INSERT OR REPLACE INTO nodes (
|
|
204
|
+
id, kind, name, qualified_name, file_path, language,
|
|
205
|
+
start_line, end_line, start_column, end_column,
|
|
206
|
+
docstring, signature, visibility,
|
|
207
|
+
is_exported, is_async, is_static, is_abstract,
|
|
208
|
+
decorators, type_parameters, return_type, updated_at
|
|
209
|
+
) VALUES (
|
|
210
|
+
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
211
|
+
@startLine, @endLine, @startColumn, @endColumn,
|
|
212
|
+
@docstring, @signature, @visibility,
|
|
213
|
+
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
214
|
+
@decorators, @typeParameters, @returnType, @updatedAt
|
|
215
|
+
)
|
|
142
216
|
`);
|
|
143
217
|
}
|
|
144
218
|
// Validate required fields to prevent SQLite bind errors
|
|
@@ -196,29 +270,29 @@ class QueryBuilder {
|
|
|
196
270
|
*/
|
|
197
271
|
updateNode(node) {
|
|
198
272
|
if (!this.stmts.updateNode) {
|
|
199
|
-
this.stmts.updateNode = this.db.prepare(`
|
|
200
|
-
UPDATE nodes SET
|
|
201
|
-
kind = @kind,
|
|
202
|
-
name = @name,
|
|
203
|
-
qualified_name = @qualifiedName,
|
|
204
|
-
file_path = @filePath,
|
|
205
|
-
language = @language,
|
|
206
|
-
start_line = @startLine,
|
|
207
|
-
end_line = @endLine,
|
|
208
|
-
start_column = @startColumn,
|
|
209
|
-
end_column = @endColumn,
|
|
210
|
-
docstring = @docstring,
|
|
211
|
-
signature = @signature,
|
|
212
|
-
visibility = @visibility,
|
|
213
|
-
is_exported = @isExported,
|
|
214
|
-
is_async = @isAsync,
|
|
215
|
-
is_static = @isStatic,
|
|
216
|
-
is_abstract = @isAbstract,
|
|
217
|
-
decorators = @decorators,
|
|
218
|
-
type_parameters = @typeParameters,
|
|
219
|
-
return_type = @returnType,
|
|
220
|
-
updated_at = @updatedAt
|
|
221
|
-
WHERE id = @id
|
|
273
|
+
this.stmts.updateNode = this.db.prepare(`
|
|
274
|
+
UPDATE nodes SET
|
|
275
|
+
kind = @kind,
|
|
276
|
+
name = @name,
|
|
277
|
+
qualified_name = @qualifiedName,
|
|
278
|
+
file_path = @filePath,
|
|
279
|
+
language = @language,
|
|
280
|
+
start_line = @startLine,
|
|
281
|
+
end_line = @endLine,
|
|
282
|
+
start_column = @startColumn,
|
|
283
|
+
end_column = @endColumn,
|
|
284
|
+
docstring = @docstring,
|
|
285
|
+
signature = @signature,
|
|
286
|
+
visibility = @visibility,
|
|
287
|
+
is_exported = @isExported,
|
|
288
|
+
is_async = @isAsync,
|
|
289
|
+
is_static = @isStatic,
|
|
290
|
+
is_abstract = @isAbstract,
|
|
291
|
+
decorators = @decorators,
|
|
292
|
+
type_parameters = @typeParameters,
|
|
293
|
+
return_type = @returnType,
|
|
294
|
+
updated_at = @updatedAt
|
|
295
|
+
WHERE id = @id
|
|
222
296
|
`);
|
|
223
297
|
}
|
|
224
298
|
// Invalidate cache before update
|
|
@@ -426,15 +500,15 @@ class QueryBuilder {
|
|
|
426
500
|
// protobuf stub) outranks the real `server/etcdserver/server.go`
|
|
427
501
|
// (470 edges) by 4×, and the boost would push the agent toward
|
|
428
502
|
// generated code.
|
|
429
|
-
this.stmts.getDominantFile = this.db.prepare(`
|
|
430
|
-
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
431
|
-
FROM edges e
|
|
432
|
-
JOIN nodes n ON e.source = n.id
|
|
433
|
-
JOIN nodes m ON e.target = m.id
|
|
434
|
-
WHERE n.file_path = m.file_path
|
|
435
|
-
GROUP BY n.file_path
|
|
436
|
-
ORDER BY edge_count DESC
|
|
437
|
-
LIMIT 20
|
|
503
|
+
this.stmts.getDominantFile = this.db.prepare(`
|
|
504
|
+
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
505
|
+
FROM edges e
|
|
506
|
+
JOIN nodes n ON e.source = n.id
|
|
507
|
+
JOIN nodes m ON e.target = m.id
|
|
508
|
+
WHERE n.file_path = m.file_path
|
|
509
|
+
GROUP BY n.file_path
|
|
510
|
+
ORDER BY edge_count DESC
|
|
511
|
+
LIMIT 20
|
|
438
512
|
`);
|
|
439
513
|
}
|
|
440
514
|
const rows = this.stmts.getDominantFile.all();
|
|
@@ -461,13 +535,13 @@ class QueryBuilder {
|
|
|
461
535
|
*/
|
|
462
536
|
getTopRouteFile() {
|
|
463
537
|
if (!this.stmts.getTopRouteFile) {
|
|
464
|
-
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
465
|
-
SELECT file_path, COUNT(*) AS cnt
|
|
466
|
-
FROM nodes
|
|
467
|
-
WHERE kind = 'route'
|
|
468
|
-
GROUP BY file_path
|
|
469
|
-
ORDER BY cnt DESC
|
|
470
|
-
LIMIT 20
|
|
538
|
+
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
539
|
+
SELECT file_path, COUNT(*) AS cnt
|
|
540
|
+
FROM nodes
|
|
541
|
+
WHERE kind = 'route'
|
|
542
|
+
GROUP BY file_path
|
|
543
|
+
ORDER BY cnt DESC
|
|
544
|
+
LIMIT 20
|
|
471
545
|
`);
|
|
472
546
|
}
|
|
473
547
|
const rows = this.stmts.getTopRouteFile.all();
|
|
@@ -498,21 +572,21 @@ class QueryBuilder {
|
|
|
498
572
|
// Edge kind varies across framework resolvers: Spring/Rails/
|
|
499
573
|
// Laravel/Drupal emit `references`, Express emits `calls`. Accept
|
|
500
574
|
// both — the semantic is the same (route → its handler).
|
|
501
|
-
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
502
|
-
SELECT
|
|
503
|
-
r.name AS url,
|
|
504
|
-
h.name AS handler,
|
|
505
|
-
h.file_path AS handler_file,
|
|
506
|
-
h.start_line AS handler_line,
|
|
507
|
-
h.kind AS handler_kind
|
|
508
|
-
FROM nodes r
|
|
509
|
-
JOIN edges e ON e.source = r.id
|
|
510
|
-
JOIN nodes h ON e.target = h.id
|
|
511
|
-
WHERE r.kind = 'route'
|
|
512
|
-
AND e.kind IN ('references', 'calls')
|
|
513
|
-
AND h.kind IN ('function', 'method', 'class')
|
|
514
|
-
ORDER BY r.file_path, r.start_line
|
|
515
|
-
LIMIT ?
|
|
575
|
+
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
576
|
+
SELECT
|
|
577
|
+
r.name AS url,
|
|
578
|
+
h.name AS handler,
|
|
579
|
+
h.file_path AS handler_file,
|
|
580
|
+
h.start_line AS handler_line,
|
|
581
|
+
h.kind AS handler_kind
|
|
582
|
+
FROM nodes r
|
|
583
|
+
JOIN edges e ON e.source = r.id
|
|
584
|
+
JOIN nodes h ON e.target = h.id
|
|
585
|
+
WHERE r.kind = 'route'
|
|
586
|
+
AND e.kind IN ('references', 'calls')
|
|
587
|
+
AND h.kind IN ('function', 'method', 'class')
|
|
588
|
+
ORDER BY r.file_path, r.start_line
|
|
589
|
+
LIMIT ?
|
|
516
590
|
`);
|
|
517
591
|
}
|
|
518
592
|
const rows = this.stmts.getRoutingManifest.all(limit);
|
|
@@ -586,7 +660,15 @@ class QueryBuilder {
|
|
|
586
660
|
this.stmts.getNodesByName = this.db.prepare('SELECT * FROM nodes WHERE name = ?');
|
|
587
661
|
}
|
|
588
662
|
const rows = this.stmts.getNodesByName.all(name);
|
|
589
|
-
|
|
663
|
+
const main = rows.map(rowToNode);
|
|
664
|
+
if (!this.hasOhosApiAttached())
|
|
665
|
+
return main;
|
|
666
|
+
const apiRows = this.db
|
|
667
|
+
.prepare('SELECT * FROM ohos_api.nodes WHERE name = ?')
|
|
668
|
+
.all(name);
|
|
669
|
+
const seen = new Set(main.map((n) => n.id));
|
|
670
|
+
const api = apiRows.map((r) => this.mapOhosApiNodeRow(r)).filter((n) => !seen.has(n.id));
|
|
671
|
+
return [...main, ...api];
|
|
590
672
|
}
|
|
591
673
|
/**
|
|
592
674
|
* Get nodes by exact qualified name match (uses idx_nodes_qualified_name index)
|
|
@@ -722,8 +804,44 @@ class QueryBuilder {
|
|
|
722
804
|
return lowered.some((n) => nm.includes(n));
|
|
723
805
|
});
|
|
724
806
|
}
|
|
807
|
+
if (this.hasOhosApiAttached() && text.length >= 2) {
|
|
808
|
+
results = this.mergeOhosApiTextSearch(text, { kinds, languages, limit }, results);
|
|
809
|
+
}
|
|
725
810
|
return results;
|
|
726
811
|
}
|
|
812
|
+
mergeOhosApiTextSearch(text, options, existing) {
|
|
813
|
+
const { kinds, languages, limit = 100 } = options;
|
|
814
|
+
const seen = new Set(existing.map((r) => r.node.id));
|
|
815
|
+
const merged = [...existing];
|
|
816
|
+
const apiLimit = Math.min(20, Math.max(5, Math.floor(limit / 4)));
|
|
817
|
+
let sql = `
|
|
818
|
+
SELECT nodes.*, 0.9 as score
|
|
819
|
+
FROM ohos_api.nodes
|
|
820
|
+
WHERE (name LIKE ? OR qualified_name LIKE ?)
|
|
821
|
+
`;
|
|
822
|
+
const pattern = `%${text}%`;
|
|
823
|
+
const params = [pattern, pattern];
|
|
824
|
+
if (kinds && kinds.length > 0) {
|
|
825
|
+
sql += ` AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
826
|
+
params.push(...kinds);
|
|
827
|
+
}
|
|
828
|
+
if (languages && languages.length > 0) {
|
|
829
|
+
sql += ` AND language IN (${languages.map(() => '?').join(',')})`;
|
|
830
|
+
params.push(...languages);
|
|
831
|
+
}
|
|
832
|
+
sql += ' LIMIT ?';
|
|
833
|
+
params.push(apiLimit);
|
|
834
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
835
|
+
for (const row of rows) {
|
|
836
|
+
const node = this.mapOhosApiNodeRow(row);
|
|
837
|
+
if (seen.has(node.id))
|
|
838
|
+
continue;
|
|
839
|
+
seen.add(node.id);
|
|
840
|
+
merged.push({ node, score: row.score });
|
|
841
|
+
}
|
|
842
|
+
merged.sort((a, b) => b.score - a.score);
|
|
843
|
+
return merged.slice(0, limit);
|
|
844
|
+
}
|
|
727
845
|
/**
|
|
728
846
|
* Match-everything path used when the user supplied only field
|
|
729
847
|
* filters (`kind:function lang:typescript`) with no text. Returns
|
|
@@ -838,11 +956,11 @@ class QueryBuilder {
|
|
|
838
956
|
// Fetch 5x requested limit so post-hoc rescoring (kindBonus, pathRelevance,
|
|
839
957
|
// nameMatchBonus) can promote results that BM25 alone undervalues.
|
|
840
958
|
const ftsLimit = Math.max(limit * 5, 100);
|
|
841
|
-
let sql = `
|
|
842
|
-
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
843
|
-
FROM nodes_fts
|
|
844
|
-
JOIN nodes ON nodes_fts.id = nodes.id
|
|
845
|
-
WHERE nodes_fts MATCH ?
|
|
959
|
+
let sql = `
|
|
960
|
+
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
961
|
+
FROM nodes_fts
|
|
962
|
+
JOIN nodes ON nodes_fts.id = nodes.id
|
|
963
|
+
WHERE nodes_fts MATCH ?
|
|
846
964
|
`;
|
|
847
965
|
const params = [ftsQuery];
|
|
848
966
|
if (kinds && kinds.length > 0) {
|
|
@@ -873,21 +991,21 @@ class QueryBuilder {
|
|
|
873
991
|
*/
|
|
874
992
|
searchNodesLike(query, options) {
|
|
875
993
|
const { kinds, languages, limit = 100, offset = 0 } = options;
|
|
876
|
-
let sql = `
|
|
877
|
-
SELECT nodes.*,
|
|
878
|
-
CASE
|
|
879
|
-
WHEN name = ? THEN 1.0
|
|
880
|
-
WHEN name LIKE ? THEN 0.9
|
|
881
|
-
WHEN name LIKE ? THEN 0.8
|
|
882
|
-
WHEN qualified_name LIKE ? THEN 0.7
|
|
883
|
-
ELSE 0.5
|
|
884
|
-
END as score
|
|
885
|
-
FROM nodes
|
|
886
|
-
WHERE (
|
|
887
|
-
name LIKE ? OR
|
|
888
|
-
qualified_name LIKE ? OR
|
|
889
|
-
name LIKE ?
|
|
890
|
-
)
|
|
994
|
+
let sql = `
|
|
995
|
+
SELECT nodes.*,
|
|
996
|
+
CASE
|
|
997
|
+
WHEN name = ? THEN 1.0
|
|
998
|
+
WHEN name LIKE ? THEN 0.9
|
|
999
|
+
WHEN name LIKE ? THEN 0.8
|
|
1000
|
+
WHEN qualified_name LIKE ? THEN 0.7
|
|
1001
|
+
ELSE 0.5
|
|
1002
|
+
END as score
|
|
1003
|
+
FROM nodes
|
|
1004
|
+
WHERE (
|
|
1005
|
+
name LIKE ? OR
|
|
1006
|
+
qualified_name LIKE ? OR
|
|
1007
|
+
name LIKE ?
|
|
1008
|
+
)
|
|
891
1009
|
`;
|
|
892
1010
|
// Pattern variants for better matching
|
|
893
1011
|
const exactMatch = query;
|
|
@@ -961,10 +1079,10 @@ class QueryBuilder {
|
|
|
961
1079
|
const allResults = [];
|
|
962
1080
|
const seenIds = new Set();
|
|
963
1081
|
for (const name of names) {
|
|
964
|
-
let sql = `
|
|
965
|
-
SELECT nodes.*, 1.0 as score
|
|
966
|
-
FROM nodes
|
|
967
|
-
WHERE name COLLATE NOCASE = ?
|
|
1082
|
+
let sql = `
|
|
1083
|
+
SELECT nodes.*, 1.0 as score
|
|
1084
|
+
FROM nodes
|
|
1085
|
+
WHERE name COLLATE NOCASE = ?
|
|
968
1086
|
`;
|
|
969
1087
|
const params = [name];
|
|
970
1088
|
if (kinds && kinds.length > 0) {
|
|
@@ -994,6 +1112,32 @@ class QueryBuilder {
|
|
|
994
1112
|
seenIds.add(r.node.id);
|
|
995
1113
|
allResults.push(r);
|
|
996
1114
|
}
|
|
1115
|
+
if (this.hasOhosApiAttached()) {
|
|
1116
|
+
let apiSql = `
|
|
1117
|
+
SELECT nodes.*, 0.95 as score
|
|
1118
|
+
FROM ohos_api.nodes
|
|
1119
|
+
WHERE name COLLATE NOCASE = ?
|
|
1120
|
+
`;
|
|
1121
|
+
const apiParams = [name];
|
|
1122
|
+
if (kinds && kinds.length > 0) {
|
|
1123
|
+
apiSql += ` AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
1124
|
+
apiParams.push(...kinds);
|
|
1125
|
+
}
|
|
1126
|
+
if (languages && languages.length > 0) {
|
|
1127
|
+
apiSql += ` AND language IN (${languages.map(() => '?').join(',')})`;
|
|
1128
|
+
apiParams.push(...languages);
|
|
1129
|
+
}
|
|
1130
|
+
apiSql += ' LIMIT ?';
|
|
1131
|
+
apiParams.push(perNameLimit);
|
|
1132
|
+
const apiRows = this.db.prepare(apiSql).all(...apiParams);
|
|
1133
|
+
for (const row of apiRows) {
|
|
1134
|
+
const node = this.mapOhosApiNodeRow(row);
|
|
1135
|
+
if (seenIds.has(node.id))
|
|
1136
|
+
continue;
|
|
1137
|
+
seenIds.add(node.id);
|
|
1138
|
+
allResults.push({ node, score: row.score });
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
997
1141
|
}
|
|
998
1142
|
// Sort all results by score so co-located results bubble up
|
|
999
1143
|
allResults.sort((a, b) => b.score - a.score);
|
|
@@ -1008,10 +1152,10 @@ class QueryBuilder {
|
|
|
1008
1152
|
*/
|
|
1009
1153
|
findNodesByNameSubstring(substring, options = {}) {
|
|
1010
1154
|
const { kinds, languages, limit = 30, excludePrefix } = options;
|
|
1011
|
-
let sql = `
|
|
1012
|
-
SELECT nodes.*, 1.0 as score
|
|
1013
|
-
FROM nodes
|
|
1014
|
-
WHERE name LIKE ?
|
|
1155
|
+
let sql = `
|
|
1156
|
+
SELECT nodes.*, 1.0 as score
|
|
1157
|
+
FROM nodes
|
|
1158
|
+
WHERE name LIKE ?
|
|
1015
1159
|
`;
|
|
1016
1160
|
const params = [`%${substring}%`];
|
|
1017
1161
|
// Exclude prefix matches (handled by FTS-based prefix search in Step 2b)
|
|
@@ -1043,9 +1187,9 @@ class QueryBuilder {
|
|
|
1043
1187
|
*/
|
|
1044
1188
|
insertEdge(edge) {
|
|
1045
1189
|
if (!this.stmts.insertEdge) {
|
|
1046
|
-
this.stmts.insertEdge = this.db.prepare(`
|
|
1047
|
-
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1048
|
-
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1190
|
+
this.stmts.insertEdge = this.db.prepare(`
|
|
1191
|
+
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1192
|
+
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1049
1193
|
`);
|
|
1050
1194
|
}
|
|
1051
1195
|
this.stmts.insertEdge.run({
|
|
@@ -1161,12 +1305,12 @@ class QueryBuilder {
|
|
|
1161
1305
|
* it. One indexed query (idx_nodes_file_path + idx_edges_target_kind).
|
|
1162
1306
|
*/
|
|
1163
1307
|
getDependentFilePaths(filePath) {
|
|
1164
|
-
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1165
|
-
FROM edges e
|
|
1166
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1167
|
-
JOIN nodes src ON src.id = e.source
|
|
1168
|
-
WHERE tgt.file_path = ?
|
|
1169
|
-
AND e.kind != 'contains'
|
|
1308
|
+
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1309
|
+
FROM edges e
|
|
1310
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1311
|
+
JOIN nodes src ON src.id = e.source
|
|
1312
|
+
WHERE tgt.file_path = ?
|
|
1313
|
+
AND e.kind != 'contains'
|
|
1170
1314
|
AND src.file_path != ?`;
|
|
1171
1315
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1172
1316
|
return rows.map((r) => r.fp);
|
|
@@ -1178,12 +1322,12 @@ class QueryBuilder {
|
|
|
1178
1322
|
* (all kinds except `contains`); same reason imports-only is insufficient.
|
|
1179
1323
|
*/
|
|
1180
1324
|
getDependencyFilePaths(filePath) {
|
|
1181
|
-
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1182
|
-
FROM edges e
|
|
1183
|
-
JOIN nodes src ON src.id = e.source
|
|
1184
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1185
|
-
WHERE src.file_path = ?
|
|
1186
|
-
AND e.kind != 'contains'
|
|
1325
|
+
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1326
|
+
FROM edges e
|
|
1327
|
+
JOIN nodes src ON src.id = e.source
|
|
1328
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1329
|
+
WHERE src.file_path = ?
|
|
1330
|
+
AND e.kind != 'contains'
|
|
1187
1331
|
AND tgt.file_path != ?`;
|
|
1188
1332
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1189
1333
|
return rows.map((r) => r.fp);
|
|
@@ -1199,12 +1343,12 @@ class QueryBuilder {
|
|
|
1199
1343
|
* {@link getDependentFilePaths}: all kinds except `contains`.
|
|
1200
1344
|
*/
|
|
1201
1345
|
getCrossFileIncomingEdgesWithTarget(filePath) {
|
|
1202
|
-
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind
|
|
1203
|
-
FROM edges e
|
|
1204
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1205
|
-
JOIN nodes src ON src.id = e.source
|
|
1206
|
-
WHERE tgt.file_path = ?
|
|
1207
|
-
AND e.kind != 'contains'
|
|
1346
|
+
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind
|
|
1347
|
+
FROM edges e
|
|
1348
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1349
|
+
JOIN nodes src ON src.id = e.source
|
|
1350
|
+
WHERE tgt.file_path = ?
|
|
1351
|
+
AND e.kind != 'contains'
|
|
1208
1352
|
AND src.file_path != ?`;
|
|
1209
1353
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1210
1354
|
return rows.map(row => ({
|
|
@@ -1219,10 +1363,10 @@ class QueryBuilder {
|
|
|
1219
1363
|
*/
|
|
1220
1364
|
deleteArkTSCrossFileCallEdges() {
|
|
1221
1365
|
const result = this.db
|
|
1222
|
-
.prepare(`DELETE FROM edges
|
|
1223
|
-
WHERE kind = 'calls'
|
|
1224
|
-
AND provenance = 'heuristic'
|
|
1225
|
-
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1366
|
+
.prepare(`DELETE FROM edges
|
|
1367
|
+
WHERE kind = 'calls'
|
|
1368
|
+
AND provenance = 'heuristic'
|
|
1369
|
+
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1226
1370
|
AND metadata LIKE '%"sourceFile"%'`)
|
|
1227
1371
|
.run();
|
|
1228
1372
|
return result.changes;
|
|
@@ -1235,17 +1379,17 @@ class QueryBuilder {
|
|
|
1235
1379
|
*/
|
|
1236
1380
|
upsertFile(file) {
|
|
1237
1381
|
if (!this.stmts.upsertFile) {
|
|
1238
|
-
this.stmts.upsertFile = this.db.prepare(`
|
|
1239
|
-
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1240
|
-
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1241
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
1242
|
-
content_hash = @contentHash,
|
|
1243
|
-
language = @language,
|
|
1244
|
-
size = @size,
|
|
1245
|
-
modified_at = @modifiedAt,
|
|
1246
|
-
indexed_at = @indexedAt,
|
|
1247
|
-
node_count = @nodeCount,
|
|
1248
|
-
errors = @errors
|
|
1382
|
+
this.stmts.upsertFile = this.db.prepare(`
|
|
1383
|
+
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1384
|
+
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1385
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
1386
|
+
content_hash = @contentHash,
|
|
1387
|
+
language = @language,
|
|
1388
|
+
size = @size,
|
|
1389
|
+
modified_at = @modifiedAt,
|
|
1390
|
+
indexed_at = @indexedAt,
|
|
1391
|
+
node_count = @nodeCount,
|
|
1392
|
+
errors = @errors
|
|
1249
1393
|
`);
|
|
1250
1394
|
}
|
|
1251
1395
|
this.stmts.upsertFile.run({
|
|
@@ -1319,9 +1463,9 @@ class QueryBuilder {
|
|
|
1319
1463
|
*/
|
|
1320
1464
|
insertUnresolvedRef(ref) {
|
|
1321
1465
|
if (!this.stmts.insertUnresolved) {
|
|
1322
|
-
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1323
|
-
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1324
|
-
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1466
|
+
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1467
|
+
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1468
|
+
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1325
1469
|
`);
|
|
1326
1470
|
}
|
|
1327
1471
|
this.stmts.insertUnresolved.run({
|
|
@@ -1485,8 +1629,16 @@ class QueryBuilder {
|
|
|
1485
1629
|
deleteResolvedReferences(fromNodeIds) {
|
|
1486
1630
|
if (fromNodeIds.length === 0)
|
|
1487
1631
|
return;
|
|
1488
|
-
|
|
1489
|
-
this.
|
|
1632
|
+
// Chunk under SQLite's parameter limit, matching every other IN-list in
|
|
1633
|
+
// this file. The internal resolution path uses deleteSpecificResolvedReferences
|
|
1634
|
+
// instead, but QueryBuilder is part of the public API, so a library consumer
|
|
1635
|
+
// passing more ids than SQLITE_MAX_VARIABLE_NUMBER (32766 on the bundled
|
|
1636
|
+
// node:sqlite) would otherwise hit "too many SQL variables". (#540, #1001)
|
|
1637
|
+
for (let i = 0; i < fromNodeIds.length; i += SQLITE_PARAM_CHUNK_SIZE) {
|
|
1638
|
+
const chunk = fromNodeIds.slice(i, i + SQLITE_PARAM_CHUNK_SIZE);
|
|
1639
|
+
const placeholders = chunk.map(() => '?').join(',');
|
|
1640
|
+
this.db.prepare(`DELETE FROM unresolved_refs WHERE from_node_id IN (${placeholders})`).run(...chunk);
|
|
1641
|
+
}
|
|
1490
1642
|
}
|
|
1491
1643
|
/**
|
|
1492
1644
|
* Delete specific resolved references by (fromNodeId, referenceName, referenceKind) tuples.
|
|
@@ -1523,11 +1675,11 @@ class QueryBuilder {
|
|
|
1523
1675
|
*/
|
|
1524
1676
|
getStats() {
|
|
1525
1677
|
// Single query for all three aggregate counts
|
|
1526
|
-
const counts = this.db.prepare(`
|
|
1527
|
-
SELECT
|
|
1528
|
-
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
1529
|
-
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
1530
|
-
(SELECT COUNT(*) FROM files) AS file_count
|
|
1678
|
+
const counts = this.db.prepare(`
|
|
1679
|
+
SELECT
|
|
1680
|
+
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
1681
|
+
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
1682
|
+
(SELECT COUNT(*) FROM files) AS file_count
|
|
1531
1683
|
`).get();
|
|
1532
1684
|
const nodesByKind = {};
|
|
1533
1685
|
const nodeKindRows = this.db
|
|
@@ -1588,12 +1740,31 @@ class QueryBuilder {
|
|
|
1588
1740
|
}
|
|
1589
1741
|
return result;
|
|
1590
1742
|
}
|
|
1743
|
+
// ===========================================================================
|
|
1744
|
+
// MCP Query Cache
|
|
1745
|
+
// ===========================================================================
|
|
1746
|
+
clearMcpQueryCache() {
|
|
1747
|
+
this.db.exec('DELETE FROM mcp_query_cache');
|
|
1748
|
+
}
|
|
1749
|
+
getMcpQueryCache(cacheKey) {
|
|
1750
|
+
const row = this.db
|
|
1751
|
+
.prepare('SELECT tool, response FROM mcp_query_cache WHERE cache_key = ?')
|
|
1752
|
+
.get(cacheKey);
|
|
1753
|
+
return row ?? null;
|
|
1754
|
+
}
|
|
1755
|
+
setMcpQueryCache(cacheKey, tool, response, createdAt) {
|
|
1756
|
+
this.db
|
|
1757
|
+
.prepare('INSERT INTO mcp_query_cache (cache_key, tool, response, created_at) VALUES (?, ?, ?, ?) ' +
|
|
1758
|
+
'ON CONFLICT(cache_key) DO UPDATE SET tool = excluded.tool, response = excluded.response, created_at = excluded.created_at')
|
|
1759
|
+
.run(cacheKey, tool, response, createdAt);
|
|
1760
|
+
}
|
|
1591
1761
|
/**
|
|
1592
1762
|
* Clear all data from the database
|
|
1593
1763
|
*/
|
|
1594
1764
|
clear() {
|
|
1595
1765
|
this.nodeCache.clear();
|
|
1596
1766
|
this.db.transaction(() => {
|
|
1767
|
+
this.db.exec('DELETE FROM mcp_query_cache');
|
|
1597
1768
|
this.db.exec('DELETE FROM unresolved_refs');
|
|
1598
1769
|
this.db.exec('DELETE FROM edges');
|
|
1599
1770
|
this.db.exec('DELETE FROM nodes');
|