homegraph 1.2.0 → 1.5.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/README.md +48 -11
- package/dist/bin/homegraph.js +298 -72
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +117 -11
- package/dist/context/index.js.map +1 -1
- package/dist/db/index.d.ts +207 -6
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +461 -20
- 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 +19 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +157 -3
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +426 -9
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +32 -1
- package/dist/db/sqlite-adapter.d.ts +24 -17
- package/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.js +292 -36
- package/dist/db/sqlite-adapter.js.map +1 -1
- package/dist/db/wal-valve.d.ts +119 -0
- package/dist/db/wal-valve.d.ts.map +1 -0
- package/dist/db/wal-valve.js +290 -0
- package/dist/db/wal-valve.js.map +1 -0
- package/dist/directory.d.ts +9 -5
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +210 -19
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.js +3 -2
- package/dist/extraction/arkts-batch-worker.js.map +1 -1
- 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/default-ignore.d.ts +39 -0
- package/dist/extraction/default-ignore.d.ts.map +1 -0
- package/dist/extraction/default-ignore.js +221 -0
- package/dist/extraction/default-ignore.js.map +1 -0
- 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 +52 -14
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +521 -314
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +90 -6
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1579 -128
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +42 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +369 -4
- 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/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 +27 -1
- package/dist/extraction/parse-pool.d.ts.map +1 -1
- package/dist/extraction/parse-pool.js +75 -7
- package/dist/extraction/parse-pool.js.map +1 -1
- package/dist/extraction/parse-worker.js +9 -2
- package/dist/extraction/parse-worker.js.map +1 -1
- package/dist/extraction/store-worker.d.ts +20 -0
- package/dist/extraction/store-worker.d.ts.map +1 -0
- package/dist/extraction/store-worker.js +102 -0
- package/dist/extraction/store-worker.js.map +1 -0
- package/dist/extraction/store-writer.d.ts +48 -0
- package/dist/extraction/store-writer.d.ts.map +1 -0
- package/dist/extraction/store-writer.js +167 -0
- package/dist/extraction/store-writer.js.map +1 -0
- 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 +3 -1
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +38 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +801 -10
- 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/extraction/wasm-runtime-flags.d.ts +14 -4
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
- package/dist/extraction/wasm-runtime-flags.js +55 -7
- package/dist/extraction/wasm-runtime-flags.js.map +1 -1
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +1 -1
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +74 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +436 -55
- 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.d.ts +25 -3
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +62 -8
- 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 +4 -5
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +27 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +41 -6
- 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/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 +35 -4
- package/dist/mcp/query-cache.d.ts.map +1 -1
- package/dist/mcp/query-cache.js +89 -19
- package/dist/mcp/query-cache.js.map +1 -1
- package/dist/mcp/query-pool.d.ts +46 -12
- package/dist/mcp/query-pool.d.ts.map +1 -1
- package/dist/mcp/query-pool.js +100 -23
- package/dist/mcp/query-pool.js.map +1 -1
- package/dist/mcp/query-worker.d.ts +2 -2
- package/dist/mcp/query-worker.js +2 -2
- package/dist/mcp/server-instructions.d.ts +4 -27
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +39 -84
- 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 +104 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +2432 -217
- 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 +38 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +101 -2
- package/dist/project-config.js.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +178 -146
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +54 -10
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +1299 -257
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +10 -2
- package/dist/resolution/cooperative-yield.d.ts.map +1 -1
- package/dist/resolution/cooperative-yield.js +6 -4
- package/dist/resolution/cooperative-yield.js.map +1 -1
- 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/go.d.ts.map +1 -1
- package/dist/resolution/frameworks/go.js +29 -6
- package/dist/resolution/frameworks/go.js.map +1 -1
- 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 +9 -3
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +295 -11
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +146 -8
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +1089 -131
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/memory-budget.d.ts +48 -0
- package/dist/resolution/memory-budget.d.ts.map +1 -0
- package/dist/resolution/memory-budget.js +162 -0
- package/dist/resolution/memory-budget.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +12 -4
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +793 -130
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/resolver-pool.d.ts +106 -0
- package/dist/resolution/resolver-pool.d.ts.map +1 -0
- package/dist/resolution/resolver-pool.js +344 -0
- package/dist/resolution/resolver-pool.js.map +1 -0
- package/dist/resolution/resolver-worker.d.ts +17 -0
- package/dist/resolution/resolver-worker.d.ts.map +1 -0
- package/dist/resolution/resolver-worker.js +141 -0
- package/dist/resolution/resolver-worker.js.map +1 -0
- 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 +32 -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/build/diff-parser.d.ts +55 -0
- package/dist/spec/build/diff-parser.d.ts.map +1 -0
- package/dist/spec/build/diff-parser.js +205 -0
- package/dist/spec/build/diff-parser.js.map +1 -0
- package/dist/spec/build/git-scanner.d.ts +93 -0
- package/dist/spec/build/git-scanner.d.ts.map +1 -0
- package/dist/spec/build/git-scanner.js +254 -0
- package/dist/spec/build/git-scanner.js.map +1 -0
- package/dist/spec/build/pipeline.d.ts +54 -0
- package/dist/spec/build/pipeline.d.ts.map +1 -0
- package/dist/spec/build/pipeline.js +170 -0
- package/dist/spec/build/pipeline.js.map +1 -0
- package/dist/spec/build/scan.d.ts +48 -0
- package/dist/spec/build/scan.d.ts.map +1 -0
- package/dist/spec/build/scan.js +89 -0
- package/dist/spec/build/scan.js.map +1 -0
- package/dist/spec/build/scope-resolver.d.ts +50 -0
- package/dist/spec/build/scope-resolver.d.ts.map +1 -0
- package/dist/spec/build/scope-resolver.js +105 -0
- package/dist/spec/build/scope-resolver.js.map +1 -0
- package/dist/spec/build/spec-extractor.d.ts +74 -0
- package/dist/spec/build/spec-extractor.d.ts.map +1 -0
- package/dist/spec/build/spec-extractor.js +344 -0
- package/dist/spec/build/spec-extractor.js.map +1 -0
- package/dist/spec/config.d.ts +35 -1
- package/dist/spec/config.d.ts.map +1 -1
- package/dist/spec/config.js +30 -5
- package/dist/spec/config.js.map +1 -1
- package/dist/spec/db/fts.d.ts.map +1 -1
- package/dist/spec/db/fts.js +19 -50
- package/dist/spec/db/fts.js.map +1 -1
- package/dist/spec/db/index.d.ts +5 -3
- package/dist/spec/db/index.d.ts.map +1 -1
- package/dist/spec/db/index.js +16 -1
- package/dist/spec/db/index.js.map +1 -1
- package/dist/spec/db/persist.d.ts +45 -0
- package/dist/spec/db/persist.d.ts.map +1 -0
- package/dist/spec/db/persist.js +66 -0
- package/dist/spec/db/persist.js.map +1 -0
- package/dist/spec/db/relations.d.ts +80 -1
- package/dist/spec/db/relations.d.ts.map +1 -1
- package/dist/spec/db/relations.js +175 -4
- package/dist/spec/db/relations.js.map +1 -1
- package/dist/spec/db/schema.d.ts +4 -0
- package/dist/spec/db/schema.d.ts.map +1 -1
- package/dist/spec/db/schema.js +4 -0
- package/dist/spec/db/schema.js.map +1 -1
- package/dist/spec/db/schema.sql +5 -1
- package/dist/spec/db/spec-node.d.ts +5 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -1
- package/dist/spec/db/spec-node.js +11 -5
- package/dist/spec/db/spec-node.js.map +1 -1
- package/dist/spec/db/sql-utils.d.ts +11 -0
- package/dist/spec/db/sql-utils.d.ts.map +1 -0
- package/dist/spec/db/sql-utils.js +19 -0
- package/dist/spec/db/sql-utils.js.map +1 -0
- package/dist/spec/evolve/cluster-context.d.ts +30 -0
- package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
- package/dist/spec/evolve/cluster-context.js +78 -0
- package/dist/spec/evolve/cluster-context.js.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
- package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.js +93 -0
- package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +23 -7
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
- package/dist/spec/evolve/impact-locator.js +58 -14
- package/dist/spec/evolve/impact-locator.js.map +1 -1
- package/dist/spec/evolve/pipeline.d.ts +62 -25
- package/dist/spec/evolve/pipeline.d.ts.map +1 -1
- package/dist/spec/evolve/pipeline.js +436 -457
- package/dist/spec/evolve/pipeline.js.map +1 -1
- package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
- package/dist/spec/evolve/spec-rewriter.js +45 -45
- package/dist/spec/evolve/spec-rewriter.js.map +1 -1
- package/dist/spec/git/commits.d.ts +85 -0
- package/dist/spec/git/commits.d.ts.map +1 -0
- package/dist/spec/git/commits.js +218 -0
- package/dist/spec/git/commits.js.map +1 -0
- package/dist/spec/git/exec.d.ts +13 -0
- package/dist/spec/git/exec.d.ts.map +1 -0
- package/dist/spec/git/exec.js +19 -0
- package/dist/spec/git/exec.js.map +1 -0
- package/dist/spec/git/index.d.ts +9 -0
- package/dist/spec/git/index.d.ts.map +1 -0
- package/dist/spec/git/index.js +22 -0
- package/dist/spec/git/index.js.map +1 -0
- package/dist/spec/git-utils.d.ts +8 -0
- package/dist/spec/git-utils.d.ts.map +1 -0
- package/dist/spec/git-utils.js +14 -0
- package/dist/spec/git-utils.js.map +1 -0
- package/dist/spec/graph/index.d.ts +8 -0
- package/dist/spec/graph/index.d.ts.map +1 -0
- package/dist/spec/graph/index.js +17 -0
- package/dist/spec/graph/index.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +6 -35
- package/dist/spec/graph/queries.d.ts.map +1 -1
- package/dist/spec/graph/queries.js +71 -248
- package/dist/spec/graph/queries.js.map +1 -1
- package/dist/spec/llm/agent-client.d.ts +59 -0
- package/dist/spec/llm/agent-client.d.ts.map +1 -0
- package/dist/spec/llm/agent-client.js +213 -0
- package/dist/spec/llm/agent-client.js.map +1 -0
- package/dist/spec/llm/agents/claude-code.d.ts +32 -0
- package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/claude-code.js +125 -0
- package/dist/spec/llm/agents/claude-code.js.map +1 -0
- package/dist/spec/llm/agents/codex.d.ts +32 -0
- package/dist/spec/llm/agents/codex.d.ts.map +1 -0
- package/dist/spec/llm/agents/codex.js +145 -0
- package/dist/spec/llm/agents/codex.js.map +1 -0
- package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
- package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
- package/dist/spec/llm/agents/detect-utils.js +91 -0
- package/dist/spec/llm/agents/detect-utils.js.map +1 -0
- package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
- package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/deveco-code.js +165 -0
- package/dist/spec/llm/agents/deveco-code.js.map +1 -0
- package/dist/spec/llm/agents/index.d.ts +31 -0
- package/dist/spec/llm/agents/index.d.ts.map +1 -0
- package/dist/spec/llm/agents/index.js +65 -0
- package/dist/spec/llm/agents/index.js.map +1 -0
- package/dist/spec/llm/agents/types.d.ts +76 -0
- package/dist/spec/llm/agents/types.d.ts.map +1 -0
- package/dist/spec/llm/agents/types.js +15 -0
- package/dist/spec/llm/agents/types.js.map +1 -0
- package/dist/spec/llm/client.d.ts +31 -11
- package/dist/spec/llm/client.d.ts.map +1 -1
- package/dist/spec/llm/client.js +143 -81
- package/dist/spec/llm/client.js.map +1 -1
- package/dist/spec/llm/factory.d.ts +41 -0
- package/dist/spec/llm/factory.d.ts.map +1 -0
- package/dist/spec/llm/factory.js +80 -0
- package/dist/spec/llm/factory.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +24 -8
- package/dist/spec/llm/prompts.d.ts.map +1 -1
- package/dist/spec/llm/prompts.js +100 -50
- package/dist/spec/llm/prompts.js.map +1 -1
- package/dist/spec/llm/retry.d.ts +53 -0
- package/dist/spec/llm/retry.d.ts.map +1 -0
- package/dist/spec/llm/retry.js +153 -0
- package/dist/spec/llm/retry.js.map +1 -0
- package/dist/spec/mine/clusterer.d.ts +63 -0
- package/dist/spec/mine/clusterer.d.ts.map +1 -0
- package/dist/spec/mine/clusterer.js +904 -0
- package/dist/spec/mine/clusterer.js.map +1 -0
- package/dist/spec/mine/clustering/features.d.ts +38 -0
- package/dist/spec/mine/clustering/features.d.ts.map +1 -0
- package/dist/spec/mine/clustering/features.js +108 -0
- package/dist/spec/mine/clustering/features.js.map +1 -0
- package/dist/spec/mine/clustering/index.d.ts +62 -0
- package/dist/spec/mine/clustering/index.d.ts.map +1 -0
- package/dist/spec/mine/clustering/index.js +259 -0
- package/dist/spec/mine/clustering/index.js.map +1 -0
- package/dist/spec/mine/clustering/leiden.d.ts +61 -0
- package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
- package/dist/spec/mine/clustering/leiden.js +489 -0
- package/dist/spec/mine/clustering/leiden.js.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.js +98 -0
- package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
- package/dist/spec/mine/generator.d.ts +54 -0
- package/dist/spec/mine/generator.d.ts.map +1 -0
- package/dist/spec/mine/generator.js +267 -0
- package/dist/spec/mine/generator.js.map +1 -0
- package/dist/spec/mine/persist.d.ts +37 -0
- package/dist/spec/mine/persist.d.ts.map +1 -0
- package/dist/spec/mine/persist.js +170 -0
- package/dist/spec/mine/persist.js.map +1 -0
- package/dist/spec/mine/pipeline.d.ts +41 -0
- package/dist/spec/mine/pipeline.d.ts.map +1 -0
- package/dist/spec/mine/pipeline.js +236 -0
- package/dist/spec/mine/pipeline.js.map +1 -0
- package/dist/spec/mine/progress-handler.d.ts +22 -0
- package/dist/spec/mine/progress-handler.d.ts.map +1 -0
- package/dist/spec/mine/progress-handler.js +108 -0
- package/dist/spec/mine/progress-handler.js.map +1 -0
- package/dist/spec/mine/progress.d.ts +23 -0
- package/dist/spec/mine/progress.d.ts.map +1 -0
- package/dist/spec/mine/progress.js +12 -0
- package/dist/spec/mine/progress.js.map +1 -0
- package/dist/spec/mine/scanner.d.ts +59 -0
- package/dist/spec/mine/scanner.d.ts.map +1 -0
- package/dist/spec/mine/scanner.js +383 -0
- package/dist/spec/mine/scanner.js.map +1 -0
- package/dist/spec/types.d.ts +32 -0
- package/dist/spec/types.d.ts.map +1 -1
- package/dist/spec/ui/index.d.ts +9 -0
- package/dist/spec/ui/index.d.ts.map +1 -0
- package/dist/spec/ui/index.js +16 -0
- package/dist/spec/ui/index.js.map +1 -0
- package/dist/spec/ui/progress-handler.d.ts +33 -0
- package/dist/spec/ui/progress-handler.d.ts.map +1 -0
- package/dist/spec/ui/progress-handler.js +132 -0
- package/dist/spec/ui/progress-handler.js.map +1 -0
- package/dist/spec/ui/progress.d.ts +24 -0
- package/dist/spec/ui/progress.d.ts.map +1 -0
- package/dist/spec/ui/progress.js +13 -0
- package/dist/spec/ui/progress.js.map +1 -0
- package/dist/spec/utils/fs.d.ts +45 -0
- package/dist/spec/utils/fs.d.ts.map +1 -0
- package/dist/spec/utils/fs.js +163 -0
- package/dist/spec/utils/fs.js.map +1 -0
- package/dist/spec/utils/index.d.ts +12 -0
- package/dist/spec/utils/index.d.ts.map +1 -0
- package/dist/spec/utils/index.js +26 -0
- package/dist/spec/utils/index.js.map +1 -0
- package/dist/spec/utils/meta.d.ts +32 -0
- package/dist/spec/utils/meta.d.ts.map +1 -0
- package/dist/spec/utils/meta.js +122 -0
- package/dist/spec/utils/meta.js.map +1 -0
- package/dist/spec/utils/truncate.d.ts +86 -0
- package/dist/spec/utils/truncate.d.ts.map +1 -0
- package/dist/spec/utils/truncate.js +172 -0
- package/dist/spec/utils/truncate.js.map +1 -0
- package/dist/spec/utils.d.ts +4 -16
- package/dist/spec/utils.d.ts.map +1 -1
- package/dist/spec/utils.js +6 -58
- 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 +35 -6
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +127 -17
- package/dist/sync/watcher.js.map +1 -1
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +5 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/telemetry/index.js +3 -3
- package/dist/telemetry/index.js.map +1 -1
- package/dist/types.d.ts +22 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -0
- package/dist/types.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 +162 -14
- 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 +6 -2
- package/scripts/agent-eval/run-all.sh +6 -0
- package/scripts/build-bundle.sh +5 -0
- package/scripts/npm-shim.js +8 -1
- 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/data/agents.json +0 -109
- package/scripts/exp_boundary_eval/data/experiments.json +0 -140
- 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
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
45
45
|
exports.HomeGraph = exports.MCPServer = exports.LockUnavailableError = exports.FileWatcher = exports.MemoryMonitor = exports.throttle = exports.debounce = exports.processInBatches = exports.FileLock = exports.Mutex = exports.defaultLogger = exports.silentLogger = exports.getLogger = exports.setLogger = exports.ConfigError = exports.VectorError = exports.SearchError = exports.DatabaseError = exports.ParseError = exports.FileError = exports.HomeGraphError = exports.loadAllGrammars = exports.loadGrammarsForLanguages = exports.initGrammars = exports.getSupportedLanguages = exports.isGrammarLoaded = exports.isLanguageSupported = exports.detectLanguage = exports.HOMEGRAPH_DIR = exports.findNearestHomeGraphRoot = exports.isInitialized = exports.getHomeGraphDir = exports.QueryBuilder = exports.DatabaseConnection = exports.getDatabasePath = void 0;
|
|
46
46
|
const path = __importStar(require("path"));
|
|
47
47
|
const db_1 = require("./db");
|
|
48
|
+
const wal_valve_1 = require("./db/wal-valve");
|
|
48
49
|
const queries_1 = require("./db/queries");
|
|
49
50
|
const directory_1 = require("./directory");
|
|
50
51
|
const extraction_1 = require("./extraction");
|
|
@@ -58,6 +59,9 @@ const sync_1 = require("./sync");
|
|
|
58
59
|
const extraction_version_1 = require("./extraction/extraction-version");
|
|
59
60
|
const directory_2 = require("./directory");
|
|
60
61
|
const query_utils_1 = require("./search/query-utils");
|
|
62
|
+
const identifier_segments_1 = require("./search/identifier-segments");
|
|
63
|
+
const cooperative_yield_1 = require("./resolution/cooperative-yield");
|
|
64
|
+
const resolver_pool_1 = require("./resolution/resolver-pool");
|
|
61
65
|
const version_1 = require("./mcp/version");
|
|
62
66
|
// Re-export types for consumers
|
|
63
67
|
__exportStar(require("./types"), exports);
|
|
@@ -375,26 +379,74 @@ class HomeGraph {
|
|
|
375
379
|
catch {
|
|
376
380
|
return { success: false, filesIndexed: 0, filesSkipped: 0, filesErrored: 0, nodesCreated: 0, edgesCreated: 0, errors: [{ message: 'Could not acquire file lock - another process may be indexing', severity: 'error' }], durationMs: 0 };
|
|
377
381
|
}
|
|
382
|
+
const freshDb = this.queries.getNodeAndEdgeCount().nodes === 0;
|
|
383
|
+
const fastInit = process.env.HOMEGRAPH_NO_FAST_INIT !== '1' && freshDb;
|
|
384
|
+
if (fastInit) {
|
|
385
|
+
try {
|
|
386
|
+
this.db.getDb().pragma('journal_mode = MEMORY');
|
|
387
|
+
this.db.getDb().pragma('synchronous = OFF');
|
|
388
|
+
}
|
|
389
|
+
catch { /* keep WAL */ }
|
|
390
|
+
}
|
|
391
|
+
const deferWal = !fastInit && process.env.HOMEGRAPH_NO_WAL_DEFER !== '1' && this.db.getJournalMode() === 'wal';
|
|
392
|
+
let walValve = null;
|
|
393
|
+
let priorAutocheckpoint = 1000;
|
|
394
|
+
let restoreAutocheckpoint = false;
|
|
395
|
+
if (deferWal) {
|
|
396
|
+
priorAutocheckpoint = this.db.getWalAutocheckpoint();
|
|
397
|
+
this.db.setWalAutocheckpoint(0);
|
|
398
|
+
walValve = new wal_valve_1.WalCheckpointValve(this.db, (0, wal_valve_1.resolveWalValveMb)(process.env.HOMEGRAPH_WAL_VALVE_MB, this.db.getDbFileSizeBytes()), undefined, options.verbose ? (m) => console.log(`[wal-valve] ${m}`) : undefined);
|
|
399
|
+
walValve.start();
|
|
400
|
+
}
|
|
378
401
|
try {
|
|
379
402
|
const before = this.queries.getNodeAndEdgeCount();
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
403
|
+
try {
|
|
404
|
+
this.queries.setMetadata('index_state', 'indexing');
|
|
405
|
+
}
|
|
406
|
+
catch { /* metadata is advisory */ }
|
|
407
|
+
try {
|
|
408
|
+
this.queries.clearNameSegmentVocab();
|
|
409
|
+
}
|
|
410
|
+
catch { /* vocab is advisory — never fail an index over it */ }
|
|
411
|
+
this.db.beginBulkNodeLoad();
|
|
412
|
+
if (freshDb)
|
|
413
|
+
this.db.beginBulkParseLoad();
|
|
414
|
+
let result;
|
|
415
|
+
try {
|
|
416
|
+
result = await this.orchestrator.indexAll(options.onProgress, options.signal, options.verbose, walValve ? () => walValve.backpressure() : undefined, freshDb ? { dbPath: this.db.getPath(), fastInit } : null);
|
|
417
|
+
}
|
|
418
|
+
finally {
|
|
419
|
+
if (freshDb) {
|
|
420
|
+
const tIdx = Date.now();
|
|
421
|
+
await this.db.endBulkParseLoad();
|
|
422
|
+
if (process.env.HOMEGRAPH_SYNTH_TIMINGS)
|
|
423
|
+
console.error(`[phase-timing] parse-index-rebuild: ${Date.now() - tIdx}ms`);
|
|
424
|
+
}
|
|
425
|
+
const tFts = Date.now();
|
|
426
|
+
this.db.endBulkNodeLoad();
|
|
427
|
+
if (process.env.HOMEGRAPH_SYNTH_TIMINGS)
|
|
428
|
+
console.error(`[phase-timing] fts-rebuild: ${Date.now() - tFts}ms`);
|
|
429
|
+
}
|
|
430
|
+
if (walValve)
|
|
431
|
+
await walValve.foldNow();
|
|
388
432
|
if (result.success && result.filesIndexed > 0) {
|
|
389
433
|
this.resolver.initialize();
|
|
390
|
-
// Cross-file finalization (e.g. NestJS RouterModule prefixes). Runs
|
|
391
|
-
// before resolution so updated names show up in subsequent reads.
|
|
392
434
|
this.resolver.runPostExtract();
|
|
393
435
|
}
|
|
394
|
-
// Resolve references to create call/import/extends edges
|
|
395
436
|
if (result.success && result.filesIndexed > 0) {
|
|
396
|
-
// Get count without loading all refs into memory
|
|
397
437
|
const unresolvedCount = this.queries.getUnresolvedReferencesCount();
|
|
438
|
+
if (fastInit && unresolvedCount >= (0, resolver_pool_1.minRefsForPool)()) {
|
|
439
|
+
try {
|
|
440
|
+
this.db.getDb().pragma('synchronous = NORMAL');
|
|
441
|
+
this.db.getDb().pragma('journal_mode = WAL');
|
|
442
|
+
priorAutocheckpoint = this.db.getWalAutocheckpoint();
|
|
443
|
+
this.db.setWalAutocheckpoint(0);
|
|
444
|
+
restoreAutocheckpoint = true;
|
|
445
|
+
walValve = new wal_valve_1.WalCheckpointValve(this.db, undefined, undefined, options.verbose ? (m) => console.log(`[wal-valve] ${m}`) : undefined);
|
|
446
|
+
walValve.start();
|
|
447
|
+
}
|
|
448
|
+
catch { /* keep current mode; resolution still works sequentially */ }
|
|
449
|
+
}
|
|
398
450
|
options.onProgress?.({
|
|
399
451
|
phase: 'resolving',
|
|
400
452
|
current: 0,
|
|
@@ -406,34 +458,28 @@ class HomeGraph {
|
|
|
406
458
|
current,
|
|
407
459
|
total,
|
|
408
460
|
});
|
|
409
|
-
})
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
461
|
+
}, (done, totalPasses) => {
|
|
462
|
+
options.onProgress?.({
|
|
463
|
+
phase: 'linking',
|
|
464
|
+
current: done,
|
|
465
|
+
total: totalPasses,
|
|
466
|
+
});
|
|
467
|
+
}, walValve ? () => walValve.backpressure() : undefined);
|
|
414
468
|
await this.resolver.resolveChainedCallsViaConformance();
|
|
415
|
-
// Same lifecycle for `this.<member>` callback registrations whose
|
|
416
|
-
// member is inherited from a supertype (#808).
|
|
417
469
|
await this.resolver.resolveDeferredThisMemberRefs();
|
|
418
470
|
}
|
|
419
|
-
// Refresh planner stats + checkpoint the WAL after bulk writes.
|
|
420
|
-
// Cheap and non-blocking; never load-bearing for correctness.
|
|
421
471
|
if (result.success && result.filesIndexed > 0) {
|
|
422
|
-
|
|
472
|
+
if (walValve) {
|
|
473
|
+
walValve.stop();
|
|
474
|
+
await walValve.drain();
|
|
475
|
+
}
|
|
476
|
+
await this.db.runMaintenance();
|
|
423
477
|
}
|
|
424
|
-
// The orchestrator only sees extraction-phase counts; resolution and
|
|
425
|
-
// synthesizer edges (often >50% of the graph on JVM repos) come later.
|
|
426
|
-
// Recompute against the DB so the CLI summary reports the true totals.
|
|
427
478
|
if (result.success && result.filesIndexed > 0) {
|
|
428
479
|
const after = this.queries.getNodeAndEdgeCount();
|
|
429
480
|
result.nodesCreated = after.nodes - before.nodes;
|
|
430
481
|
result.edgesCreated = after.edges - before.edges;
|
|
431
482
|
}
|
|
432
|
-
// Stamp the index with the engine that built it, so `homegraph status`
|
|
433
|
-
// and `homegraph upgrade` can recommend a re-index when the running
|
|
434
|
-
// engine produces richer extraction than the one on disk. Only on a
|
|
435
|
-
// real full index — a sync touches a subset, so it must NOT advance the
|
|
436
|
-
// extraction stamp (the bulk would still be stale). See extraction-version.ts.
|
|
437
483
|
if (result.success && result.filesIndexed > 0) {
|
|
438
484
|
try {
|
|
439
485
|
this.queries.setMetadata('indexed_with_version', version_1.HomeGraphPackageVersion);
|
|
@@ -448,9 +494,54 @@ class HomeGraph {
|
|
|
448
494
|
result.errors.push({ message: ohosBinding.message, severity: 'warning', code: ohosBinding.code });
|
|
449
495
|
}
|
|
450
496
|
}
|
|
497
|
+
try {
|
|
498
|
+
if (!result.success) {
|
|
499
|
+
this.queries.setMetadata('index_state', 'failed');
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
const accounted = result.filesIndexed + result.filesSkipped + result.filesErrored;
|
|
503
|
+
const discovered = result.filesDiscovered;
|
|
504
|
+
const shortfall = discovered !== undefined ? discovered - accounted : 0;
|
|
505
|
+
if (discovered !== undefined && shortfall > 0) {
|
|
506
|
+
this.queries.setMetadata('index_state', 'partial');
|
|
507
|
+
this.queries.setMetadata('index_files_discovered', String(discovered));
|
|
508
|
+
this.queries.setMetadata('index_files_accounted', String(accounted));
|
|
509
|
+
result.errors.push({
|
|
510
|
+
message: `Index is missing ${shortfall} of ${discovered} discovered files (indexed ${result.filesIndexed}, skipped ${result.filesSkipped}, errored ${result.filesErrored}). The index is PARTIAL — re-run \`homegraph index\`.`,
|
|
511
|
+
severity: 'warning',
|
|
512
|
+
code: 'index_partial',
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
this.queries.setMetadata('index_state', 'complete');
|
|
517
|
+
if (discovered !== undefined) {
|
|
518
|
+
this.queries.setMetadata('index_files_discovered', String(discovered));
|
|
519
|
+
this.queries.setMetadata('index_files_accounted', String(accounted));
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
catch { /* metadata is advisory — never fail an index over it */ }
|
|
451
525
|
return result;
|
|
452
526
|
}
|
|
453
527
|
finally {
|
|
528
|
+
if (walValve) {
|
|
529
|
+
walValve.stop();
|
|
530
|
+
await walValve.drain();
|
|
531
|
+
}
|
|
532
|
+
if (deferWal || restoreAutocheckpoint) {
|
|
533
|
+
try {
|
|
534
|
+
this.db.setWalAutocheckpoint(priorAutocheckpoint);
|
|
535
|
+
}
|
|
536
|
+
catch { /* connection may be closing */ }
|
|
537
|
+
}
|
|
538
|
+
if (fastInit) {
|
|
539
|
+
try {
|
|
540
|
+
this.db.getDb().pragma('synchronous = NORMAL');
|
|
541
|
+
this.db.getDb().pragma('journal_mode = WAL');
|
|
542
|
+
}
|
|
543
|
+
catch { /* connection may be closing */ }
|
|
544
|
+
}
|
|
454
545
|
this.fileLock.release();
|
|
455
546
|
}
|
|
456
547
|
});
|
|
@@ -489,20 +580,41 @@ class HomeGraph {
|
|
|
489
580
|
catch {
|
|
490
581
|
return { filesChecked: 0, filesAdded: 0, filesModified: 0, filesRemoved: 0, nodesUpdated: 0, durationMs: 0 };
|
|
491
582
|
}
|
|
583
|
+
const deferWal = process.env.HOMEGRAPH_NO_WAL_DEFER !== '1' && this.db.getJournalMode() === 'wal';
|
|
584
|
+
let walValve = null;
|
|
585
|
+
let priorAutocheckpoint = 1000;
|
|
586
|
+
if (deferWal) {
|
|
587
|
+
priorAutocheckpoint = this.db.getWalAutocheckpoint();
|
|
588
|
+
this.db.setWalAutocheckpoint(0);
|
|
589
|
+
walValve = new wal_valve_1.WalCheckpointValve(this.db, (0, wal_valve_1.resolveWalValveMb)(process.env.HOMEGRAPH_WAL_VALVE_MB, this.db.getDbFileSizeBytes()), undefined, options.verbose ? (m) => console.log(`[wal-valve] ${m}`) : undefined);
|
|
590
|
+
walValve.start();
|
|
591
|
+
}
|
|
492
592
|
try {
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
593
|
+
const vocabWasEmpty = (() => {
|
|
594
|
+
try {
|
|
595
|
+
return this.queries.isNameSegmentVocabEmpty();
|
|
596
|
+
}
|
|
597
|
+
catch {
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
})();
|
|
601
|
+
const result = await this.orchestrator.sync(options.onProgress, options.paths);
|
|
602
|
+
if (walValve)
|
|
603
|
+
await walValve.foldNow();
|
|
498
604
|
if (result.filesAdded > 0 || result.filesModified > 0) {
|
|
499
605
|
this.resolver.runPostExtract();
|
|
500
606
|
}
|
|
501
|
-
|
|
502
|
-
|
|
607
|
+
else if (result.filesRemoved > 0) {
|
|
608
|
+
this.resolver.clearCaches();
|
|
609
|
+
}
|
|
610
|
+
const filesChanged = result.filesAdded > 0 || result.filesModified > 0;
|
|
611
|
+
const backpressure = walValve ? () => walValve.backpressure() : undefined;
|
|
612
|
+
if (filesChanged) {
|
|
503
613
|
if (result.changedFilePaths) {
|
|
504
|
-
|
|
614
|
+
const tRefLoad = Date.now();
|
|
505
615
|
const unresolvedRefs = this.queries.getUnresolvedReferencesByFiles(result.changedFilePaths);
|
|
616
|
+
if (process.env.HOMEGRAPH_SYNTH_TIMINGS)
|
|
617
|
+
console.error(`[phase-timing] sync-ref-load: ${Date.now() - tRefLoad}ms (${unresolvedRefs.length} refs)`);
|
|
506
618
|
options.onProgress?.({
|
|
507
619
|
phase: 'resolving',
|
|
508
620
|
current: 0,
|
|
@@ -515,9 +627,25 @@ class HomeGraph {
|
|
|
515
627
|
total,
|
|
516
628
|
});
|
|
517
629
|
});
|
|
630
|
+
const tRetry = Date.now();
|
|
631
|
+
const retryable = this.queries.getRetryableFailedReferences(this.queries.getNodeNamesByFiles(result.changedFilePaths));
|
|
632
|
+
if (retryable.length > 0) {
|
|
633
|
+
options.onProgress?.({
|
|
634
|
+
phase: 'resolving',
|
|
635
|
+
current: 0,
|
|
636
|
+
total: retryable.length,
|
|
637
|
+
});
|
|
638
|
+
await this.resolver.resolveAndPersistListYielding(retryable);
|
|
639
|
+
options.onProgress?.({
|
|
640
|
+
phase: 'resolving',
|
|
641
|
+
current: retryable.length,
|
|
642
|
+
total: retryable.length,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
if (process.env.HOMEGRAPH_SYNTH_TIMINGS)
|
|
646
|
+
console.error(`[phase-timing] sync-failed-ref-retry: ${Date.now() - tRetry}ms (${retryable.length} refs)`);
|
|
518
647
|
}
|
|
519
648
|
else {
|
|
520
|
-
// No git info — use batched resolution to avoid OOM
|
|
521
649
|
const unresolvedCount = this.queries.getUnresolvedReferencesCount();
|
|
522
650
|
options.onProgress?.({
|
|
523
651
|
phase: 'resolving',
|
|
@@ -530,23 +658,62 @@ class HomeGraph {
|
|
|
530
658
|
current,
|
|
531
659
|
total,
|
|
532
660
|
});
|
|
533
|
-
})
|
|
661
|
+
}, (done, totalPasses) => {
|
|
662
|
+
options.onProgress?.({
|
|
663
|
+
phase: 'linking',
|
|
664
|
+
current: done,
|
|
665
|
+
total: totalPasses,
|
|
666
|
+
});
|
|
667
|
+
}, backpressure);
|
|
534
668
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
669
|
+
}
|
|
670
|
+
const orphanCount = this.queries.getUnresolvedReferencesCount();
|
|
671
|
+
if (orphanCount > 0) {
|
|
672
|
+
options.onProgress?.({
|
|
673
|
+
phase: 'resolving',
|
|
674
|
+
current: 0,
|
|
675
|
+
total: orphanCount,
|
|
676
|
+
});
|
|
677
|
+
await this.resolveReferencesBatched((current, total) => {
|
|
678
|
+
options.onProgress?.({
|
|
679
|
+
phase: 'resolving',
|
|
680
|
+
current,
|
|
681
|
+
total,
|
|
682
|
+
});
|
|
683
|
+
}, (done, totalPasses) => {
|
|
684
|
+
options.onProgress?.({
|
|
685
|
+
phase: 'linking',
|
|
686
|
+
current: done,
|
|
687
|
+
total: totalPasses,
|
|
688
|
+
});
|
|
689
|
+
}, backpressure);
|
|
690
|
+
}
|
|
691
|
+
if (filesChanged || orphanCount > 0) {
|
|
538
692
|
await this.resolver.resolveChainedCallsViaConformance();
|
|
539
|
-
// Same lifecycle for `this.<member>` callback registrations whose
|
|
540
|
-
// member is inherited from a supertype (#808).
|
|
541
693
|
await this.resolver.resolveDeferredThisMemberRefs();
|
|
542
694
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
695
|
+
if (filesChanged || result.filesRemoved > 0 || orphanCount > 0) {
|
|
696
|
+
await this.db.runMaintenance();
|
|
697
|
+
}
|
|
698
|
+
try {
|
|
699
|
+
if (vocabWasEmpty && this.queries.getNodeAndEdgeCount().nodes > 0) {
|
|
700
|
+
await this.rebuildNameSegmentVocab();
|
|
701
|
+
}
|
|
546
702
|
}
|
|
703
|
+
catch { /* vocab is advisory — never fail a sync over it */ }
|
|
547
704
|
return result;
|
|
548
705
|
}
|
|
549
706
|
finally {
|
|
707
|
+
if (walValve) {
|
|
708
|
+
walValve.stop();
|
|
709
|
+
await walValve.drain();
|
|
710
|
+
}
|
|
711
|
+
if (deferWal) {
|
|
712
|
+
try {
|
|
713
|
+
this.db.setWalAutocheckpoint(priorAutocheckpoint);
|
|
714
|
+
}
|
|
715
|
+
catch { /* connection may be closing */ }
|
|
716
|
+
}
|
|
550
717
|
this.fileLock.release();
|
|
551
718
|
}
|
|
552
719
|
});
|
|
@@ -572,8 +739,8 @@ class HomeGraph {
|
|
|
572
739
|
watch(options = {}) {
|
|
573
740
|
if (this.watcher?.isActive())
|
|
574
741
|
return true;
|
|
575
|
-
this.watcher = new sync_1.FileWatcher(this.projectRoot, async () => {
|
|
576
|
-
const result = await this.sync();
|
|
742
|
+
this.watcher = new sync_1.FileWatcher(this.projectRoot, async (paths) => {
|
|
743
|
+
const result = await this.sync({ paths });
|
|
577
744
|
// sync() returns this exact zero-shape iff it failed to acquire the
|
|
578
745
|
// file lock (a real empty sync always has filesChecked > 0 because
|
|
579
746
|
// scanDirectory ran). Surface that to the watcher as a typed error
|
|
@@ -660,6 +827,18 @@ class HomeGraph {
|
|
|
660
827
|
getQueryBuilder() {
|
|
661
828
|
return this.queries;
|
|
662
829
|
}
|
|
830
|
+
/**
|
|
831
|
+
* Completeness of the last full index run. `'complete'` is the only good
|
|
832
|
+
* state. `'indexing'` after the fact means a run was killed mid-index;
|
|
833
|
+
* `'partial'` means the run finished but silently dropped files;
|
|
834
|
+
* `'failed'` means it reported failure. `null` = index predates this marker.
|
|
835
|
+
*/
|
|
836
|
+
getIndexState() {
|
|
837
|
+
const raw = this.queries.getMetadata('index_state');
|
|
838
|
+
return raw === 'indexing' || raw === 'complete' || raw === 'partial' || raw === 'failed'
|
|
839
|
+
? raw
|
|
840
|
+
: null;
|
|
841
|
+
}
|
|
663
842
|
/**
|
|
664
843
|
* Which engine built the current index: the package version + extraction
|
|
665
844
|
* version stamped at the last full `indexAll`. Either field is null for an
|
|
@@ -725,12 +904,33 @@ class HomeGraph {
|
|
|
725
904
|
* Resolve references in batches to keep memory bounded on large codebases.
|
|
726
905
|
* Processes chunks of unresolved refs, persisting results after each batch.
|
|
727
906
|
*/
|
|
728
|
-
async resolveReferencesBatched(onProgress) {
|
|
729
|
-
return this.resolver.resolveAndPersistBatched(onProgress
|
|
907
|
+
async resolveReferencesBatched(onProgress, onSynthesisProgress, backpressure) {
|
|
908
|
+
return this.resolver.resolveAndPersistBatched(onProgress, undefined, onSynthesisProgress, {
|
|
909
|
+
dbPath: this.db.getPath(),
|
|
910
|
+
bulkEdgeLoad: {
|
|
911
|
+
begin: () => this.db.beginBulkEdgeLoad(),
|
|
912
|
+
end: () => this.db.endBulkEdgeLoad(),
|
|
913
|
+
},
|
|
914
|
+
refIndexLoad: {
|
|
915
|
+
begin: () => this.db.beginBulkRefLoad(),
|
|
916
|
+
end: () => this.db.endBulkRefLoad(),
|
|
917
|
+
},
|
|
918
|
+
backpressure,
|
|
919
|
+
});
|
|
730
920
|
}
|
|
731
921
|
/**
|
|
732
922
|
* Get detected frameworks in the project
|
|
733
923
|
*/
|
|
924
|
+
/**
|
|
925
|
+
* References extracted but never attempted by a resolution pass. Zero on a
|
|
926
|
+
* healthy index — a completed pass consumes every pending row (resolving it
|
|
927
|
+
* or parking it as failed, #1240). Non-zero at rest means a pass was
|
|
928
|
+
* interrupted mid-run (#1187), so some files' call edges are missing; the
|
|
929
|
+
* next `sync` sweeps them.
|
|
930
|
+
*/
|
|
931
|
+
getPendingReferenceCount() {
|
|
932
|
+
return this.queries.getUnresolvedReferencesCount();
|
|
933
|
+
}
|
|
734
934
|
getDetectedFrameworks() {
|
|
735
935
|
return this.resolver.getDetectedFrameworks();
|
|
736
936
|
}
|
|
@@ -752,9 +952,8 @@ class HomeGraph {
|
|
|
752
952
|
return stats;
|
|
753
953
|
}
|
|
754
954
|
/**
|
|
755
|
-
* Active SQLite backend
|
|
756
|
-
*
|
|
757
|
-
* `homegraph_status` MCP tool alongside the effective journal mode.
|
|
955
|
+
* Active SQLite backend (`native` = better-sqlite3, or `wasm` fallback).
|
|
956
|
+
* Surfaced via `homegraph status` / `homegraph_status` with journal mode.
|
|
758
957
|
*/
|
|
759
958
|
getBackend() {
|
|
760
959
|
return this.db.getBackend();
|
|
@@ -797,6 +996,16 @@ class HomeGraph {
|
|
|
797
996
|
getNodesByName(name) {
|
|
798
997
|
return this.queries.getNodesByName(name);
|
|
799
998
|
}
|
|
999
|
+
/**
|
|
1000
|
+
* Nodes whose name CONTAINS `substring` (LIKE scan, ASCII-case-insensitive,
|
|
1001
|
+
* shortest-first). The camel-infix lookup FTS can't do — `profileInfo`
|
|
1002
|
+
* inside `getProfileInfoV2` is one FTS token (#1196).
|
|
1003
|
+
*/
|
|
1004
|
+
getNodesByNameSubstring(substring, options = {}) {
|
|
1005
|
+
return this.queries
|
|
1006
|
+
.findNodesByNameSubstring(substring, options)
|
|
1007
|
+
.map((r) => r.node);
|
|
1008
|
+
}
|
|
800
1009
|
/**
|
|
801
1010
|
* Search nodes by text
|
|
802
1011
|
*/
|
|
@@ -810,6 +1019,178 @@ class HomeGraph {
|
|
|
810
1019
|
* bias, which would otherwise pull overloaded tokens toward whichever stack
|
|
811
1020
|
* embeds the project name.
|
|
812
1021
|
*/
|
|
1022
|
+
/**
|
|
1023
|
+
* Graph-derived prompt matching for the front-load hook's MEDIUM tier:
|
|
1024
|
+
* which indexed symbols do these prose words name? "state machine des
|
|
1025
|
+
* commandes" → `OrderStateMachine`, in any human language whose technical
|
|
1026
|
+
* nouns are Latin script — no keyword list involved.
|
|
1027
|
+
*
|
|
1028
|
+
* Precision comes from the repo's own naming statistics, not vocabulary:
|
|
1029
|
+
* - CO-OCCURRENCE: ≥2 words that are segments of the SAME name ("state" +
|
|
1030
|
+
* "machine" → OrderStateMachine) is strong evidence and always qualifies.
|
|
1031
|
+
* - RARITY: a single matched word qualifies only when its segment is
|
|
1032
|
+
* discriminative here (≤ {@link SEGMENT_RARITY_CEILING} distinct names) —
|
|
1033
|
+
* "checkout" in a shop backend yes, "state" in a react app no.
|
|
1034
|
+
* Every candidate is re-verified against `nodes` before being returned
|
|
1035
|
+
* (vocab rows are proposals; deletions leave orphans by design), so a
|
|
1036
|
+
* returned symbol is guaranteed to exist right now.
|
|
1037
|
+
*/
|
|
1038
|
+
getSegmentMatches(words, limit = 6) {
|
|
1039
|
+
if (words.length === 0)
|
|
1040
|
+
return [];
|
|
1041
|
+
// Variant → original word (plural folding), for coverage accounting.
|
|
1042
|
+
const variantToWord = new Map();
|
|
1043
|
+
for (const word of words) {
|
|
1044
|
+
for (const variant of (0, identifier_segments_1.segmentLookupVariants)(word)) {
|
|
1045
|
+
if (!variantToWord.has(variant))
|
|
1046
|
+
variantToWord.set(variant, word);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
const variants = [...variantToWord.keys()];
|
|
1050
|
+
// Tier A: co-occurrence. The SQL folds variants back to their original
|
|
1051
|
+
// word (#1146), so minWords=2 means two distinct PROMPT WORDS — a name
|
|
1052
|
+
// matching both `service` and `services` can't tie with (or crowd past
|
|
1053
|
+
// the LIMIT) a genuine two-word match. The JS re-check below recomputes
|
|
1054
|
+
// the fold from live segments as the honesty layer.
|
|
1055
|
+
const variantPairs = [...variantToWord.entries()].map(([segment, word]) => ({ segment, word }));
|
|
1056
|
+
const candidates = [];
|
|
1057
|
+
for (const hit of this.queries.getSegmentCoOccurrence(variantPairs, 2, 24)) {
|
|
1058
|
+
const matched = this.wordsMatchingName(hit.name, variantToWord);
|
|
1059
|
+
if (matched.size >= 2)
|
|
1060
|
+
candidates.push({ name: hit.name, matchedWords: matched });
|
|
1061
|
+
}
|
|
1062
|
+
// Tier B: single rare word. Only when co-occurrence found nothing — a
|
|
1063
|
+
// co-occurring name is categorically stronger evidence — and under
|
|
1064
|
+
// stricter rules, because one word is thin: the word must be ≥5 chars
|
|
1065
|
+
// (measured FPs: "this", "typo"); the segment must appear in AT LEAST TWO
|
|
1066
|
+
// names (a concept the codebase is about clusters across names —
|
|
1067
|
+
// CheckoutService/CheckoutController — while a prose coincidence is a
|
|
1068
|
+
// singleton: measured FP "deploy to PRODUCTION" → the one name
|
|
1069
|
+
// matchesNonProductionDir); and the candidate name must have ≥2 segments
|
|
1070
|
+
// (a bare common verb matching a bare function name — "write" → `write` —
|
|
1071
|
+
// is prose coincidence, not the user naming a symbol).
|
|
1072
|
+
if (candidates.length === 0) {
|
|
1073
|
+
const singleWordVariants = variants.filter((v) => variantToWord.get(v).length >= 5);
|
|
1074
|
+
const counts = this.queries.getSegmentNameCounts(singleWordVariants);
|
|
1075
|
+
const rare = [...counts.entries()]
|
|
1076
|
+
.filter(([, n]) => n >= 2 && n <= HomeGraph.SEGMENT_RARITY_CEILING)
|
|
1077
|
+
.sort((a, b) => a[1] - b[1])
|
|
1078
|
+
.slice(0, 2);
|
|
1079
|
+
for (const [variant] of rare) {
|
|
1080
|
+
const word = variantToWord.get(variant);
|
|
1081
|
+
for (const name of this.queries.getNamesForSegment(variant, 12)) {
|
|
1082
|
+
if ((0, identifier_segments_1.splitIdentifierSegments)(name).length < 2)
|
|
1083
|
+
continue;
|
|
1084
|
+
candidates.push({ name, matchedWords: new Set([word]) });
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
// Verify against nodes (the honesty gate) and pick a representative
|
|
1089
|
+
// definition per name. A name whose only nodes are file/import kind has
|
|
1090
|
+
// no real definition to point at — surfacing the import statement instead
|
|
1091
|
+
// reads as a matched symbol but isn't one (#1144) — so it's skipped, the
|
|
1092
|
+
// same way an orphaned vocab row is. (Import names no longer enter the
|
|
1093
|
+
// vocab at write time, but rows written before that exclusion persist
|
|
1094
|
+
// until the next full index.)
|
|
1095
|
+
const out = [];
|
|
1096
|
+
const seen = new Set();
|
|
1097
|
+
candidates.sort((a, b) => b.matchedWords.size - a.matchedWords.size || a.name.length - b.name.length);
|
|
1098
|
+
for (const candidate of candidates) {
|
|
1099
|
+
if (out.length >= limit)
|
|
1100
|
+
break;
|
|
1101
|
+
if (seen.has(candidate.name))
|
|
1102
|
+
continue;
|
|
1103
|
+
seen.add(candidate.name);
|
|
1104
|
+
const nodes = this.queries.getNodesByName(candidate.name);
|
|
1105
|
+
if (nodes.length === 0)
|
|
1106
|
+
continue; // orphaned vocab row — name no longer exists
|
|
1107
|
+
const rep = nodes.find((n) => n.kind !== 'file' && n.kind !== 'import');
|
|
1108
|
+
if (!rep)
|
|
1109
|
+
continue; // no real definition — don't surface an import/file as one
|
|
1110
|
+
out.push({
|
|
1111
|
+
name: candidate.name,
|
|
1112
|
+
kind: rep.kind,
|
|
1113
|
+
filePath: rep.filePath,
|
|
1114
|
+
startLine: rep.startLine ?? 0,
|
|
1115
|
+
matchedWords: [...candidate.matchedWords].sort(),
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
return out;
|
|
1119
|
+
}
|
|
1120
|
+
/** A single word ("state") can match hundreds of names in a big repo — that
|
|
1121
|
+
* is noise, not signal. Ceiling for the single-word tier; co-occurrence is
|
|
1122
|
+
* exempt because two words on one name is already discriminative. */
|
|
1123
|
+
static SEGMENT_RARITY_CEILING = 25;
|
|
1124
|
+
/** Which of the prompt's original words match `name`'s segments (via
|
|
1125
|
+
* variants). Segments are recomputed in JS — a name-keyed vocab lookup
|
|
1126
|
+
* would scan the (segment, name) primary key. */
|
|
1127
|
+
wordsMatchingName(name, variantToWord) {
|
|
1128
|
+
const segments = new Set((0, identifier_segments_1.splitIdentifierSegments)(name));
|
|
1129
|
+
const matched = new Set();
|
|
1130
|
+
for (const [variant, word] of variantToWord) {
|
|
1131
|
+
if (segments.has(variant))
|
|
1132
|
+
matched.add(word);
|
|
1133
|
+
}
|
|
1134
|
+
return matched;
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* One-shot upgrade heal for callers that open the graph WITHOUT syncing —
|
|
1138
|
+
* concretely the prompt hook, whose MEDIUM tier reads the segment
|
|
1139
|
+
* vocabulary: a database migrated from before the vocab table existed
|
|
1140
|
+
* starts with it empty, and the only other backfill lives inside `sync()`,
|
|
1141
|
+
* which such callers never run (#1142). Returns true when the vocab is
|
|
1142
|
+
* usable (already populated — the overwhelmingly common one-SELECT case —
|
|
1143
|
+
* or healed here); false when it isn't (empty graph, or another process
|
|
1144
|
+
* holds the index lock — that process's own sync heals it).
|
|
1145
|
+
*/
|
|
1146
|
+
async healSegmentVocabIfEmpty() {
|
|
1147
|
+
const empty = (() => {
|
|
1148
|
+
try {
|
|
1149
|
+
return this.queries.isNameSegmentVocabEmpty();
|
|
1150
|
+
}
|
|
1151
|
+
catch {
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
})();
|
|
1155
|
+
if (!empty)
|
|
1156
|
+
return true;
|
|
1157
|
+
if (this.queries.getNodeAndEdgeCount().nodes === 0)
|
|
1158
|
+
return false;
|
|
1159
|
+
return this.indexMutex.withLock(async () => {
|
|
1160
|
+
try {
|
|
1161
|
+
this.fileLock.acquire();
|
|
1162
|
+
}
|
|
1163
|
+
catch {
|
|
1164
|
+
return false; // an index/sync is running — it backfills the vocab itself
|
|
1165
|
+
}
|
|
1166
|
+
try {
|
|
1167
|
+
if (!this.queries.isNameSegmentVocabEmpty())
|
|
1168
|
+
return true; // raced: healed meanwhile
|
|
1169
|
+
await this.rebuildNameSegmentVocab();
|
|
1170
|
+
return true;
|
|
1171
|
+
}
|
|
1172
|
+
finally {
|
|
1173
|
+
this.fileLock.release();
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Rebuild the segment vocabulary from the current graph, batched and
|
|
1179
|
+
* yielding — the upgrade-heal path for indexes built before the vocab table
|
|
1180
|
+
* existed. Runs inside the index mutex/lock (sync and
|
|
1181
|
+
* healSegmentVocabIfEmpty hold them).
|
|
1182
|
+
*/
|
|
1183
|
+
async rebuildNameSegmentVocab() {
|
|
1184
|
+
const maybeYield = (0, cooperative_yield_1.createYielder)();
|
|
1185
|
+
const BATCH = 2000;
|
|
1186
|
+
for (let offset = 0;; offset += BATCH) {
|
|
1187
|
+
const names = this.queries.getDistinctNodeNames(BATCH, offset);
|
|
1188
|
+
if (names.length === 0)
|
|
1189
|
+
break;
|
|
1190
|
+
this.queries.insertNameSegmentsBatch(names);
|
|
1191
|
+
await maybeYield();
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
813
1194
|
getProjectNameTokens() {
|
|
814
1195
|
return this.queries.getProjectNameTokens();
|
|
815
1196
|
}
|