src-mcp 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +721 -0
- package/assets/languages.json +219 -0
- package/assets/queries/_javascript/highlights.scm +36 -0
- package/assets/queries/_javascript/locals.scm +14 -0
- package/assets/queries/_javascript/tags.scm +88 -0
- package/assets/queries/_jsx/highlights.scm +43 -0
- package/assets/queries/_jsx/indents.scm +6 -0
- package/assets/queries/_jsx/textobjects.scm +7 -0
- package/assets/queries/_typescript/highlights.scm +148 -0
- package/assets/queries/_typescript/indents.scm +5 -0
- package/assets/queries/_typescript/locals.scm +34 -0
- package/assets/queries/_typescript/tags.scm +23 -0
- package/assets/queries/_typescript/textobjects.scm +12 -0
- package/assets/queries/c/highlights.scm +167 -0
- package/assets/queries/c/indents.scm +51 -0
- package/assets/queries/c/injections.scm +2 -0
- package/assets/queries/c/locals.scm +38 -0
- package/assets/queries/c/rainbows.scm +29 -0
- package/assets/queries/c/tags.scm +9 -0
- package/assets/queries/c/textobjects.scm +27 -0
- package/assets/queries/c_sharp/highlights.scm +208 -0
- package/assets/queries/c_sharp/injections.scm +2 -0
- package/assets/queries/c_sharp/tags.scm +21 -0
- package/assets/queries/c_sharp/textobjects.scm +20 -0
- package/assets/queries/cpp/highlights.scm +177 -0
- package/assets/queries/cpp/indents.scm +3 -0
- package/assets/queries/cpp/injections.scm +4 -0
- package/assets/queries/cpp/rainbows.scm +49 -0
- package/assets/queries/cpp/tags.scm +12 -0
- package/assets/queries/cpp/textobjects.scm +7 -0
- package/assets/queries/ecma/highlights.scm +288 -0
- package/assets/queries/ecma/indents.scm +28 -0
- package/assets/queries/ecma/injections.scm +100 -0
- package/assets/queries/ecma/locals.scm +26 -0
- package/assets/queries/ecma/rainbows.scm +28 -0
- package/assets/queries/ecma/textobjects.scm +45 -0
- package/assets/queries/go/highlights.scm +236 -0
- package/assets/queries/go/indents.scm +40 -0
- package/assets/queries/go/injections.scm +92 -0
- package/assets/queries/go/locals.scm +25 -0
- package/assets/queries/go/rainbows.scm +33 -0
- package/assets/queries/go/tags.scm +30 -0
- package/assets/queries/go/textobjects.scm +33 -0
- package/assets/queries/html/highlights.scm +47 -0
- package/assets/queries/html/injections.scm +10 -0
- package/assets/queries/html/rainbows.scm +13 -0
- package/assets/queries/html/textobjects.scm +9 -0
- package/assets/queries/java/highlights.scm +227 -0
- package/assets/queries/java/indents.scm +35 -0
- package/assets/queries/java/injections.scm +2 -0
- package/assets/queries/java/rainbows.scm +35 -0
- package/assets/queries/java/tags.scm +27 -0
- package/assets/queries/java/textobjects.scm +44 -0
- package/assets/queries/javascript/highlights.scm +3 -0
- package/assets/queries/javascript/indents.scm +3 -0
- package/assets/queries/javascript/injections.scm +3 -0
- package/assets/queries/javascript/locals.scm +3 -0
- package/assets/queries/javascript/rainbows.scm +1 -0
- package/assets/queries/javascript/tags.scm +3 -0
- package/assets/queries/javascript/textobjects.scm +3 -0
- package/assets/queries/jsx/highlights.scm +3 -0
- package/assets/queries/jsx/indents.scm +3 -0
- package/assets/queries/jsx/injections.scm +3 -0
- package/assets/queries/jsx/locals.scm +3 -0
- package/assets/queries/jsx/rainbows.scm +9 -0
- package/assets/queries/jsx/tags.scm +3 -0
- package/assets/queries/jsx/textobjects.scm +3 -0
- package/assets/queries/kotlin/folds.scm +17 -0
- package/assets/queries/kotlin/highlights.scm +330 -0
- package/assets/queries/kotlin/indents.scm +44 -0
- package/assets/queries/kotlin/injections.scm +42 -0
- package/assets/queries/kotlin/locals.scm +23 -0
- package/assets/queries/kotlin/tags.scm +12 -0
- package/assets/queries/kotlin/textobjects.scm +45 -0
- package/assets/queries/ocaml/highlights.scm +151 -0
- package/assets/queries/ocaml/indents.scm +12 -0
- package/assets/queries/ocaml/injections.scm +2 -0
- package/assets/queries/ocaml/locals.scm +24 -0
- package/assets/queries/php/highlights.scm +319 -0
- package/assets/queries/php/indents.scm +18 -0
- package/assets/queries/php/injections.scm +25 -0
- package/assets/queries/php/rainbows.scm +15 -0
- package/assets/queries/php/tags.scm +26 -0
- package/assets/queries/php/textobjects.scm +52 -0
- package/assets/queries/python/highlights.scm +308 -0
- package/assets/queries/python/indents.scm +84 -0
- package/assets/queries/python/injections.scm +14 -0
- package/assets/queries/python/locals.scm +50 -0
- package/assets/queries/python/rainbows.scm +30 -0
- package/assets/queries/python/tags.scm +14 -0
- package/assets/queries/python/textobjects.scm +35 -0
- package/assets/queries/ruby/highlights.scm +191 -0
- package/assets/queries/ruby/indents.scm +24 -0
- package/assets/queries/ruby/injections.scm +35 -0
- package/assets/queries/ruby/locals.scm +20 -0
- package/assets/queries/ruby/rainbows.scm +28 -0
- package/assets/queries/ruby/tags.scm +64 -0
- package/assets/queries/ruby/textobjects.scm +56 -0
- package/assets/queries/rust/highlights.scm +514 -0
- package/assets/queries/rust/indents.scm +148 -0
- package/assets/queries/rust/injections.scm +170 -0
- package/assets/queries/rust/locals.scm +28 -0
- package/assets/queries/rust/rainbows.scm +60 -0
- package/assets/queries/rust/tags.scm +26 -0
- package/assets/queries/rust/textobjects.scm +85 -0
- package/assets/queries/scala/highlights.scm +267 -0
- package/assets/queries/scala/indents.scm +22 -0
- package/assets/queries/scala/injections.scm +16 -0
- package/assets/queries/scala/locals.scm +14 -0
- package/assets/queries/scala/textobjects.scm +65 -0
- package/assets/queries/svelte/folds.scm +13 -0
- package/assets/queries/svelte/highlights.scm +38 -0
- package/assets/queries/svelte/indents.scm +24 -0
- package/assets/queries/svelte/injections.scm +46 -0
- package/assets/queries/svelte/locals.scm +1 -0
- package/assets/queries/swift/highlights.scm +200 -0
- package/assets/queries/swift/indents.scm +100 -0
- package/assets/queries/swift/injections.scm +10 -0
- package/assets/queries/swift/locals.scm +19 -0
- package/assets/queries/swift/rainbows.scm +60 -0
- package/assets/queries/swift/textobjects.scm +23 -0
- package/assets/queries/tsx/highlights.scm +3 -0
- package/assets/queries/tsx/indents.scm +3 -0
- package/assets/queries/tsx/injections.scm +3 -0
- package/assets/queries/tsx/locals.scm +3 -0
- package/assets/queries/tsx/rainbows.scm +2 -0
- package/assets/queries/tsx/tags.scm +3 -0
- package/assets/queries/tsx/textobjects.scm +3 -0
- package/assets/queries/typescript/highlights.scm +3 -0
- package/assets/queries/typescript/indents.scm +3 -0
- package/assets/queries/typescript/injections.scm +3 -0
- package/assets/queries/typescript/locals.scm +3 -0
- package/assets/queries/typescript/rainbows.scm +19 -0
- package/assets/queries/typescript/tags.scm +3 -0
- package/assets/queries/typescript/textobjects.scm +3 -0
- package/assets/wasm/tree-sitter-c.wasm +0 -0
- package/assets/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/assets/wasm/tree-sitter-cpp.wasm +0 -0
- package/assets/wasm/tree-sitter-go.wasm +0 -0
- package/assets/wasm/tree-sitter-html.wasm +0 -0
- package/assets/wasm/tree-sitter-java.wasm +0 -0
- package/assets/wasm/tree-sitter-javascript.wasm +0 -0
- package/assets/wasm/tree-sitter-kotlin.wasm +0 -0
- package/assets/wasm/tree-sitter-ocaml.wasm +0 -0
- package/assets/wasm/tree-sitter-php.wasm +0 -0
- package/assets/wasm/tree-sitter-python.wasm +0 -0
- package/assets/wasm/tree-sitter-ruby.wasm +0 -0
- package/assets/wasm/tree-sitter-rust.wasm +0 -0
- package/assets/wasm/tree-sitter-scala.wasm +0 -0
- package/assets/wasm/tree-sitter-svelte.wasm +0 -0
- package/assets/wasm/tree-sitter-swift.wasm +0 -0
- package/assets/wasm/tree-sitter-tsx.wasm +0 -0
- package/assets/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/adapter.d.ts +7 -0
- package/dist/cli/adapter.d.ts.map +1 -0
- package/dist/cli/adapter.js +39 -0
- package/dist/cli/adapter.js.map +1 -0
- package/dist/cli/commands/index.d.ts +24 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +13 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/serve.command.d.ts +21 -0
- package/dist/cli/commands/serve.command.d.ts.map +1 -0
- package/dist/cli/commands/serve.command.js +62 -0
- package/dist/cli/commands/serve.command.js.map +1 -0
- package/dist/cli/commands/version.command.d.ts +2 -0
- package/dist/cli/commands/version.command.d.ts.map +1 -0
- package/dist/cli/commands/version.command.js +12 -0
- package/dist/cli/commands/version.command.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parser.d.ts +7 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +99 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/config/index.d.ts +24 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +38 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/ast/index.d.ts +82 -0
- package/dist/core/ast/index.d.ts.map +1 -0
- package/dist/core/ast/index.js +204 -0
- package/dist/core/ast/index.js.map +1 -0
- package/dist/core/ast/types.d.ts +152 -0
- package/dist/core/ast/types.d.ts.map +1 -0
- package/dist/core/ast/types.js +5 -0
- package/dist/core/ast/types.js.map +1 -0
- package/dist/core/constants.d.ts +17 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +49 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/embeddings/callgraph.d.ts +98 -0
- package/dist/core/embeddings/callgraph.d.ts.map +1 -0
- package/dist/core/embeddings/callgraph.js +415 -0
- package/dist/core/embeddings/callgraph.js.map +1 -0
- package/dist/core/embeddings/chunker.d.ts +37 -0
- package/dist/core/embeddings/chunker.d.ts.map +1 -0
- package/dist/core/embeddings/chunker.js +298 -0
- package/dist/core/embeddings/chunker.js.map +1 -0
- package/dist/core/embeddings/client.d.ts +30 -0
- package/dist/core/embeddings/client.d.ts.map +1 -0
- package/dist/core/embeddings/client.js +65 -0
- package/dist/core/embeddings/client.js.map +1 -0
- package/dist/core/embeddings/crossfile.d.ts +58 -0
- package/dist/core/embeddings/crossfile.d.ts.map +1 -0
- package/dist/core/embeddings/crossfile.js +202 -0
- package/dist/core/embeddings/crossfile.js.map +1 -0
- package/dist/core/embeddings/enricher.d.ts +53 -0
- package/dist/core/embeddings/enricher.d.ts.map +1 -0
- package/dist/core/embeddings/enricher.js +308 -0
- package/dist/core/embeddings/enricher.js.map +1 -0
- package/dist/core/embeddings/index.d.ts +13 -0
- package/dist/core/embeddings/index.d.ts.map +1 -0
- package/dist/core/embeddings/index.js +20 -0
- package/dist/core/embeddings/index.js.map +1 -0
- package/dist/core/embeddings/reranker.d.ts +41 -0
- package/dist/core/embeddings/reranker.d.ts.map +1 -0
- package/dist/core/embeddings/reranker.js +117 -0
- package/dist/core/embeddings/reranker.js.map +1 -0
- package/dist/core/embeddings/store.d.ts +93 -0
- package/dist/core/embeddings/store.d.ts.map +1 -0
- package/dist/core/embeddings/store.js +304 -0
- package/dist/core/embeddings/store.js.map +1 -0
- package/dist/core/embeddings/types.d.ts +77 -0
- package/dist/core/embeddings/types.d.ts.map +1 -0
- package/dist/core/embeddings/types.js +5 -0
- package/dist/core/embeddings/types.js.map +1 -0
- package/dist/core/embeddings/watcher.d.ts +130 -0
- package/dist/core/embeddings/watcher.d.ts.map +1 -0
- package/dist/core/embeddings/watcher.js +448 -0
- package/dist/core/embeddings/watcher.js.map +1 -0
- package/dist/core/fallback/index.d.ts +26 -0
- package/dist/core/fallback/index.d.ts.map +1 -0
- package/dist/core/fallback/index.js +76 -0
- package/dist/core/fallback/index.js.map +1 -0
- package/dist/core/parser/index.d.ts +64 -0
- package/dist/core/parser/index.d.ts.map +1 -0
- package/dist/core/parser/index.js +205 -0
- package/dist/core/parser/index.js.map +1 -0
- package/dist/core/parser/languages.d.ts +26 -0
- package/dist/core/parser/languages.d.ts.map +1 -0
- package/dist/core/parser/languages.js +101 -0
- package/dist/core/parser/languages.js.map +1 -0
- package/dist/core/queries/helpers.d.ts +72 -0
- package/dist/core/queries/helpers.d.ts.map +1 -0
- package/dist/core/queries/helpers.js +101 -0
- package/dist/core/queries/helpers.js.map +1 -0
- package/dist/core/queries/index.d.ts +144 -0
- package/dist/core/queries/index.d.ts.map +1 -0
- package/dist/core/queries/index.js +396 -0
- package/dist/core/queries/index.js.map +1 -0
- package/dist/core/queries/loader.d.ts +46 -0
- package/dist/core/queries/loader.d.ts.map +1 -0
- package/dist/core/queries/loader.js +216 -0
- package/dist/core/queries/loader.js.map +1 -0
- package/dist/core/queries/patterns.d.ts +10 -0
- package/dist/core/queries/patterns.d.ts.map +1 -0
- package/dist/core/queries/patterns.js +112 -0
- package/dist/core/queries/patterns.js.map +1 -0
- package/dist/core/symbols/index.d.ts +70 -0
- package/dist/core/symbols/index.d.ts.map +1 -0
- package/dist/core/symbols/index.js +359 -0
- package/dist/core/symbols/index.js.map +1 -0
- package/dist/core/unified/index.d.ts +118 -0
- package/dist/core/unified/index.d.ts.map +1 -0
- package/dist/core/unified/index.js +428 -0
- package/dist/core/unified/index.js.map +1 -0
- package/dist/core/utils/assets.d.ts +34 -0
- package/dist/core/utils/assets.d.ts.map +1 -0
- package/dist/core/utils/assets.js +85 -0
- package/dist/core/utils/assets.js.map +1 -0
- package/dist/core/utils/cache.d.ts +43 -0
- package/dist/core/utils/cache.d.ts.map +1 -0
- package/dist/core/utils/cache.js +60 -0
- package/dist/core/utils/cache.js.map +1 -0
- package/dist/core/utils/index.d.ts +7 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +10 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/core/utils/tsconfig.d.ts +34 -0
- package/dist/core/utils/tsconfig.d.ts.map +1 -0
- package/dist/core/utils/tsconfig.js +173 -0
- package/dist/core/utils/tsconfig.js.map +1 -0
- package/dist/features/analyze-file/index.d.ts +15 -0
- package/dist/features/analyze-file/index.d.ts.map +1 -0
- package/dist/features/analyze-file/index.js +164 -0
- package/dist/features/analyze-file/index.js.map +1 -0
- package/dist/features/get-call-graph/index.d.ts +24 -0
- package/dist/features/get-call-graph/index.d.ts.map +1 -0
- package/dist/features/get-call-graph/index.js +246 -0
- package/dist/features/get-call-graph/index.js.map +1 -0
- package/dist/features/get-index-status/index.d.ts +20 -0
- package/dist/features/get-index-status/index.d.ts.map +1 -0
- package/dist/features/get-index-status/index.js +90 -0
- package/dist/features/get-index-status/index.js.map +1 -0
- package/dist/features/index-codebase/index.d.ts +24 -0
- package/dist/features/index-codebase/index.d.ts.map +1 -0
- package/dist/features/index-codebase/index.js +283 -0
- package/dist/features/index-codebase/index.js.map +1 -0
- package/dist/features/index.d.ts +15 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +28 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/info/index.d.ts +19 -0
- package/dist/features/info/index.d.ts.map +1 -0
- package/dist/features/info/index.js +41 -0
- package/dist/features/info/index.js.map +1 -0
- package/dist/features/list-symbols/index.d.ts +22 -0
- package/dist/features/list-symbols/index.d.ts.map +1 -0
- package/dist/features/list-symbols/index.js +74 -0
- package/dist/features/list-symbols/index.js.map +1 -0
- package/dist/features/parse-ast/index.d.ts +12 -0
- package/dist/features/parse-ast/index.d.ts.map +1 -0
- package/dist/features/parse-ast/index.js +71 -0
- package/dist/features/parse-ast/index.js.map +1 -0
- package/dist/features/query-code/index.d.ts +23 -0
- package/dist/features/query-code/index.d.ts.map +1 -0
- package/dist/features/query-code/index.js +96 -0
- package/dist/features/query-code/index.js.map +1 -0
- package/dist/features/search-code/index.d.ts +39 -0
- package/dist/features/search-code/index.d.ts.map +1 -0
- package/dist/features/search-code/index.js +258 -0
- package/dist/features/search-code/index.js.map +1 -0
- package/dist/features/types.d.ts +14 -0
- package/dist/features/types.d.ts.map +1 -0
- package/dist/features/types.js +2 -0
- package/dist/features/types.js.map +1 -0
- package/dist/features/update-index/index.d.ts +24 -0
- package/dist/features/update-index/index.d.ts.map +1 -0
- package/dist/features/update-index/index.js +358 -0
- package/dist/features/update-index/index.js.map +1 -0
- package/dist/features/utils/content.d.ts +30 -0
- package/dist/features/utils/content.d.ts.map +1 -0
- package/dist/features/utils/content.js +49 -0
- package/dist/features/utils/content.js.map +1 -0
- package/dist/features/utils/index.d.ts +6 -0
- package/dist/features/utils/index.d.ts.map +1 -0
- package/dist/features/utils/index.js +8 -0
- package/dist/features/utils/index.js.map +1 -0
- package/dist/features/utils/result.d.ts +37 -0
- package/dist/features/utils/result.d.ts.map +1 -0
- package/dist/features/utils/result.js +53 -0
- package/dist/features/utils/result.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +188 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +3 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +17 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +24 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/adapter.d.ts +4 -0
- package/dist/tools/adapter.d.ts.map +1 -0
- package/dist/tools/adapter.js +28 -0
- package/dist/tools/adapter.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/colors.d.ts +24 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +30 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +57 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/spinner.d.ts +11 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +36 -0
- package/dist/utils/spinner.js.map +1 -0
- package/package.json +110 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code chunker for splitting source files into embeddable chunks
|
|
3
|
+
*
|
|
4
|
+
* Uses tree-sitter for semantic chunking based on symbols (functions, classes, etc.)
|
|
5
|
+
* This produces much better embeddings than character-based splitting.
|
|
6
|
+
*/
|
|
7
|
+
import * as crypto from "node:crypto";
|
|
8
|
+
import { parseCode } from "@core/parser";
|
|
9
|
+
import { extractSymbols } from "@core/symbols";
|
|
10
|
+
import { logger } from "@utils";
|
|
11
|
+
/**
|
|
12
|
+
* Generate a unique ID for a chunk
|
|
13
|
+
*/
|
|
14
|
+
function generateChunkId(filePath, content, startLine) {
|
|
15
|
+
const hash = crypto
|
|
16
|
+
.createHash("md5")
|
|
17
|
+
.update(`${filePath}:${String(startLine)}:${content}`)
|
|
18
|
+
.digest("hex")
|
|
19
|
+
.slice(0, 12);
|
|
20
|
+
return `chunk_${hash}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Detect language from file extension
|
|
24
|
+
*/
|
|
25
|
+
export function detectLanguage(filePath) {
|
|
26
|
+
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
|
|
27
|
+
const extensionMap = {
|
|
28
|
+
ts: "typescript",
|
|
29
|
+
tsx: "typescript",
|
|
30
|
+
js: "javascript",
|
|
31
|
+
jsx: "javascript",
|
|
32
|
+
mjs: "javascript",
|
|
33
|
+
cjs: "javascript",
|
|
34
|
+
py: "python",
|
|
35
|
+
rs: "rust",
|
|
36
|
+
go: "go",
|
|
37
|
+
java: "java",
|
|
38
|
+
kt: "kotlin",
|
|
39
|
+
rb: "ruby",
|
|
40
|
+
php: "php",
|
|
41
|
+
c: "c",
|
|
42
|
+
cpp: "cpp",
|
|
43
|
+
h: "c",
|
|
44
|
+
hpp: "cpp",
|
|
45
|
+
cs: "csharp",
|
|
46
|
+
swift: "swift",
|
|
47
|
+
scala: "scala",
|
|
48
|
+
vue: "vue",
|
|
49
|
+
svelte: "svelte",
|
|
50
|
+
md: "markdown",
|
|
51
|
+
json: "json",
|
|
52
|
+
yaml: "yaml",
|
|
53
|
+
yml: "yaml",
|
|
54
|
+
toml: "toml",
|
|
55
|
+
xml: "xml",
|
|
56
|
+
html: "html",
|
|
57
|
+
css: "css",
|
|
58
|
+
scss: "scss",
|
|
59
|
+
less: "less",
|
|
60
|
+
sql: "sql",
|
|
61
|
+
sh: "bash",
|
|
62
|
+
bash: "bash",
|
|
63
|
+
zsh: "bash",
|
|
64
|
+
};
|
|
65
|
+
return extensionMap[ext] ?? "unknown";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get line number from byte offset
|
|
69
|
+
*/
|
|
70
|
+
function getLineFromOffset(content, offset) {
|
|
71
|
+
const before = content.slice(0, offset);
|
|
72
|
+
return (before.match(/\n/g) ?? []).length + 1;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract code content for a symbol using its offsets
|
|
76
|
+
*/
|
|
77
|
+
function getSymbolContent(content, symbol) {
|
|
78
|
+
return content.slice(symbol.start.offset, symbol.end.offset);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Split large content into smaller chunks while respecting line boundaries
|
|
82
|
+
*/
|
|
83
|
+
function splitLargeContent(content, maxSize, overlap) {
|
|
84
|
+
// Normalize line endings (handle CRLF and CR)
|
|
85
|
+
const normalizedContent = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
86
|
+
if (normalizedContent.length <= maxSize) {
|
|
87
|
+
return [normalizedContent];
|
|
88
|
+
}
|
|
89
|
+
const chunks = [];
|
|
90
|
+
const lines = normalizedContent.split("\n");
|
|
91
|
+
let currentChunk = [];
|
|
92
|
+
let currentSize = 0;
|
|
93
|
+
for (const line of lines) {
|
|
94
|
+
const lineSize = line.length + 1; // +1 for newline
|
|
95
|
+
if (currentSize + lineSize > maxSize && currentChunk.length > 0) {
|
|
96
|
+
chunks.push(currentChunk.join("\n"));
|
|
97
|
+
// Keep overlap lines
|
|
98
|
+
const overlapLines = [];
|
|
99
|
+
let overlapSize = 0;
|
|
100
|
+
for (let i = currentChunk.length - 1; i >= 0 && overlapSize < overlap; i--) {
|
|
101
|
+
const l = currentChunk[i];
|
|
102
|
+
if (l !== undefined) {
|
|
103
|
+
overlapLines.unshift(l);
|
|
104
|
+
overlapSize += l.length + 1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
currentChunk = overlapLines;
|
|
108
|
+
currentSize = overlapSize;
|
|
109
|
+
}
|
|
110
|
+
currentChunk.push(line);
|
|
111
|
+
currentSize += lineSize;
|
|
112
|
+
}
|
|
113
|
+
if (currentChunk.length > 0) {
|
|
114
|
+
chunks.push(currentChunk.join("\n"));
|
|
115
|
+
}
|
|
116
|
+
return chunks;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create a chunk from content
|
|
120
|
+
*/
|
|
121
|
+
function createChunk(filePath, language, content, startLine, endLine, symbolName, symbolType) {
|
|
122
|
+
return {
|
|
123
|
+
id: generateChunkId(filePath, content, startLine),
|
|
124
|
+
content,
|
|
125
|
+
filePath,
|
|
126
|
+
language,
|
|
127
|
+
startLine,
|
|
128
|
+
endLine,
|
|
129
|
+
symbolName,
|
|
130
|
+
symbolType,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Chunk a source file using tree-sitter for semantic boundaries
|
|
135
|
+
*
|
|
136
|
+
* Strategy:
|
|
137
|
+
* 1. Parse file with tree-sitter and extract symbols
|
|
138
|
+
* 2. Each function/class/method becomes its own chunk
|
|
139
|
+
* 3. Code between symbols (imports, top-level code) is grouped together
|
|
140
|
+
* 4. Large symbols are split at line boundaries if they exceed maxSize
|
|
141
|
+
*/
|
|
142
|
+
export async function chunkFile(filePath, content, config) {
|
|
143
|
+
const language = detectLanguage(filePath);
|
|
144
|
+
const maxSize = config.defaultChunkSize;
|
|
145
|
+
const overlap = config.defaultChunkOverlap;
|
|
146
|
+
// Try to parse with tree-sitter
|
|
147
|
+
let symbols = [];
|
|
148
|
+
try {
|
|
149
|
+
const parseResult = await parseCode(content, { filePath });
|
|
150
|
+
const result = extractSymbols(parseResult.tree, parseResult.languageInstance, parseResult.language);
|
|
151
|
+
symbols = result.symbols;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
logger.debug(`Tree-sitter parsing failed for ${filePath}, using fallback chunking: ${error instanceof Error ? error.message : String(error)}`);
|
|
155
|
+
// Fallback to simple line-based chunking
|
|
156
|
+
return fallbackChunk(filePath, content, language, maxSize, overlap);
|
|
157
|
+
}
|
|
158
|
+
// If no symbols found, use fallback
|
|
159
|
+
if (symbols.length === 0) {
|
|
160
|
+
return fallbackChunk(filePath, content, language, maxSize, overlap);
|
|
161
|
+
}
|
|
162
|
+
// Sort symbols by start offset
|
|
163
|
+
const sortedSymbols = [...symbols].sort((a, b) => a.start.offset - b.start.offset);
|
|
164
|
+
// Build regions: symbols + gaps between them
|
|
165
|
+
const regions = [];
|
|
166
|
+
let lastEndOffset = 0;
|
|
167
|
+
for (const symbol of sortedSymbols) {
|
|
168
|
+
// Add gap before this symbol (if any significant content)
|
|
169
|
+
if (symbol.start.offset > lastEndOffset) {
|
|
170
|
+
const gapContent = content
|
|
171
|
+
.slice(lastEndOffset, symbol.start.offset)
|
|
172
|
+
.trim();
|
|
173
|
+
if (gapContent.length > 0) {
|
|
174
|
+
regions.push({
|
|
175
|
+
content: content.slice(lastEndOffset, symbol.start.offset),
|
|
176
|
+
startOffset: lastEndOffset,
|
|
177
|
+
endOffset: symbol.start.offset,
|
|
178
|
+
startLine: getLineFromOffset(content, lastEndOffset),
|
|
179
|
+
endLine: getLineFromOffset(content, symbol.start.offset),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Add symbol region
|
|
184
|
+
const symbolContent = getSymbolContent(content, symbol);
|
|
185
|
+
regions.push({
|
|
186
|
+
content: symbolContent,
|
|
187
|
+
startOffset: symbol.start.offset,
|
|
188
|
+
endOffset: symbol.end.offset,
|
|
189
|
+
startLine: symbol.start.line,
|
|
190
|
+
endLine: symbol.end.line,
|
|
191
|
+
symbolName: symbol.name,
|
|
192
|
+
symbolType: symbol.type,
|
|
193
|
+
});
|
|
194
|
+
lastEndOffset = Math.max(lastEndOffset, symbol.end.offset);
|
|
195
|
+
}
|
|
196
|
+
// Add trailing content after last symbol
|
|
197
|
+
if (lastEndOffset < content.length) {
|
|
198
|
+
const trailingContent = content.slice(lastEndOffset).trim();
|
|
199
|
+
if (trailingContent.length > 0) {
|
|
200
|
+
regions.push({
|
|
201
|
+
content: content.slice(lastEndOffset),
|
|
202
|
+
startOffset: lastEndOffset,
|
|
203
|
+
endOffset: content.length,
|
|
204
|
+
startLine: getLineFromOffset(content, lastEndOffset),
|
|
205
|
+
endLine: getLineFromOffset(content, content.length),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Convert regions to chunks, splitting large ones
|
|
210
|
+
const chunks = [];
|
|
211
|
+
for (const region of regions) {
|
|
212
|
+
const regionContent = region.content.trim();
|
|
213
|
+
if (regionContent.length === 0) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (regionContent.length <= maxSize) {
|
|
217
|
+
// Small enough, create single chunk
|
|
218
|
+
chunks.push(createChunk(filePath, language, regionContent, region.startLine, region.endLine, region.symbolName, region.symbolType));
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
// Too large, split it
|
|
222
|
+
const parts = splitLargeContent(regionContent, maxSize, overlap);
|
|
223
|
+
let currentLine = region.startLine;
|
|
224
|
+
for (const part of parts) {
|
|
225
|
+
const partLines = (part.match(/\n/g) ?? []).length + 1;
|
|
226
|
+
chunks.push(createChunk(filePath, language, part, currentLine, currentLine + partLines - 1, region.symbolName, region.symbolType));
|
|
227
|
+
currentLine += partLines - Math.floor(overlap / 50); // Approximate line overlap
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return chunks;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Fallback chunking when tree-sitter fails or finds no symbols
|
|
235
|
+
* Uses simple line-based splitting
|
|
236
|
+
*/
|
|
237
|
+
function fallbackChunk(filePath, content, language, maxSize, overlap) {
|
|
238
|
+
// Handle empty content
|
|
239
|
+
if (content.trim().length === 0) {
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
const chunks = [];
|
|
243
|
+
const parts = splitLargeContent(content, maxSize, overlap);
|
|
244
|
+
let currentLine = 1;
|
|
245
|
+
for (const part of parts) {
|
|
246
|
+
const partLines = (part.match(/\n/g) ?? []).length + 1;
|
|
247
|
+
chunks.push(createChunk(filePath, language, part, currentLine, currentLine + partLines - 1));
|
|
248
|
+
currentLine += partLines - Math.floor(overlap / 50);
|
|
249
|
+
}
|
|
250
|
+
return chunks;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Chunk multiple files
|
|
254
|
+
*/
|
|
255
|
+
export async function chunkFiles(files, config) {
|
|
256
|
+
const allChunks = [];
|
|
257
|
+
for (const file of files) {
|
|
258
|
+
const chunks = await chunkFile(file.path, file.content, config);
|
|
259
|
+
allChunks.push(...chunks);
|
|
260
|
+
}
|
|
261
|
+
return allChunks;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Supported file extensions for indexing
|
|
265
|
+
*/
|
|
266
|
+
export const SUPPORTED_EXTENSIONS = [
|
|
267
|
+
".ts",
|
|
268
|
+
".tsx",
|
|
269
|
+
".js",
|
|
270
|
+
".jsx",
|
|
271
|
+
".mjs",
|
|
272
|
+
".cjs",
|
|
273
|
+
".py",
|
|
274
|
+
".rs",
|
|
275
|
+
".go",
|
|
276
|
+
".java",
|
|
277
|
+
".kt",
|
|
278
|
+
".rb",
|
|
279
|
+
".php",
|
|
280
|
+
".c",
|
|
281
|
+
".cpp",
|
|
282
|
+
".h",
|
|
283
|
+
".hpp",
|
|
284
|
+
".cs",
|
|
285
|
+
".swift",
|
|
286
|
+
".scala",
|
|
287
|
+
".vue",
|
|
288
|
+
".svelte",
|
|
289
|
+
".md",
|
|
290
|
+
];
|
|
291
|
+
/**
|
|
292
|
+
* Check if a file should be indexed
|
|
293
|
+
*/
|
|
294
|
+
export function shouldIndexFile(filePath) {
|
|
295
|
+
const ext = "." + (filePath.split(".").pop()?.toLowerCase() ?? "");
|
|
296
|
+
return SUPPORTED_EXTENSIONS.includes(ext);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=chunker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunker.js","sourceRoot":"","sources":["../../../src/core/embeddings/chunker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama client for generating embeddings
|
|
3
|
+
* Uses the official ollama library
|
|
4
|
+
*/
|
|
5
|
+
import type { EmbeddingConfig } from "@core/embeddings/types";
|
|
6
|
+
export declare class OllamaClient {
|
|
7
|
+
private readonly client;
|
|
8
|
+
private readonly model;
|
|
9
|
+
constructor(config: Pick<EmbeddingConfig, "ollamaBaseUrl" | "embeddingModel">);
|
|
10
|
+
/**
|
|
11
|
+
* Generate embeddings for a single text
|
|
12
|
+
*/
|
|
13
|
+
embed(text: string): Promise<number[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Generate embeddings for multiple texts in a single request
|
|
16
|
+
*/
|
|
17
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if Ollama is reachable and the model is available
|
|
20
|
+
*/
|
|
21
|
+
healthCheck(): Promise<{
|
|
22
|
+
ok: boolean;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create a new Ollama client with default config
|
|
28
|
+
*/
|
|
29
|
+
export declare function createOllamaClient(config: Pick<EmbeddingConfig, "ollamaBaseUrl" | "embeddingModel">): OllamaClient;
|
|
30
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/embeddings/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAG7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,gBAAgB,CAAC;IAMnE;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAa5C;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAStD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAqB9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,gBAAgB,CAAC,GAChE,YAAY,CAEd"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama client for generating embeddings
|
|
3
|
+
* Uses the official ollama library
|
|
4
|
+
*/
|
|
5
|
+
import { Ollama } from "ollama";
|
|
6
|
+
export class OllamaClient {
|
|
7
|
+
client;
|
|
8
|
+
model;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.client = new Ollama({ host: config.ollamaBaseUrl });
|
|
11
|
+
this.model = config.embeddingModel;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate embeddings for a single text
|
|
15
|
+
*/
|
|
16
|
+
async embed(text) {
|
|
17
|
+
const response = await this.client.embed({
|
|
18
|
+
model: this.model,
|
|
19
|
+
input: text,
|
|
20
|
+
});
|
|
21
|
+
const result = response.embeddings[0];
|
|
22
|
+
if (!result) {
|
|
23
|
+
throw new Error("No embedding returned from Ollama");
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate embeddings for multiple texts in a single request
|
|
29
|
+
*/
|
|
30
|
+
async embedBatch(texts) {
|
|
31
|
+
const response = await this.client.embed({
|
|
32
|
+
model: this.model,
|
|
33
|
+
input: texts,
|
|
34
|
+
});
|
|
35
|
+
return response.embeddings;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if Ollama is reachable and the model is available
|
|
39
|
+
*/
|
|
40
|
+
async healthCheck() {
|
|
41
|
+
try {
|
|
42
|
+
const response = await this.client.list();
|
|
43
|
+
const models = response.models;
|
|
44
|
+
const modelExists = models.some((m) => m.name === this.model || m.name.startsWith(`${this.model}:`));
|
|
45
|
+
if (!modelExists) {
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
error: `Model "${this.model}" not found. Run: ollama pull ${this.model}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return { ok: true };
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
55
|
+
return { ok: false, error: `Cannot connect to Ollama: ${message}` };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create a new Ollama client with default config
|
|
61
|
+
*/
|
|
62
|
+
export function createOllamaClient(config) {
|
|
63
|
+
return new OllamaClient(config);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/embeddings/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,OAAO,YAAY;IACN,MAAM,CAAS;IACf,KAAK,CAAS;IAE/B,YACE,MAAiE;QAEjE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YACvC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YACvC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,UAAU,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CACpE,CAAC;YAEF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,UAAU,IAAI,CAAC,KAAK,iCAAiC,IAAI,CAAC,KAAK,EAAE;iBACzE,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,OAAO,EAAE,EAAE,CAAC;QACtE,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAiE;IAEjE,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-file context resolution for enriched embeddings
|
|
3
|
+
*
|
|
4
|
+
* Resolves imports and includes relevant symbol definitions from
|
|
5
|
+
* imported files to provide better context for semantic search.
|
|
6
|
+
*/
|
|
7
|
+
import type { Export, Import, Symbol } from "@core/ast/types";
|
|
8
|
+
/**
|
|
9
|
+
* Resolved import with source file information
|
|
10
|
+
*/
|
|
11
|
+
export interface ResolvedImport {
|
|
12
|
+
/** Original import statement */
|
|
13
|
+
import: Import;
|
|
14
|
+
/** Resolved absolute file path (null if unresolved) */
|
|
15
|
+
resolvedPath: string | null;
|
|
16
|
+
/** Exported symbols from the resolved file */
|
|
17
|
+
symbols: Symbol[];
|
|
18
|
+
/** Exports from the resolved file */
|
|
19
|
+
exports: Export[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Cross-file context for a chunk
|
|
23
|
+
*/
|
|
24
|
+
export interface CrossFileContext {
|
|
25
|
+
/** Resolved imports with their definitions */
|
|
26
|
+
resolvedImports: ResolvedImport[];
|
|
27
|
+
/** Summary of imported symbols used */
|
|
28
|
+
importedSymbolsSummary: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Options for cross-file resolution
|
|
32
|
+
*/
|
|
33
|
+
export interface CrossFileOptions {
|
|
34
|
+
/** Project root directory */
|
|
35
|
+
projectRoot: string;
|
|
36
|
+
/** Path aliases (e.g., {"@core": "src/core"}) */
|
|
37
|
+
pathAliases?: Record<string, string>;
|
|
38
|
+
/** Maximum number of imports to resolve */
|
|
39
|
+
maxImports?: number;
|
|
40
|
+
/** Maximum symbols per imported file */
|
|
41
|
+
maxSymbolsPerFile?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Clear the resolved file cache
|
|
45
|
+
*/
|
|
46
|
+
export declare function clearCrossFileCache(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve imports and get cross-file context
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveCrossFileContext(imports: Import[], currentFilePath: string, options: CrossFileOptions): Promise<CrossFileContext>;
|
|
51
|
+
/**
|
|
52
|
+
* Get cross-file cache statistics
|
|
53
|
+
*/
|
|
54
|
+
export declare function getCrossFileCacheStats(): {
|
|
55
|
+
files: number;
|
|
56
|
+
entries: string[];
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=crossfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crossfile.d.ts","sourceRoot":"","sources":["../../../src/core/embeddings/crossfile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,8CAA8C;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qCAAqC;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,uCAAuC;IACvC,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAYD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAqJD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EAAE,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CA0D3B;AAiCD;;GAEG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAKA"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-file context resolution for enriched embeddings
|
|
3
|
+
*
|
|
4
|
+
* Resolves imports and includes relevant symbol definitions from
|
|
5
|
+
* imported files to provide better context for semantic search.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { parseCode } from "@core/parser";
|
|
10
|
+
import { extractExports, extractSymbols } from "@core/symbols";
|
|
11
|
+
import { registerCache } from "@core/utils";
|
|
12
|
+
import { logger } from "@utils";
|
|
13
|
+
const resolvedFileCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Clear the resolved file cache
|
|
16
|
+
*/
|
|
17
|
+
export function clearCrossFileCache() {
|
|
18
|
+
resolvedFileCache.clear();
|
|
19
|
+
}
|
|
20
|
+
// Register cache for centralized clearing
|
|
21
|
+
registerCache("embeddings:crossFileCache", clearCrossFileCache);
|
|
22
|
+
/**
|
|
23
|
+
* Common file extensions to try when resolving imports
|
|
24
|
+
*/
|
|
25
|
+
const EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
26
|
+
/**
|
|
27
|
+
* Resolve an import source to an absolute file path
|
|
28
|
+
*/
|
|
29
|
+
function resolveImportPath(importSource, currentFilePath, options) {
|
|
30
|
+
const { projectRoot, pathAliases = {} } = options;
|
|
31
|
+
// Skip external packages (node_modules)
|
|
32
|
+
if (!importSource.startsWith(".") &&
|
|
33
|
+
!importSource.startsWith("@") &&
|
|
34
|
+
!Object.keys(pathAliases).some((alias) => importSource.startsWith(alias))) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
let resolvedPath;
|
|
38
|
+
// Handle path aliases
|
|
39
|
+
for (const [alias, target] of Object.entries(pathAliases)) {
|
|
40
|
+
if (importSource.startsWith(alias)) {
|
|
41
|
+
const relativePart = importSource.slice(alias.length);
|
|
42
|
+
resolvedPath = path.join(projectRoot, target, relativePart);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Handle relative imports
|
|
47
|
+
if (resolvedPath === undefined) {
|
|
48
|
+
if (importSource.startsWith(".")) {
|
|
49
|
+
const currentDir = path.dirname(currentFilePath);
|
|
50
|
+
resolvedPath = path.resolve(currentDir, importSource);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Unresolved alias or external package
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Try to find the actual file
|
|
58
|
+
// First, check if it's a direct file with extension
|
|
59
|
+
for (const ext of EXTENSIONS) {
|
|
60
|
+
const withExt = resolvedPath + ext;
|
|
61
|
+
if (fs.existsSync(withExt) && fs.statSync(withExt).isFile()) {
|
|
62
|
+
return withExt;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Check if the path itself exists and is a file (already has extension)
|
|
66
|
+
if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isFile()) {
|
|
67
|
+
return resolvedPath;
|
|
68
|
+
}
|
|
69
|
+
// Check for index file in directory
|
|
70
|
+
for (const ext of EXTENSIONS) {
|
|
71
|
+
const indexPath = path.join(resolvedPath, `index${ext}`);
|
|
72
|
+
if (fs.existsSync(indexPath) && fs.statSync(indexPath).isFile()) {
|
|
73
|
+
return indexPath;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Analyze a resolved file and extract its symbols
|
|
80
|
+
*/
|
|
81
|
+
async function analyzeResolvedFile(filePath) {
|
|
82
|
+
// Check cache
|
|
83
|
+
const cached = resolvedFileCache.get(filePath);
|
|
84
|
+
if (cached !== undefined) {
|
|
85
|
+
return cached;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
89
|
+
const parseResult = await parseCode(content, { filePath });
|
|
90
|
+
const { symbols } = extractSymbols(parseResult.tree, parseResult.languageInstance, parseResult.language);
|
|
91
|
+
const exports = extractExports(parseResult.tree, parseResult.languageInstance, parseResult.language);
|
|
92
|
+
const result = { symbols, exports };
|
|
93
|
+
resolvedFileCache.set(filePath, result);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logger.debug(`Failed to analyze ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
98
|
+
resolvedFileCache.set(filePath, null);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find symbols that match imported names
|
|
104
|
+
*/
|
|
105
|
+
function findImportedSymbols(importStatement, symbols, exports) {
|
|
106
|
+
const importedNames = new Set();
|
|
107
|
+
// Collect all imported names
|
|
108
|
+
for (const name of importStatement.names) {
|
|
109
|
+
importedNames.add(name.name);
|
|
110
|
+
}
|
|
111
|
+
// If namespace import, include all exported symbols
|
|
112
|
+
if (importStatement.isNamespace) {
|
|
113
|
+
const exportedNames = new Set(exports.map((e) => e.name));
|
|
114
|
+
return symbols.filter((s) => exportedNames.has(s.name));
|
|
115
|
+
}
|
|
116
|
+
// If default import, look for default export
|
|
117
|
+
if (importStatement.isDefault) {
|
|
118
|
+
const defaultExport = exports.find((e) => e.isDefault);
|
|
119
|
+
if (defaultExport) {
|
|
120
|
+
importedNames.add(defaultExport.name);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Find matching symbols
|
|
124
|
+
return symbols.filter((s) => importedNames.has(s.name));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Resolve imports and get cross-file context
|
|
128
|
+
*/
|
|
129
|
+
export async function resolveCrossFileContext(imports, currentFilePath, options) {
|
|
130
|
+
const maxImports = options.maxImports ?? 10;
|
|
131
|
+
const maxSymbolsPerFile = options.maxSymbolsPerFile ?? 5;
|
|
132
|
+
const resolvedImports = [];
|
|
133
|
+
// Process imports (limited to maxImports)
|
|
134
|
+
for (const imp of imports.slice(0, maxImports)) {
|
|
135
|
+
const resolvedPath = resolveImportPath(imp.source, currentFilePath, options);
|
|
136
|
+
if (!resolvedPath) {
|
|
137
|
+
resolvedImports.push({
|
|
138
|
+
import: imp,
|
|
139
|
+
resolvedPath: null,
|
|
140
|
+
symbols: [],
|
|
141
|
+
exports: [],
|
|
142
|
+
});
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const analysis = await analyzeResolvedFile(resolvedPath);
|
|
146
|
+
if (!analysis) {
|
|
147
|
+
resolvedImports.push({
|
|
148
|
+
import: imp,
|
|
149
|
+
resolvedPath,
|
|
150
|
+
symbols: [],
|
|
151
|
+
exports: [],
|
|
152
|
+
});
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
// Find symbols that match the imported names
|
|
156
|
+
const importedSymbols = findImportedSymbols(imp, analysis.symbols, analysis.exports).slice(0, maxSymbolsPerFile);
|
|
157
|
+
resolvedImports.push({
|
|
158
|
+
import: imp,
|
|
159
|
+
resolvedPath,
|
|
160
|
+
symbols: importedSymbols,
|
|
161
|
+
exports: analysis.exports,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// Build summary of imported symbols
|
|
165
|
+
const summary = buildImportedSymbolsSummary(resolvedImports);
|
|
166
|
+
return {
|
|
167
|
+
resolvedImports,
|
|
168
|
+
importedSymbolsSummary: summary,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Build a summary string of imported symbols for enrichment
|
|
173
|
+
*/
|
|
174
|
+
function buildImportedSymbolsSummary(resolvedImports) {
|
|
175
|
+
const lines = [];
|
|
176
|
+
for (const resolved of resolvedImports) {
|
|
177
|
+
if (resolved.symbols.length === 0) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
// Group by import source
|
|
181
|
+
const symbolDescriptions = resolved.symbols.map((s) => {
|
|
182
|
+
if (s.signature) {
|
|
183
|
+
return `${s.name}: ${s.signature}`;
|
|
184
|
+
}
|
|
185
|
+
return `${s.name} (${s.type})`;
|
|
186
|
+
});
|
|
187
|
+
if (symbolDescriptions.length > 0) {
|
|
188
|
+
lines.push(`From ${resolved.import.source}: ${symbolDescriptions.join("; ")}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return lines.join("\n");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get cross-file cache statistics
|
|
195
|
+
*/
|
|
196
|
+
export function getCrossFileCacheStats() {
|
|
197
|
+
return {
|
|
198
|
+
files: resolvedFileCache.size,
|
|
199
|
+
entries: Array.from(resolvedFileCache.keys()),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=crossfile.js.map
|