@mka-rainmaker/ama 0.1.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.
Files changed (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -0
  3. package/dist/analyzers/baseline/analyzer.d.ts +47 -0
  4. package/dist/analyzers/baseline/analyzer.d.ts.map +1 -0
  5. package/dist/analyzers/baseline/analyzer.js +84 -0
  6. package/dist/analyzers/baseline/analyzer.js.map +1 -0
  7. package/dist/analyzers/baseline/c.d.ts +12 -0
  8. package/dist/analyzers/baseline/c.d.ts.map +1 -0
  9. package/dist/analyzers/baseline/c.js +56 -0
  10. package/dist/analyzers/baseline/c.js.map +1 -0
  11. package/dist/analyzers/baseline/config.d.ts +21 -0
  12. package/dist/analyzers/baseline/config.d.ts.map +1 -0
  13. package/dist/analyzers/baseline/config.js +32 -0
  14. package/dist/analyzers/baseline/config.js.map +1 -0
  15. package/dist/analyzers/baseline/csharp.d.ts +9 -0
  16. package/dist/analyzers/baseline/csharp.d.ts.map +1 -0
  17. package/dist/analyzers/baseline/csharp.js +107 -0
  18. package/dist/analyzers/baseline/csharp.js.map +1 -0
  19. package/dist/analyzers/baseline/go.d.ts +11 -0
  20. package/dist/analyzers/baseline/go.d.ts.map +1 -0
  21. package/dist/analyzers/baseline/go.js +66 -0
  22. package/dist/analyzers/baseline/go.js.map +1 -0
  23. package/dist/analyzers/baseline/java.d.ts +9 -0
  24. package/dist/analyzers/baseline/java.d.ts.map +1 -0
  25. package/dist/analyzers/baseline/java.js +50 -0
  26. package/dist/analyzers/baseline/java.js.map +1 -0
  27. package/dist/analyzers/baseline/javascript.d.ts +10 -0
  28. package/dist/analyzers/baseline/javascript.d.ts.map +1 -0
  29. package/dist/analyzers/baseline/javascript.js +55 -0
  30. package/dist/analyzers/baseline/javascript.js.map +1 -0
  31. package/dist/analyzers/baseline/kotlin.d.ts +11 -0
  32. package/dist/analyzers/baseline/kotlin.d.ts.map +1 -0
  33. package/dist/analyzers/baseline/kotlin.js +67 -0
  34. package/dist/analyzers/baseline/kotlin.js.map +1 -0
  35. package/dist/analyzers/baseline/paths.d.ts +6 -0
  36. package/dist/analyzers/baseline/paths.d.ts.map +1 -0
  37. package/dist/analyzers/baseline/paths.js +17 -0
  38. package/dist/analyzers/baseline/paths.js.map +1 -0
  39. package/dist/analyzers/baseline/php.d.ts +11 -0
  40. package/dist/analyzers/baseline/php.d.ts.map +1 -0
  41. package/dist/analyzers/baseline/php.js +76 -0
  42. package/dist/analyzers/baseline/php.js.map +1 -0
  43. package/dist/analyzers/baseline/python.d.ts +10 -0
  44. package/dist/analyzers/baseline/python.d.ts.map +1 -0
  45. package/dist/analyzers/baseline/python.js +63 -0
  46. package/dist/analyzers/baseline/python.js.map +1 -0
  47. package/dist/analyzers/baseline/rust.d.ts +10 -0
  48. package/dist/analyzers/baseline/rust.d.ts.map +1 -0
  49. package/dist/analyzers/baseline/rust.js +45 -0
  50. package/dist/analyzers/baseline/rust.js.map +1 -0
  51. package/dist/analyzers/baseline/swift.d.ts +11 -0
  52. package/dist/analyzers/baseline/swift.d.ts.map +1 -0
  53. package/dist/analyzers/baseline/swift.js +19 -0
  54. package/dist/analyzers/baseline/swift.js.map +1 -0
  55. package/dist/analyzers/baseline/treesitter.d.ts +11 -0
  56. package/dist/analyzers/baseline/treesitter.d.ts.map +1 -0
  57. package/dist/analyzers/baseline/treesitter.js +87 -0
  58. package/dist/analyzers/baseline/treesitter.js.map +1 -0
  59. package/dist/analyzers/baseline/walk.d.ts +26 -0
  60. package/dist/analyzers/baseline/walk.d.ts.map +1 -0
  61. package/dist/analyzers/baseline/walk.js +76 -0
  62. package/dist/analyzers/baseline/walk.js.map +1 -0
  63. package/dist/analyzers/registry.d.ts +19 -0
  64. package/dist/analyzers/registry.d.ts.map +1 -0
  65. package/dist/analyzers/registry.js +43 -0
  66. package/dist/analyzers/registry.js.map +1 -0
  67. package/dist/analyzers/sfc/analyzer.d.ts +17 -0
  68. package/dist/analyzers/sfc/analyzer.d.ts.map +1 -0
  69. package/dist/analyzers/sfc/analyzer.js +141 -0
  70. package/dist/analyzers/sfc/analyzer.js.map +1 -0
  71. package/dist/analyzers/sidecar/analyzer.d.ts +29 -0
  72. package/dist/analyzers/sidecar/analyzer.d.ts.map +1 -0
  73. package/dist/analyzers/sidecar/analyzer.js +114 -0
  74. package/dist/analyzers/sidecar/analyzer.js.map +1 -0
  75. package/dist/analyzers/sidecar/protocol.d.ts +508 -0
  76. package/dist/analyzers/sidecar/protocol.d.ts.map +1 -0
  77. package/dist/analyzers/sidecar/protocol.js +102 -0
  78. package/dist/analyzers/sidecar/protocol.js.map +1 -0
  79. package/dist/analyzers/types.d.ts +46 -0
  80. package/dist/analyzers/types.d.ts.map +1 -0
  81. package/dist/analyzers/types.js +2 -0
  82. package/dist/analyzers/types.js.map +1 -0
  83. package/dist/analyzers/typescript/analyzer.d.ts +126 -0
  84. package/dist/analyzers/typescript/analyzer.d.ts.map +1 -0
  85. package/dist/analyzers/typescript/analyzer.js +1600 -0
  86. package/dist/analyzers/typescript/analyzer.js.map +1 -0
  87. package/dist/cli/commands/cycles.d.ts +6 -0
  88. package/dist/cli/commands/cycles.d.ts.map +1 -0
  89. package/dist/cli/commands/cycles.js +27 -0
  90. package/dist/cli/commands/cycles.js.map +1 -0
  91. package/dist/cli/commands/files.d.ts +6 -0
  92. package/dist/cli/commands/files.d.ts.map +1 -0
  93. package/dist/cli/commands/files.js +33 -0
  94. package/dist/cli/commands/files.js.map +1 -0
  95. package/dist/cli/commands/impact.d.ts +18 -0
  96. package/dist/cli/commands/impact.d.ts.map +1 -0
  97. package/dist/cli/commands/impact.js +113 -0
  98. package/dist/cli/commands/impact.js.map +1 -0
  99. package/dist/cli/commands/lifecycle.d.ts +5 -0
  100. package/dist/cli/commands/lifecycle.d.ts.map +1 -0
  101. package/dist/cli/commands/lifecycle.js +83 -0
  102. package/dist/cli/commands/lifecycle.js.map +1 -0
  103. package/dist/cli/commands/query.d.ts +31 -0
  104. package/dist/cli/commands/query.d.ts.map +1 -0
  105. package/dist/cli/commands/query.js +187 -0
  106. package/dist/cli/commands/query.js.map +1 -0
  107. package/dist/cli/commands/search.d.ts +21 -0
  108. package/dist/cli/commands/search.d.ts.map +1 -0
  109. package/dist/cli/commands/search.js +160 -0
  110. package/dist/cli/commands/search.js.map +1 -0
  111. package/dist/cli/commands/status.d.ts +6 -0
  112. package/dist/cli/commands/status.d.ts.map +1 -0
  113. package/dist/cli/commands/status.js +63 -0
  114. package/dist/cli/commands/status.js.map +1 -0
  115. package/dist/cli/commands/sync.d.ts +6 -0
  116. package/dist/cli/commands/sync.d.ts.map +1 -0
  117. package/dist/cli/commands/sync.js +57 -0
  118. package/dist/cli/commands/sync.js.map +1 -0
  119. package/dist/cli/emit.d.ts +9 -0
  120. package/dist/cli/emit.d.ts.map +1 -0
  121. package/dist/cli/emit.js +10 -0
  122. package/dist/cli/emit.js.map +1 -0
  123. package/dist/cli/index.d.ts +37 -0
  124. package/dist/cli/index.d.ts.map +1 -0
  125. package/dist/cli/index.js +128 -0
  126. package/dist/cli/index.js.map +1 -0
  127. package/dist/cli/paths.d.ts +7 -0
  128. package/dist/cli/paths.d.ts.map +1 -0
  129. package/dist/cli/paths.js +10 -0
  130. package/dist/cli/paths.js.map +1 -0
  131. package/dist/cli/query-runner.d.ts +13 -0
  132. package/dist/cli/query-runner.d.ts.map +1 -0
  133. package/dist/cli/query-runner.js +33 -0
  134. package/dist/cli/query-runner.js.map +1 -0
  135. package/dist/graph/dispatch.d.ts +17 -0
  136. package/dist/graph/dispatch.d.ts.map +1 -0
  137. package/dist/graph/dispatch.js +82 -0
  138. package/dist/graph/dispatch.js.map +1 -0
  139. package/dist/graph/id.d.ts +19 -0
  140. package/dist/graph/id.d.ts.map +1 -0
  141. package/dist/graph/id.js +17 -0
  142. package/dist/graph/id.js.map +1 -0
  143. package/dist/graph/index.d.ts +6 -0
  144. package/dist/graph/index.d.ts.map +1 -0
  145. package/dist/graph/index.js +4 -0
  146. package/dist/graph/index.js.map +1 -0
  147. package/dist/graph/types.d.ts +71 -0
  148. package/dist/graph/types.d.ts.map +1 -0
  149. package/dist/graph/types.js +52 -0
  150. package/dist/graph/types.js.map +1 -0
  151. package/dist/indexer/debouncer.d.ts +32 -0
  152. package/dist/indexer/debouncer.d.ts.map +1 -0
  153. package/dist/indexer/debouncer.js +81 -0
  154. package/dist/indexer/debouncer.js.map +1 -0
  155. package/dist/indexer/ignore.d.ts +55 -0
  156. package/dist/indexer/ignore.d.ts.map +1 -0
  157. package/dist/indexer/ignore.js +170 -0
  158. package/dist/indexer/ignore.js.map +1 -0
  159. package/dist/indexer/indexer.d.ts +112 -0
  160. package/dist/indexer/indexer.d.ts.map +1 -0
  161. package/dist/indexer/indexer.js +392 -0
  162. package/dist/indexer/indexer.js.map +1 -0
  163. package/dist/indexer/watcher.d.ts +50 -0
  164. package/dist/indexer/watcher.d.ts.map +1 -0
  165. package/dist/indexer/watcher.js +86 -0
  166. package/dist/indexer/watcher.js.map +1 -0
  167. package/dist/mcp/build-info.d.ts +16 -0
  168. package/dist/mcp/build-info.d.ts.map +1 -0
  169. package/dist/mcp/build-info.js +54 -0
  170. package/dist/mcp/build-info.js.map +1 -0
  171. package/dist/mcp/http.d.ts +18 -0
  172. package/dist/mcp/http.d.ts.map +1 -0
  173. package/dist/mcp/http.js +145 -0
  174. package/dist/mcp/http.js.map +1 -0
  175. package/dist/mcp/server.d.ts +22 -0
  176. package/dist/mcp/server.d.ts.map +1 -0
  177. package/dist/mcp/server.js +401 -0
  178. package/dist/mcp/server.js.map +1 -0
  179. package/dist/mcp/session.d.ts +155 -0
  180. package/dist/mcp/session.d.ts.map +1 -0
  181. package/dist/mcp/session.js +319 -0
  182. package/dist/mcp/session.js.map +1 -0
  183. package/dist/query/service.d.ts +329 -0
  184. package/dist/query/service.d.ts.map +1 -0
  185. package/dist/query/service.js +959 -0
  186. package/dist/query/service.js.map +1 -0
  187. package/dist/runtime/entrypoint.d.ts +11 -0
  188. package/dist/runtime/entrypoint.d.ts.map +1 -0
  189. package/dist/runtime/entrypoint.js +22 -0
  190. package/dist/runtime/entrypoint.js.map +1 -0
  191. package/dist/runtime/quiet-sqlite-warning.d.ts +14 -0
  192. package/dist/runtime/quiet-sqlite-warning.d.ts.map +1 -0
  193. package/dist/runtime/quiet-sqlite-warning.js +26 -0
  194. package/dist/runtime/quiet-sqlite-warning.js.map +1 -0
  195. package/dist/runtime/wasm-tier.d.ts +2 -0
  196. package/dist/runtime/wasm-tier.d.ts.map +1 -0
  197. package/dist/runtime/wasm-tier.js +54 -0
  198. package/dist/runtime/wasm-tier.js.map +1 -0
  199. package/dist/store/memory.d.ts +54 -0
  200. package/dist/store/memory.d.ts.map +1 -0
  201. package/dist/store/memory.js +210 -0
  202. package/dist/store/memory.js.map +1 -0
  203. package/dist/store/sqlite.d.ts +38 -0
  204. package/dist/store/sqlite.d.ts.map +1 -0
  205. package/dist/store/sqlite.js +298 -0
  206. package/dist/store/sqlite.js.map +1 -0
  207. package/dist/store/types.d.ts +76 -0
  208. package/dist/store/types.d.ts.map +1 -0
  209. package/dist/store/types.js +2 -0
  210. package/dist/store/types.js.map +1 -0
  211. package/package.json +59 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Baseline (syntactic) spec for Swift. tree-sitter-swift carries a `name` field,
3
+ * so no special extraction is needed. `class`, `struct`, and `enum` share one
4
+ * `class_declaration` (an enum is refined to Enum by its `enum_class_body`;
5
+ * structs stay Class at this tier); `protocol_declaration` is an Interface; and
6
+ * `function_declaration` covers free functions and methods, which nest under
7
+ * their type (e.g. `Sample.square`). (ama-p3a)
8
+ */
9
+ export const swiftSpec = {
10
+ language: "swift",
11
+ extensions: [".swift"],
12
+ grammar: "swift",
13
+ symbols: {
14
+ class_declaration: { kind: "Class", kindByChild: { enum_class_body: "Enum" } },
15
+ protocol_declaration: { kind: "Interface" },
16
+ function_declaration: { kind: "Function" },
17
+ },
18
+ };
19
+ //# sourceMappingURL=swift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift.js","sourceRoot":"","sources":["../../../src/analyzers/baseline/swift.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiB;IACrC,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,CAAC,QAAQ,CAAC;IACtB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE;QACP,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE;QAC9E,oBAAoB,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC3C,oBAAoB,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;KAC3C;CACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ import Parser from "web-tree-sitter";
2
+ /** How many parsers have been allocated (test hook for the no-leak guarantee). */
3
+ export declare function parsersAllocated(): number;
4
+ /**
5
+ * Parse source code in `language` into a tree-sitter CST, loading (and caching)
6
+ * the grammar on first use. Rejects for a language with no bundled grammar.
7
+ */
8
+ export declare function parse(language: string, code: string): Promise<Parser.Tree>;
9
+ /** Languages that have a bundled grammar (so a baseline analyzer can claim them). */
10
+ export declare function supportedLanguages(): string[];
11
+ //# sourceMappingURL=treesitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treesitter.d.ts","sourceRoot":"","sources":["../../../src/analyzers/baseline/treesitter.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,iBAAiB,CAAC;AA4CrC,kFAAkF;AAClF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AA8BD;;;GAGG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAQhF;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C"}
@@ -0,0 +1,87 @@
1
+ import * as fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import * as path from "node:path";
4
+ import Parser from "web-tree-sitter";
5
+ const require = createRequire(import.meta.url);
6
+ /**
7
+ * Languages we ship a prebuilt tree-sitter grammar for (via `tree-sitter-wasms`),
8
+ * mapped to the grammar's wasm filename. Grow this as baseline analyzers land.
9
+ *
10
+ * The runtime (`web-tree-sitter`) is pinned to match the grammar bundle's ABI:
11
+ * `tree-sitter-wasms@0.1.13` grammars are built with tree-sitter 0.20.x, so the
12
+ * runtime must be `web-tree-sitter@0.20.x` — a newer runtime fails to load them.
13
+ */
14
+ const GRAMMARS = {
15
+ python: "tree-sitter-python.wasm",
16
+ javascript: "tree-sitter-javascript.wasm",
17
+ // For SFC `<script lang="ts">` bodies parsed by the SfcAnalyzer (the deep TS
18
+ // analyzer still owns `.ts`/`.tsx` files themselves). (ama-q1u)
19
+ typescript: "tree-sitter-typescript.wasm",
20
+ java: "tree-sitter-java.wasm",
21
+ csharp: "tree-sitter-c_sharp.wasm",
22
+ go: "tree-sitter-go.wasm",
23
+ rust: "tree-sitter-rust.wasm",
24
+ php: "tree-sitter-php.wasm",
25
+ c: "tree-sitter-c.wasm",
26
+ cpp: "tree-sitter-cpp.wasm",
27
+ kotlin: "tree-sitter-kotlin.wasm",
28
+ swift: "tree-sitter-swift.wasm",
29
+ };
30
+ /** Runtime init is one-shot; each grammar is loaded once and cached. */
31
+ let runtime;
32
+ const grammars = new Map();
33
+ /**
34
+ * One reused parser. A web-tree-sitter `Parser` holds WASM linear memory and
35
+ * must be freed with `.delete()`; allocating a fresh one per file (and never
36
+ * deleting it) leaks ~a parser per source file, which across a large
37
+ * multi-language index exhausts process memory and crashes V8 with a fatal
38
+ * WASM-compilation OOM. Reusing one is safe because `setLanguage` + `parse` is a
39
+ * synchronous block — concurrent `parse()` calls can't interleave it. (ama-5o1)
40
+ */
41
+ let parser;
42
+ let parserAllocCount = 0;
43
+ /** How many parsers have been allocated (test hook for the no-leak guarantee). */
44
+ export function parsersAllocated() {
45
+ return parserAllocCount;
46
+ }
47
+ /** Absolute path to a file bundled inside an installed package. */
48
+ function packageFile(pkg, ...rel) {
49
+ return path.join(path.dirname(require.resolve(`${pkg}/package.json`)), ...rel);
50
+ }
51
+ function initRuntime() {
52
+ // Point Emscripten at the runtime wasm explicitly so init works regardless of
53
+ // the process cwd (vitest, the dev loop, an installed CLI).
54
+ runtime ??= Parser.init({ locateFile: () => packageFile("web-tree-sitter", "tree-sitter.wasm") });
55
+ return runtime;
56
+ }
57
+ /** Load a grammar on demand, caching the (async) result per language. */
58
+ function loadLanguage(language) {
59
+ const file = GRAMMARS[language];
60
+ if (!file) {
61
+ return Promise.reject(new Error(`No bundled tree-sitter grammar for language: ${language}`));
62
+ }
63
+ let pending = grammars.get(language);
64
+ if (!pending) {
65
+ pending = initRuntime().then(() => Parser.Language.load(fs.readFileSync(packageFile("tree-sitter-wasms", "out", file))));
66
+ grammars.set(language, pending);
67
+ }
68
+ return pending;
69
+ }
70
+ /**
71
+ * Parse source code in `language` into a tree-sitter CST, loading (and caching)
72
+ * the grammar on first use. Rejects for a language with no bundled grammar.
73
+ */
74
+ export async function parse(language, code) {
75
+ const lang = await loadLanguage(language);
76
+ if (!parser) {
77
+ parser = new Parser();
78
+ parserAllocCount++;
79
+ }
80
+ parser.setLanguage(lang);
81
+ return parser.parse(code);
82
+ }
83
+ /** Languages that have a bundled grammar (so a baseline analyzer can claim them). */
84
+ export function supportedLanguages() {
85
+ return Object.keys(GRAMMARS);
86
+ }
87
+ //# sourceMappingURL=treesitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treesitter.js","sourceRoot":"","sources":["../../../src/analyzers/baseline/treesitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type Parser from "web-tree-sitter";
2
+ import { type GraphEdge, type GraphNode, type NodeKind } from "../../graph/index.js";
3
+ /** How to turn one kind of CST node into a graph symbol. */
4
+ export interface SymbolRule {
5
+ /** Graph node kind to emit (the fallback when {@link kindByChild} matches nothing). */
6
+ readonly kind: NodeKind;
7
+ /** CST field holding the symbol's identifier (default "name"). */
8
+ readonly nameField?: string;
9
+ /**
10
+ * Refine the kind by a child node's type — for languages where one CST node
11
+ * covers several kinds (e.g. Go's `type_spec` is a `struct_type` → Class, an
12
+ * `interface_type` → Interface, else a TypeAlias). First matching named child
13
+ * wins; falls back to {@link kind}.
14
+ */
15
+ readonly kindByChild?: Readonly<Record<string, NodeKind>>;
16
+ }
17
+ /**
18
+ * Walk named CST children, emitting a symbol node for each that matches a
19
+ * {@link SymbolRule} (with a `Defines` edge from its container and a dotted
20
+ * qualified name for nesting), and recursing. Shared by the {@link BaselineAnalyzer}
21
+ * and the SFC analyzer; `lineOffset` is added to every emitted line so a fragment
22
+ * parsed out of a larger file (an SFC `<script>` block) maps back to file lines.
23
+ * (ama-q1u)
24
+ */
25
+ export declare function walkSymbols(node: Parser.SyntaxNode, symbols: Readonly<Record<string, SymbolRule>>, rel: string, containerId: string, prefix: string, nodes: GraphNode[], edges: GraphEdge[], lineOffset?: number): void;
26
+ //# sourceMappingURL=walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../../src/analyzers/baseline/walk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAE/F,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC3D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,UAAU,EACvB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAAE,EAClB,KAAK,EAAE,SAAS,EAAE,EAClB,UAAU,SAAI,GACb,IAAI,CA2BN"}
@@ -0,0 +1,76 @@
1
+ import { symbolId } from "../../graph/index.js";
2
+ /**
3
+ * Walk named CST children, emitting a symbol node for each that matches a
4
+ * {@link SymbolRule} (with a `Defines` edge from its container and a dotted
5
+ * qualified name for nesting), and recursing. Shared by the {@link BaselineAnalyzer}
6
+ * and the SFC analyzer; `lineOffset` is added to every emitted line so a fragment
7
+ * parsed out of a larger file (an SFC `<script>` block) maps back to file lines.
8
+ * (ama-q1u)
9
+ */
10
+ export function walkSymbols(node, symbols, rel, containerId, prefix, nodes, edges, lineOffset = 0) {
11
+ for (const child of node.namedChildren) {
12
+ const rule = symbols[child.type];
13
+ const name = rule ? symbolName(child, rule) : undefined;
14
+ if (rule && name) {
15
+ const qualifiedName = prefix ? `${prefix}.${name}` : name;
16
+ const id = symbolId({ file: rel, qualifiedName });
17
+ nodes.push({
18
+ id,
19
+ kind: kindFor(rule, child),
20
+ name,
21
+ file: rel,
22
+ qualifiedName,
23
+ tier: "baseline",
24
+ range: {
25
+ startLine: child.startPosition.row + 1 + lineOffset,
26
+ endLine: child.endPosition.row + 1 + lineOffset,
27
+ },
28
+ });
29
+ edges.push({ from: containerId, to: id, kind: "Defines" });
30
+ // Descend into the symbol so members nest under it (e.g. `Class.method`).
31
+ walkSymbols(child, symbols, rel, id, qualifiedName, nodes, edges, lineOffset);
32
+ }
33
+ else {
34
+ // Not a symbol (or anonymous) — keep looking for symbols inside it.
35
+ walkSymbols(child, symbols, rel, containerId, prefix, nodes, edges, lineOffset);
36
+ }
37
+ }
38
+ }
39
+ /** A symbol's name, by descending tiers of grammar convention:
40
+ * 1. a `name` field (most languages);
41
+ * 2. a `declarator` field drilled to its identifier (C/C++ — ama-s8q.9);
42
+ * 3. the first identifier-like child (Kotlin et al. name declarations
43
+ * positionally, with no field — ama-0ze). */
44
+ function symbolName(node, rule) {
45
+ const named = node.childForFieldName(rule.nameField ?? "name");
46
+ if (named)
47
+ return named.text;
48
+ const decl = node.childForFieldName("declarator");
49
+ if (decl)
50
+ return declaratorIdentifier(decl);
51
+ for (const child of node.namedChildren) {
52
+ if (child.type.endsWith("identifier"))
53
+ return child.text;
54
+ }
55
+ return undefined;
56
+ }
57
+ /** Drill a C/C++ declarator (function_declarator, pointer_declarator, …) down its
58
+ * `declarator` field to the identifier it ultimately names. (ama-s8q.9) */
59
+ function declaratorIdentifier(node) {
60
+ if (node.type.endsWith("identifier"))
61
+ return node.text;
62
+ const inner = node.childForFieldName("declarator");
63
+ return inner ? declaratorIdentifier(inner) : undefined;
64
+ }
65
+ /** Resolve a symbol's kind, refining by a child node type when the rule asks. */
66
+ function kindFor(rule, node) {
67
+ if (rule.kindByChild) {
68
+ for (const child of node.namedChildren) {
69
+ const refined = rule.kindByChild[child.type];
70
+ if (refined)
71
+ return refined;
72
+ }
73
+ }
74
+ return rule.kind;
75
+ }
76
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../src/analyzers/baseline/walk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Analyzer } from "./types.js";
2
+ /**
3
+ * Selects an analyzer for a file by its extension. The indexer asks the registry
4
+ * "who handles this file?" so adding a language is just registering an analyzer.
5
+ */
6
+ export declare class AnalyzerRegistry {
7
+ private readonly byExtension;
8
+ private readonly analyzers;
9
+ register(analyzer: Analyzer): void;
10
+ /** Register an analyzer only if it reports itself available — for sidecars whose
11
+ * subprocess may be absent. Returns whether it was registered. An analyzer without
12
+ * an {@link Analyzer.isAvailable} probe (every in-process one) always registers. */
13
+ registerIfAvailable(analyzer: Analyzer): Promise<boolean>;
14
+ /** The analyzer for a file path, or undefined if no language handles it. */
15
+ forFile(path: string): Analyzer | undefined;
16
+ /** All registered analyzers, in registration order. */
17
+ all(): Analyzer[];
18
+ }
19
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/analyzers/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAE5C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAelC;;yFAEqF;IAC/E,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/D,4EAA4E;IAC5E,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAM3C,uDAAuD;IACvD,GAAG,IAAI,QAAQ,EAAE;CAGlB"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Selects an analyzer for a file by its extension. The indexer asks the registry
3
+ * "who handles this file?" so adding a language is just registering an analyzer.
4
+ */
5
+ export class AnalyzerRegistry {
6
+ byExtension = new Map();
7
+ analyzers = [];
8
+ register(analyzer) {
9
+ this.analyzers.push(analyzer);
10
+ for (const ext of analyzer.extensions) {
11
+ const key = ext.toLowerCase();
12
+ const existing = this.byExtension.get(key);
13
+ // Deep beats baseline for the same extension, regardless of registration order —
14
+ // so a deep sidecar takes over a language the baseline also claims. Same tier keeps
15
+ // the first registered. This is the "deep-if-available" routing rule; availability
16
+ // is gated upstream by {@link registerIfAvailable}. (ama-3bb.4)
17
+ if (!existing || (analyzer.tier === "deep" && existing.tier === "baseline")) {
18
+ this.byExtension.set(key, analyzer);
19
+ }
20
+ }
21
+ }
22
+ /** Register an analyzer only if it reports itself available — for sidecars whose
23
+ * subprocess may be absent. Returns whether it was registered. An analyzer without
24
+ * an {@link Analyzer.isAvailable} probe (every in-process one) always registers. */
25
+ async registerIfAvailable(analyzer) {
26
+ const available = (await analyzer.isAvailable?.()) ?? true;
27
+ if (available)
28
+ this.register(analyzer);
29
+ return available;
30
+ }
31
+ /** The analyzer for a file path, or undefined if no language handles it. */
32
+ forFile(path) {
33
+ const dot = path.lastIndexOf(".");
34
+ if (dot < 0)
35
+ return undefined;
36
+ return this.byExtension.get(path.slice(dot).toLowerCase());
37
+ }
38
+ /** All registered analyzers, in registration order. */
39
+ all() {
40
+ return this.analyzers.slice();
41
+ }
42
+ }
43
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/analyzers/registry.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACV,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,SAAS,GAAe,EAAE,CAAC;IAE5C,QAAQ,CAAC,QAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3C,iFAAiF;YACjF,oFAAoF;YACpF,mFAAmF;YACnF,gEAAgE;YAChE,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC;gBAC5E,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;yFAEqF;IACrF,KAAK,CAAC,mBAAmB,CAAC,QAAkB;QAC1C,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QAC3D,IAAI,SAAS;YAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,4EAA4E;IAC5E,OAAO,CAAC,IAAY;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,uDAAuD;IACvD,GAAG;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { AnalysisResult, Analyzer } from "../types.js";
2
+ /**
3
+ * Baseline (syntactic) analyzer for single-file components. A `.vue`/`.svelte` file
4
+ * becomes a {@link "Component"} node named after the file; the modules its `<script>`
5
+ * imports become File→File `Imports` edges; and the symbols the `<script>` declares
6
+ * (functions, classes, methods, types) become nodes with file-relative line numbers,
7
+ * so SFCs are searchable, connected, and navigable. Calls/types resolution is deep-tier
8
+ * and out of scope. One instance per language (vue/svelte) for honest coverage. (ama-krw, ama-q1u)
9
+ */
10
+ export declare class SfcAnalyzer implements Analyzer {
11
+ readonly language: string;
12
+ readonly extensions: readonly string[];
13
+ readonly tier = "baseline";
14
+ constructor(language: string, extensions: readonly string[]);
15
+ analyze(root: string, files: string[]): Promise<AnalysisResult>;
16
+ }
17
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/sfc/analyzer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA2D5D;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,QAAQ;IAIxC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE;IAJxC,QAAQ,CAAC,IAAI,cAAc;gBAGhB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,MAAM,EAAE;IAGlC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CA+DtE"}
@@ -0,0 +1,141 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { fileId, symbolId } from "../../graph/index.js";
4
+ import { parse } from "../baseline/treesitter.js";
5
+ import { walkSymbols } from "../baseline/walk.js";
6
+ /** Extensions an SFC `<script>` import may resolve to — sibling components, plus
7
+ * the TS/JS modules they pull in (composables, stores, utils). */
8
+ const SFC_EXTENSIONS = [".vue", ".svelte", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
9
+ /** Symbols a `<script>` defines, by tree-sitter-typescript node type (which parses
10
+ * plain JS too). Baseline-tier breadth: declarations, not calls/types. (ama-q1u) */
11
+ const SFC_SYMBOLS = {
12
+ function_declaration: { kind: "Function" },
13
+ generator_function_declaration: { kind: "Function" },
14
+ class_declaration: { kind: "Class" },
15
+ abstract_class_declaration: { kind: "Class" },
16
+ method_definition: { kind: "Method" },
17
+ interface_declaration: { kind: "Interface" },
18
+ type_alias_declaration: { kind: "TypeAlias" },
19
+ enum_declaration: { kind: "Enum" },
20
+ };
21
+ /** Candidate repo-relative files for a relative SFC import specifier, resolved against
22
+ * the importer's directory. An explicit known extension is used as-is; otherwise each
23
+ * SFC/TS/JS extension and an `/index.*` variant is tried. A bare/package specifier
24
+ * (not `./` or `../`) is external and yields no candidates. (ama-krw) */
25
+ function sfcCandidates(specifier, importerRel) {
26
+ if (!specifier.startsWith("./") && !specifier.startsWith("../"))
27
+ return [];
28
+ const base = path.posix.join(path.posix.dirname(importerRel), specifier);
29
+ if (/\.(?:vue|svelte|tsx?|jsx?|mjs|cjs)$/.test(specifier))
30
+ return [base];
31
+ return [
32
+ ...SFC_EXTENSIONS.map((e) => base + e),
33
+ ...SFC_EXTENSIONS.map((e) => `${base}/index${e}`),
34
+ ];
35
+ }
36
+ /** Each `<script>` block's source paired with the file line its content starts on, so a
37
+ * symbol parsed out of the block maps back to a real file line. Vue allows two blocks
38
+ * (`<script>` + `<script setup>`); Svelte adds `<script context="module">`. */
39
+ function scriptBlocks(code) {
40
+ const blocks = [];
41
+ for (const m of code.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script>/gi)) {
42
+ const content = m[1] ?? "";
43
+ const contentStart = (m.index ?? 0) + m[0].length - content.length - "</script>".length;
44
+ const lineOffset = code.slice(0, contentStart).split("\n").length - 1;
45
+ blocks.push({ code: content, lineOffset });
46
+ }
47
+ return blocks;
48
+ }
49
+ /** Module specifiers a `<script>` imports or re-exports: `… from "x"` (import,
50
+ * `export … from`), side-effect `import "x"`, and dynamic `import("x")` — the last
51
+ * is how SFCs lazy-load components/routes, so it belongs in the import graph too.
52
+ * Baseline (syntactic) breadth: a best-effort scan, not a full parse. (ama-krw, ama-grb) */
53
+ function importSpecifiers(script) {
54
+ const specs = [];
55
+ for (const m of script.matchAll(/\bfrom\s*['"]([^'"]+)['"]/g))
56
+ specs.push(m[1]);
57
+ for (const m of script.matchAll(/\bimport\s*['"]([^'"]+)['"]/g))
58
+ specs.push(m[1]);
59
+ for (const m of script.matchAll(/\bimport\s*\(\s*['"]([^'"]+)['"]/g))
60
+ specs.push(m[1]);
61
+ return specs;
62
+ }
63
+ /**
64
+ * Baseline (syntactic) analyzer for single-file components. A `.vue`/`.svelte` file
65
+ * becomes a {@link "Component"} node named after the file; the modules its `<script>`
66
+ * imports become File→File `Imports` edges; and the symbols the `<script>` declares
67
+ * (functions, classes, methods, types) become nodes with file-relative line numbers,
68
+ * so SFCs are searchable, connected, and navigable. Calls/types resolution is deep-tier
69
+ * and out of scope. One instance per language (vue/svelte) for honest coverage. (ama-krw, ama-q1u)
70
+ */
71
+ export class SfcAnalyzer {
72
+ language;
73
+ extensions;
74
+ tier = "baseline";
75
+ constructor(language, extensions) {
76
+ this.language = language;
77
+ this.extensions = extensions;
78
+ }
79
+ async analyze(root, files) {
80
+ const nodes = [];
81
+ const edges = [];
82
+ for (const rel of files) {
83
+ // Per-file isolation, like the BaselineAnalyzer: build locally, merge on success,
84
+ // so a mid-parse throw on one SFC leaves no partial nodes behind.
85
+ try {
86
+ const code = fs.readFileSync(path.join(root, rel), "utf8");
87
+ const fileNodes = [];
88
+ const fileEdges = [];
89
+ const endLine = code.split("\n").length;
90
+ const id = fileId(rel);
91
+ fileNodes.push({
92
+ id,
93
+ kind: "File",
94
+ name: path.basename(rel),
95
+ file: rel,
96
+ qualifiedName: "",
97
+ tier: "baseline",
98
+ range: { startLine: 1, endLine },
99
+ });
100
+ // The SFC file *is* a component, named from the filename (Foo.vue → Foo).
101
+ const name = path.basename(rel, path.extname(rel));
102
+ const componentId = symbolId({ file: rel, qualifiedName: name });
103
+ fileNodes.push({
104
+ id: componentId,
105
+ kind: "Component",
106
+ name,
107
+ file: rel,
108
+ qualifiedName: name,
109
+ tier: "baseline",
110
+ range: { startLine: 1, endLine },
111
+ });
112
+ fileEdges.push({ from: id, to: componentId, kind: "Defines" });
113
+ for (const { code: script, lineOffset } of scriptBlocks(code)) {
114
+ // <script> imports → File→File Imports edges (the import graph).
115
+ for (const specifier of importSpecifiers(script)) {
116
+ const target = sfcCandidates(specifier, rel).find((c) => fs.existsSync(path.join(root, c)));
117
+ if (target && target !== rel)
118
+ fileEdges.push({ from: id, to: fileId(target), kind: "Imports" });
119
+ }
120
+ // <script> declarations → symbol nodes, parsed with the TS grammar (it parses
121
+ // plain JS too) and offset back to file lines. A WASM Tree must be freed.
122
+ const tree = await parse("typescript", script);
123
+ try {
124
+ walkSymbols(tree.rootNode, SFC_SYMBOLS, rel, id, "", fileNodes, fileEdges, lineOffset);
125
+ }
126
+ finally {
127
+ tree.delete();
128
+ }
129
+ }
130
+ nodes.push(...fileNodes);
131
+ edges.push(...fileEdges);
132
+ }
133
+ catch (err) {
134
+ console.error(`[ama] ${this.language} analyzer failed on ${rel}; skipping it. ` +
135
+ `${err instanceof Error ? err.message : String(err)}`);
136
+ }
137
+ }
138
+ return { nodes, edges };
139
+ }
140
+ }
141
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/analyzers/sfc/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { AnalysisResult, Analyzer } from "../types.js";
2
+ /**
3
+ * Drives an out-of-process deep analyzer (a "sidecar") over the {@link ./protocol.ts}
4
+ * contract. Implements {@link Analyzer} (tier `deep`) so it plugs in alongside the
5
+ * in-process analyzers, but delegates the actual work to a subprocess (e.g. a Roslyn or
6
+ * native-Java tool) that speaks NDJSON over stdio.
7
+ *
8
+ * One subprocess per `analyze` call (one per language batch per index): spawn, send the
9
+ * `analyze` request on stdin, read the matching `result` from stdout, then tear it down.
10
+ * The sidecar's stderr is inherited so its logs reach Ama's stderr, never the protocol
11
+ * stream. A spawn failure, a malformed message, an `error` reply, or an exit-without-result
12
+ * rejects — the indexer's per-analyzer isolation then skips this language (graceful
13
+ * fall-through to baseline is the routing layer's job, ama-3bb.4). (ama-3bb.1)
14
+ */
15
+ export declare class SidecarAnalyzer implements Analyzer {
16
+ readonly language: string;
17
+ readonly extensions: readonly string[];
18
+ private readonly command;
19
+ private readonly args;
20
+ readonly tier = "deep";
21
+ constructor(language: string, extensions: readonly string[], command: string, args?: readonly string[]);
22
+ /** Probe whether the sidecar can start and speak the protocol: spawn it and wait for
23
+ * its `ready` handshake within `timeoutMs`. A spawn failure, an early exit, or a
24
+ * timeout means unavailable — routing then leaves the language to the baseline tier
25
+ * rather than dropping it. (ama-3bb.4) */
26
+ isAvailable(timeoutMs?: number): Promise<boolean>;
27
+ analyze(root: string, files: string[]): Promise<AnalysisResult>;
28
+ }
29
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/sidecar/analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5D;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAI5C,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANvB,QAAQ,CAAC,IAAI,UAAU;gBAGZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,MAAM,EAAE,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAS,MAAM,EAAO;IAG/C;;;+CAG2C;IAC3C,WAAW,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B/C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CA8ChE"}