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
|
@@ -38,9 +38,65 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
38
38
|
};
|
|
39
39
|
})();
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.STOP_WORDS = void 0;
|
|
41
|
+
exports.IMPLEMENTATION_ENTRY_NAME_RE = exports.STOP_WORDS = exports.QUERY_SOURCE_FILE_EXT = void 0;
|
|
42
42
|
exports.normalizeNameToken = normalizeNameToken;
|
|
43
|
+
exports.extractFileBasenamesFromQuery = extractFileBasenamesFromQuery;
|
|
44
|
+
exports.extractPathSegmentsFromQuery = extractPathSegmentsFromQuery;
|
|
45
|
+
exports.queryMentionsCodeContext = queryMentionsCodeContext;
|
|
46
|
+
exports.extractKitModuleNamesFromQuery = extractKitModuleNamesFromQuery;
|
|
47
|
+
exports.extractKitSubmoduleNamesFromQuery = extractKitSubmoduleNamesFromQuery;
|
|
48
|
+
exports.queryAsKitModuleCapabilitySurvey = queryAsKitModuleCapabilitySurvey;
|
|
49
|
+
exports.isMemberLikeIdentifier = isMemberLikeIdentifier;
|
|
50
|
+
exports.queryHasNamedMemberFocus = queryHasNamedMemberFocus;
|
|
51
|
+
exports.queryAsNamedComponentAction = queryAsNamedComponentAction;
|
|
52
|
+
exports.queryAsOutOfRepoSdkCatalog = queryAsOutOfRepoSdkCatalog;
|
|
53
|
+
exports.queryShouldPreferExploreOverSearch = queryShouldPreferExploreOverSearch;
|
|
54
|
+
exports.shouldBuildKitModuleUsageSurvey = shouldBuildKitModuleUsageSurvey;
|
|
55
|
+
exports.extractMemberAccessFromQuery = extractMemberAccessFromQuery;
|
|
56
|
+
exports.extractImportSearchTerms = extractImportSearchTerms;
|
|
57
|
+
exports.fileMatchesQueryBasename = fileMatchesQueryBasename;
|
|
58
|
+
exports.resolveImportLineFromNode = resolveImportLineFromNode;
|
|
43
59
|
exports.deriveProjectNameTokens = deriveProjectNameTokens;
|
|
60
|
+
exports.extractDependencySymbolsFromQuery = extractDependencySymbolsFromQuery;
|
|
61
|
+
exports.queryNamesConfigFile = queryNamesConfigFile;
|
|
62
|
+
exports.hasSymbolFilterInQuery = hasSymbolFilterInQuery;
|
|
63
|
+
exports.hasImportInventoryFilter = hasImportInventoryFilter;
|
|
64
|
+
exports.queryAsApiUsageSurvey = queryAsApiUsageSurvey;
|
|
65
|
+
exports.extractApiUsageTokens = extractApiUsageTokens;
|
|
66
|
+
exports.shouldBuildApiUsageSurvey = shouldBuildApiUsageSurvey;
|
|
67
|
+
exports.queryAsCallerOrMethodSurvey = queryAsCallerOrMethodSurvey;
|
|
68
|
+
exports.queryIsTypeNameFocus = queryIsTypeNameFocus;
|
|
69
|
+
exports.queryAsInheritanceSurvey = queryAsInheritanceSurvey;
|
|
70
|
+
exports.shouldBuildCallerInventory = shouldBuildCallerInventory;
|
|
71
|
+
exports.extractCallerSurveySymbols = extractCallerSurveySymbols;
|
|
72
|
+
exports.queryAsCrossModuleFlowSurvey = queryAsCrossModuleFlowSurvey;
|
|
73
|
+
exports.queryAsDataSourceSurvey = queryAsDataSourceSurvey;
|
|
74
|
+
exports.extractLocalDetailAnchors = extractLocalDetailAnchors;
|
|
75
|
+
exports.queryNeedsCoNamedUseBridge = queryNeedsCoNamedUseBridge;
|
|
76
|
+
exports.queryAsLocalSymbolDetail = queryAsLocalSymbolDetail;
|
|
77
|
+
exports.queryHasFocusedNamedAnchors = queryHasFocusedNamedAnchors;
|
|
78
|
+
exports.shouldUseCompactExploreBudget = shouldUseCompactExploreBudget;
|
|
79
|
+
exports.shouldFocusOnQueryNamedDefs = shouldFocusOnQueryNamedDefs;
|
|
80
|
+
exports.queryAsInterpretationSurvey = queryAsInterpretationSurvey;
|
|
81
|
+
exports.queryAsTestOnlyInterpretation = queryAsTestOnlyInterpretation;
|
|
82
|
+
exports.extractMechanismEntrySeeds = extractMechanismEntrySeeds;
|
|
83
|
+
exports.shouldTryLightMechanismExplore = shouldTryLightMechanismExplore;
|
|
84
|
+
exports.shouldTryFastInventoryExplore = shouldTryFastInventoryExplore;
|
|
85
|
+
exports.shouldBuildInheritanceSurvey = shouldBuildInheritanceSurvey;
|
|
86
|
+
exports.shouldBuildMemberSurvey = shouldBuildMemberSurvey;
|
|
87
|
+
exports.shouldBuildConfigSection = shouldBuildConfigSection;
|
|
88
|
+
exports.extractDomainSearchTerms = extractDomainSearchTerms;
|
|
89
|
+
exports.queryAsMechanismSurvey = queryAsMechanismSurvey;
|
|
90
|
+
exports.queryAsDomainFileSurvey = queryAsDomainFileSurvey;
|
|
91
|
+
exports.shouldBuildDomainFileSurvey = shouldBuildDomainFileSurvey;
|
|
92
|
+
exports.isImplementationEntrySymbol = isImplementationEntrySymbol;
|
|
93
|
+
exports.shouldCompactImportListing = shouldCompactImportListing;
|
|
94
|
+
exports.shouldLimitToQueryNamedFile = shouldLimitToQueryNamedFile;
|
|
95
|
+
exports.queryNamesMultipleExploreAnchors = queryNamesMultipleExploreAnchors;
|
|
96
|
+
exports.shouldOmitSourceBodies = shouldOmitSourceBodies;
|
|
97
|
+
exports.shouldFocusOnNamedTypeFile = shouldFocusOnNamedTypeFile;
|
|
98
|
+
exports.extractTypeNamesFromQuery = extractTypeNamesFromQuery;
|
|
99
|
+
exports.hasConcreteExploreAnchors = hasConcreteExploreAnchors;
|
|
44
100
|
exports.getStemVariants = getStemVariants;
|
|
45
101
|
exports.extractSearchTerms = extractSearchTerms;
|
|
46
102
|
exports.scorePathRelevance = scorePathRelevance;
|
|
@@ -50,10 +106,268 @@ exports.kindBonus = kindBonus;
|
|
|
50
106
|
exports.isDistinctiveIdentifier = isDistinctiveIdentifier;
|
|
51
107
|
const fs = __importStar(require("fs"));
|
|
52
108
|
const path = __importStar(require("path"));
|
|
109
|
+
const utils_1 = require("../utils");
|
|
53
110
|
/** Normalize a name to a comparable token: lowercase, alphanumerics only. */
|
|
54
111
|
function normalizeNameToken(raw) {
|
|
55
112
|
return raw.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
56
113
|
}
|
|
114
|
+
/** Source/config extensions recognized in natural-language queries. */
|
|
115
|
+
exports.QUERY_SOURCE_FILE_EXT = 'ets|ts|tsx|js|jsx|mjs|cjs|json5?|ya?ml|toml|hpp|h|cpp|c|cmake';
|
|
116
|
+
/**
|
|
117
|
+
* File basenames from queries — supports `Foo.ets` and path-style `common\\constants.ets`.
|
|
118
|
+
*/
|
|
119
|
+
function extractFileBasenamesFromQuery(query) {
|
|
120
|
+
const basenames = new Set();
|
|
121
|
+
const ext = exports.QUERY_SOURCE_FILE_EXT;
|
|
122
|
+
const pathStyle = new RegExp(`(?:^|[/\\\\])([A-Za-z][A-Za-z0-9_-]*)\\.(?:${ext})\\b`, 'gi');
|
|
123
|
+
const wordStyle = new RegExp(`\\b([A-Za-z][A-Za-z0-9_-]*)\\.(?:${ext})\\b`, 'gi');
|
|
124
|
+
for (const re of [pathStyle, wordStyle]) {
|
|
125
|
+
let m;
|
|
126
|
+
while ((m = re.exec(query)) !== null) {
|
|
127
|
+
if (m[1] && m[1].length >= 2)
|
|
128
|
+
basenames.add(m[1]);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const m of query.matchAll(/\b([A-Za-z][A-Za-z0-9_-]*)\.test\.(?:ets|ts|tsx)\b/gi)) {
|
|
132
|
+
if (m[1] && m[1].length >= 2) {
|
|
133
|
+
basenames.add(m[1]);
|
|
134
|
+
basenames.delete('test');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (/\bCMakeLists\.txt\b/i.test(query))
|
|
138
|
+
basenames.add('CMakeLists');
|
|
139
|
+
for (const m of query.matchAll(/\b([A-Za-z][A-Za-z0-9_-]*)\.d\.ts\b/gi)) {
|
|
140
|
+
if (m[1] && m[1].length >= 2)
|
|
141
|
+
basenames.add(m[1]);
|
|
142
|
+
}
|
|
143
|
+
return [...basenames];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Path-shaped anchors from a query — `feature/foo`, `staticcommon/launchercommon`.
|
|
147
|
+
*/
|
|
148
|
+
function extractPathSegmentsFromQuery(query) {
|
|
149
|
+
const segments = new Set();
|
|
150
|
+
for (const m of query.matchAll(/(?:^|[\s,;])([a-z][a-z0-9_-]*(?:[\\/][a-z][a-z0-9_-]+)+)\b/gi)) {
|
|
151
|
+
if (m[1])
|
|
152
|
+
segments.add(m[1].replace(/\\/g, '/'));
|
|
153
|
+
}
|
|
154
|
+
return [...segments];
|
|
155
|
+
}
|
|
156
|
+
/** Query names code/API context (kit paths, extensions, member access) — not NL keywords. */
|
|
157
|
+
function queryMentionsCodeContext(query) {
|
|
158
|
+
return (/@kit\.|@ohos\./i.test(query)
|
|
159
|
+
|| /\bapi\b/i.test(query)
|
|
160
|
+
|| new RegExp(`\\.(?:${exports.QUERY_SOURCE_FILE_EXT}|d\\.ts)\\b`, 'i').test(query)
|
|
161
|
+
|| /\bCMakeLists\.txt\b/i.test(query)
|
|
162
|
+
|| extractMemberAccessFromQuery(query).length > 0
|
|
163
|
+
|| extractKitModuleNamesFromQuery(query).length > 0);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* HarmonyOS @kit module names — from `@kit.ArkTS` literals or PascalCase `*Kit` tokens
|
|
167
|
+
* (e.g. ServiceCollaborationKit in "调用 ServiceCollaborationKit 需要…").
|
|
168
|
+
*/
|
|
169
|
+
function extractKitModuleNamesFromQuery(query) {
|
|
170
|
+
const names = new Set();
|
|
171
|
+
for (const m of query.matchAll(/@kit\.([A-Za-z][A-Za-z0-9]*)/gi)) {
|
|
172
|
+
if (m[1])
|
|
173
|
+
names.add(m[1]);
|
|
174
|
+
}
|
|
175
|
+
for (const m of query.matchAll(/\b([A-Z][A-Za-z0-9]*Kit)\b/g)) {
|
|
176
|
+
if (m[1] && m[1].length >= 5)
|
|
177
|
+
names.add(m[1]);
|
|
178
|
+
}
|
|
179
|
+
return [...names];
|
|
180
|
+
}
|
|
181
|
+
/** Submodule tokens from queries like `util模块` / `util 模块`. */
|
|
182
|
+
function extractKitSubmoduleNamesFromQuery(query) {
|
|
183
|
+
const names = new Set();
|
|
184
|
+
for (const m of query.matchAll(/([a-z][a-z0-9_]{1,24})模块/gi)) {
|
|
185
|
+
if (m[1] && m[1].length >= 2)
|
|
186
|
+
names.add(m[1]);
|
|
187
|
+
}
|
|
188
|
+
for (const m of query.matchAll(/\b([a-z][a-z0-9_]*)\s+模块\b/gi)) {
|
|
189
|
+
if (m[1] && m[1].length >= 2)
|
|
190
|
+
names.add(m[1]);
|
|
191
|
+
}
|
|
192
|
+
return [...names];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* "@kit.X 的 Y 模块有哪些功能" — SDK API docs are outside the repo; answer from
|
|
196
|
+
* indexed import/usage only.
|
|
197
|
+
*/
|
|
198
|
+
function queryAsKitModuleCapabilitySurvey(query) {
|
|
199
|
+
if (extractKitModuleNamesFromQuery(query).length === 0)
|
|
200
|
+
return false;
|
|
201
|
+
const capability = /有哪些功能|有什么功能|哪些功能|模块功能|功能有哪些|what\s+(?:are\s+the\s+)?features|module\s+features|kit\s+features/i.test(query);
|
|
202
|
+
if (!capability)
|
|
203
|
+
return false;
|
|
204
|
+
return /@kit\.|模块|\bkit\b/i.test(query) || extractKitSubmoduleNamesFromQuery(query).length > 0;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Out-of-repo SDK / kit **capability or API catalog** questions — wrong shape
|
|
208
|
+
* for HomeGraph (graph has imports/usages, not official feature lists).
|
|
209
|
+
* Shape-driven: kit token + catalog phrasing; never matches a specific product name.
|
|
210
|
+
*/
|
|
211
|
+
/**
|
|
212
|
+
* Member-like / event-handler identifiers — useful as graph seeds (isExpired,
|
|
213
|
+
* onClick) but NOT as "which files import X" inventory filters. Treating them
|
|
214
|
+
* as import inventory makes explore return a dependency list and forces agents
|
|
215
|
+
* back to Grep.
|
|
216
|
+
*/
|
|
217
|
+
function isMemberLikeIdentifier(token) {
|
|
218
|
+
if (!token || token.length < 2)
|
|
219
|
+
return false;
|
|
220
|
+
if (/^(is|has|get|set|on)[A-Z0-9_]/.test(token))
|
|
221
|
+
return true;
|
|
222
|
+
if (/^on[A-Z]/.test(token))
|
|
223
|
+
return true;
|
|
224
|
+
// camelCase property/method: first lower, later upper
|
|
225
|
+
return /^[a-z][a-zA-Z0-9]*[A-Z]/.test(token);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Named Type + member (dot form, or co-named Type + member-like token).
|
|
229
|
+
* Structural — no product/question nouns.
|
|
230
|
+
*/
|
|
231
|
+
function queryHasNamedMemberFocus(query) {
|
|
232
|
+
if (extractMemberAccessFromQuery(query).length > 0)
|
|
233
|
+
return true;
|
|
234
|
+
const types = extractTypeNamesFromQuery(query);
|
|
235
|
+
if (types.length === 0 || types.length > 3)
|
|
236
|
+
return false;
|
|
237
|
+
return extractDependencySymbolsFromQuery(query).some((d) => isMemberLikeIdentifier(d));
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Named UI/component symbol + event token (onClick / click) — "what happens when
|
|
241
|
+
* this control fires" is a one-symbol / callees question, not an import survey.
|
|
242
|
+
*/
|
|
243
|
+
function queryAsNamedComponentAction(query) {
|
|
244
|
+
const types = extractTypeNamesFromQuery(query);
|
|
245
|
+
if (types.length < 1 || types.length > 2)
|
|
246
|
+
return false;
|
|
247
|
+
const looksUi = types.some((t) => /(Button|Component|View|Page|Dialog|Bar|Item|Panel|Menu|Chip|Card)$/i.test(t));
|
|
248
|
+
if (!looksUi)
|
|
249
|
+
return false;
|
|
250
|
+
const deps = extractDependencySymbolsFromQuery(query);
|
|
251
|
+
if (deps.some((d) => /^on[A-Z]/.test(d) || /^(click|tap|press)$/i.test(d)))
|
|
252
|
+
return true;
|
|
253
|
+
// Optional thin intent — only with a UI-looking Type already present.
|
|
254
|
+
return /点击|单击|按下|按钮|onClick|onTap|会发生什么|what\s+happens|when\s+(?:clicked|pressed)/i.test(query);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Out-of-repo SDK catalog (kept for survey omit logic — not as a refuse list).
|
|
258
|
+
*/
|
|
259
|
+
function queryAsOutOfRepoSdkCatalog(query) {
|
|
260
|
+
if (queryAsKitModuleCapabilitySurvey(query))
|
|
261
|
+
return true;
|
|
262
|
+
const catalog = /有哪些(?:功能|API|接口|方法|能力)|提供(?:哪些|什么)|模块有哪些|what\s+(?:are\s+the\s+)?(?:apis?|features|methods)|(?:api|feature)\s+(?:list|catalog)|official\s+(?:api|sdk)\s+docs|module\s+features|kit\s+features/i.test(query);
|
|
263
|
+
if (!catalog)
|
|
264
|
+
return false;
|
|
265
|
+
return /@kit\.|\b[A-Z][A-Za-z0-9]*Kit\b/i.test(query);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Question already names files/symbols/@kit — prefer explore over FTS search.
|
|
269
|
+
*/
|
|
270
|
+
function queryShouldPreferExploreOverSearch(query) {
|
|
271
|
+
const q = query.trim();
|
|
272
|
+
if (!q)
|
|
273
|
+
return false;
|
|
274
|
+
if (/^[A-Za-z_][\w]*$/.test(q))
|
|
275
|
+
return true;
|
|
276
|
+
if (extractFileBasenamesFromQuery(query).length > 0
|
|
277
|
+
|| extractTypeNamesFromQuery(query).length > 0
|
|
278
|
+
|| extractMemberAccessFromQuery(query).length > 0
|
|
279
|
+
|| extractImportSearchTerms(query).length > 0
|
|
280
|
+
|| extractKitModuleNamesFromQuery(query).length > 0) {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
return extractDependencySymbolsFromQuery(query).some((d) => isDistinctiveIdentifier(d));
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* In-repo kit/import **usage** inventory (call sites / which files import).
|
|
287
|
+
*/
|
|
288
|
+
function shouldBuildKitModuleUsageSurvey(query) {
|
|
289
|
+
if (queryAsOutOfRepoSdkCatalog(query) || queryAsKitModuleCapabilitySurvey(query))
|
|
290
|
+
return false;
|
|
291
|
+
if (extractKitModuleNamesFromQuery(query).length === 0
|
|
292
|
+
&& extractImportSearchTerms(query).length === 0) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
return /依赖|引用|哪里用|哪些代码|哪里调用|哪些.*(?:依赖|引用|使用)|import\s+sites?|usages?\b|\buses\b|call\s*sites?/i.test(query);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Member-access patterns from a query — `obj.method`, `Type.method`, or `.member`.
|
|
299
|
+
*/
|
|
300
|
+
function extractMemberAccessFromQuery(query) {
|
|
301
|
+
const results = [];
|
|
302
|
+
const seen = new Set();
|
|
303
|
+
for (const m of query.matchAll(/\b([a-zA-Z_][\w]*(?:\.[a-zA-Z_][\w]*)+)\b/g)) {
|
|
304
|
+
const dotted = m[1];
|
|
305
|
+
if (!dotted || seen.has(dotted))
|
|
306
|
+
continue;
|
|
307
|
+
const parts = dotted.split('.');
|
|
308
|
+
if (parts.length < 2)
|
|
309
|
+
continue;
|
|
310
|
+
const member = parts[parts.length - 1];
|
|
311
|
+
if (member.length < 2)
|
|
312
|
+
continue;
|
|
313
|
+
seen.add(dotted);
|
|
314
|
+
results.push({
|
|
315
|
+
receiver: parts.slice(0, -1).join('.'),
|
|
316
|
+
member,
|
|
317
|
+
dotted,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
for (const m of query.matchAll(/\.([A-Za-z_][\w]*)\b/g)) {
|
|
321
|
+
const member = m[1];
|
|
322
|
+
const dotted = `.${member}`;
|
|
323
|
+
if (seen.has(dotted))
|
|
324
|
+
continue;
|
|
325
|
+
seen.add(dotted);
|
|
326
|
+
results.push({ member, dotted });
|
|
327
|
+
}
|
|
328
|
+
return results;
|
|
329
|
+
}
|
|
330
|
+
/** Terms for targeted import-node FTS (kit modules and their @kit.* paths). */
|
|
331
|
+
function extractImportSearchTerms(query) {
|
|
332
|
+
const terms = new Set();
|
|
333
|
+
for (const kit of extractKitModuleNamesFromQuery(query)) {
|
|
334
|
+
terms.add(kit);
|
|
335
|
+
terms.add(`@kit.${kit}`);
|
|
336
|
+
}
|
|
337
|
+
return [...terms];
|
|
338
|
+
}
|
|
339
|
+
/** True when the file's basename matches a basename named in the query (Foo.ets, bar.ts, …). */
|
|
340
|
+
function fileMatchesQueryBasename(filePath, basenames) {
|
|
341
|
+
if (basenames.length === 0)
|
|
342
|
+
return false;
|
|
343
|
+
const base = path.basename(filePath).toLowerCase();
|
|
344
|
+
return basenames.some((b) => {
|
|
345
|
+
const stem = b.toLowerCase();
|
|
346
|
+
return base === stem || base.startsWith(`${stem}.`);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Full `import … from '…'` line for an import node — reads from disk when the
|
|
351
|
+
* stored signature is module-only (common for @kit.* extraction).
|
|
352
|
+
*/
|
|
353
|
+
function resolveImportLineFromNode(node, projectRoot) {
|
|
354
|
+
const fromSig = (node.signature || '').trim();
|
|
355
|
+
if (/import\b|from\s+['"]/.test(fromSig))
|
|
356
|
+
return fromSig;
|
|
357
|
+
if (node.startLine > 0) {
|
|
358
|
+
try {
|
|
359
|
+
const abs = (0, utils_1.validatePathWithinRoot)(projectRoot, node.filePath);
|
|
360
|
+
if (abs) {
|
|
361
|
+
const lines = fs.readFileSync(abs, 'utf-8').split('\n');
|
|
362
|
+
const raw = (lines[node.startLine - 1] || '').trim();
|
|
363
|
+
if (raw)
|
|
364
|
+
return raw;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
catch { /* fall through */ }
|
|
368
|
+
}
|
|
369
|
+
return fromSig || node.name;
|
|
370
|
+
}
|
|
57
371
|
/**
|
|
58
372
|
* Tokens that name the PROJECT as a whole — its `go.mod` module, `package.json`
|
|
59
373
|
* name, or repo root directory — rather than any specific symbol. A user
|
|
@@ -118,6 +432,582 @@ exports.STOP_WORDS = new Set([
|
|
|
118
432
|
'code', 'file', 'files', 'function', 'method', 'class', 'type',
|
|
119
433
|
'fix', 'bug', 'called',
|
|
120
434
|
]);
|
|
435
|
+
/**
|
|
436
|
+
* Lowercase API / import symbol names in a dependency question (taskpool, formInfo).
|
|
437
|
+
* Used to filter import sites to the symbol actually asked about, not every @kit.ArkTS import.
|
|
438
|
+
*/
|
|
439
|
+
function extractDependencySymbolsFromQuery(query) {
|
|
440
|
+
const symbols = new Set();
|
|
441
|
+
for (const ma of extractMemberAccessFromQuery(query)) {
|
|
442
|
+
if (ma.member.length >= 3 && !exports.STOP_WORDS.has(ma.member.toLowerCase())) {
|
|
443
|
+
symbols.add(ma.member);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
for (const m of query.matchAll(/\b([a-z][a-zA-Z0-9]{3,})\b/g)) {
|
|
447
|
+
const sym = m[1];
|
|
448
|
+
if (!exports.STOP_WORDS.has(sym.toLowerCase()))
|
|
449
|
+
symbols.add(sym);
|
|
450
|
+
}
|
|
451
|
+
// Lowercase API tokens (statfs, napi_wrap) when the query is clearly about code.
|
|
452
|
+
if (queryMentionsCodeContext(query)) {
|
|
453
|
+
for (const m of query.matchAll(/\b([a-z][a-z0-9_]{4,})\b/g)) {
|
|
454
|
+
const sym = m[1];
|
|
455
|
+
if (!exports.STOP_WORDS.has(sym) && isDistinctiveIdentifier(sym))
|
|
456
|
+
symbols.add(sym);
|
|
457
|
+
else if (!exports.STOP_WORDS.has(sym) && sym.length >= 6)
|
|
458
|
+
symbols.add(sym);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
for (const kit of extractKitModuleNamesFromQuery(query)) {
|
|
462
|
+
symbols.delete(kit);
|
|
463
|
+
symbols.delete(kit.charAt(0).toLowerCase() + kit.slice(1));
|
|
464
|
+
}
|
|
465
|
+
return [...symbols];
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Query text names a config/manifest file by basename + extension (structural, not a hardcoded whitelist).
|
|
469
|
+
*/
|
|
470
|
+
function queryNamesConfigFile(query) {
|
|
471
|
+
if (/\b[\w./\\-]+\.(?:json5?|ya?ml|toml|xml|ini|properties)\b/i.test(query))
|
|
472
|
+
return true;
|
|
473
|
+
const basenames = extractFileBasenamesFromQuery(query);
|
|
474
|
+
if (basenames.length === 0)
|
|
475
|
+
return false;
|
|
476
|
+
return /\.(?:json5?|ya?ml|toml)/i.test(query);
|
|
477
|
+
}
|
|
478
|
+
/** Query names concrete import/kit/symbol tokens usable to filter dependency sites. */
|
|
479
|
+
function hasSymbolFilterInQuery(query) {
|
|
480
|
+
return (extractDependencySymbolsFromQuery(query).length > 0
|
|
481
|
+
|| extractKitModuleNamesFromQuery(query).length > 0
|
|
482
|
+
|| extractImportSearchTerms(query).length > 0);
|
|
483
|
+
}
|
|
484
|
+
/** Import-inventory omit/compact — @kit.* or distinctive symbol; not generic terms like "item". */
|
|
485
|
+
function hasImportInventoryFilter(query) {
|
|
486
|
+
if (extractKitModuleNamesFromQuery(query).length > 0)
|
|
487
|
+
return true;
|
|
488
|
+
const deps = extractDependencySymbolsFromQuery(query).filter((d) => !isMemberLikeIdentifier(d));
|
|
489
|
+
if (deps.some((d) => isDistinctiveIdentifier(d)))
|
|
490
|
+
return true;
|
|
491
|
+
// API usage surveys (statfs, napi_wrap) — filter to the named API token.
|
|
492
|
+
if (queryAsApiUsageSurvey(query) && deps.some((d) => d.length >= 5))
|
|
493
|
+
return true;
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
/** Where-is-API-used / call-site intent (statfs, snake_case APIs, "哪里使用了 X"). */
|
|
497
|
+
function queryAsApiUsageSurvey(query) {
|
|
498
|
+
return (/哪里使用|何处使用|哪些地方使用|在哪里使用|什么地方使用|项目中.*使用|使用了.*API|API端点|调用.*API|使用了哪些调用|哪些调用方法|调用方法|使用了哪些方法|where\s+(?:is|are).+(?:used|called)|which\s+(?:files?|code)\s+(?:use|call)/i.test(query));
|
|
499
|
+
}
|
|
500
|
+
/** API / SDK tokens named in the query — lowercase deps + PascalCase modules (Telephony). */
|
|
501
|
+
function extractApiUsageTokens(query) {
|
|
502
|
+
const tokens = new Set();
|
|
503
|
+
for (const d of extractDependencySymbolsFromQuery(query)) {
|
|
504
|
+
if (d.length >= 4)
|
|
505
|
+
tokens.add(d);
|
|
506
|
+
}
|
|
507
|
+
for (const t of extractTypeNamesFromQuery(query)) {
|
|
508
|
+
if (t.length >= 4)
|
|
509
|
+
tokens.add(t);
|
|
510
|
+
}
|
|
511
|
+
return [...tokens];
|
|
512
|
+
}
|
|
513
|
+
function shouldBuildApiUsageSurvey(query) {
|
|
514
|
+
return queryAsApiUsageSurvey(query) && extractApiUsageTokens(query).length > 0;
|
|
515
|
+
}
|
|
516
|
+
/** Caller / method survey intent — not every PascalCase token. */
|
|
517
|
+
function queryAsCallerOrMethodSurvey(query) {
|
|
518
|
+
return (/哪里调用|何处调用|谁调用|调用了|callers?\s+of|who\s+calls|called\s+by|哪些.*调用|外部.*调用|\bexternal\b/i.test(query)
|
|
519
|
+
|| /哪些方法|which\s+methods|methods?\s+(?:are\s+)?called/i.test(query)
|
|
520
|
+
// Agents often write "Type … methods … callers" / bare "callers" without "of".
|
|
521
|
+
|| /\bcallers?\b/i.test(query)
|
|
522
|
+
|| /methods?.{0,40}\bcall/i.test(query));
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Query is essentially just type name(s) (plus filler). Used for *inheritance*
|
|
526
|
+
* surveys when agents pass bare `Rectangle` — NOT for every PascalCase token
|
|
527
|
+
* (that wrongly classified callbacks like `OnSurfaceChangedCB` as types and
|
|
528
|
+
* blocked the compact callable path).
|
|
529
|
+
*/
|
|
530
|
+
function queryIsTypeNameFocus(query) {
|
|
531
|
+
const types = extractTypeNamesFromQuery(query);
|
|
532
|
+
if (types.length < 1 || types.length > 3)
|
|
533
|
+
return false;
|
|
534
|
+
// Callable-ish suffixes — treat as function/method focus, not type hierarchy.
|
|
535
|
+
if (types.every((t) => /(?:CB|Callback|Handler|Listener|Fn|Func|Proc)$/i.test(t))) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
let rest = query;
|
|
539
|
+
for (const t of types) {
|
|
540
|
+
rest = rest.replace(new RegExp(`\\b${t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'g'), ' ');
|
|
541
|
+
}
|
|
542
|
+
rest = rest
|
|
543
|
+
.replace(/\b(class|struct|interface|type|enum|the|a|an|of|for|in|project|code|repo|file|files|what|which|who|how|is|are|does|do|list|show|find|get|all|有哪些|哪些|什么|是|的|类|项目中|项目里)\b/gi, ' ')
|
|
544
|
+
.replace(/[^\w\u4e00-\u9fff]+/g, ' ')
|
|
545
|
+
.trim();
|
|
546
|
+
return rest.length === 0;
|
|
547
|
+
}
|
|
548
|
+
/** Subtype / extends-base intent (Chinese 子类 or English subclass/extends Type). */
|
|
549
|
+
function queryAsInheritanceSurvey(query) {
|
|
550
|
+
// Note: `subclasses?` does NOT match "subclass" (the `?` only applies to the
|
|
551
|
+
// final `s` of "subclasses"). Use `subclass(?:es)?`.
|
|
552
|
+
// Likewise `extend(?:s|ing)` requires a suffix — bare "extend" needs `extends?`.
|
|
553
|
+
return (/子类|继承|subclass(?:es)?/i.test(query)
|
|
554
|
+
|| /\bextends\s+[A-Z][A-Za-z0-9_]*/.test(query)
|
|
555
|
+
|| /\b(?:classes?\s+)?(?:that\s+)?extends?\s+[A-Z][A-Za-z0-9_]*/i.test(query));
|
|
556
|
+
}
|
|
557
|
+
function shouldBuildCallerInventory(query) {
|
|
558
|
+
if (extractCallerSurveySymbols(query).length === 0)
|
|
559
|
+
return false;
|
|
560
|
+
// "Which Telephony methods does the project use" is an API/import survey —
|
|
561
|
+
// not a class→callers inventory (SDK modules often have zero local defs).
|
|
562
|
+
if (shouldBuildApiUsageSurvey(query)
|
|
563
|
+
&& /使用了哪些调用|哪些调用方法|调用方法|使用了哪些方法/.test(query)) {
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
// Require real caller/method intent — bare PascalCase alone is NOT enough
|
|
567
|
+
// (that emptied inventory → blocked compact → 15K full explore on callbacks).
|
|
568
|
+
return queryAsCallerOrMethodSurvey(query);
|
|
569
|
+
}
|
|
570
|
+
/** Symbols to list callers for — types, free functions (SortWidgets), snake_case APIs. */
|
|
571
|
+
function extractCallerSurveySymbols(query) {
|
|
572
|
+
const names = new Set(extractTypeNamesFromQuery(query));
|
|
573
|
+
if (!queryAsCallerOrMethodSurvey(query))
|
|
574
|
+
return [...names];
|
|
575
|
+
for (const d of extractDependencySymbolsFromQuery(query)) {
|
|
576
|
+
if (d.length >= 4)
|
|
577
|
+
names.add(d);
|
|
578
|
+
}
|
|
579
|
+
return [...names].filter((n) => n.length >= 3);
|
|
580
|
+
}
|
|
581
|
+
/** Cross-module call-chain intent (A → B → engine). */
|
|
582
|
+
function queryAsCrossModuleFlowSurvey(query) {
|
|
583
|
+
const types = extractTypeNamesFromQuery(query);
|
|
584
|
+
if (types.length < 2)
|
|
585
|
+
return false;
|
|
586
|
+
return /经过|跨模块|调用链|链路|流程|到达|落到|再到|渲染|落盘|then\s+to|across\s+modules/i.test(query);
|
|
587
|
+
}
|
|
588
|
+
/** Data-source / upstream-service intent (来源于哪个服务 / which service). */
|
|
589
|
+
function queryAsDataSourceSurvey(query) {
|
|
590
|
+
return /来源于|数据来源|来自哪个|哪个系统服务|来自什么服务|data\s+source|which\s+service|来源.*服务/i.test(query);
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Local one/few-symbol behavior or contract — NOT multi-file mechanism / inventory.
|
|
594
|
+
* These questions need a small body (or callers list), not a 24K related-file dump.
|
|
595
|
+
*/
|
|
596
|
+
function extractLocalDetailAnchors(query) {
|
|
597
|
+
const names = new Set();
|
|
598
|
+
for (const t of extractTypeNamesFromQuery(query))
|
|
599
|
+
names.add(t);
|
|
600
|
+
for (const d of extractDependencySymbolsFromQuery(query)) {
|
|
601
|
+
if (d.length >= 3)
|
|
602
|
+
names.add(d);
|
|
603
|
+
}
|
|
604
|
+
for (const ma of extractMemberAccessFromQuery(query)) {
|
|
605
|
+
names.add(ma.member);
|
|
606
|
+
if (ma.receiver)
|
|
607
|
+
names.add(ma.receiver);
|
|
608
|
+
}
|
|
609
|
+
// ALL_CAPS / snake macros (ARGS_POS_0, KEY_CODE_POWER)
|
|
610
|
+
for (const m of query.matchAll(/\b([A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+)\b/g)) {
|
|
611
|
+
if (m[1] && m[1].length >= 4)
|
|
612
|
+
names.add(m[1]);
|
|
613
|
+
}
|
|
614
|
+
// Drop path/extension/verb noise that long NL explores otherwise seed on
|
|
615
|
+
// (`cpp`, `calls`, `include`, `render`…) — that ballooned neighbor fan-out.
|
|
616
|
+
const ANCHOR_NOISE = new Set([
|
|
617
|
+
...exports.STOP_WORDS,
|
|
618
|
+
'cpp', 'hpp', 'ets', 'ts', 'tsx', 'js', 'jsx', 'h', 'c', 'cc', 'cxx',
|
|
619
|
+
'calls', 'call', 'calling', 'called', 'callers', 'caller', 'include', 'includes', 'import', 'imports',
|
|
620
|
+
'render', 'frame', 'sync', 'thread', 'subthread', 'layout', 'method', 'methods',
|
|
621
|
+
'function', 'functions', 'file', 'files', 'src', 'main', 'define', 'visible',
|
|
622
|
+
]);
|
|
623
|
+
const ranked = [...names].filter((n) => n.length >= 3 && !ANCHOR_NOISE.has(n.toLowerCase()));
|
|
624
|
+
// Prefer PascalCase / dotted members first — they're the real anchors.
|
|
625
|
+
ranked.sort((a, b) => {
|
|
626
|
+
const score = (s) => (/^[A-Z]/.test(s) ? 2 : 0) + (s.includes('.') ? 1 : 0) + Math.min(s.length, 20) / 20;
|
|
627
|
+
return score(b) - score(a) || a.localeCompare(b);
|
|
628
|
+
});
|
|
629
|
+
return ranked.slice(0, 4);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Caller survey that also asks how a co-named type becomes visible / used.
|
|
633
|
+
* Inventory-only (paths) is incomplete — need compact body + callers together.
|
|
634
|
+
*/
|
|
635
|
+
function queryNeedsCoNamedUseBridge(query) {
|
|
636
|
+
if (!queryAsCallerOrMethodSurvey(query))
|
|
637
|
+
return false;
|
|
638
|
+
const anchors = extractLocalDetailAnchors(query);
|
|
639
|
+
if (anchors.length < 2)
|
|
640
|
+
return false;
|
|
641
|
+
// Narrow intent only — bare "visible/include/import" matched too many NL queries.
|
|
642
|
+
return /定义可见|确保.*可见|头文件可见|definition\s+visible|visible\s+definition|how\s+.+\s+visible/i.test(query);
|
|
643
|
+
}
|
|
644
|
+
function queryAsLocalSymbolDetail(query) {
|
|
645
|
+
if (queryAsCrossModuleFlowSurvey(query))
|
|
646
|
+
return false;
|
|
647
|
+
if (queryAsDomainFileSurvey(query))
|
|
648
|
+
return false;
|
|
649
|
+
if (shouldBuildKitModuleUsageSurvey(query))
|
|
650
|
+
return false;
|
|
651
|
+
if (shouldBuildApiUsageSurvey(query))
|
|
652
|
+
return false;
|
|
653
|
+
// Caller + co-named visibility → compact (body + callers), not inventory-only.
|
|
654
|
+
if (queryNeedsCoNamedUseBridge(query))
|
|
655
|
+
return true;
|
|
656
|
+
if (shouldBuildCallerInventory(query))
|
|
657
|
+
return false;
|
|
658
|
+
if (queryAsDataSourceSurvey(query))
|
|
659
|
+
return false;
|
|
660
|
+
// Named UI control + event: compact body + callees (not import inventory).
|
|
661
|
+
if (queryAsNamedComponentAction(query))
|
|
662
|
+
return true;
|
|
663
|
+
// Type.member / Type + isFoo co-named — even if the agent stripped Chinese verbs.
|
|
664
|
+
if (queryHasNamedMemberFocus(query) && !queryAsMechanismSurvey(query))
|
|
665
|
+
return true;
|
|
666
|
+
if (queryAsMechanismSurvey(query))
|
|
667
|
+
return false;
|
|
668
|
+
const anchors = extractLocalDetailAnchors(query);
|
|
669
|
+
if (anchors.length < 1)
|
|
670
|
+
return false;
|
|
671
|
+
if (queryAsInterpretationSurvey(query))
|
|
672
|
+
return true;
|
|
673
|
+
const pinpoint = /什么作用|做什么|起什么|用途|含义|语义|什么功能|上下游|上游|下游|upstream|downstream|返回|失败|为\s*0|为0|时(?:会|会)|会如何|会怎样|会发生什么|是否(?:应该|会|能)|Promise|async|同步|异步|宏定义|宏|指针|生命周期|冲突|误响应|触发|什么时候|入参|when\s+.+\s+(?:return|fail|trigger)|what\s+does|what\s+happens|meaning|purpose/i.test(query)
|
|
674
|
+
|| (/回调|callback/i.test(query) && anchors.length > 0);
|
|
675
|
+
if (!pinpoint)
|
|
676
|
+
return false;
|
|
677
|
+
const types = extractTypeNamesFromQuery(query);
|
|
678
|
+
if (types.length >= 5)
|
|
679
|
+
return false;
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Agent already named 1–3 concrete symbols. Those must take compact explore —
|
|
684
|
+
* never fall through to findRelevantContext (10k+ Dynamic-dispatch dumps + Read).
|
|
685
|
+
*/
|
|
686
|
+
function queryHasFocusedNamedAnchors(query) {
|
|
687
|
+
if (queryAsMechanismSurvey(query) || queryAsCrossModuleFlowSurvey(query))
|
|
688
|
+
return false;
|
|
689
|
+
if (shouldTryFastInventoryExplore(query))
|
|
690
|
+
return false;
|
|
691
|
+
const anchors = extractLocalDetailAnchors(query);
|
|
692
|
+
return anchors.length >= 1 && anchors.length <= 3;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Prefer a tight explore budget: local-detail questions, or named-symbol
|
|
696
|
+
* questions that are not mechanism / cross-module flows.
|
|
697
|
+
*/
|
|
698
|
+
function shouldUseCompactExploreBudget(query) {
|
|
699
|
+
if (queryAsMechanismSurvey(query) || queryAsCrossModuleFlowSurvey(query))
|
|
700
|
+
return false;
|
|
701
|
+
// Inventory surveys own the type-name / hierarchy / "who calls Type" shape —
|
|
702
|
+
// do not shrink those into a definition-only budget.
|
|
703
|
+
if (shouldTryFastInventoryExplore(query))
|
|
704
|
+
return false;
|
|
705
|
+
if (queryAsLocalSymbolDetail(query))
|
|
706
|
+
return true;
|
|
707
|
+
if (queryIsTypeNameFocus(query))
|
|
708
|
+
return false;
|
|
709
|
+
const types = extractTypeNamesFromQuery(query);
|
|
710
|
+
const deps = extractDependencySymbolsFromQuery(query);
|
|
711
|
+
return types.length + deps.length >= 1 && types.length <= 2;
|
|
712
|
+
}
|
|
713
|
+
/** Keep rendering to files that define symbols named in the query. */
|
|
714
|
+
function shouldFocusOnQueryNamedDefs(query, hasFlowPath, multiAnchorQuery) {
|
|
715
|
+
if (hasFlowPath || multiAnchorQuery)
|
|
716
|
+
return false;
|
|
717
|
+
if (shouldFocusOnNamedTypeFile(query, hasFlowPath, multiAnchorQuery))
|
|
718
|
+
return true;
|
|
719
|
+
if (!queryAsLocalSymbolDetail(query) && !shouldUseCompactExploreBudget(query))
|
|
720
|
+
return false;
|
|
721
|
+
return (extractTypeNamesFromQuery(query).length > 0
|
|
722
|
+
|| extractDependencySymbolsFromQuery(query).length > 0
|
|
723
|
+
|| extractMemberAccessFromQuery(query).length > 0);
|
|
724
|
+
}
|
|
725
|
+
/** Single named file + role/interpretation intent (test.ets method purpose). */
|
|
726
|
+
function queryAsInterpretationSurvey(query) {
|
|
727
|
+
if (extractFileBasenamesFromQuery(query).length !== 1)
|
|
728
|
+
return false;
|
|
729
|
+
return /什么作用|起什么|做什么|用途|meaning|role|purpose|返回.*起|在.*中起/i.test(query);
|
|
730
|
+
}
|
|
731
|
+
/** Interpretation scoped to a `.test.ets` / `.test.ts` file — production code is out of scope. */
|
|
732
|
+
function queryAsTestOnlyInterpretation(query) {
|
|
733
|
+
if (!queryAsInterpretationSurvey(query))
|
|
734
|
+
return false;
|
|
735
|
+
return /\.test\.(?:ets|ts|tsx)\b/i.test(query);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Mechanism-query entry symbol seeds from query shape — symbols the user actually named,
|
|
739
|
+
* not a corpus-specific synonym table.
|
|
740
|
+
*/
|
|
741
|
+
function extractMechanismEntrySeeds(query) {
|
|
742
|
+
const seeds = new Set();
|
|
743
|
+
for (const t of extractTypeNamesFromQuery(query))
|
|
744
|
+
seeds.add(t);
|
|
745
|
+
for (const s of extractDependencySymbolsFromQuery(query)) {
|
|
746
|
+
if (s.length >= 3)
|
|
747
|
+
seeds.add(s);
|
|
748
|
+
}
|
|
749
|
+
for (const imp of extractImportSearchTerms(query))
|
|
750
|
+
seeds.add(imp);
|
|
751
|
+
for (const ma of extractMemberAccessFromQuery(query)) {
|
|
752
|
+
seeds.add(ma.member);
|
|
753
|
+
if (ma.receiver)
|
|
754
|
+
seeds.add(ma.receiver);
|
|
755
|
+
}
|
|
756
|
+
for (const m of query.matchAll(/\b([A-Z][A-Za-z0-9]*(?:Manager|Service|Handler|Parser|Extension|Controller|Subscriber|Provider))\b/g)) {
|
|
757
|
+
if (m[1])
|
|
758
|
+
seeds.add(m[1]);
|
|
759
|
+
}
|
|
760
|
+
for (const term of extractDomainSearchTerms(query)) {
|
|
761
|
+
if (/^[\x00-\x7F]+$/.test(term) && exports.IMPLEMENTATION_ENTRY_NAME_RE.test(term)) {
|
|
762
|
+
seeds.add(term);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return [...seeds].filter((s) => s.length >= 3).slice(0, 12);
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Lightweight mechanism explore — seed symbols + flow spine only, no full
|
|
769
|
+
* findRelevantContext (keeps MCP calls fast and avoids agent grep fallback).
|
|
770
|
+
*/
|
|
771
|
+
function shouldTryLightMechanismExplore(query) {
|
|
772
|
+
if (queryAsCrossModuleFlowSurvey(query))
|
|
773
|
+
return false;
|
|
774
|
+
if (queryAsInterpretationSurvey(query))
|
|
775
|
+
return false;
|
|
776
|
+
// Named UI control + event → seed the control and follow callees (click flow).
|
|
777
|
+
if (queryAsNamedComponentAction(query)) {
|
|
778
|
+
return extractTypeNamesFromQuery(query).length >= 1
|
|
779
|
+
|| extractMechanismEntrySeeds(query).length >= 1;
|
|
780
|
+
}
|
|
781
|
+
if (!queryAsMechanismSurvey(query))
|
|
782
|
+
return false;
|
|
783
|
+
return extractMechanismEntrySeeds(query).length >= 1
|
|
784
|
+
|| extractDomainSearchTerms(query).length >= 1;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Skip expensive subgraph gathering — inventory sections alone answer the query.
|
|
788
|
+
*/
|
|
789
|
+
function shouldTryFastInventoryExplore(query) {
|
|
790
|
+
if (queryAsCrossModuleFlowSurvey(query))
|
|
791
|
+
return false;
|
|
792
|
+
if (shouldTryLightMechanismExplore(query))
|
|
793
|
+
return false;
|
|
794
|
+
if (queryAsInterpretationSurvey(query))
|
|
795
|
+
return false;
|
|
796
|
+
// Caller paths alone cannot answer "which call makes Type X visible" — compact.
|
|
797
|
+
if (queryNeedsCoNamedUseBridge(query))
|
|
798
|
+
return false;
|
|
799
|
+
// One named symbol / UI action / Type.member — inventory path is the wrong shape
|
|
800
|
+
// (returns import sites for isExpired/onClick and agents fall back to Grep).
|
|
801
|
+
if (queryAsLocalSymbolDetail(query) || queryHasNamedMemberFocus(query) || queryAsNamedComponentAction(query)) {
|
|
802
|
+
return false;
|
|
803
|
+
}
|
|
804
|
+
const types = extractTypeNamesFromQuery(query);
|
|
805
|
+
if (types.length >= 2 && !queryAsCallerOrMethodSurvey(query))
|
|
806
|
+
return false;
|
|
807
|
+
const inventoryDeps = extractDependencySymbolsFromQuery(query).filter((d) => !isMemberLikeIdentifier(d));
|
|
808
|
+
return (shouldBuildDomainFileSurvey(query)
|
|
809
|
+
|| shouldBuildApiUsageSurvey(query)
|
|
810
|
+
|| shouldBuildKitModuleUsageSurvey(query)
|
|
811
|
+
|| (hasImportInventoryFilter(query)
|
|
812
|
+
&& (inventoryDeps.length > 0 || extractKitModuleNamesFromQuery(query).length > 0)
|
|
813
|
+
&& inventoryDeps.length > 0)
|
|
814
|
+
|| shouldBuildCallerInventory(query)
|
|
815
|
+
|| shouldBuildInheritanceSurvey(query)
|
|
816
|
+
|| shouldBuildMemberSurvey(query)
|
|
817
|
+
|| shouldBuildConfigSection(query)
|
|
818
|
+
|| queryAsDataSourceSurvey(query));
|
|
819
|
+
}
|
|
820
|
+
function shouldBuildInheritanceSurvey(query) {
|
|
821
|
+
if (queryAsInheritanceSurvey(query) && extractTypeNamesFromQuery(query).length > 0)
|
|
822
|
+
return true;
|
|
823
|
+
// Bare / near-bare type queries — agent search("Foo") for subtypes/overview.
|
|
824
|
+
return queryIsTypeNameFocus(query);
|
|
825
|
+
}
|
|
826
|
+
function shouldBuildMemberSurvey(query) {
|
|
827
|
+
return extractMemberAccessFromQuery(query).length > 0;
|
|
828
|
+
}
|
|
829
|
+
function shouldBuildConfigSection(query) {
|
|
830
|
+
return queryNamesConfigFile(query);
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Domain terms for broad file/usage surveys — Chinese noun phrases, type names,
|
|
834
|
+
* path segments, and distinctive API tokens. Strips only generic survey
|
|
835
|
+
* boilerplate (有哪些 / 如何 / …) — never a product-noun whitelist.
|
|
836
|
+
*/
|
|
837
|
+
function extractDomainSearchTerms(query) {
|
|
838
|
+
const terms = new Set();
|
|
839
|
+
for (const t of extractTypeNamesFromQuery(query))
|
|
840
|
+
terms.add(t);
|
|
841
|
+
for (const seg of extractPathSegmentsFromQuery(query)) {
|
|
842
|
+
const leaf = seg.split(/[/\\]/).pop();
|
|
843
|
+
if (leaf && leaf.length >= 3)
|
|
844
|
+
terms.add(leaf);
|
|
845
|
+
}
|
|
846
|
+
for (const s of extractDependencySymbolsFromQuery(query)) {
|
|
847
|
+
if (s.length >= 4)
|
|
848
|
+
terms.add(s);
|
|
849
|
+
}
|
|
850
|
+
for (const kit of extractKitModuleNamesFromQuery(query)) {
|
|
851
|
+
terms.delete(kit);
|
|
852
|
+
terms.delete(kit.charAt(0).toLowerCase() + kit.slice(1));
|
|
853
|
+
}
|
|
854
|
+
const stripped = query
|
|
855
|
+
.replace(/[@#][\w.]+/g, ' ')
|
|
856
|
+
.replace(/哪些文件|有哪些|什么|如何|怎样|怎么|项目中|项目里|项目|涉及|相关的?|文件|模块|功能|吗|?|\?|有使用|是否|有没有|使用|不同|区别|对比|这个|那个|是怎样|是如何|怎么|如何|它与|它和/g, ' ')
|
|
857
|
+
.replace(/\s+/g, ' ')
|
|
858
|
+
.trim();
|
|
859
|
+
for (const m of stripped.matchAll(/[\u4e00-\u9fff]{2,12}/g)) {
|
|
860
|
+
let t = m[0].replace(/^与/, '');
|
|
861
|
+
if (t.length >= 2)
|
|
862
|
+
terms.add(t);
|
|
863
|
+
}
|
|
864
|
+
if (queryMentionsCodeContext(query)) {
|
|
865
|
+
for (const m of query.matchAll(/\b([a-z][a-zA-Z0-9]{4,})\b/g)) {
|
|
866
|
+
const w = m[1];
|
|
867
|
+
if (!exports.STOP_WORDS.has(w.toLowerCase()))
|
|
868
|
+
terms.add(w);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return [...terms].filter((t) => t.length >= 2).slice(0, 12);
|
|
872
|
+
}
|
|
873
|
+
/** How/implementation/mechanism intent — needs entry symbols + flow, not flat file list. */
|
|
874
|
+
function queryAsMechanismSurvey(query) {
|
|
875
|
+
return /如何(?:实现|获取|做|处理|管理)|怎样(?:实现|获取|做)|怎么(?:实现|获取|做)|是如何|是怎么|how\s+(?:is|does|are|to\s+(?:get|implement|work))|机制|流程|架构|多线程|多进程|multithread|multi-thread/i.test(query);
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Broad domain survey — related files, usage existence, or concept comparison.
|
|
879
|
+
* Omits source when the file inventory is the complete answer.
|
|
880
|
+
*/
|
|
881
|
+
function queryAsDomainFileSurvey(query) {
|
|
882
|
+
if (queryAsKitModuleCapabilitySurvey(query))
|
|
883
|
+
return false;
|
|
884
|
+
if (queryAsCallerOrMethodSurvey(query))
|
|
885
|
+
return false;
|
|
886
|
+
if (shouldBuildApiUsageSurvey(query))
|
|
887
|
+
return false;
|
|
888
|
+
if (hasImportInventoryFilter(query))
|
|
889
|
+
return false;
|
|
890
|
+
if (shouldBuildMemberSurvey(query))
|
|
891
|
+
return false;
|
|
892
|
+
if (extractFileBasenamesFromQuery(query).length > 0)
|
|
893
|
+
return false;
|
|
894
|
+
if (queryAsMechanismSurvey(query))
|
|
895
|
+
return false;
|
|
896
|
+
const listing = /哪些文件|有哪些.*文件|相关的?\s*文件|涉及.*文件|which\s+files?|files?\s+(?:are\s+)?related/i.test(query);
|
|
897
|
+
const usage = /有使用|是否使用|有没有使用|使用了.*吗|is\s+.+\s+used/i.test(query);
|
|
898
|
+
const compare = /有什么不同|区别|difference|vs\.?|versus|对比/i.test(query);
|
|
899
|
+
const broad = /有哪些|哪些/.test(query) && extractTypeNamesFromQuery(query).length === 0;
|
|
900
|
+
return listing || usage || compare || broad;
|
|
901
|
+
}
|
|
902
|
+
function shouldBuildDomainFileSurvey(query) {
|
|
903
|
+
return queryAsDomainFileSurvey(query) && extractDomainSearchTerms(query).length > 0;
|
|
904
|
+
}
|
|
905
|
+
/** Callable/class names that commonly anchor implementation flows. */
|
|
906
|
+
exports.IMPLEMENTATION_ENTRY_NAME_RE = /Manager|Service|Handler|Extension|Parser|Helper|Controller|Provider|Worker|Backup|Restore|Subscription|Monitor|Coordinator|Delegate|Adapter|Factory|Processor/i;
|
|
907
|
+
function isImplementationEntrySymbol(name, domainTerms) {
|
|
908
|
+
if (!exports.IMPLEMENTATION_ENTRY_NAME_RE.test(name))
|
|
909
|
+
return false;
|
|
910
|
+
const asciiDomains = domainTerms.filter((t) => /^[\x00-\x7F]+$/.test(t));
|
|
911
|
+
if (asciiDomains.length === 0)
|
|
912
|
+
return true;
|
|
913
|
+
const nl = name.toLowerCase();
|
|
914
|
+
return asciiDomains.some((t) => {
|
|
915
|
+
const tl = t.toLowerCase();
|
|
916
|
+
return nl.includes(tl) || (tl.length >= 4 && nl.includes(tl.slice(0, 4)));
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
/** Compact import list when query filters symbols and at least one site matches. */
|
|
920
|
+
function shouldCompactImportListing(siteCount, hasSymbolFilter) {
|
|
921
|
+
if (!hasSymbolFilter)
|
|
922
|
+
return false;
|
|
923
|
+
return siteCount >= 1;
|
|
924
|
+
}
|
|
925
|
+
/** Single file basename anchor with no flow — render that file only. */
|
|
926
|
+
function shouldLimitToQueryNamedFile(query, hasFlowPath, multiAnchorQuery) {
|
|
927
|
+
if (hasFlowPath || multiAnchorQuery)
|
|
928
|
+
return false;
|
|
929
|
+
return extractFileBasenamesFromQuery(query).length === 1;
|
|
930
|
+
}
|
|
931
|
+
/** Multiple named anchors in one query → trace/connect intent, not flat inventory. */
|
|
932
|
+
function queryNamesMultipleExploreAnchors(query) {
|
|
933
|
+
const typeCount = extractTypeNamesFromQuery(query).length;
|
|
934
|
+
const memberCount = extractMemberAccessFromQuery(query).length;
|
|
935
|
+
const fileCount = extractFileBasenamesFromQuery(query).length;
|
|
936
|
+
const pathCount = extractPathSegmentsFromQuery(query).length;
|
|
937
|
+
if (typeCount >= 2 || memberCount >= 2)
|
|
938
|
+
return true;
|
|
939
|
+
return typeCount + memberCount + fileCount + pathCount >= 2;
|
|
940
|
+
}
|
|
941
|
+
/** Omit source bodies when inventory sections suffice and the graph found no flow path. */
|
|
942
|
+
function shouldOmitSourceBodies(inv, hasFlowPath, multiAnchorQuery) {
|
|
943
|
+
if (hasFlowPath || multiAnchorQuery)
|
|
944
|
+
return false;
|
|
945
|
+
if (inv.configRendered)
|
|
946
|
+
return true;
|
|
947
|
+
if (inv.kitModuleSurveyRendered)
|
|
948
|
+
return true;
|
|
949
|
+
if (inv.inheritanceListed)
|
|
950
|
+
return true;
|
|
951
|
+
// Filtered import lists are complete answers (even a single site).
|
|
952
|
+
if (inv.hasFilteredImports && inv.importSiteCount >= 1)
|
|
953
|
+
return true;
|
|
954
|
+
// Caller / method inventory (paths only).
|
|
955
|
+
if (inv.callerBulletCount >= 1)
|
|
956
|
+
return true;
|
|
957
|
+
// Member-usage survey (e.g. `.drawModifier`) — paths in inventory, not full bodies.
|
|
958
|
+
if (inv.memberFileCount >= 2 && !inv.hasFilteredImports)
|
|
959
|
+
return true;
|
|
960
|
+
// Domain file/usage survey — paths + top symbols, not full bodies.
|
|
961
|
+
if (inv.domainFileCount >= 1)
|
|
962
|
+
return true;
|
|
963
|
+
// API call-site survey (statfs, napi_*, …) — paths only.
|
|
964
|
+
if (inv.apiUsageFileCount >= 1)
|
|
965
|
+
return true;
|
|
966
|
+
// Upstream data-source survey (BadgeManager → notification service).
|
|
967
|
+
if (inv.dataSourceEdgeCount >= 1)
|
|
968
|
+
return true;
|
|
969
|
+
return false;
|
|
970
|
+
}
|
|
971
|
+
/** Single named type + member/callback intent — render that type's file only. */
|
|
972
|
+
function shouldFocusOnNamedTypeFile(query, hasFlowPath, multiAnchorQuery) {
|
|
973
|
+
if (hasFlowPath || multiAnchorQuery)
|
|
974
|
+
return false;
|
|
975
|
+
if (extractFileBasenamesFromQuery(query).length > 0)
|
|
976
|
+
return false;
|
|
977
|
+
const types = extractTypeNamesFromQuery(query);
|
|
978
|
+
if (types.length !== 1)
|
|
979
|
+
return false;
|
|
980
|
+
return (extractMemberAccessFromQuery(query).length > 0
|
|
981
|
+
|| /回调|callback|事件处理|事件|成员|member|字段|field|属性|property|函数体|方法体/i.test(query));
|
|
982
|
+
}
|
|
983
|
+
/** PascalCase type / class names mentioned in the query (Configuration, BadgeManager). */
|
|
984
|
+
function extractTypeNamesFromQuery(query) {
|
|
985
|
+
const names = new Set();
|
|
986
|
+
for (const m of query.matchAll(/\b([A-Z][A-Za-z0-9]*(?:[A-Z][a-z]+)+|[A-Z][a-z][A-Za-z0-9]*)\b/g)) {
|
|
987
|
+
if (m[1] && m[1].length >= 3)
|
|
988
|
+
names.add(m[1]);
|
|
989
|
+
}
|
|
990
|
+
for (const base of extractFileBasenamesFromQuery(query)) {
|
|
991
|
+
if (/^[A-Z]/.test(base))
|
|
992
|
+
names.add(base);
|
|
993
|
+
}
|
|
994
|
+
return [...names];
|
|
995
|
+
}
|
|
996
|
+
/** True when the query names concrete indexed-code anchors (for explore-first guidance). */
|
|
997
|
+
function hasConcreteExploreAnchors(query) {
|
|
998
|
+
if (extractFileBasenamesFromQuery(query).length > 0
|
|
999
|
+
|| extractPathSegmentsFromQuery(query).length > 0
|
|
1000
|
+
|| extractKitModuleNamesFromQuery(query).length > 0
|
|
1001
|
+
|| extractMemberAccessFromQuery(query).length > 0
|
|
1002
|
+
|| extractTypeNamesFromQuery(query).length > 0
|
|
1003
|
+
|| /\b[A-Za-z_][\w]*::[A-Za-z_][\w]*/.test(query)) {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
const deps = extractDependencySymbolsFromQuery(query);
|
|
1007
|
+
if (deps.some((d) => isDistinctiveIdentifier(d)))
|
|
1008
|
+
return true;
|
|
1009
|
+
return queryMentionsCodeContext(query) && deps.length > 0;
|
|
1010
|
+
}
|
|
121
1011
|
/**
|
|
122
1012
|
* Generate stem variants of a search term by removing common English suffixes.
|
|
123
1013
|
* Used for FTS query expansion so "caching" also finds "cache", "eviction" finds "evict", etc.
|
|
@@ -189,10 +1079,37 @@ function getStemVariants(term) {
|
|
|
189
1079
|
function extractSearchTerms(query, options) {
|
|
190
1080
|
const includeStems = options?.stems !== false;
|
|
191
1081
|
const tokens = new Set();
|
|
1082
|
+
let match;
|
|
1083
|
+
for (const kit of extractKitModuleNamesFromQuery(query)) {
|
|
1084
|
+
tokens.add(kit.toLowerCase());
|
|
1085
|
+
}
|
|
1086
|
+
for (const base of extractFileBasenamesFromQuery(query)) {
|
|
1087
|
+
if (base.length >= 2)
|
|
1088
|
+
tokens.add(base.toLowerCase());
|
|
1089
|
+
}
|
|
1090
|
+
for (const seg of extractPathSegmentsFromQuery(query)) {
|
|
1091
|
+
for (const part of seg.split('/')) {
|
|
1092
|
+
if (part.length >= 3)
|
|
1093
|
+
tokens.add(part.toLowerCase());
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
for (const ma of extractMemberAccessFromQuery(query)) {
|
|
1097
|
+
if (ma.member.length >= 3)
|
|
1098
|
+
tokens.add(ma.member.toLowerCase());
|
|
1099
|
+
if (ma.receiver && ma.receiver.length >= 3)
|
|
1100
|
+
tokens.add(ma.receiver.toLowerCase());
|
|
1101
|
+
}
|
|
1102
|
+
// C++ qualified names
|
|
1103
|
+
const cppQualPattern = /\b([A-Za-z_][\w]*)(::)([A-Za-z_][\w]*)\b/g;
|
|
1104
|
+
while ((match = cppQualPattern.exec(query)) !== null) {
|
|
1105
|
+
if (match[1] && match[1].length >= 3)
|
|
1106
|
+
tokens.add(match[1].toLowerCase());
|
|
1107
|
+
if (match[3] && match[3].length >= 3)
|
|
1108
|
+
tokens.add(match[3].toLowerCase());
|
|
1109
|
+
}
|
|
192
1110
|
// First, extract and preserve compound identifiers before splitting
|
|
193
1111
|
// CamelCase: scrapeLoop, UserService, getCallGraph
|
|
194
1112
|
const compoundPattern = /\b([a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z]+)+|[A-Z][a-z]+(?:[A-Z][a-z]*)+)\b/g;
|
|
195
|
-
let match;
|
|
196
1113
|
while ((match = compoundPattern.exec(query)) !== null) {
|
|
197
1114
|
if (match[1] && match[1].length >= 3) {
|
|
198
1115
|
tokens.add(match[1].toLowerCase()); // preserve full compound: "scrapeloop"
|