homegraph 1.1.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -18
- 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 +709 -168
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +85 -0
- package/dist/context/index.js.map +1 -1
- package/dist/db/index.d.ts +84 -5
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +217 -14
- 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 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +131 -2
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +473 -9
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +52 -1
- package/dist/db/wal-valve.d.ts +106 -0
- package/dist/db/wal-valve.d.ts.map +1 -0
- package/dist/db/wal-valve.js +208 -0
- package/dist/db/wal-valve.js.map +1 -0
- package/dist/directory.d.ts +36 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +274 -0
- 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/cfml-extractor.d.ts +107 -0
- package/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/dist/extraction/cfml-extractor.js +494 -0
- package/dist/extraction/cfml-extractor.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/grammars.d.ts +25 -1
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +177 -24
- package/dist/extraction/grammars.js.map +1 -1
- package/dist/extraction/index.d.ts +55 -2
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +923 -381
- 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 +98 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +563 -1
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/cfquery.d.ts +12 -0
- package/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/dist/extraction/languages/cfquery.js +28 -0
- package/dist/extraction/languages/cfquery.js.map +1 -0
- package/dist/extraction/languages/cfscript.d.ts +3 -0
- package/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/dist/extraction/languages/cfscript.js +73 -0
- package/dist/extraction/languages/cfscript.js.map +1 -0
- package/dist/extraction/languages/cobol.d.ts +33 -0
- package/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/dist/extraction/languages/cobol.js +499 -0
- package/dist/extraction/languages/cobol.js.map +1 -0
- package/dist/extraction/languages/erlang.d.ts +3 -0
- package/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/dist/extraction/languages/erlang.js +350 -0
- package/dist/extraction/languages/erlang.js.map +1 -0
- package/dist/extraction/languages/index.d.ts.map +1 -1
- package/dist/extraction/languages/index.js +16 -0
- package/dist/extraction/languages/index.js.map +1 -1
- package/dist/extraction/languages/nix.d.ts +3 -0
- package/dist/extraction/languages/nix.d.ts.map +1 -0
- package/dist/extraction/languages/nix.js +294 -0
- package/dist/extraction/languages/nix.js.map +1 -0
- 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/languages/solidity.d.ts +3 -0
- package/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/dist/extraction/languages/solidity.js +293 -0
- package/dist/extraction/languages/solidity.js.map +1 -0
- package/dist/extraction/languages/terraform.d.ts +3 -0
- package/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/dist/extraction/languages/terraform.js +641 -0
- package/dist/extraction/languages/terraform.js.map +1 -0
- package/dist/extraction/languages/vbnet.d.ts +11 -0
- package/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/dist/extraction/languages/vbnet.js +141 -0
- package/dist/extraction/languages/vbnet.js.map +1 -0
- package/dist/extraction/mybatis-extractor.d.ts +30 -10
- package/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/dist/extraction/mybatis-extractor.js +140 -38
- package/dist/extraction/mybatis-extractor.js.map +1 -1
- package/dist/extraction/parse-pool.d.ts +152 -0
- package/dist/extraction/parse-pool.d.ts.map +1 -0
- package/dist/extraction/parse-pool.js +387 -0
- package/dist/extraction/parse-pool.js.map +1 -0
- package/dist/extraction/parse-worker.js +9 -2
- package/dist/extraction/parse-worker.js.map +1 -1
- package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/dist/extraction/tree-sitter-helpers.js +1 -0
- package/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/dist/extraction/tree-sitter-types.d.ts +20 -1
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +59 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +952 -37
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +77 -18
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +85 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +426 -9
- package/dist/index.js.map +1 -1
- package/dist/installer/index.d.ts +42 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +97 -2
- package/dist/installer/index.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 +73 -3
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +258 -40
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/dist/mcp/dynamic-boundaries.js +2 -1
- package/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/dist/mcp/early-ppid.d.ts +26 -0
- package/dist/mcp/early-ppid.d.ts.map +1 -0
- package/dist/mcp/early-ppid.js +29 -0
- package/dist/mcp/early-ppid.js.map +1 -0
- package/dist/mcp/engine.d.ts +16 -0
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +100 -2
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +66 -49
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/liveness-watchdog.d.ts +18 -1
- package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/dist/mcp/liveness-watchdog.js +73 -13
- package/dist/mcp/liveness-watchdog.js.map +1 -1
- package/dist/mcp/memory-budget.d.ts +30 -0
- package/dist/mcp/memory-budget.d.ts.map +1 -0
- package/dist/mcp/memory-budget.js +123 -0
- package/dist/mcp/memory-budget.js.map +1 -0
- 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/proxy.d.ts.map +1 -1
- package/dist/mcp/proxy.js +88 -4
- package/dist/mcp/proxy.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +56 -0
- package/dist/mcp/query-cache.d.ts.map +1 -0
- package/dist/mcp/query-cache.js +261 -0
- package/dist/mcp/query-cache.js.map +1 -0
- package/dist/mcp/query-pool.d.ts +128 -0
- package/dist/mcp/query-pool.d.ts.map +1 -0
- package/dist/mcp/query-pool.js +374 -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 +4 -29
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +39 -86
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/session.d.ts +14 -0
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +28 -1
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/startup-handshake.d.ts +44 -0
- package/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/dist/mcp/startup-handshake.js +73 -0
- package/dist/mcp/startup-handshake.js.map +1 -0
- package/dist/mcp/tools.d.ts +179 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +3027 -192
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/transport.d.ts.map +1 -1
- package/dist/mcp/transport.js +18 -0
- package/dist/mcp/transport.js.map +1 -1
- package/dist/project-config.d.ts +58 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +141 -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/resolution/c-fnptr-synthesizer.d.ts +2 -29
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +866 -148
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +9 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +1232 -183
- 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/frameworks/cics.d.ts +20 -0
- package/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/dist/resolution/frameworks/cics.js +90 -0
- package/dist/resolution/frameworks/cics.js.map +1 -0
- package/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/dist/resolution/frameworks/index.js +3 -0
- package/dist/resolution/frameworks/index.js.map +1 -1
- package/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/dist/resolution/frameworks/java.js +14 -6
- package/dist/resolution/frameworks/java.js.map +1 -1
- package/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/dist/resolution/frameworks/terraform.js +277 -0
- package/dist/resolution/frameworks/terraform.js.map +1 -0
- package/dist/resolution/goframe-synthesizer.d.ts +2 -1
- package/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
- package/dist/resolution/goframe-synthesizer.js +8 -3
- package/dist/resolution/goframe-synthesizer.js.map +1 -1
- package/dist/resolution/import-resolver.d.ts +7 -0
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +129 -4
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +65 -3
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +477 -59
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +22 -3
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +657 -39
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/strip-comments.d.ts +1 -1
- package/dist/resolution/strip-comments.d.ts.map +1 -1
- package/dist/resolution/strip-comments.js +49 -0
- package/dist/resolution/strip-comments.js.map +1 -1
- package/dist/resolution/types.d.ts +29 -0
- package/dist/resolution/types.d.ts.map +1 -1
- package/dist/resolution/workspace-packages.d.ts +10 -0
- package/dist/resolution/workspace-packages.d.ts.map +1 -1
- package/dist/resolution/workspace-packages.js +142 -4
- package/dist/resolution/workspace-packages.js.map +1 -1
- package/dist/search/identifier-segments.d.ts +60 -0
- package/dist/search/identifier-segments.d.ts.map +1 -0
- package/dist/search/identifier-segments.js +176 -0
- package/dist/search/identifier-segments.js.map +1 -0
- package/dist/search/query-utils.d.ts +201 -0
- package/dist/search/query-utils.d.ts.map +1 -1
- package/dist/search/query-utils.js +919 -2
- package/dist/search/query-utils.js.map +1 -1
- package/dist/spec/config.d.ts +7 -11
- package/dist/spec/config.d.ts.map +1 -1
- package/dist/spec/config.js +77 -48
- package/dist/spec/config.js.map +1 -1
- package/dist/spec/db/fragment-node.d.ts +1 -0
- package/dist/spec/db/fragment-node.d.ts.map +1 -1
- package/dist/spec/db/fragment-node.js +8 -0
- package/dist/spec/db/fragment-node.js.map +1 -1
- package/dist/spec/db/fts.d.ts +14 -0
- package/dist/spec/db/fts.d.ts.map +1 -1
- package/dist/spec/db/fts.js +43 -4
- package/dist/spec/db/fts.js.map +1 -1
- package/dist/spec/db/schema.d.ts +6 -3
- package/dist/spec/db/schema.d.ts.map +1 -1
- package/dist/spec/db/schema.js +36 -4
- package/dist/spec/db/schema.js.map +1 -1
- package/dist/spec/db/schema.sql +11 -1
- package/dist/spec/evolve/logic-checker.d.ts +2 -2
- package/dist/spec/evolve/logic-checker.d.ts.map +1 -1
- package/dist/spec/evolve/logic-checker.js +3 -27
- package/dist/spec/evolve/logic-checker.js.map +1 -1
- package/dist/spec/evolve/pipeline.d.ts +21 -19
- package/dist/spec/evolve/pipeline.d.ts.map +1 -1
- package/dist/spec/evolve/pipeline.js +284 -31
- package/dist/spec/evolve/pipeline.js.map +1 -1
- package/dist/spec/evolve/spec-rewriter.d.ts +2 -2
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
- package/dist/spec/evolve/spec-rewriter.js +7 -31
- package/dist/spec/evolve/spec-rewriter.js.map +1 -1
- package/dist/spec/graph/queries.d.ts +97 -0
- package/dist/spec/graph/queries.d.ts.map +1 -1
- package/dist/spec/graph/queries.js +225 -0
- package/dist/spec/graph/queries.js.map +1 -1
- 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/git-scanner.d.ts +12 -0
- package/dist/spec/mining/git-scanner.d.ts.map +1 -1
- package/dist/spec/mining/git-scanner.js +41 -0
- package/dist/spec/mining/git-scanner.js.map +1 -1
- package/dist/spec/mining/pipeline.d.ts.map +1 -1
- package/dist/spec/mining/pipeline.js +14 -1
- package/dist/spec/mining/pipeline.js.map +1 -1
- package/dist/spec/utils.d.ts +2 -1
- package/dist/spec/utils.d.ts.map +1 -1
- package/dist/spec/utils.js +3 -1
- package/dist/spec/utils.js.map +1 -1
- package/dist/sync/git-hooks.d.ts.map +1 -1
- package/dist/sync/git-hooks.js +2 -0
- package/dist/sync/git-hooks.js.map +1 -1
- package/dist/sync/watcher.d.ts +10 -5
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +51 -14
- package/dist/sync/watcher.js.map +1 -1
- package/dist/sync/worktree.d.ts +9 -0
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +45 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/types.d.ts +25 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -0
- package/dist/types.js.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.d.ts +32 -0
- package/dist/upgrade/index.d.ts.map +1 -1
- package/dist/upgrade/index.js +163 -15
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/remove-binary.d.ts +87 -0
- package/dist/upgrade/remove-binary.d.ts.map +1 -0
- package/dist/upgrade/remove-binary.js +289 -0
- package/dist/upgrade/remove-binary.js.map +1 -0
- package/dist/upgrade/update-check.d.ts +92 -0
- package/dist/upgrade/update-check.d.ts.map +1 -0
- package/dist/upgrade/update-check.js +258 -0
- package/dist/upgrade/update-check.js.map +1 -0
- package/package.json +4 -4
- 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-all.sh +6 -0
- package/scripts/build-bundle.sh +5 -0
- package/scripts/exp_boundary_eval/README.md +247 -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/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/npm-shim.js +32 -3
- package/scripts/ohos-sdk-publish.mjs +133 -0
- package/scripts/qa_eval/README.md +0 -407
- package/scripts/qa_eval/_test_deveco_probe.py +0 -41
- package/scripts/qa_eval/agent_runner.py +0 -526
- package/scripts/qa_eval/data/.gitignore +0 -4
- package/scripts/qa_eval/data/test-set.jsonl +0 -2
- package/scripts/qa_eval/eval_metrics.py +0 -274
- package/scripts/qa_eval/external_agent.py +0 -976
- package/scripts/qa_eval/llm_config.py +0 -92
- package/scripts/qa_eval/memory_monitor.py +0 -132
- package/scripts/qa_eval/my_answer_accuracy.py +0 -187
- package/scripts/qa_eval/requirements.txt +0 -2
- package/scripts/qa_eval/run_pipeline.py +0 -804
- package/scripts/qa_eval/stats_efficiency.py +0 -279
- package/scripts/qa_eval/stats_scores.py +0 -207
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/** Default: 60s — ~300× shorter than the 5h #850 wedge, far longer than any real main-thread block. */
|
|
2
2
|
export declare const DEFAULT_WATCHDOG_TIMEOUT_MS = 60000;
|
|
3
|
+
/**
|
|
4
|
+
* Hard cap on disk-progress deferral: after this many timeouts' worth of
|
|
5
|
+
* CONTINUOUS heartbeat silence the process is killed even if the watched files
|
|
6
|
+
* keep advancing (a wedge coinciding with unrelated file writes, or I/O hung
|
|
7
|
+
* beyond any legitimate statement). 10× the 60s default ⇒ 10 minutes.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PROGRESS_CAP_MULTIPLIER = 10;
|
|
3
10
|
/** Parse the timeout env, falling back to the default for missing/invalid values. */
|
|
4
11
|
export declare function parseWatchdogTimeoutMs(raw: string | undefined, fallback?: number): number;
|
|
5
12
|
/** Derive a heartbeat cadence that emits several beats inside the timeout window. */
|
|
@@ -8,11 +15,21 @@ export interface WatchdogHandle {
|
|
|
8
15
|
/** Stop heartbeating and shut the watchdog child down. Idempotent. */
|
|
9
16
|
stop(): void;
|
|
10
17
|
}
|
|
18
|
+
export interface WatchdogOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Files whose size/mtime advancing counts as forward progress (the SQLite
|
|
21
|
+
* DB + `-wal` for an in-process indexer). With paths supplied, a silent
|
|
22
|
+
* timeout only kills when the files did NOT advance — see the header. Omit
|
|
23
|
+
* for pure heartbeat behavior (the daemon, whose main thread never runs
|
|
24
|
+
* long synchronous work).
|
|
25
|
+
*/
|
|
26
|
+
progressPaths?: string[];
|
|
27
|
+
}
|
|
11
28
|
/**
|
|
12
29
|
* Install the main-thread liveness watchdog for a long-lived process. Returns a
|
|
13
30
|
* handle to stop it, or `null` when disabled or when the child can't be spawned
|
|
14
31
|
* (degraded, never throws — a missing watchdog must never keep a process from
|
|
15
32
|
* starting).
|
|
16
33
|
*/
|
|
17
|
-
export declare function installMainThreadWatchdog(): WatchdogHandle | null;
|
|
34
|
+
export declare function installMainThreadWatchdog(options?: WatchdogOptions): WatchdogHandle | null;
|
|
18
35
|
//# sourceMappingURL=liveness-watchdog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveness-watchdog.d.ts","sourceRoot":"","sources":["../../src/mcp/liveness-watchdog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"liveness-watchdog.d.ts","sourceRoot":"","sources":["../../src/mcp/liveness-watchdog.ts"],"names":[],"mappings":"AAwDA,uGAAuG;AACvG,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAQ1C,qFAAqF;AACrF,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,GAAE,MAAoC,GAC7C,MAAM,CAIR;AAED,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/D;AASD,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,IAAI,IAAI,IAAI,CAAC;CACd;AA8DD,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,GAAG,IAAI,CAgE9F"}
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.DEFAULT_WATCHDOG_TIMEOUT_MS = void 0;
|
|
36
|
+
exports.PROGRESS_CAP_MULTIPLIER = exports.DEFAULT_WATCHDOG_TIMEOUT_MS = void 0;
|
|
37
37
|
exports.parseWatchdogTimeoutMs = parseWatchdogTimeoutMs;
|
|
38
38
|
exports.deriveCheckIntervalMs = deriveCheckIntervalMs;
|
|
39
39
|
exports.installMainThreadWatchdog = installMainThreadWatchdog;
|
|
@@ -68,16 +68,39 @@ exports.installMainThreadWatchdog = installMainThreadWatchdog;
|
|
|
68
68
|
* orphan).
|
|
69
69
|
*
|
|
70
70
|
* **Won't fire on real work.** Heavy parsing runs in the parse worker
|
|
71
|
-
* (off-thread) and indexing shells out to a child process, so the
|
|
72
|
-
* thread only ever does fast, bounded work. The default timeout
|
|
73
|
-
* 5h #850 wedge shorter, yet far longer than any legitimate
|
|
74
|
-
* Opt out with `HOMEGRAPH_NO_WATCHDOG=1`; tune with
|
|
71
|
+
* (off-thread) and the daemon's indexing shells out to a child process, so the
|
|
72
|
+
* daemon's main thread only ever does fast, bounded work. The default timeout
|
|
73
|
+
* is ~300× the 5h #850 wedge shorter, yet far longer than any legitimate
|
|
74
|
+
* main-thread block. Opt out with `HOMEGRAPH_NO_WATCHDOG=1`; tune with
|
|
75
|
+
* `HOMEGRAPH_WATCHDOG_TIMEOUT_MS`.
|
|
76
|
+
*
|
|
77
|
+
* **Disk-progress deferral (`progressPaths`).** The CLI `index`/`init` path is
|
|
78
|
+
* different: it runs the SQLite store on this thread, and one long synchronous
|
|
79
|
+
* statement on severely degraded storage can block the loop past the timeout
|
|
80
|
+
* with the process perfectly healthy (#1231: killed a valid index on a
|
|
81
|
+
* 150-IOPS disk). Heartbeat silence alone cannot tell that apart from a wedge —
|
|
82
|
+
* but the disk can: a wedged CPU loop makes no forward progress on the DB
|
|
83
|
+
* files, while a slow store advances them. When the caller supplies
|
|
84
|
+
* `progressPaths` (the SQLite DB + `-wal`), the child checks them at each
|
|
85
|
+
* silent timeout: size/mtime advanced ⇒ defer the kill and keep watching;
|
|
86
|
+
* unchanged ⇒ kill as before. Deferral is bounded by a hard cap
|
|
87
|
+
* (`PROGRESS_CAP_MULTIPLIER` × timeout) of continuous silence, so a wedge
|
|
88
|
+
* coinciding with unrelated file activity — or I/O hung beyond all reason —
|
|
89
|
+
* still dies. A true wedge with no disk progress dies at the base timeout,
|
|
90
|
+
* exactly as before.
|
|
75
91
|
*/
|
|
76
92
|
const fs = __importStar(require("fs"));
|
|
77
93
|
const os = __importStar(require("os"));
|
|
78
94
|
const child_process_1 = require("child_process");
|
|
79
95
|
/** Default: 60s — ~300× shorter than the 5h #850 wedge, far longer than any real main-thread block. */
|
|
80
96
|
exports.DEFAULT_WATCHDOG_TIMEOUT_MS = 60_000;
|
|
97
|
+
/**
|
|
98
|
+
* Hard cap on disk-progress deferral: after this many timeouts' worth of
|
|
99
|
+
* CONTINUOUS heartbeat silence the process is killed even if the watched files
|
|
100
|
+
* keep advancing (a wedge coinciding with unrelated file writes, or I/O hung
|
|
101
|
+
* beyond any legitimate statement). 10× the 60s default ⇒ 10 minutes.
|
|
102
|
+
*/
|
|
103
|
+
exports.PROGRESS_CAP_MULTIPLIER = 10;
|
|
81
104
|
/** `true` for `1/true/yes/on` (case-insensitive); `false` otherwise. */
|
|
82
105
|
function isEnvTruthy(raw) {
|
|
83
106
|
if (!raw)
|
|
@@ -115,15 +138,50 @@ const CHILD_SOURCE = `
|
|
|
115
138
|
const fs = require('fs');
|
|
116
139
|
const parentPid = Number(process.argv[1]);
|
|
117
140
|
const timeoutMs = Number(process.argv[2]);
|
|
141
|
+
const capMs = Number(process.argv[3]);
|
|
142
|
+
const progressPaths = process.argv.slice(4);
|
|
118
143
|
const secs = Math.round(timeoutMs / 1000);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
try { fs.writeSync(2, MSG); } catch (e) {}
|
|
144
|
+
function kill(extra) {
|
|
145
|
+
try { fs.writeSync(2, Buffer.from('[HomeGraph] Main thread unresponsive for ~' + secs + 's' + (extra || '') + ' — killing the wedged process so a fresh one can start (#850). Disable with HOMEGRAPH_NO_WATCHDOG=1.\\n')); } catch (e) {}
|
|
122
146
|
try { process.kill(parentPid, 'SIGKILL'); } catch (e) {}
|
|
123
147
|
process.exit(0);
|
|
124
148
|
}
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
// Fingerprint of the watched files (size + mtime). A change between checks is
|
|
150
|
+
// forward disk progress — a slow synchronous SQLite statement, not a wedge.
|
|
151
|
+
function snap() {
|
|
152
|
+
let s = '';
|
|
153
|
+
for (const p of progressPaths) {
|
|
154
|
+
try { const st = fs.statSync(p); s += st.size + ':' + st.mtimeMs + ';'; } catch (e) { s += 'x;'; }
|
|
155
|
+
}
|
|
156
|
+
return s;
|
|
157
|
+
}
|
|
158
|
+
let lastSnap = progressPaths.length ? snap() : '';
|
|
159
|
+
let lastSnapAt = Date.now();
|
|
160
|
+
let silentSince = null; // start of the current continuous-silence episode
|
|
161
|
+
function onTimeout() {
|
|
162
|
+
if (!progressPaths.length) return kill('');
|
|
163
|
+
const now = Date.now();
|
|
164
|
+
if (silentSince === null) silentSince = now - timeoutMs; // silence began ~one timeout ago
|
|
165
|
+
const cur = snap();
|
|
166
|
+
if (cur !== lastSnap && now - silentSince < capMs) {
|
|
167
|
+
// The event loop is blocked but the DB files are advancing: a legitimate
|
|
168
|
+
// long store on slow storage. Defer, re-baseline, keep watching.
|
|
169
|
+
lastSnap = cur;
|
|
170
|
+
timer = setTimeout(onTimeout, timeoutMs);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
kill(cur !== lastSnap ? ' despite ongoing disk activity (hard cap ' + Math.round(capMs / 1000) + 's reached)' : '');
|
|
174
|
+
}
|
|
175
|
+
let timer = setTimeout(onTimeout, timeoutMs);
|
|
176
|
+
process.stdin.on('data', () => {
|
|
177
|
+
silentSince = null;
|
|
178
|
+
// Keep the baseline fresh while healthy (throttled — a stat per second).
|
|
179
|
+
if (progressPaths.length) {
|
|
180
|
+
const t = Date.now();
|
|
181
|
+
if (t - lastSnapAt >= 1000) { lastSnap = snap(); lastSnapAt = t; }
|
|
182
|
+
}
|
|
183
|
+
clearTimeout(timer); timer = setTimeout(onTimeout, timeoutMs);
|
|
184
|
+
});
|
|
127
185
|
process.stdin.on('end', () => process.exit(0)); // parent closed the pipe (exited) -> no orphan
|
|
128
186
|
process.stdin.on('error', () => process.exit(0)); // pipe broke -> parent gone
|
|
129
187
|
process.stdin.resume();
|
|
@@ -134,17 +192,19 @@ process.stdin.resume();
|
|
|
134
192
|
* (degraded, never throws — a missing watchdog must never keep a process from
|
|
135
193
|
* starting).
|
|
136
194
|
*/
|
|
137
|
-
function installMainThreadWatchdog() {
|
|
195
|
+
function installMainThreadWatchdog(options = {}) {
|
|
138
196
|
if (isEnvTruthy(process.env.HOMEGRAPH_NO_WATCHDOG))
|
|
139
197
|
return null;
|
|
140
198
|
const timeoutMs = parseWatchdogTimeoutMs(process.env.HOMEGRAPH_WATCHDOG_TIMEOUT_MS);
|
|
141
199
|
const checkMs = deriveCheckIntervalMs(timeoutMs);
|
|
200
|
+
const capMs = timeoutMs * exports.PROGRESS_CAP_MULTIPLIER;
|
|
201
|
+
const progressPaths = options.progressPaths ?? [];
|
|
142
202
|
let child;
|
|
143
203
|
try {
|
|
144
204
|
// No execArgv inheritance (unlike Worker), so the child carries none of our
|
|
145
205
|
// V8 flags — it runs no WASM and needs none. stderr inherits the parent's
|
|
146
206
|
// fd 2 so the kill notice lands wherever the parent logs (daemon.log).
|
|
147
|
-
child = (0, child_process_1.spawn)(process.execPath, ['-e', CHILD_SOURCE, String(process.pid), String(timeoutMs)], {
|
|
207
|
+
child = (0, child_process_1.spawn)(process.execPath, ['-e', CHILD_SOURCE, String(process.pid), String(timeoutMs), String(capMs), ...progressPaths], {
|
|
148
208
|
stdio: ['pipe', 'ignore', 'inherit'],
|
|
149
209
|
windowsHide: true,
|
|
150
210
|
// The watchdog touches no files; keep its cwd off the project/temp dir
|
|
@@ -185,7 +245,7 @@ function installMainThreadWatchdog() {
|
|
|
185
245
|
stdin.unref?.();
|
|
186
246
|
}
|
|
187
247
|
catch { /* ignore */ }
|
|
188
|
-
debug(`armed (child pid ${child.pid ?? '?'}): timeoutMs=${timeoutMs} checkMs=${checkMs}`);
|
|
248
|
+
debug(`armed (child pid ${child.pid ?? '?'}): timeoutMs=${timeoutMs} checkMs=${checkMs} progressPaths=${progressPaths.length}`);
|
|
189
249
|
let stopped = false;
|
|
190
250
|
return {
|
|
191
251
|
stop() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveness-watchdog.js","sourceRoot":"","sources":["../../src/mcp/liveness-watchdog.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"liveness-watchdog.js","sourceRoot":"","sources":["../../src/mcp/liveness-watchdog.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EA,wDAOC;AAGD,sDAEC;AA2FD,8DAgEC;AAjPD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,uCAAyB;AACzB,uCAAyB;AACzB,iDAAoD;AAEpD,uGAAuG;AAC1F,QAAA,2BAA2B,GAAG,MAAM,CAAC;AAElD;;;;;GAKG;AACU,QAAA,uBAAuB,GAAG,EAAE,CAAC;AAE1C,wEAAwE;AACxE,SAAS,WAAW,CAAC,GAAuB;IAC1C,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,qFAAqF;AACrF,SAAgB,sBAAsB,CACpC,GAAuB,EACvB,WAAmB,mCAA2B;IAE9C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpD,CAAC;AAED,qFAAqF;AACrF,SAAgB,qBAAqB,CAAC,SAAiB;IACrD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,2EAA2E;AAC3E,SAAS,KAAK,CAAC,GAAW;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC;YAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAOD;;;;;;GAMG;AACH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDpB,CAAC;AAaF;;;;;GAKG;AACH,SAAgB,yBAAyB,CAAC,UAA2B,EAAE;IACrE,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhE,MAAM,SAAS,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IACpF,MAAM,OAAO,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,SAAS,GAAG,+BAAuB,CAAC;IAClD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAElD,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,4EAA4E;QAC5E,0EAA0E;QAC1E,uEAAuE;QACvE,KAAK,GAAG,IAAA,qBAAK,EACX,OAAO,CAAC,QAAQ,EAChB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,aAAa,CAAC,EAC7F;YACE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC;YACpC,WAAW,EAAE,IAAI;YACjB,uEAAuE;YACvE,mEAAmE;YACnE,uBAAuB;YACvB,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE;SACjB,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC7C,IAAI,CAAC;YAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,6EAA6E;IAC7E,mEAAmE;IACnE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAsD,CAAC,CAAC,CAAC;IAChF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAEjE,8EAA8E;IAC9E,6EAA6E;IAC7E,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,IAAI,CAAC;YAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACvD,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,SAAS,CAAC,KAAK,EAAE,CAAC;IAElB,6EAA6E;IAC7E,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,IAAI,CAAC;QAAE,KAA2C,CAAC,KAAK,EAAE,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAEtF,KAAK,CAAC,oBAAoB,KAAK,CAAC,GAAG,IAAI,GAAG,gBAAgB,SAAS,YAAY,OAAO,kBAAkB,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhI,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO;QACL,IAAI;YACF,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,aAAa,CAAC,SAAS,CAAC,CAAC;YACzB,IAAI,CAAC;gBAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,6BAA6B;YACzE,IAAI,CAAC;gBAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,sBAAsB;QACrE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide RSS budget for the HomeGraph MCP / daemon process.
|
|
3
|
+
*
|
|
4
|
+
* Large indexes (~hundreds of MB SQLite) + catch-up sync (tree-sitter re-parse)
|
|
5
|
+
* + unbounded callers/explore graphs previously pushed a single Node process
|
|
6
|
+
* into multi-GB RSS. Agents measure the parent process tree, so that shows up
|
|
7
|
+
* as ~5GB "peaks". Cap the HomeGraph process itself so *no* query or background
|
|
8
|
+
* path can quietly grow without bound.
|
|
9
|
+
*
|
|
10
|
+
* Override with `HOMEGRAPH_MAX_RSS_MB` (clamped 256–4096). Default 1024.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveMaxRssMb(): number;
|
|
13
|
+
export declare function getProcessRssMb(): number;
|
|
14
|
+
export declare function isOverRssBudget(maxMb?: number): boolean;
|
|
15
|
+
/** Soft tripwire — stop growing (catch-up etc.) before the hard tool refusal. */
|
|
16
|
+
export declare function isNearRssBudget(maxMb?: number): boolean;
|
|
17
|
+
export declare function rssBudgetPartialText(context?: string): string;
|
|
18
|
+
export declare function rssBudgetPartialResult(context?: string): {
|
|
19
|
+
content: Array<{
|
|
20
|
+
type: 'text';
|
|
21
|
+
text: string;
|
|
22
|
+
}>;
|
|
23
|
+
isError: false;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* MCP catch-up sync re-scans + may re-parse dirty files — the multi-GB path on
|
|
27
|
+
* large indexes. Skip unless explicitly forced.
|
|
28
|
+
*/
|
|
29
|
+
export declare function shouldSkipCatchUpSync(dbPath: string | null | undefined): boolean;
|
|
30
|
+
//# sourceMappingURL=memory-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-budget.d.ts","sourceRoot":"","sources":["../../src/mcp/memory-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAED,wBAAgB,eAAe,CAAC,KAAK,GAAE,MAA0B,GAAG,OAAO,CAE1E;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,KAAK,GAAE,MAA0B,GAAG,OAAO,CAE1E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG;IACxD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,KAAK,CAAC;CAChB,CAKA;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAahF"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Process-wide RSS budget for the HomeGraph MCP / daemon process.
|
|
4
|
+
*
|
|
5
|
+
* Large indexes (~hundreds of MB SQLite) + catch-up sync (tree-sitter re-parse)
|
|
6
|
+
* + unbounded callers/explore graphs previously pushed a single Node process
|
|
7
|
+
* into multi-GB RSS. Agents measure the parent process tree, so that shows up
|
|
8
|
+
* as ~5GB "peaks". Cap the HomeGraph process itself so *no* query or background
|
|
9
|
+
* path can quietly grow without bound.
|
|
10
|
+
*
|
|
11
|
+
* Override with `HOMEGRAPH_MAX_RSS_MB` (clamped 256–4096). Default 1024.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.resolveMaxRssMb = resolveMaxRssMb;
|
|
48
|
+
exports.getProcessRssMb = getProcessRssMb;
|
|
49
|
+
exports.isOverRssBudget = isOverRssBudget;
|
|
50
|
+
exports.isNearRssBudget = isNearRssBudget;
|
|
51
|
+
exports.rssBudgetPartialText = rssBudgetPartialText;
|
|
52
|
+
exports.rssBudgetPartialResult = rssBudgetPartialResult;
|
|
53
|
+
exports.shouldSkipCatchUpSync = shouldSkipCatchUpSync;
|
|
54
|
+
const fs = __importStar(require("fs"));
|
|
55
|
+
const DEFAULT_MAX_RSS_MB = 1024;
|
|
56
|
+
const MIN_MAX_RSS_MB = 256;
|
|
57
|
+
const MAX_MAX_RSS_MB = 4096;
|
|
58
|
+
/** Index files at/above this size skip MCP catch-up sync unless forced. */
|
|
59
|
+
const LARGE_INDEX_SKIP_CATCHUP_BYTES = 64 * 1024 * 1024;
|
|
60
|
+
function resolveMaxRssMb() {
|
|
61
|
+
const raw = process.env.HOMEGRAPH_MAX_RSS_MB;
|
|
62
|
+
if (raw === undefined || raw === '')
|
|
63
|
+
return DEFAULT_MAX_RSS_MB;
|
|
64
|
+
const n = Number(raw);
|
|
65
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
66
|
+
return DEFAULT_MAX_RSS_MB;
|
|
67
|
+
return Math.min(MAX_MAX_RSS_MB, Math.max(MIN_MAX_RSS_MB, Math.floor(n)));
|
|
68
|
+
}
|
|
69
|
+
function getProcessRssMb() {
|
|
70
|
+
try {
|
|
71
|
+
return process.memoryUsage().rss / (1024 * 1024);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function isOverRssBudget(maxMb = resolveMaxRssMb()) {
|
|
78
|
+
return getProcessRssMb() >= maxMb;
|
|
79
|
+
}
|
|
80
|
+
/** Soft tripwire — stop growing (catch-up etc.) before the hard tool refusal. */
|
|
81
|
+
function isNearRssBudget(maxMb = resolveMaxRssMb()) {
|
|
82
|
+
return getProcessRssMb() >= maxMb * 0.7;
|
|
83
|
+
}
|
|
84
|
+
function rssBudgetPartialText(context) {
|
|
85
|
+
const max = resolveMaxRssMb();
|
|
86
|
+
const now = Math.round(getProcessRssMb());
|
|
87
|
+
const where = context ? ` (${context})` : '';
|
|
88
|
+
return (`⚠️ **Partial result** — HomeGraph hit its process memory budget ` +
|
|
89
|
+
`(~${now}MB RSS, limit ${max}MB)${where}. This is NOT an error. ` +
|
|
90
|
+
`Retry ONE tighter \`homegraph_explore\` / \`homegraph_callers\` with a concrete ` +
|
|
91
|
+
`symbol name — do not fan out dozens of caller lookups, and do not grep the same symbols.`);
|
|
92
|
+
}
|
|
93
|
+
function rssBudgetPartialResult(context) {
|
|
94
|
+
return {
|
|
95
|
+
content: [{ type: 'text', text: rssBudgetPartialText(context) }],
|
|
96
|
+
isError: false,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* MCP catch-up sync re-scans + may re-parse dirty files — the multi-GB path on
|
|
101
|
+
* large indexes. Skip unless explicitly forced.
|
|
102
|
+
*/
|
|
103
|
+
function shouldSkipCatchUpSync(dbPath) {
|
|
104
|
+
const force = process.env.HOMEGRAPH_FORCE_CATCHUP_SYNC;
|
|
105
|
+
if (force === '1' || force === 'true' || force === 'yes')
|
|
106
|
+
return false;
|
|
107
|
+
const skip = process.env.HOMEGRAPH_SKIP_CATCHUP_SYNC;
|
|
108
|
+
if (skip === '1' || skip === 'true' || skip === 'yes')
|
|
109
|
+
return true;
|
|
110
|
+
if (isNearRssBudget())
|
|
111
|
+
return true;
|
|
112
|
+
if (!dbPath)
|
|
113
|
+
return false;
|
|
114
|
+
try {
|
|
115
|
+
if (fs.statSync(dbPath).size >= LARGE_INDEX_SKIP_CATCHUP_BYTES)
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
/* missing — allow catch-up attempt */
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=memory-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-budget.js","sourceRoot":"","sources":["../../src/mcp/memory-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,4 +41,22 @@ export interface SupervisionState {
|
|
|
41
41
|
* supervisor and should shut down, or null while it is still supervised.
|
|
42
42
|
*/
|
|
43
43
|
export declare function supervisionLostReason(state: SupervisionState): string | null;
|
|
44
|
+
/** Default PPID poll cadence (ms). Shared by the MCP server and CLI commands. */
|
|
45
|
+
export declare const DEFAULT_PPID_POLL_MS = 5000;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the PPID watchdog poll interval from an env override
|
|
48
|
+
* (`CODEGRAPH_PPID_POLL_MS`). A value of `0` disables the watchdog entirely
|
|
49
|
+
* (escape hatch for embedded scenarios where the parent legitimately re-parents
|
|
50
|
+
* the process on purpose). Anything non-numeric or negative falls back to the
|
|
51
|
+
* default.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parsePpidPollMs(raw: string | undefined): number;
|
|
54
|
+
/**
|
|
55
|
+
* Parse the host PID propagated across the `--liftoff-only` re-exec
|
|
56
|
+
* (`CODEGRAPH_HOST_PPID`). Returns a positive integer PID, or null when
|
|
57
|
+
* unset/invalid — the direct-launch path, where the watchdog falls back to
|
|
58
|
+
* `process.ppid` divergence. PIDs of 0/1 are rejected (0 = unknown, 1 = init,
|
|
59
|
+
* i.e. already orphaned), so the watchdog doesn't latch onto init.
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseHostPpid(raw: string | undefined): number | null;
|
|
44
62
|
//# sourceMappingURL=ppid-watchdog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ppid-watchdog.d.ts","sourceRoot":"","sources":["../../src/mcp/ppid-watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+EAA+E;IAC/E,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAmB5E"}
|
|
1
|
+
{"version":3,"file":"ppid-watchdog.d.ts","sourceRoot":"","sources":["../../src/mcp/ppid-watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+EAA+E;IAC/E,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAmB5E;AAED,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM/D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKpE"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_PPID_POLL_MS = void 0;
|
|
3
4
|
exports.supervisionLostReason = supervisionLostReason;
|
|
5
|
+
exports.parsePpidPollMs = parsePpidPollMs;
|
|
6
|
+
exports.parseHostPpid = parseHostPpid;
|
|
4
7
|
/**
|
|
5
8
|
* Returns a human-readable reason string when the process has lost its
|
|
6
9
|
* supervisor and should shut down, or null while it is still supervised.
|
|
@@ -24,4 +27,38 @@ function supervisionLostReason(state) {
|
|
|
24
27
|
}
|
|
25
28
|
return null;
|
|
26
29
|
}
|
|
30
|
+
/** Default PPID poll cadence (ms). Shared by the MCP server and CLI commands. */
|
|
31
|
+
exports.DEFAULT_PPID_POLL_MS = 5000;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the PPID watchdog poll interval from an env override
|
|
34
|
+
* (`CODEGRAPH_PPID_POLL_MS`). A value of `0` disables the watchdog entirely
|
|
35
|
+
* (escape hatch for embedded scenarios where the parent legitimately re-parents
|
|
36
|
+
* the process on purpose). Anything non-numeric or negative falls back to the
|
|
37
|
+
* default.
|
|
38
|
+
*/
|
|
39
|
+
function parsePpidPollMs(raw) {
|
|
40
|
+
if (raw === undefined || raw === '')
|
|
41
|
+
return exports.DEFAULT_PPID_POLL_MS;
|
|
42
|
+
const parsed = Number(raw);
|
|
43
|
+
if (!Number.isFinite(parsed))
|
|
44
|
+
return exports.DEFAULT_PPID_POLL_MS;
|
|
45
|
+
if (parsed < 0)
|
|
46
|
+
return exports.DEFAULT_PPID_POLL_MS;
|
|
47
|
+
return Math.floor(parsed);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse the host PID propagated across the `--liftoff-only` re-exec
|
|
51
|
+
* (`CODEGRAPH_HOST_PPID`). Returns a positive integer PID, or null when
|
|
52
|
+
* unset/invalid — the direct-launch path, where the watchdog falls back to
|
|
53
|
+
* `process.ppid` divergence. PIDs of 0/1 are rejected (0 = unknown, 1 = init,
|
|
54
|
+
* i.e. already orphaned), so the watchdog doesn't latch onto init.
|
|
55
|
+
*/
|
|
56
|
+
function parseHostPpid(raw) {
|
|
57
|
+
if (raw === undefined || raw === '')
|
|
58
|
+
return null;
|
|
59
|
+
const parsed = Number(raw);
|
|
60
|
+
if (!Number.isInteger(parsed) || parsed <= 1)
|
|
61
|
+
return null;
|
|
62
|
+
return parsed;
|
|
63
|
+
}
|
|
27
64
|
//# sourceMappingURL=ppid-watchdog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ppid-watchdog.js","sourceRoot":"","sources":["../../src/mcp/ppid-watchdog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ppid-watchdog.js","sourceRoot":"","sources":["../../src/mcp/ppid-watchdog.ts"],"names":[],"mappings":";;;AA2CA,sDAmBC;AAYD,0CAMC;AASD,sCAKC;AAvDD;;;GAGG;AACH,SAAgB,qBAAqB,CAAC,KAAuB;IAC3D,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAEpD,8EAA8E;IAC9E,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;QACjC,OAAO,QAAQ,YAAY,OAAO,WAAW,EAAE,CAAC;IAClD,CAAC;IACD,yEAAyE;IACzE,2EAA2E;IAC3E,0DAA0D;IAC1D,IAAI,QAAQ,KAAK,OAAO,IAAI,YAAY,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACvE,OAAO,cAAc,YAAY,SAAS,CAAC;IAC7C,CAAC;IACD,uEAAuE;IACvE,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,YAAY,QAAQ,SAAS,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iFAAiF;AACpE,QAAA,oBAAoB,GAAG,IAAI,CAAC;AAEzC;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,GAAuB;IACrD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,4BAAoB,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,4BAAoB,CAAC;IAC1D,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,4BAAoB,CAAC;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,GAAuB;IACnD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/mcp/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/mcp/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAqB,WAAW,EAAwB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/mcp/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAqB,WAAW,EAAwB,MAAM,UAAU,CAAC;AAWhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAc1C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAK9E;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,OAAO,EAAE,SAAS,GAAG,iBAAiB,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAgC,GAChD,OAAO,CAAC,WAAW,CAAC,CAqCtB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAgC,GAChD,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC,CAgCjD;AAsBD;+DAC+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC;yFACqF;IACrF,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C;6EACyE;IACzE,UAAU,IAAI,SAAS,CAAC;IACxB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4PpF"}
|
package/dist/mcp/proxy.js
CHANGED
|
@@ -60,12 +60,15 @@ const fs = __importStar(require("fs"));
|
|
|
60
60
|
const net = __importStar(require("net"));
|
|
61
61
|
const wasm_runtime_flags_1 = require("../extraction/wasm-runtime-flags");
|
|
62
62
|
const daemon_1 = require("./daemon");
|
|
63
|
+
const early_ppid_1 = require("./early-ppid");
|
|
63
64
|
const ppid_watchdog_1 = require("./ppid-watchdog");
|
|
65
|
+
const startup_handshake_1 = require("./startup-handshake");
|
|
64
66
|
const stdin_teardown_1 = require("./stdin-teardown");
|
|
65
67
|
const version_1 = require("./version");
|
|
66
68
|
const session_1 = require("./session");
|
|
67
69
|
const server_instructions_1 = require("./server-instructions");
|
|
68
70
|
const tools_1 = require("./tools");
|
|
71
|
+
const query_pool_1 = require("./query-pool");
|
|
69
72
|
const telemetry_1 = require("../telemetry");
|
|
70
73
|
/** Default poll cadence for the PPID watchdog (same as the direct server). */
|
|
71
74
|
const DEFAULT_PPID_POLL_MS = 5000;
|
|
@@ -183,7 +186,7 @@ function sendClientHello(socket) {
|
|
|
183
186
|
const clientHello = {
|
|
184
187
|
homegraph_client: 1,
|
|
185
188
|
pid: process.pid,
|
|
186
|
-
hostPid: parseHostPpid(process.env[wasm_runtime_flags_1.HOST_PPID_ENV]) ??
|
|
189
|
+
hostPid: parseHostPpid(process.env[wasm_runtime_flags_1.HOST_PPID_ENV]) ?? early_ppid_1.EARLY_PPID,
|
|
187
190
|
};
|
|
188
191
|
try {
|
|
189
192
|
socket.write(JSON.stringify(clientHello) + '\n');
|
|
@@ -220,6 +223,11 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
220
223
|
// new session starts), these would otherwise hang forever; we re-serve them
|
|
221
224
|
// in-process so the host always gets a reply.
|
|
222
225
|
const inflight = new Map();
|
|
226
|
+
// tools/call forwarded to the daemon that hit the proxy-side deadline.
|
|
227
|
+
// Late daemon replies for these ids are dropped so the client isn't confused
|
|
228
|
+
// by a second response after it already got Partial (or timed out itself).
|
|
229
|
+
const timedOutToolIds = new Set();
|
|
230
|
+
const toolDeadlineTimers = new Map();
|
|
223
231
|
const trackInflight = (line) => {
|
|
224
232
|
try {
|
|
225
233
|
const m = JSON.parse(line);
|
|
@@ -235,10 +243,56 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
235
243
|
}
|
|
236
244
|
catch { /* host gone */ }
|
|
237
245
|
};
|
|
246
|
+
/** Proxy-side deadline — daemon wedging must not become empty client `-32001`. */
|
|
247
|
+
const armToolCallDeadline = (id) => {
|
|
248
|
+
if (id === undefined || id === null)
|
|
249
|
+
return;
|
|
250
|
+
const prev = toolDeadlineTimers.get(id);
|
|
251
|
+
if (prev)
|
|
252
|
+
clearTimeout(prev);
|
|
253
|
+
const deadlineMs = (0, query_pool_1.resolveToolDeadlineMs)();
|
|
254
|
+
const timer = setTimeout(() => {
|
|
255
|
+
toolDeadlineTimers.delete(id);
|
|
256
|
+
if (!inflight.has(id))
|
|
257
|
+
return; // already answered
|
|
258
|
+
inflight.delete(id);
|
|
259
|
+
timedOutToolIds.add(id);
|
|
260
|
+
const secs = Math.max(1, Math.round(deadlineMs / 1000));
|
|
261
|
+
writeClient({
|
|
262
|
+
jsonrpc: '2.0',
|
|
263
|
+
id,
|
|
264
|
+
result: {
|
|
265
|
+
content: [{
|
|
266
|
+
type: 'text',
|
|
267
|
+
text: `⚠️ **Partial result** — HomeGraph did not finish within ${secs}s (daemon busy or wedged). ` +
|
|
268
|
+
`This is NOT an error. Retry ONE \`homegraph_explore\` with concrete symbol/file names — ` +
|
|
269
|
+
`do not stack search+explore, and do not grep symbols you already named.`,
|
|
270
|
+
}],
|
|
271
|
+
isError: false,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
}, deadlineMs);
|
|
275
|
+
toolDeadlineTimers.set(id, timer);
|
|
276
|
+
};
|
|
277
|
+
const clearToolCallDeadline = (id) => {
|
|
278
|
+
const t = toolDeadlineTimers.get(id);
|
|
279
|
+
if (t) {
|
|
280
|
+
clearTimeout(t);
|
|
281
|
+
toolDeadlineTimers.delete(id);
|
|
282
|
+
}
|
|
283
|
+
if (timedOutToolIds.has(id)) {
|
|
284
|
+
timedOutToolIds.delete(id);
|
|
285
|
+
return 'already-timed-out';
|
|
286
|
+
}
|
|
287
|
+
return 'ok';
|
|
288
|
+
};
|
|
238
289
|
const shutdown = () => {
|
|
239
290
|
if (shuttingDown)
|
|
240
291
|
return;
|
|
241
292
|
shuttingDown = true;
|
|
293
|
+
for (const t of toolDeadlineTimers.values())
|
|
294
|
+
clearTimeout(t);
|
|
295
|
+
toolDeadlineTimers.clear();
|
|
242
296
|
try {
|
|
243
297
|
daemonSocket?.destroy();
|
|
244
298
|
}
|
|
@@ -291,6 +345,8 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
291
345
|
const routeToDaemon = (line) => {
|
|
292
346
|
if (daemonStatus === 'ready' && daemonSocket) {
|
|
293
347
|
trackInflight(line);
|
|
348
|
+
if (process.env.HOMEGRAPH_MCP_DEBUG)
|
|
349
|
+
process.stderr.write(`[mcp-debug] proxy->daemon ${line.slice(0, 80)}\n`);
|
|
294
350
|
try {
|
|
295
351
|
daemonSocket.write(line.endsWith('\n') ? line : line + '\n');
|
|
296
352
|
}
|
|
@@ -300,6 +356,8 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
300
356
|
void handleLocally(line);
|
|
301
357
|
}
|
|
302
358
|
else {
|
|
359
|
+
if (process.env.HOMEGRAPH_MCP_DEBUG)
|
|
360
|
+
process.stderr.write(`[mcp-debug] proxy-buffer(${daemonStatus}) ${line.slice(0, 80)}\n`);
|
|
303
361
|
pending.push(line);
|
|
304
362
|
}
|
|
305
363
|
};
|
|
@@ -331,7 +389,7 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
331
389
|
version: typeof initParams.clientInfo.version === 'string' ? initParams.clientInfo.version : undefined,
|
|
332
390
|
};
|
|
333
391
|
}
|
|
334
|
-
writeClient({ jsonrpc: '2.0', id: msg.id, result: { protocolVersion: session_1.PROTOCOL_VERSION, capabilities: { tools: {} }, serverInfo: session_1.SERVER_INFO, instructions: server_instructions_1.SERVER_INSTRUCTIONS } });
|
|
392
|
+
writeClient({ jsonrpc: '2.0', id: msg.id, result: { protocolVersion: session_1.PROTOCOL_VERSION, capabilities: { tools: {} }, serverInfo: session_1.SERVER_INFO, instructions: (0, session_1.initializeInstructions)(server_instructions_1.SERVER_INSTRUCTIONS) } });
|
|
335
393
|
routeToDaemon(line); // prime the daemon so it resolves the project (its reply is suppressed below)
|
|
336
394
|
}
|
|
337
395
|
else if (msg.method === 'tools/list') {
|
|
@@ -349,6 +407,9 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
349
407
|
writeClient({ jsonrpc: '2.0', id: msg.id, result: { prompts: [] } });
|
|
350
408
|
}
|
|
351
409
|
else {
|
|
410
|
+
if (msg.method === 'tools/call' && msg.id !== undefined) {
|
|
411
|
+
armToolCallDeadline(msg.id);
|
|
412
|
+
}
|
|
352
413
|
routeToDaemon(line);
|
|
353
414
|
}
|
|
354
415
|
}
|
|
@@ -359,6 +420,16 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
359
420
|
// busy-spinning the event loop (#799).
|
|
360
421
|
(0, stdin_teardown_1.treatStdinFailureAsShutdown)(shutdown);
|
|
361
422
|
startPpidWatchdogNoSocket(shutdown);
|
|
423
|
+
// Backstop for a launch abandoned before any of the above can see it: killed
|
|
424
|
+
// launcher + held-open pipes + reparent that beat the EARLY_PPID capture
|
|
425
|
+
// (#1185). A server that never receives a single byte isn't serving anyone.
|
|
426
|
+
// Armed after the stdin 'data' consumer above so no bytes are emitted while
|
|
427
|
+
// only the backstop's listener exists.
|
|
428
|
+
(0, startup_handshake_1.armStartupHandshakeTimeout)(() => {
|
|
429
|
+
process.stderr.write('[HomeGraph MCP] No MCP traffic since startup; assuming an abandoned launch and shutting down (#1185). ' +
|
|
430
|
+
'Tune with HOMEGRAPH_STARTUP_HANDSHAKE_TIMEOUT_MS (0 disables).\n');
|
|
431
|
+
shutdown();
|
|
432
|
+
});
|
|
362
433
|
// ---- daemon connection (background) ----
|
|
363
434
|
let socket = null;
|
|
364
435
|
try {
|
|
@@ -388,7 +459,12 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
388
459
|
resp = JSON.parse(line);
|
|
389
460
|
}
|
|
390
461
|
catch { /* not JSON — relay verbatim */ }
|
|
462
|
+
if (process.env.HOMEGRAPH_MCP_DEBUG)
|
|
463
|
+
process.stderr.write(`[mcp-debug] daemon->proxy ${line.slice(0, 80)}\n`);
|
|
391
464
|
if (resp && resp.id !== undefined && ('result' in resp || 'error' in resp)) {
|
|
465
|
+
if (clearToolCallDeadline(resp.id) === 'already-timed-out') {
|
|
466
|
+
continue; // client already got Partial from the proxy deadline
|
|
467
|
+
}
|
|
392
468
|
inflight.delete(resp.id); // answered — no longer in flight
|
|
393
469
|
// Suppress the daemon's reply to the initialize we forwarded to prime it
|
|
394
470
|
// (the client already got the local handshake response).
|
|
@@ -422,6 +498,8 @@ async function runLocalHandshakeProxy(deps) {
|
|
|
422
498
|
socket.on('error', onDaemonLost);
|
|
423
499
|
for (const line of pending) {
|
|
424
500
|
trackInflight(line);
|
|
501
|
+
if (process.env.HOMEGRAPH_MCP_DEBUG)
|
|
502
|
+
process.stderr.write(`[mcp-debug] proxy-flush ${line.slice(0, 80)}\n`);
|
|
425
503
|
try {
|
|
426
504
|
socket.write(line + '\n');
|
|
427
505
|
}
|
|
@@ -445,7 +523,10 @@ function startPpidWatchdogNoSocket(onDeath) {
|
|
|
445
523
|
const pollMs = parsePollMs(process.env.HOMEGRAPH_PPID_POLL_MS);
|
|
446
524
|
if (pollMs <= 0)
|
|
447
525
|
return;
|
|
448
|
-
|
|
526
|
+
// Baseline from the CLI entry's earliest capture, not process.ppid here —
|
|
527
|
+
// a launcher killed during our first ~100ms would otherwise leave the
|
|
528
|
+
// baseline at 1 and blind the divergence check forever (#1185).
|
|
529
|
+
const originalPpid = early_ppid_1.EARLY_PPID;
|
|
449
530
|
const hostPpid = parseHostPpid(process.env[wasm_runtime_flags_1.HOST_PPID_ENV]);
|
|
450
531
|
const timer = setInterval(() => {
|
|
451
532
|
const reason = (0, ppid_watchdog_1.supervisionLostReason)({
|
|
@@ -588,7 +669,10 @@ function startPpidWatchdog(socket) {
|
|
|
588
669
|
const pollMs = parsePollMs(process.env.HOMEGRAPH_PPID_POLL_MS);
|
|
589
670
|
if (pollMs <= 0)
|
|
590
671
|
return;
|
|
591
|
-
|
|
672
|
+
// Baseline from the CLI entry's earliest capture, not process.ppid here —
|
|
673
|
+
// a launcher killed during our first ~100ms would otherwise leave the
|
|
674
|
+
// baseline at 1 and blind the divergence check forever (#1185).
|
|
675
|
+
const originalPpid = early_ppid_1.EARLY_PPID;
|
|
592
676
|
const hostPpid = parseHostPpid(process.env[wasm_runtime_flags_1.HOST_PPID_ENV]);
|
|
593
677
|
const timer = setInterval(() => {
|
|
594
678
|
const reason = (0, ppid_watchdog_1.supervisionLostReason)({
|