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
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Query pool — runs CPU-heavy read-tool calls on a pool of worker threads so
|
|
4
|
+
* the shared daemon's main event loop stays free for the MCP transport.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists: see {@link ./query-worker}. One daemon, one event loop, one
|
|
7
|
+
* synchronous SQLite connection serializes every concurrent `codegraph_explore`
|
|
8
|
+
* AND starves the transport (a 10-way wave delivered 0 transport heartbeats in
|
|
9
|
+
* 25s — responses can't flush until the whole batch drains, so clients time
|
|
10
|
+
* out). Spreading the dispatch across worker threads (each its own WAL read
|
|
11
|
+
* connection) restores true multi-core parallelism and an idle main loop.
|
|
12
|
+
*
|
|
13
|
+
* Properties:
|
|
14
|
+
* - lazy growth: one warm worker on construct, grows to `size` on demand, so a
|
|
15
|
+
* single-agent session pays for one connection and a 10-subagent burst grows
|
|
16
|
+
* to the core budget.
|
|
17
|
+
* - crash recovery: a dead worker is respawned and its in-flight call retried
|
|
18
|
+
* once; a poison call that keeps crashing fails gracefully (never wedges the
|
|
19
|
+
* pool). A crash budget trips a circuit breaker (`healthy` → false) so the
|
|
20
|
+
* caller falls back to in-process dispatch instead of thrashing respawns.
|
|
21
|
+
* - graceful backstop: a call that can't be served within `softTimeoutMs`
|
|
22
|
+
* resolves with SUCCESS-shaped "busy, retry" guidance — never `isError`, so
|
|
23
|
+
* a momentary overload can't teach the agent to abandon codegraph — instead
|
|
24
|
+
* of hanging past the client's hard timeout.
|
|
25
|
+
*/
|
|
26
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
29
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
30
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
31
|
+
}
|
|
32
|
+
Object.defineProperty(o, k2, desc);
|
|
33
|
+
}) : (function(o, m, k, k2) {
|
|
34
|
+
if (k2 === undefined) k2 = k;
|
|
35
|
+
o[k2] = m[k];
|
|
36
|
+
}));
|
|
37
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
38
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
39
|
+
}) : function(o, v) {
|
|
40
|
+
o["default"] = v;
|
|
41
|
+
});
|
|
42
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
43
|
+
var ownKeys = function(o) {
|
|
44
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
45
|
+
var ar = [];
|
|
46
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
47
|
+
return ar;
|
|
48
|
+
};
|
|
49
|
+
return ownKeys(o);
|
|
50
|
+
};
|
|
51
|
+
return function (mod) {
|
|
52
|
+
if (mod && mod.__esModule) return mod;
|
|
53
|
+
var result = {};
|
|
54
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
55
|
+
__setModuleDefault(result, mod);
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
})();
|
|
59
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
|
+
exports.QueryPool = void 0;
|
|
61
|
+
exports.resolvePoolSize = resolvePoolSize;
|
|
62
|
+
const worker_threads_1 = require("worker_threads");
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
const os = __importStar(require("os"));
|
|
65
|
+
/** Compiled sibling — `query-worker.js` lives next to this file in `dist/mcp/`. */
|
|
66
|
+
const WORKER_FILE = path.join(__dirname, 'query-worker.js');
|
|
67
|
+
/** Default linger before a queued call is answered with busy-guidance. */
|
|
68
|
+
const DEFAULT_BUSY_TIMEOUT_MS = 45_000; // < the ~60s MCP client request timeout
|
|
69
|
+
/** Hard ceiling on pool size regardless of core count / env. */
|
|
70
|
+
const MAX_POOL_SIZE = 16;
|
|
71
|
+
/**
|
|
72
|
+
* Total worker deaths before the pool declares itself unhealthy and the caller
|
|
73
|
+
* reverts to in-process dispatch. High enough to ride out a few transient
|
|
74
|
+
* crashes, low enough that a systematically-broken worker (e.g. a platform that
|
|
75
|
+
* can't spawn threads) degrades quickly instead of respawning forever.
|
|
76
|
+
*/
|
|
77
|
+
const CRASH_BUDGET = 12;
|
|
78
|
+
/**
|
|
79
|
+
* Max workers cold-starting at once. A worker's cold start is heavy — full
|
|
80
|
+
* module load (tree-sitter etc.) + opening a large WAL DB — and starting the
|
|
81
|
+
* whole pool simultaneously thrashes CPU/I-O so badly it can stall the daemon's
|
|
82
|
+
* main loop for tens of seconds. Warming a couple at a time keeps each start
|
|
83
|
+
* fast; as one reports ready the next begins, so the pool still reaches full
|
|
84
|
+
* size within a few calls of a burst, just without the thundering herd.
|
|
85
|
+
*/
|
|
86
|
+
const MAX_CONCURRENT_SPAWN = 2;
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the pool size from the `CODEGRAPH_QUERY_POOL_SIZE` override and the
|
|
89
|
+
* machine's core count. `0` (or a negative) explicitly disables the pool (the
|
|
90
|
+
* caller serves in-process — today's behavior). Unset → `clamp(cores-1, 1, 16)`:
|
|
91
|
+
* leave a core for the main loop + OS, but never zero, since even one worker
|
|
92
|
+
* frees the transport and lets responses flush incrementally.
|
|
93
|
+
*/
|
|
94
|
+
function resolvePoolSize(envVal, cpuCount) {
|
|
95
|
+
if (envVal !== undefined && envVal !== '') {
|
|
96
|
+
const n = Number(envVal);
|
|
97
|
+
if (Number.isFinite(n) && n >= 0)
|
|
98
|
+
return Math.min(Math.floor(n), MAX_POOL_SIZE);
|
|
99
|
+
// non-numeric / negative → fall through to the default
|
|
100
|
+
}
|
|
101
|
+
return Math.max(1, Math.min(cpuCount - 1, MAX_POOL_SIZE));
|
|
102
|
+
}
|
|
103
|
+
function resolveBusyTimeoutMs() {
|
|
104
|
+
const raw = process.env.CODEGRAPH_QUERY_BUSY_TIMEOUT_MS;
|
|
105
|
+
if (raw === undefined || raw === '')
|
|
106
|
+
return DEFAULT_BUSY_TIMEOUT_MS;
|
|
107
|
+
const n = Number(raw);
|
|
108
|
+
if (!Number.isFinite(n) || n < 1000)
|
|
109
|
+
return DEFAULT_BUSY_TIMEOUT_MS;
|
|
110
|
+
return Math.floor(n);
|
|
111
|
+
}
|
|
112
|
+
/** Success-shaped overload guidance (NEVER isError — see the abandonment rule). */
|
|
113
|
+
function busyGuidance(waitedMs) {
|
|
114
|
+
const secs = Math.max(1, Math.round(waitedMs / 1000));
|
|
115
|
+
return {
|
|
116
|
+
content: [{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: `CodeGraph is busy serving other concurrent requests right now (this call waited ${secs}s in the queue). ` +
|
|
119
|
+
`This is NOT an error and the index is fine — wait a few seconds and retry this exact call; it will return normally. ` +
|
|
120
|
+
`If you can't wait, use your built-in tools for just this one step.`,
|
|
121
|
+
}],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
class QueryPool {
|
|
125
|
+
idle = [];
|
|
126
|
+
queue = [];
|
|
127
|
+
inflight = new Map();
|
|
128
|
+
workers = new Set();
|
|
129
|
+
// Workers spawned but not yet 'ready'. Growth must count these so a single
|
|
130
|
+
// first call (with the eager worker still starting) doesn't spawn the WHOLE
|
|
131
|
+
// pool at once — N simultaneous cold worker starts (each a full module load +
|
|
132
|
+
// a large DB open) saturate the box and starve the main loop. Grow only when
|
|
133
|
+
// the queue outstrips idle + pending.
|
|
134
|
+
pendingWorkers = new Set();
|
|
135
|
+
nextId = 1;
|
|
136
|
+
totalCrashes = 0;
|
|
137
|
+
destroyed = false;
|
|
138
|
+
root;
|
|
139
|
+
maxSize;
|
|
140
|
+
softTimeoutMs;
|
|
141
|
+
maxRetries;
|
|
142
|
+
createWorker;
|
|
143
|
+
constructor(opts) {
|
|
144
|
+
this.root = opts.root;
|
|
145
|
+
this.maxSize = Math.max(1, Math.min(opts.size ?? Math.max(1, os.cpus().length - 1), MAX_POOL_SIZE));
|
|
146
|
+
this.softTimeoutMs = opts.softTimeoutMs ?? resolveBusyTimeoutMs();
|
|
147
|
+
this.maxRetries = opts.maxRetries ?? 1;
|
|
148
|
+
this.createWorker = opts.createWorker ?? (() => new worker_threads_1.Worker(WORKER_FILE, { workerData: { root: this.root } }));
|
|
149
|
+
this.spawnOne(); // one eager warm worker, ready for the first call
|
|
150
|
+
}
|
|
151
|
+
/** Pool size cap (for logging/status). */
|
|
152
|
+
get size() { return this.maxSize; }
|
|
153
|
+
/** Live worker count (for tests/status). */
|
|
154
|
+
get liveWorkers() { return this.workers.size; }
|
|
155
|
+
/**
|
|
156
|
+
* False once the crash budget is exhausted (or after destroy). The ToolHandler
|
|
157
|
+
* checks this and falls back to in-process dispatch — a broken worker platform
|
|
158
|
+
* degrades to today's behavior instead of failing tool calls.
|
|
159
|
+
*/
|
|
160
|
+
get healthy() {
|
|
161
|
+
return !this.destroyed && this.totalCrashes < CRASH_BUDGET;
|
|
162
|
+
}
|
|
163
|
+
spawnOne() {
|
|
164
|
+
if (this.destroyed || this.workers.size >= this.maxSize)
|
|
165
|
+
return;
|
|
166
|
+
let w;
|
|
167
|
+
try {
|
|
168
|
+
w = this.createWorker();
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
this.totalCrashes++; // counts toward the circuit breaker
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.workers.add(w);
|
|
175
|
+
this.pendingWorkers.add(w);
|
|
176
|
+
w.on('message', (m) => this.onMessage(w, (m ?? {})));
|
|
177
|
+
w.on('error', () => this.onWorkerGone(w));
|
|
178
|
+
w.on('exit', (code) => { if (code !== 0)
|
|
179
|
+
this.onWorkerGone(w); });
|
|
180
|
+
}
|
|
181
|
+
onMessage(w, m) {
|
|
182
|
+
if (!m)
|
|
183
|
+
return;
|
|
184
|
+
if (m.type === 'ready') {
|
|
185
|
+
this.pendingWorkers.delete(w);
|
|
186
|
+
if (m.ok === false)
|
|
187
|
+
this.totalCrashes++; // hard open failure
|
|
188
|
+
this.idle.push(w);
|
|
189
|
+
this.drain();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (m.type === 'result') {
|
|
193
|
+
const job = this.inflight.get(w);
|
|
194
|
+
this.inflight.delete(w);
|
|
195
|
+
this.idle.push(w);
|
|
196
|
+
if (job)
|
|
197
|
+
this.settle(job, m.result ?? busyGuidance(0));
|
|
198
|
+
this.drain();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// A worker died (crash hook, OOM, segfault, exit≠0). Respawn a replacement and
|
|
202
|
+
// retry its in-flight job once; a job that keeps crashing workers fails
|
|
203
|
+
// gracefully so it can't loop the pool forever.
|
|
204
|
+
onWorkerGone(w) {
|
|
205
|
+
if (!this.workers.has(w))
|
|
206
|
+
return; // already handled (error+exit both fire)
|
|
207
|
+
this.workers.delete(w);
|
|
208
|
+
this.pendingWorkers.delete(w);
|
|
209
|
+
this.idle = this.idle.filter((x) => x !== w);
|
|
210
|
+
this.totalCrashes++;
|
|
211
|
+
const job = this.inflight.get(w);
|
|
212
|
+
this.inflight.delete(w);
|
|
213
|
+
try {
|
|
214
|
+
void w.terminate();
|
|
215
|
+
}
|
|
216
|
+
catch { /* already gone */ }
|
|
217
|
+
if (this.healthy)
|
|
218
|
+
this.spawnOne(); // keep capacity
|
|
219
|
+
if (job) {
|
|
220
|
+
if (job.retries < this.maxRetries && this.healthy) {
|
|
221
|
+
job.retries++;
|
|
222
|
+
this.queue.unshift(job); // head of line — retry promptly
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this.settle(job, { isError: true, content: [{ type: 'text', text: 'codegraph worker crashed; please retry the call.' }] });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
this.drain();
|
|
229
|
+
}
|
|
230
|
+
drain() {
|
|
231
|
+
// Grow toward maxSize while queued work outstrips workers that are idle OR
|
|
232
|
+
// already on their way up (pending) — so we never spawn the whole pool for a
|
|
233
|
+
// single call whose eager worker just hasn't reported ready yet.
|
|
234
|
+
while (this.queue.length > this.idle.length + this.pendingWorkers.size &&
|
|
235
|
+
this.workers.size < this.maxSize &&
|
|
236
|
+
this.pendingWorkers.size < MAX_CONCURRENT_SPAWN &&
|
|
237
|
+
this.healthy) {
|
|
238
|
+
this.spawnOne();
|
|
239
|
+
}
|
|
240
|
+
while (this.idle.length && this.queue.length) {
|
|
241
|
+
// Skip jobs the backstop already answered.
|
|
242
|
+
let job;
|
|
243
|
+
while (this.queue.length && (job = this.queue.shift()) && job.settled)
|
|
244
|
+
job = undefined;
|
|
245
|
+
if (!job || job.settled)
|
|
246
|
+
break;
|
|
247
|
+
const w = this.idle.pop();
|
|
248
|
+
this.inflight.set(w, job);
|
|
249
|
+
w.postMessage({ type: 'call', id: job.id, toolName: job.toolName, args: job.args });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
settle(job, result) {
|
|
253
|
+
if (job.settled)
|
|
254
|
+
return; // already answered (by backstop or worker)
|
|
255
|
+
job.settled = true;
|
|
256
|
+
if (job.softTimer)
|
|
257
|
+
clearTimeout(job.softTimer);
|
|
258
|
+
job.resolve(result);
|
|
259
|
+
}
|
|
260
|
+
/** Run a read tool on the pool. Always resolves (never rejects). */
|
|
261
|
+
run(toolName, args) {
|
|
262
|
+
return new Promise((resolve) => {
|
|
263
|
+
const job = {
|
|
264
|
+
id: this.nextId++, toolName, args, resolve,
|
|
265
|
+
retries: 0, settled: false, enqueuedAt: Date.now(),
|
|
266
|
+
};
|
|
267
|
+
// Don't let the caller wait past softTimeoutMs. The worker may still be
|
|
268
|
+
// busy (we can't cancel synchronous CPU), but the CLIENT gets a prompt,
|
|
269
|
+
// success-shaped "retry" instead of a hard timeout.
|
|
270
|
+
job.softTimer = setTimeout(() => {
|
|
271
|
+
if (!job.settled)
|
|
272
|
+
this.settle(job, busyGuidance(Date.now() - job.enqueuedAt));
|
|
273
|
+
}, this.softTimeoutMs);
|
|
274
|
+
job.softTimer.unref?.();
|
|
275
|
+
this.queue.push(job);
|
|
276
|
+
this.drain();
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/** Terminate all workers and answer any outstanding calls gracefully. */
|
|
280
|
+
async destroy() {
|
|
281
|
+
if (this.destroyed)
|
|
282
|
+
return;
|
|
283
|
+
this.destroyed = true;
|
|
284
|
+
const ws = [...this.workers];
|
|
285
|
+
this.workers.clear();
|
|
286
|
+
this.pendingWorkers.clear();
|
|
287
|
+
this.idle = [];
|
|
288
|
+
for (const job of [...this.inflight.values(), ...this.queue]) {
|
|
289
|
+
this.settle(job, { isError: true, content: [{ type: 'text', text: 'codegraph is shutting down; retry shortly.' }] });
|
|
290
|
+
}
|
|
291
|
+
this.inflight.clear();
|
|
292
|
+
this.queue = [];
|
|
293
|
+
await Promise.all(ws.map((w) => Promise.resolve(w.terminate()).catch(() => { })));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
exports.QueryPool = QueryPool;
|
|
297
|
+
//# sourceMappingURL=query-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-pool.js","sourceRoot":"","sources":["../../src/mcp/query-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query worker thread — issue: concurrent MCP tool calls starve the daemon.
|
|
3
|
+
*
|
|
4
|
+
* The shared daemon serves every session on ONE event loop with synchronous
|
|
5
|
+
* `node:sqlite`. `codegraph_explore` is CPU-heavy (FTS + RWR/personalized-
|
|
6
|
+
* PageRank + impact + output building) stitched together by microtask `await`s,
|
|
7
|
+
* so N concurrent explores keep the microtask queue continuously full and
|
|
8
|
+
* starve the macrotask phases — timers AND socket I/O. The transport freezes:
|
|
9
|
+
* no response flushes, no request is read, until the whole batch drains. With
|
|
10
|
+
* ~10 subagents that routinely exceeds the MCP client's request timeout.
|
|
11
|
+
*
|
|
12
|
+
* This worker moves the heavy read-tool dispatch OFF the daemon's main loop.
|
|
13
|
+
* Each worker owns its OWN read connection (node:sqlite WAL allows N concurrent
|
|
14
|
+
* readers across connections — verified: a worker reader sees the main writer's
|
|
15
|
+
* committed catch-up/watcher writes), so {@link QueryPool} runs N tool calls in
|
|
16
|
+
* true parallel up to core count while the main loop stays free for the MCP
|
|
17
|
+
* transport. The worker runs {@link ToolHandler.executeReadTool} — validation +
|
|
18
|
+
* dispatch + error classification — and returns the raw {@link ToolResult}; the
|
|
19
|
+
* MAIN thread keeps the catch-up gate, the watcher-state notices (staleness /
|
|
20
|
+
* worktree), `codegraph_status`, and telemetry, none of which a watcher-less
|
|
21
|
+
* read connection can answer.
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=query-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-worker.d.ts","sourceRoot":"","sources":["../../src/mcp/query-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Query worker thread — issue: concurrent MCP tool calls starve the daemon.
|
|
4
|
+
*
|
|
5
|
+
* The shared daemon serves every session on ONE event loop with synchronous
|
|
6
|
+
* `node:sqlite`. `codegraph_explore` is CPU-heavy (FTS + RWR/personalized-
|
|
7
|
+
* PageRank + impact + output building) stitched together by microtask `await`s,
|
|
8
|
+
* so N concurrent explores keep the microtask queue continuously full and
|
|
9
|
+
* starve the macrotask phases — timers AND socket I/O. The transport freezes:
|
|
10
|
+
* no response flushes, no request is read, until the whole batch drains. With
|
|
11
|
+
* ~10 subagents that routinely exceeds the MCP client's request timeout.
|
|
12
|
+
*
|
|
13
|
+
* This worker moves the heavy read-tool dispatch OFF the daemon's main loop.
|
|
14
|
+
* Each worker owns its OWN read connection (node:sqlite WAL allows N concurrent
|
|
15
|
+
* readers across connections — verified: a worker reader sees the main writer's
|
|
16
|
+
* committed catch-up/watcher writes), so {@link QueryPool} runs N tool calls in
|
|
17
|
+
* true parallel up to core count while the main loop stays free for the MCP
|
|
18
|
+
* transport. The worker runs {@link ToolHandler.executeReadTool} — validation +
|
|
19
|
+
* dispatch + error classification — and returns the raw {@link ToolResult}; the
|
|
20
|
+
* MAIN thread keeps the catch-up gate, the watcher-state notices (staleness /
|
|
21
|
+
* worktree), `codegraph_status`, and telemetry, none of which a watcher-less
|
|
22
|
+
* read connection can answer.
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
const worker_threads_1 = require("worker_threads");
|
|
26
|
+
// Mirror the engine's lazy-require of the heavy CodeGraph + tools chain. This
|
|
27
|
+
// module is only ever loaded as a Worker, so the require runs once on spawn.
|
|
28
|
+
const loadCodeGraph = () => require('../index').default;
|
|
29
|
+
const loadToolHandler = () => require('./tools').ToolHandler;
|
|
30
|
+
if (worker_threads_1.parentPort) {
|
|
31
|
+
const port = worker_threads_1.parentPort;
|
|
32
|
+
const { root } = worker_threads_1.workerData;
|
|
33
|
+
// Open the default project's READ connection once, at spawn. Other repos are
|
|
34
|
+
// opened lazily on first cross-project (projectPath) call by the ToolHandler's
|
|
35
|
+
// own per-handler cache. openSync does not start a watcher — workers are pure
|
|
36
|
+
// readers; the single watcher/writer stays on the daemon's main thread.
|
|
37
|
+
let handler = null;
|
|
38
|
+
let initError = null;
|
|
39
|
+
try {
|
|
40
|
+
const cg = loadCodeGraph().openSync(root);
|
|
41
|
+
handler = new (loadToolHandler())(cg);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
initError = err instanceof Error ? err.message : String(err);
|
|
45
|
+
}
|
|
46
|
+
// Tell the pool we're up. `ok:false` lets the pool count a hard open failure
|
|
47
|
+
// against its crash budget (→ fall back to in-process) without hanging.
|
|
48
|
+
port.postMessage({ type: 'ready', ok: initError === null, error: initError });
|
|
49
|
+
port.on('message', (msg) => {
|
|
50
|
+
if (!msg || msg.type !== 'call')
|
|
51
|
+
return;
|
|
52
|
+
void serve(msg);
|
|
53
|
+
});
|
|
54
|
+
const serve = async (msg) => {
|
|
55
|
+
// Test-only crash hook so the pool's worker-recovery path is exercisable
|
|
56
|
+
// deterministically. Gated behind an env flag only the suite sets — inert in
|
|
57
|
+
// normal operation (and `__test_crash__` isn't a real tool name anyway).
|
|
58
|
+
if (msg.toolName === '__test_crash__' && process.env.CODEGRAPH_QUERY_WORKER_ALLOW_TEST_CRASH === '1') {
|
|
59
|
+
process.exit(13);
|
|
60
|
+
}
|
|
61
|
+
if (!handler) {
|
|
62
|
+
port.postMessage({
|
|
63
|
+
type: 'result',
|
|
64
|
+
id: msg.id,
|
|
65
|
+
result: errorResult(`codegraph worker could not open the project: ${initError}`),
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
// executeReadTool already classifies NotIndexed/PathRefusal/internal errors
|
|
71
|
+
// into a ToolResult and never throws — the catch is belt-and-suspenders.
|
|
72
|
+
const result = await handler.executeReadTool(msg.toolName, msg.args);
|
|
73
|
+
port.postMessage({ type: 'result', id: msg.id, result });
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
port.postMessage({
|
|
77
|
+
type: 'result',
|
|
78
|
+
id: msg.id,
|
|
79
|
+
result: errorResult(err instanceof Error ? err.message : String(err)),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function errorResult(text) {
|
|
85
|
+
return { isError: true, content: [{ type: 'text', text }] };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=query-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-worker.js","sourceRoot":"","sources":["../../src/mcp/query-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,13 +11,11 @@
|
|
|
11
11
|
* - Reinforce "explore instead of Read/Grep" for indexed code
|
|
12
12
|
* - Anti-patterns (don't re-verify with grep; don't hand-reconstruct flows)
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* tools (node/search/callers/…) stay defined and are re-enablable via
|
|
18
|
-
* HOMEGRAPH_MCP_TOOLS, but they are NOT listed to agents, so don't name them.
|
|
14
|
+
* HomeGraph exposes the full tool surface by default (search, node, explore,
|
|
15
|
+
* spec tools, …). Lead with homegraph_explore for structural questions; the
|
|
16
|
+
* other tools are available when a narrower step helps.
|
|
19
17
|
*/
|
|
20
|
-
export declare const SERVER_INSTRUCTIONS = "#
|
|
18
|
+
export declare const SERVER_INSTRUCTIONS = "# HomeGraph \u2014 code intelligence over an indexed knowledge graph\n\nHomeGraph is a SQLite knowledge graph of every symbol, edge, and file in\nthe workspace \u2014 pre-computed structure you would otherwise re-derive by\nreading files (cached intelligence: thousands of parse/trace decisions you\ndon't pay to re-reason each run). Reads are sub-millisecond; the index lags\nwrites by ~1s through the file watcher. Reach for it BEFORE *and* while\nwriting or editing code \u2014 not just for questions: one call returns the\nverbatim source PLUS who calls it and what it affects, so you edit with the\nblast radius in view. More accurate context, in far fewer tokens and\nround-trips than reading files yourself.\n\n## Primary tool: homegraph_explore \u2014 use it instead of reading files\n\nFor structural and flow questions, `homegraph_explore` is Read-equivalent. It\ntakes either a natural-language question or a bag of symbol/file names and\nreturns the **verbatim, line-numbered source** of the relevant symbols\ngrouped by file \u2014 the same `<n>\\t<line>` shape `Read` gives you, safe to\n`Edit` from \u2014 PLUS the call path among them (including dynamic-dispatch hops\nlike callbacks, React re-render, and JSX children that grep can't follow) and\na blast-radius summary of what depends on them.\n\nWhether you're answering \"how does X work\" or implementing a change (fixing a\nbug, adding a feature), call `homegraph_explore` before you Read. ONE call\nusually answers the whole question. HomeGraph IS the pre-built search index \u2014\nso running your own grep + read loop, or delegating the lookup to a separate\nfile-reading sub-task/agent, repeats work homegraph already did and costs more\nfor the same answer. A direct homegraph answer is typically one to a few\ncalls; a grep/read exploration is dozens.\n\n## How to query\n\n- **Almost any question \u2014 \"how does X work\", architecture, a bug, \"what/where is X\", or surveying an area** \u2192 `homegraph_explore` with a natural-language question or the relevant names. ONE capped call returns the verbatim source grouped by file; most often the ONLY call you need.\n- **\"How does X reach/become Y? / the flow / the path from X to Y\"** \u2192 `homegraph_explore`, naming the symbols that span the flow (e.g. `mutateElement renderScene`) \u2014 it surfaces the call path among them, riding dynamic-dispatch hops, and returns their source.\n- **Reading or editing a file/symbol you can name** \u2192 put its name or file path in the `homegraph_explore` query \u2014 it returns that current line-numbered source (safe to `Edit` from) with the call path and blast radius attached, so you don't Read it separately. For an overloaded name it returns every matching definition's body in one call.\n- **Need more?** Call `homegraph_explore` again with more specific names \u2014 treat the source it returns as already Read.\n\n## Anti-patterns\n\n- **Trust homegraph's results \u2014 don't re-verify them with grep.** They come from a full AST parse; re-checking with grep is slower, less accurate, and wastes context.\n- **Don't grep or Read first** to find or understand indexed code \u2014 ONE `homegraph_explore` returns the relevant symbols' source together in a single round-trip. Reach for raw `Read`/`Grep` only to confirm a specific detail homegraph didn't cover, or for what homegraph doesn't index (configs, docs).\n- **Don't reconstruct a flow by hand** \u2014 name the endpoints in one `homegraph_explore` and it surfaces the path between them, dynamic-dispatch hops included.\n- **After editing, check the staleness banner.** When a tool response starts with \"\u26A0\uFE0F Some files referenced below were edited since the last index sync\u2026\", the listed files are pending re-index \u2014 Read those specific files for accurate content. Every file NOT in that banner is fresh, so still trust homegraph. A different, rarer banner \u2014 \"\u26A0\uFE0F HomeGraph auto-sync is DISABLED\u2026\" \u2014 means live watching stopped entirely (the whole index is frozen, not just a few files); until it's resolved, Read files directly to confirm anything that may have changed.\n\n## Limitations\n\n- If a tool reports a project isn't indexed (no `.homegraph/`), stop calling homegraph tools for that project for the rest of the session and use your built-in tools there instead. Indexing is the user's decision \u2014 mention they can run `homegraph init` if it comes up, but don't run it yourself.\n- Index lags file writes by ~1 second.\n- Cross-file resolution is best-effort name matching; ambiguous calls may return multiple candidates.\n- No live correctness validation \u2014 that's still the TypeScript compiler / test suite / linter's job. HomeGraph supplements those with structural context they don't have.\n";
|
|
21
19
|
/**
|
|
22
20
|
* Instructions variant sent when the server's own root has NO homegraph index.
|
|
23
21
|
*
|
|
@@ -30,5 +28,5 @@ export declare const SERVER_INSTRUCTIONS = "# Codegraph \u2014 code intelligence
|
|
|
30
28
|
* project playbook ({@link SERVER_INSTRUCTIONS}) is sent instead when the root
|
|
31
29
|
* IS indexed, so the common case stays tight.
|
|
32
30
|
*/
|
|
33
|
-
export declare const SERVER_INSTRUCTIONS_NO_ROOT_INDEX = "#
|
|
31
|
+
export declare const SERVER_INSTRUCTIONS_NO_ROOT_INDEX = "# HomeGraph \u2014 available (per-project; pass projectPath)\n\nHomeGraph is a SQLite knowledge graph of a codebase's symbols, edges, and\nfiles: one `homegraph_explore` call returns the verbatim, line-numbered source\nof the relevant symbols PLUS the call paths between them and a blast-radius\nsummary \u2014 replacing a grep + Read loop with one round-trip.\n\nThis server started somewhere with no `.homegraph/` of its own, so there is no\ndefault project \u2014 but the tools are available and work **per project**:\n\n- To query a project that HAS a `.homegraph/` index (e.g. a service inside a\n monorepo, or a second repo), pass its path as `projectPath` to\n `homegraph_explore` (and any other homegraph tool). HomeGraph resolves the\n nearest `.homegraph/` at or above that path and answers from it \u2014 for as many\n projects as you like in one session.\n- For a project with no `.homegraph/`, use your built-in tools (Read/Grep/Glob)\n for that project. Indexing is the user's decision \u2014 don't run it yourself, but\n if it comes up they can run `homegraph init` in a project to enable homegraph\n there (a new index is picked up live, no restart).\n";
|
|
34
32
|
//# sourceMappingURL=server-instructions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-instructions.d.ts","sourceRoot":"","sources":["../../src/mcp/server-instructions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server-instructions.d.ts","sourceRoot":"","sources":["../../src/mcp/server-instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,4sJAkD/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,4pCAmB7C,CAAC"}
|