agentic-qe 3.8.6 → 3.8.8

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 (250) hide show
  1. package/.claude/agents/n8n/n8n-base-agent.md +4 -35
  2. package/.claude/agents/n8n/n8n-bdd-scenario-tester.md +4 -25
  3. package/.claude/agents/n8n/n8n-chaos-tester.md +4 -26
  4. package/.claude/agents/n8n/n8n-ci-orchestrator.md +4 -27
  5. package/.claude/agents/n8n/n8n-compliance-validator.md +4 -25
  6. package/.claude/agents/n8n/n8n-expression-validator.md +4 -25
  7. package/.claude/agents/n8n/n8n-integration-test.md +4 -27
  8. package/.claude/agents/n8n/n8n-monitoring-validator.md +4 -26
  9. package/.claude/agents/n8n/n8n-node-validator.md +4 -25
  10. package/.claude/agents/n8n/n8n-performance-tester.md +4 -29
  11. package/.claude/agents/n8n/n8n-security-auditor.md +4 -26
  12. package/.claude/agents/n8n/n8n-trigger-test.md +4 -27
  13. package/.claude/agents/n8n/n8n-unit-tester.md +4 -25
  14. package/.claude/agents/n8n/n8n-version-comparator.md +4 -26
  15. package/.claude/agents/n8n/n8n-workflow-executor.md +4 -26
  16. package/.claude/agents/v3/qe-accessibility-auditor.md +21 -55
  17. package/.claude/agents/v3/qe-bdd-generator.md +23 -58
  18. package/.claude/agents/v3/qe-chaos-engineer.md +21 -54
  19. package/.claude/agents/v3/qe-code-complexity.md +21 -54
  20. package/.claude/agents/v3/qe-code-intelligence.md +21 -54
  21. package/.claude/agents/v3/qe-contract-validator.md +21 -53
  22. package/.claude/agents/v3/qe-coverage-specialist.md +23 -79
  23. package/.claude/agents/v3/qe-defect-predictor.md +23 -76
  24. package/.claude/agents/v3/qe-dependency-mapper.md +21 -53
  25. package/.claude/agents/v3/qe-deployment-advisor.md +21 -54
  26. package/.claude/agents/v3/qe-devils-advocate.md +212 -238
  27. package/.claude/agents/v3/qe-flaky-hunter.md +21 -53
  28. package/.claude/agents/v3/qe-fleet-commander.md +21 -54
  29. package/.claude/agents/v3/qe-gap-detector.md +23 -79
  30. package/.claude/agents/v3/qe-graphql-tester.md +21 -54
  31. package/.claude/agents/v3/qe-impact-analyzer.md +21 -53
  32. package/.claude/agents/v3/qe-integration-architect.md +2 -2
  33. package/.claude/agents/v3/qe-integration-tester.md +15 -36
  34. package/.claude/agents/v3/qe-kg-builder.md +21 -53
  35. package/.claude/agents/v3/qe-learning-coordinator.md +21 -51
  36. package/.claude/agents/v3/qe-load-tester.md +21 -55
  37. package/.claude/agents/v3/qe-message-broker-tester.md +345 -385
  38. package/.claude/agents/v3/qe-metrics-optimizer.md +21 -54
  39. package/.claude/agents/v3/qe-middleware-validator.md +389 -428
  40. package/.claude/agents/v3/qe-mutation-tester.md +21 -54
  41. package/.claude/agents/v3/qe-odata-contract-tester.md +443 -489
  42. package/.claude/agents/v3/qe-parallel-executor.md +21 -52
  43. package/.claude/agents/v3/qe-pattern-learner.md +23 -70
  44. package/.claude/agents/v3/qe-pentest-validator.md +322 -359
  45. package/.claude/agents/v3/qe-performance-tester.md +21 -54
  46. package/.claude/agents/v3/qe-product-factors-assessor.md +339 -376
  47. package/.claude/agents/v3/qe-property-tester.md +21 -53
  48. package/.claude/agents/v3/qe-quality-criteria-recommender.md +379 -410
  49. package/.claude/agents/v3/qe-quality-gate.md +17 -64
  50. package/.claude/agents/v3/qe-queen-coordinator.md +71 -121
  51. package/.claude/agents/v3/qe-qx-partner.md +23 -64
  52. package/.claude/agents/v3/qe-regression-analyzer.md +21 -54
  53. package/.claude/agents/v3/qe-requirements-validator.md +23 -66
  54. package/.claude/agents/v3/qe-responsive-tester.md +21 -54
  55. package/.claude/agents/v3/qe-retry-handler.md +21 -53
  56. package/.claude/agents/v3/qe-risk-assessor.md +23 -58
  57. package/.claude/agents/v3/qe-root-cause-analyzer.md +21 -53
  58. package/.claude/agents/v3/qe-sap-idoc-tester.md +371 -412
  59. package/.claude/agents/v3/qe-sap-rfc-tester.md +323 -362
  60. package/.claude/agents/v3/qe-security-auditor.md +21 -54
  61. package/.claude/agents/v3/qe-security-scanner.md +21 -58
  62. package/.claude/agents/v3/qe-soap-tester.md +307 -345
  63. package/.claude/agents/v3/qe-sod-analyzer.md +486 -533
  64. package/.claude/agents/v3/qe-tdd-specialist.md +17 -42
  65. package/.claude/agents/v3/qe-test-architect.md +23 -58
  66. package/.claude/agents/v3/qe-test-idea-rewriter.md +351 -375
  67. package/.claude/agents/v3/qe-transfer-specialist.md +21 -55
  68. package/.claude/agents/v3/qe-visual-tester.md +15 -37
  69. package/.claude/agents/v3/subagents/qe-code-reviewer.md +21 -54
  70. package/.claude/agents/v3/subagents/qe-integration-reviewer.md +21 -54
  71. package/.claude/agents/v3/subagents/qe-performance-reviewer.md +21 -54
  72. package/.claude/agents/v3/subagents/qe-security-reviewer.md +21 -54
  73. package/.claude/agents/v3/subagents/qe-tdd-green.md +21 -53
  74. package/.claude/agents/v3/subagents/qe-tdd-red.md +21 -53
  75. package/.claude/agents/v3/subagents/qe-tdd-refactor.md +21 -53
  76. package/.claude/skills/.validation/schemas/skill-eval.schema.json +5 -5
  77. package/.claude/skills/.validation/skill-validation-mcp-integration.md +32 -81
  78. package/.claude/skills/agentic-quality-engineering/SKILL.md +31 -60
  79. package/.claude/skills/iterative-loop/SKILL.md +2 -2
  80. package/.claude/skills/pair-programming/SKILL.md +2 -2
  81. package/.claude/skills/performance-testing/SKILL.md +1 -1
  82. package/.claude/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +2 -2
  83. package/.claude/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +6 -6
  84. package/.claude/skills/qcsd-development-swarm/steps/01-flag-detection.md +2 -2
  85. package/.claude/skills/qcsd-development-swarm/steps/07-learning-persistence.md +6 -6
  86. package/.claude/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +6 -6
  87. package/.claude/skills/qcsd-production-swarm/steps/01-flag-detection.md +202 -206
  88. package/.claude/skills/qcsd-production-swarm/steps/07-learning-persistence.md +157 -185
  89. package/.claude/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +87 -91
  90. package/.claude/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +49 -53
  91. package/.claude/skills/qe-chaos-resilience/SKILL.md +2 -2
  92. package/.claude/skills/qe-code-intelligence/SKILL.md +2 -2
  93. package/.claude/skills/qe-coverage-analysis/SKILL.md +2 -2
  94. package/.claude/skills/qe-defect-intelligence/SKILL.md +2 -2
  95. package/.claude/skills/qe-iterative-loop/SKILL.md +12 -12
  96. package/.claude/skills/qe-learning-optimization/SKILL.md +2 -2
  97. package/.claude/skills/qe-quality-assessment/SKILL.md +2 -2
  98. package/.claude/skills/qe-requirements-validation/SKILL.md +2 -2
  99. package/.claude/skills/qe-test-execution/SKILL.md +2 -2
  100. package/.claude/skills/qe-test-generation/SKILL.md +2 -2
  101. package/.claude/skills/qe-visual-accessibility/SKILL.md +2 -2
  102. package/.claude/skills/quality-metrics/SKILL.md +1 -1
  103. package/.claude/skills/security-testing/SKILL.md +1 -1
  104. package/.claude/skills/skills-manifest.json +1 -1
  105. package/.claude/skills/validation-pipeline/SKILL.md +2 -2
  106. package/.claude/skills/verification-quality/SKILL.md +2 -2
  107. package/CHANGELOG.md +41 -0
  108. package/assets/agents/v3/qe-accessibility-auditor.md +21 -55
  109. package/assets/agents/v3/qe-bdd-generator.md +23 -58
  110. package/assets/agents/v3/qe-chaos-engineer.md +21 -54
  111. package/assets/agents/v3/qe-code-complexity.md +21 -54
  112. package/assets/agents/v3/qe-code-intelligence.md +21 -54
  113. package/assets/agents/v3/qe-contract-validator.md +21 -53
  114. package/assets/agents/v3/qe-coverage-specialist.md +23 -79
  115. package/assets/agents/v3/qe-defect-predictor.md +23 -76
  116. package/assets/agents/v3/qe-dependency-mapper.md +21 -53
  117. package/assets/agents/v3/qe-deployment-advisor.md +21 -54
  118. package/assets/agents/v3/qe-devils-advocate.md +212 -238
  119. package/assets/agents/v3/qe-flaky-hunter.md +21 -53
  120. package/assets/agents/v3/qe-fleet-commander.md +21 -54
  121. package/assets/agents/v3/qe-gap-detector.md +23 -79
  122. package/assets/agents/v3/qe-graphql-tester.md +21 -54
  123. package/assets/agents/v3/qe-impact-analyzer.md +21 -53
  124. package/assets/agents/v3/qe-integration-architect.md +2 -2
  125. package/assets/agents/v3/qe-integration-tester.md +15 -36
  126. package/assets/agents/v3/qe-kg-builder.md +21 -53
  127. package/assets/agents/v3/qe-learning-coordinator.md +21 -51
  128. package/assets/agents/v3/qe-load-tester.md +21 -55
  129. package/assets/agents/v3/qe-message-broker-tester.md +345 -385
  130. package/assets/agents/v3/qe-metrics-optimizer.md +21 -54
  131. package/assets/agents/v3/qe-middleware-validator.md +389 -428
  132. package/assets/agents/v3/qe-mutation-tester.md +21 -54
  133. package/assets/agents/v3/qe-odata-contract-tester.md +443 -489
  134. package/assets/agents/v3/qe-parallel-executor.md +21 -52
  135. package/assets/agents/v3/qe-pattern-learner.md +23 -70
  136. package/assets/agents/v3/qe-pentest-validator.md +322 -359
  137. package/assets/agents/v3/qe-performance-tester.md +21 -54
  138. package/assets/agents/v3/qe-product-factors-assessor.md +339 -376
  139. package/assets/agents/v3/qe-property-tester.md +21 -53
  140. package/assets/agents/v3/qe-quality-criteria-recommender.md +379 -410
  141. package/assets/agents/v3/qe-quality-gate.md +17 -64
  142. package/assets/agents/v3/qe-queen-coordinator.md +71 -121
  143. package/assets/agents/v3/qe-qx-partner.md +23 -64
  144. package/assets/agents/v3/qe-regression-analyzer.md +21 -54
  145. package/assets/agents/v3/qe-requirements-validator.md +23 -66
  146. package/assets/agents/v3/qe-responsive-tester.md +21 -54
  147. package/assets/agents/v3/qe-retry-handler.md +21 -53
  148. package/assets/agents/v3/qe-risk-assessor.md +23 -58
  149. package/assets/agents/v3/qe-root-cause-analyzer.md +21 -53
  150. package/assets/agents/v3/qe-sap-idoc-tester.md +371 -412
  151. package/assets/agents/v3/qe-sap-rfc-tester.md +323 -362
  152. package/assets/agents/v3/qe-security-auditor.md +21 -54
  153. package/assets/agents/v3/qe-security-scanner.md +21 -58
  154. package/assets/agents/v3/qe-soap-tester.md +307 -345
  155. package/assets/agents/v3/qe-sod-analyzer.md +486 -533
  156. package/assets/agents/v3/qe-tdd-specialist.md +17 -42
  157. package/assets/agents/v3/qe-test-architect.md +23 -58
  158. package/assets/agents/v3/qe-test-idea-rewriter.md +351 -375
  159. package/assets/agents/v3/qe-transfer-specialist.md +21 -55
  160. package/assets/agents/v3/qe-visual-tester.md +15 -37
  161. package/assets/agents/v3/subagents/qe-code-reviewer.md +21 -54
  162. package/assets/agents/v3/subagents/qe-integration-reviewer.md +21 -54
  163. package/assets/agents/v3/subagents/qe-performance-reviewer.md +21 -54
  164. package/assets/agents/v3/subagents/qe-security-reviewer.md +21 -54
  165. package/assets/agents/v3/subagents/qe-tdd-green.md +21 -53
  166. package/assets/agents/v3/subagents/qe-tdd-red.md +21 -53
  167. package/assets/agents/v3/subagents/qe-tdd-refactor.md +21 -53
  168. package/assets/governance/constitution.md +1 -1
  169. package/assets/governance/shards/chaos-resilience.shard.md +1 -1
  170. package/assets/governance/shards/code-intelligence.shard.md +1 -1
  171. package/assets/governance/shards/contract-testing.shard.md +1 -1
  172. package/assets/governance/shards/coverage-analysis.shard.md +1 -1
  173. package/assets/governance/shards/defect-intelligence.shard.md +1 -1
  174. package/assets/governance/shards/learning-optimization.shard.md +1 -1
  175. package/assets/governance/shards/quality-assessment.shard.md +1 -1
  176. package/assets/governance/shards/requirements-validation.shard.md +1 -1
  177. package/assets/governance/shards/security-compliance.shard.md +1 -1
  178. package/assets/governance/shards/test-execution.shard.md +1 -1
  179. package/assets/governance/shards/test-generation.shard.md +1 -1
  180. package/assets/governance/shards/visual-accessibility.shard.md +1 -1
  181. package/assets/grammars/tree-sitter-c_sharp.wasm +0 -0
  182. package/assets/grammars/tree-sitter-java.wasm +0 -0
  183. package/assets/grammars/tree-sitter-python.wasm +0 -0
  184. package/assets/grammars/tree-sitter-rust.wasm +0 -0
  185. package/assets/grammars/tree-sitter-swift.wasm +0 -0
  186. package/assets/skills/.validation/schemas/skill-eval.schema.json +5 -5
  187. package/assets/skills/.validation/skill-validation-mcp-integration.md +32 -81
  188. package/assets/skills/agentic-quality-engineering/SKILL.md +31 -60
  189. package/assets/skills/pair-programming/SKILL.md +2 -2
  190. package/assets/skills/performance-testing/SKILL.md +1 -1
  191. package/assets/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +2 -2
  192. package/assets/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +6 -6
  193. package/assets/skills/qcsd-development-swarm/steps/01-flag-detection.md +2 -2
  194. package/assets/skills/qcsd-development-swarm/steps/07-learning-persistence.md +6 -6
  195. package/assets/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +6 -6
  196. package/assets/skills/qcsd-production-swarm/steps/01-flag-detection.md +202 -206
  197. package/assets/skills/qcsd-production-swarm/steps/07-learning-persistence.md +157 -185
  198. package/assets/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +87 -91
  199. package/assets/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +49 -53
  200. package/assets/skills/qe-chaos-resilience/SKILL.md +2 -2
  201. package/assets/skills/qe-code-intelligence/SKILL.md +2 -2
  202. package/assets/skills/qe-coverage-analysis/SKILL.md +2 -2
  203. package/assets/skills/qe-defect-intelligence/SKILL.md +2 -2
  204. package/assets/skills/qe-iterative-loop/SKILL.md +12 -12
  205. package/assets/skills/qe-learning-optimization/SKILL.md +2 -2
  206. package/assets/skills/qe-quality-assessment/SKILL.md +2 -2
  207. package/assets/skills/qe-requirements-validation/SKILL.md +2 -2
  208. package/assets/skills/qe-test-execution/SKILL.md +2 -2
  209. package/assets/skills/qe-test-generation/SKILL.md +2 -2
  210. package/assets/skills/qe-visual-accessibility/SKILL.md +2 -2
  211. package/assets/skills/quality-metrics/SKILL.md +1 -1
  212. package/assets/skills/security-testing/SKILL.md +1 -1
  213. package/assets/skills/validation-pipeline/SKILL.md +2 -2
  214. package/assets/skills/verification-quality/SKILL.md +2 -2
  215. package/dist/cli/bundle.js +5240 -4631
  216. package/dist/cli/command-registry.js +3 -1
  217. package/dist/cli/commands/init.js +2 -0
  218. package/dist/cli/commands/memory.d.ts +11 -0
  219. package/dist/cli/commands/memory.js +333 -0
  220. package/dist/cli/completions/index.d.ts +17 -0
  221. package/dist/cli/completions/index.js +49 -1
  222. package/dist/cli/handlers/hypergraph-handler.d.ts +27 -0
  223. package/dist/cli/handlers/hypergraph-handler.js +248 -0
  224. package/dist/cli/handlers/index.d.ts +1 -0
  225. package/dist/cli/handlers/index.js +1 -0
  226. package/dist/cli/handlers/init-handler.d.ts +1 -0
  227. package/dist/cli/handlers/init-handler.js +18 -6
  228. package/dist/cli/index.js +2 -0
  229. package/dist/coordination/protocols/code-intelligence-index.js +2 -11
  230. package/dist/domains/code-intelligence/coordinator-hypergraph.js +1 -1
  231. package/dist/domains/code-intelligence/coordinator.d.ts +5 -0
  232. package/dist/domains/code-intelligence/coordinator.js +35 -3
  233. package/dist/init/phases/06-code-intelligence.d.ts +8 -3
  234. package/dist/init/phases/06-code-intelligence.js +70 -32
  235. package/dist/init/phases/08-mcp.js +10 -0
  236. package/dist/init/phases/phase-interface.d.ts +2 -0
  237. package/dist/mcp/bundle.js +1507 -1506
  238. package/dist/mcp/handlers/hypergraph-handler.d.ts +27 -0
  239. package/dist/mcp/handlers/hypergraph-handler.js +140 -0
  240. package/dist/mcp/handlers/index.d.ts +1 -0
  241. package/dist/mcp/handlers/index.js +2 -0
  242. package/dist/mcp/server.js +19 -0
  243. package/dist/mcp/tool-scoping.js +5 -0
  244. package/dist/shared/code-index-extractor.d.ts +23 -0
  245. package/dist/shared/code-index-extractor.js +101 -0
  246. package/dist/shared/parsers/multi-language-parser.d.ts +4 -1
  247. package/dist/shared/parsers/multi-language-parser.js +73 -1
  248. package/dist/shared/parsers/tree-sitter-wasm-parser.d.ts +32 -0
  249. package/dist/shared/parsers/tree-sitter-wasm-parser.js +1034 -0
  250. package/package.json +2 -1
@@ -0,0 +1,1034 @@
1
+ /**
2
+ * Tree-sitter WASM Parser (ADR-076 Amendment 2026-03-24)
3
+ *
4
+ * Provides AST-based parsing for Python, Java, C#, Rust, Swift using
5
+ * web-tree-sitter WASM grammars. Achieves ~100% accuracy for identifying
6
+ * functions, classes, imports, properties, and complexity — eliminating
7
+ * the ~2-3% edge cases (code in strings, complex generics) that regex misses.
8
+ *
9
+ * Lazy-loads WASM grammars on first parse per language.
10
+ * Falls back to regex parsers with user-facing log warnings when WASM
11
+ * initialization fails (missing dependency, incompatible Node version, etc.).
12
+ */
13
+ import * as fs from 'node:fs';
14
+ import Module from 'node:module';
15
+ import * as path from 'node:path';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { createLogger } from '../../logging/logger-factory.js';
18
+ const logger = createLogger('TreeSitterWASM');
19
+ const GRAMMAR_CONFIG = {
20
+ python: {
21
+ wasmFile: 'tree-sitter-python.wasm',
22
+ nodeTypes: {
23
+ functionDecl: ['function_definition'],
24
+ classDecl: ['class_definition'],
25
+ importDecl: ['import_statement', 'import_from_statement'],
26
+ },
27
+ },
28
+ java: {
29
+ wasmFile: 'tree-sitter-java.wasm',
30
+ nodeTypes: {
31
+ functionDecl: ['method_declaration', 'constructor_declaration'],
32
+ classDecl: ['class_declaration', 'interface_declaration'],
33
+ importDecl: ['import_declaration'],
34
+ },
35
+ },
36
+ csharp: {
37
+ wasmFile: 'tree-sitter-c_sharp.wasm',
38
+ nodeTypes: {
39
+ functionDecl: ['method_declaration', 'constructor_declaration'],
40
+ classDecl: ['class_declaration', 'interface_declaration'],
41
+ importDecl: ['using_directive'],
42
+ },
43
+ },
44
+ rust: {
45
+ wasmFile: 'tree-sitter-rust.wasm',
46
+ nodeTypes: {
47
+ functionDecl: ['function_item'],
48
+ classDecl: [],
49
+ importDecl: ['use_declaration'],
50
+ implBlock: 'impl_item',
51
+ structDecl: 'struct_item',
52
+ },
53
+ },
54
+ swift: {
55
+ wasmFile: 'tree-sitter-swift.wasm',
56
+ nodeTypes: {
57
+ functionDecl: ['function_declaration'],
58
+ classDecl: ['class_declaration'],
59
+ importDecl: ['import_declaration'],
60
+ structDecl: 'struct_declaration',
61
+ protocolDecl: 'protocol_declaration',
62
+ },
63
+ },
64
+ };
65
+ // ============================================================================
66
+ // Shared WASM Initialization (singleton)
67
+ // ============================================================================
68
+ let treeSitterModule = null;
69
+ let initPromise = null;
70
+ let initFailCount = 0;
71
+ const MAX_INIT_RETRIES = 3;
72
+ const loadedLanguages = new Map();
73
+ /**
74
+ * Resolve grammar WASM file path. Tries multiple locations to handle:
75
+ * - Source: src/shared/parsers/ -> ../../../assets/grammars/
76
+ * - CLI bundle: dist/cli/bundle.js -> ../../assets/grammars/
77
+ * - MCP bundle: dist/mcp/bundle.js -> ../../assets/grammars/
78
+ * - Installed package: node_modules/agentic-qe/ -> assets/grammars/
79
+ */
80
+ function resolveGrammarPath(wasmFile) {
81
+ const thisDir = fileURLToPath(new URL('.', import.meta.url));
82
+ const candidates = [
83
+ // From source (src/shared/parsers/)
84
+ path.resolve(thisDir, '..', '..', '..', 'assets', 'grammars', wasmFile),
85
+ // From dist bundle (dist/cli/ or dist/mcp/)
86
+ path.resolve(thisDir, '..', '..', 'assets', 'grammars', wasmFile),
87
+ // From package root via cwd (fallback)
88
+ path.resolve(process.cwd(), 'assets', 'grammars', wasmFile),
89
+ // From dist root (dist/)
90
+ path.resolve(thisDir, '..', 'assets', 'grammars', wasmFile),
91
+ ];
92
+ for (const candidate of candidates) {
93
+ if (fs.existsSync(candidate))
94
+ return candidate;
95
+ }
96
+ throw new Error(`Grammar file ${wasmFile} not found. Searched: ${candidates.join(', ')}`);
97
+ }
98
+ async function ensureTreeSitterInit() {
99
+ if (initFailCount >= MAX_INIT_RETRIES) {
100
+ throw new Error(`web-tree-sitter failed to initialize after ${MAX_INIT_RETRIES} attempts`);
101
+ }
102
+ if (treeSitterModule)
103
+ return;
104
+ if (!initPromise) {
105
+ initPromise = (async () => {
106
+ try {
107
+ const mod = await import('web-tree-sitter');
108
+ const TreeSitter = mod.default || mod;
109
+ await TreeSitter.init();
110
+ treeSitterModule = TreeSitter;
111
+ initFailCount = 0; // Reset on success
112
+ logger.info('web-tree-sitter WASM runtime initialized');
113
+ }
114
+ catch (err) {
115
+ initFailCount++;
116
+ initPromise = null; // Allow retry on next call
117
+ const msg = err instanceof Error ? err.message : String(err);
118
+ logger.warn(`web-tree-sitter WASM init failed (attempt ${initFailCount}/${MAX_INIT_RETRIES}): ${msg}. ` +
119
+ (initFailCount < MAX_INIT_RETRIES ? 'Will retry on next parse.' : 'Falling back to regex permanently.'));
120
+ throw err;
121
+ }
122
+ })();
123
+ }
124
+ return initPromise;
125
+ }
126
+ async function loadLanguage(lang) {
127
+ const cached = loadedLanguages.get(lang);
128
+ if (cached)
129
+ return cached;
130
+ await ensureTreeSitterInit();
131
+ const config = GRAMMAR_CONFIG[lang];
132
+ if (!config)
133
+ throw new Error(`No WASM grammar config for ${lang}`);
134
+ try {
135
+ // Resolve WASM file from bundled assets/grammars/ (shipped with the package)
136
+ const wasmPath = resolveGrammarPath(config.wasmFile);
137
+ const language = await treeSitterModule.Language.load(wasmPath);
138
+ loadedLanguages.set(lang, language);
139
+ logger.info(`Loaded tree-sitter WASM grammar for ${lang}`);
140
+ return language;
141
+ }
142
+ catch (err) {
143
+ const msg = err instanceof Error ? err.message : String(err);
144
+ logger.warn(`Failed to load WASM grammar for ${lang}: ${msg}. Falling back to regex parser.`);
145
+ throw err;
146
+ }
147
+ }
148
+ // ============================================================================
149
+ // AST Node Helpers
150
+ // ============================================================================
151
+ function findChildren(node, types) {
152
+ const results = [];
153
+ for (let i = 0; i < node.childCount; i++) {
154
+ const child = node.child(i);
155
+ if (types.includes(child.type)) {
156
+ results.push(child);
157
+ }
158
+ }
159
+ return results;
160
+ }
161
+ function findDescendants(node, types, maxDepth = 10) {
162
+ const results = [];
163
+ function walk(n, depth) {
164
+ if (depth > maxDepth)
165
+ return;
166
+ for (let i = 0; i < n.childCount; i++) {
167
+ const child = n.child(i);
168
+ if (types.includes(child.type)) {
169
+ results.push(child);
170
+ }
171
+ walk(child, depth + 1);
172
+ }
173
+ }
174
+ walk(node, 0);
175
+ return results;
176
+ }
177
+ function getModifiers(node) {
178
+ const mods = [];
179
+ for (let i = 0; i < node.childCount; i++) {
180
+ const child = node.child(i);
181
+ if (child.type === 'modifiers' || child.type === 'modifier' || child.type === 'visibility_modifier') {
182
+ mods.push(child.text.trim());
183
+ }
184
+ }
185
+ return mods;
186
+ }
187
+ function hasModifier(node, mod) {
188
+ return getModifiers(node).some(m => m.includes(mod));
189
+ }
190
+ /**
191
+ * Compute cyclomatic complexity by counting branching AST nodes in a function body.
192
+ * Baseline of 1 + count of (if, while, for, for_in, match/switch, case, &&, ||, catch, ?:).
193
+ */
194
+ const COMPLEXITY_NODE_TYPES = new Set([
195
+ // Branching
196
+ 'if_statement', 'if_expression', 'if_let_statement',
197
+ 'while_statement', 'while_expression',
198
+ 'for_statement', 'for_in_statement', 'for_expression', 'enhanced_for_statement',
199
+ 'match_expression', 'switch_statement', 'switch_expression',
200
+ 'case_clause', 'match_arm', 'switch_entry',
201
+ // Exception handling
202
+ 'catch_clause', 'except_clause', 'catch_block',
203
+ // Short-circuit operators
204
+ 'binary_expression', // checked for && / || below
205
+ // Ternary
206
+ 'conditional_expression', 'ternary_expression',
207
+ ]);
208
+ const SHORT_CIRCUIT_OPS = new Set(['&&', '||', 'and', 'or']);
209
+ function computeComplexity(bodyNode) {
210
+ if (!bodyNode)
211
+ return 1;
212
+ let complexity = 1;
213
+ function walk(node) {
214
+ if (COMPLEXITY_NODE_TYPES.has(node.type)) {
215
+ if (node.type === 'binary_expression') {
216
+ // Only count && and || operators
217
+ const op = node.childForFieldName('operator');
218
+ if (op && SHORT_CIRCUIT_OPS.has(op.text)) {
219
+ complexity++;
220
+ }
221
+ }
222
+ else {
223
+ complexity++;
224
+ }
225
+ }
226
+ for (let i = 0; i < node.childCount; i++) {
227
+ walk(node.child(i));
228
+ }
229
+ }
230
+ walk(bodyNode);
231
+ return complexity;
232
+ }
233
+ /**
234
+ * Extract properties/fields from a class body AST node.
235
+ */
236
+ function extractProperties(bodyNode, language) {
237
+ if (!bodyNode)
238
+ return [];
239
+ const props = [];
240
+ for (let i = 0; i < bodyNode.childCount; i++) {
241
+ const child = bodyNode.child(i);
242
+ switch (language) {
243
+ case 'java':
244
+ if (child.type === 'field_declaration') {
245
+ const mods = getModifiers(child);
246
+ const type = child.childForFieldName('type')?.text?.trim();
247
+ const declarator = child.childForFieldName('declarator');
248
+ const name = declarator?.childForFieldName('name')?.text ?? declarator?.text?.split(/[=;]/)[0]?.trim() ?? '';
249
+ if (name) {
250
+ props.push({
251
+ name,
252
+ type: type || undefined,
253
+ isPublic: mods.some(m => m.includes('public')),
254
+ isReadonly: mods.some(m => m.includes('final')),
255
+ });
256
+ }
257
+ }
258
+ break;
259
+ case 'csharp':
260
+ if (child.type === 'field_declaration' || child.type === 'property_declaration') {
261
+ const mods = getModifiers(child);
262
+ const type = child.childForFieldName('type')?.text?.trim();
263
+ const name = child.childForFieldName('name')?.text ?? '';
264
+ if (name) {
265
+ props.push({
266
+ name,
267
+ type: type || undefined,
268
+ isPublic: mods.some(m => m.includes('public')),
269
+ isReadonly: mods.some(m => m.includes('readonly')),
270
+ });
271
+ }
272
+ }
273
+ break;
274
+ case 'rust':
275
+ if (child.type === 'field_declaration') {
276
+ const name = child.childForFieldName('name')?.text ?? '';
277
+ const type = child.childForFieldName('type')?.text?.trim();
278
+ const isPub = hasModifier(child, 'pub');
279
+ if (name) {
280
+ props.push({ name, type: type || undefined, isPublic: isPub, isReadonly: false });
281
+ }
282
+ }
283
+ break;
284
+ case 'swift':
285
+ if (child.type === 'property_declaration') {
286
+ const mods = getSwiftModifiers(child);
287
+ const name = child.childForFieldName('name')?.text ?? '';
288
+ const type = child.childForFieldName('type')?.text?.trim();
289
+ const isPublic = mods.includes('public') || mods.includes('open');
290
+ const isReadonly = child.text.includes('let ');
291
+ if (name) {
292
+ props.push({ name, type: type || undefined, isPublic, isReadonly });
293
+ }
294
+ }
295
+ break;
296
+ case 'python':
297
+ // Python class attributes from assignment in __init__ or class body
298
+ if (child.type === 'expression_statement') {
299
+ const expr = child.child(0);
300
+ if (expr?.type === 'assignment') {
301
+ const left = expr.childForFieldName('left');
302
+ if (left?.type === 'attribute' || left?.type === 'identifier') {
303
+ const name = left.text.replace('self.', '');
304
+ props.push({ name, type: undefined, isPublic: !name.startsWith('_'), isReadonly: false });
305
+ }
306
+ }
307
+ }
308
+ break;
309
+ }
310
+ }
311
+ return props;
312
+ }
313
+ // ============================================================================
314
+ // Language-Specific Extractors
315
+ // ============================================================================
316
+ // --- Python ---
317
+ function extractPythonFunctions(nodes) {
318
+ return nodes.map(node => {
319
+ const name = node.childForFieldName('name')?.text ?? '';
320
+ const paramsNode = node.childForFieldName('parameters');
321
+ const returnTypeNode = node.childForFieldName('return_type');
322
+ const bodyNode = node.childForFieldName('body');
323
+ const isAsync = node.text.trimStart().startsWith('async');
324
+ const decorators = collectPythonDecorators(node);
325
+ return {
326
+ name,
327
+ parameters: parsePythonParams(paramsNode),
328
+ returnType: returnTypeNode?.text?.trim() || undefined,
329
+ isAsync,
330
+ isPublic: !name.startsWith('_'),
331
+ complexity: computeComplexity(bodyNode),
332
+ decorators,
333
+ genericParams: [],
334
+ startLine: node.startPosition.row + 1,
335
+ endLine: node.endPosition.row + 1,
336
+ };
337
+ });
338
+ }
339
+ function parsePythonParams(paramsNode) {
340
+ if (!paramsNode)
341
+ return [];
342
+ const params = [];
343
+ for (let i = 0; i < paramsNode.childCount; i++) {
344
+ const child = paramsNode.child(i);
345
+ if (child.type === 'identifier') {
346
+ const name = child.text;
347
+ if (name === 'self' || name === 'cls')
348
+ continue;
349
+ params.push({ name, type: undefined, isOptional: false, defaultValue: undefined });
350
+ }
351
+ else if (child.type === 'typed_parameter') {
352
+ const name = child.child(0)?.text ?? '';
353
+ if (name === 'self' || name === 'cls')
354
+ continue;
355
+ const type = child.childForFieldName('type')?.text?.trim();
356
+ params.push({ name, type: type || undefined, isOptional: false, defaultValue: undefined });
357
+ }
358
+ else if (child.type === 'default_parameter' || child.type === 'typed_default_parameter') {
359
+ const name = child.childForFieldName('name')?.text ?? child.child(0)?.text ?? '';
360
+ if (name === 'self' || name === 'cls')
361
+ continue;
362
+ const type = child.childForFieldName('type')?.text?.trim();
363
+ const defaultValue = child.childForFieldName('value')?.text?.trim();
364
+ params.push({ name, type: type || undefined, isOptional: true, defaultValue: defaultValue || undefined });
365
+ }
366
+ else if (child.type === 'list_splat_pattern' || child.type === 'dictionary_splat_pattern') {
367
+ const name = child.text;
368
+ params.push({ name, type: undefined, isOptional: true, defaultValue: undefined });
369
+ }
370
+ }
371
+ return params;
372
+ }
373
+ function collectPythonDecorators(funcNode) {
374
+ const decorators = [];
375
+ const parent = funcNode.parent;
376
+ if (!parent)
377
+ return decorators;
378
+ // Decorated definitions wrap the function node
379
+ if (parent.type === 'decorated_definition') {
380
+ for (let i = 0; i < parent.childCount; i++) {
381
+ const child = parent.child(i);
382
+ if (child.type === 'decorator') {
383
+ decorators.push(child.text.trim());
384
+ }
385
+ }
386
+ }
387
+ return decorators;
388
+ }
389
+ function extractPythonClasses(nodes) {
390
+ return nodes.map(node => {
391
+ const name = node.childForFieldName('name')?.text ?? '';
392
+ const body = node.childForFieldName('body');
393
+ // Extract base classes from superclasses (argument_list)
394
+ const superclasses = node.childForFieldName('superclasses');
395
+ const bases = [];
396
+ if (superclasses) {
397
+ for (let i = 0; i < superclasses.childCount; i++) {
398
+ const child = superclasses.child(i);
399
+ if (child.isNamed)
400
+ bases.push(child.text);
401
+ }
402
+ }
403
+ // Extract methods from body
404
+ const methodNodes = body ? findDescendants(body, ['function_definition'], 2) : [];
405
+ const methods = extractPythonFunctions(methodNodes);
406
+ const decorators = collectPythonDecorators(node);
407
+ return {
408
+ name,
409
+ methods,
410
+ properties: extractProperties(body, 'python'),
411
+ isPublic: !name.startsWith('_'),
412
+ implements: [],
413
+ extends: bases[0] || undefined,
414
+ decorators,
415
+ startLine: node.startPosition.row + 1,
416
+ endLine: node.endPosition.row + 1,
417
+ };
418
+ });
419
+ }
420
+ function extractPythonImports(nodes) {
421
+ return nodes.map(node => {
422
+ if (node.type === 'import_from_statement') {
423
+ const module = node.childForFieldName('module_name')?.text ?? '';
424
+ const namedImports = [];
425
+ for (let i = 0; i < node.childCount; i++) {
426
+ const child = node.child(i);
427
+ const fieldName = node.fieldNameForChild(i);
428
+ if (fieldName === 'name' && child.isNamed) {
429
+ namedImports.push(child.text);
430
+ }
431
+ }
432
+ return { module, namedImports, isTypeOnly: false };
433
+ }
434
+ // import_statement
435
+ const nameNode = node.childForFieldName('name');
436
+ return {
437
+ module: nameNode?.text ?? '',
438
+ namedImports: [],
439
+ isTypeOnly: false,
440
+ };
441
+ });
442
+ }
443
+ // --- Java ---
444
+ function extractJavaFunctions(nodes) {
445
+ return nodes.map(node => {
446
+ const name = node.childForFieldName('name')?.text ?? '';
447
+ const returnTypeNode = node.childForFieldName('type');
448
+ const paramsNode = node.childForFieldName('parameters');
449
+ const bodyNode = node.childForFieldName('body');
450
+ const modifiers = getModifiers(node);
451
+ const isPublic = modifiers.some(m => m.includes('public'));
452
+ const isAsync = returnTypeNode?.text?.includes('CompletableFuture') ?? false;
453
+ const decorators = extractJavaAnnotations(node);
454
+ return {
455
+ name,
456
+ parameters: parseJavaParams(paramsNode),
457
+ returnType: returnTypeNode?.text === 'void' ? undefined : returnTypeNode?.text?.trim(),
458
+ isAsync,
459
+ isPublic,
460
+ complexity: computeComplexity(bodyNode),
461
+ decorators,
462
+ genericParams: [],
463
+ startLine: node.startPosition.row + 1,
464
+ endLine: node.endPosition.row + 1,
465
+ };
466
+ });
467
+ }
468
+ function parseJavaParams(paramsNode) {
469
+ if (!paramsNode)
470
+ return [];
471
+ const params = [];
472
+ for (let i = 0; i < paramsNode.childCount; i++) {
473
+ const child = paramsNode.child(i);
474
+ if (child.type === 'formal_parameter' || child.type === 'spread_parameter') {
475
+ const name = child.childForFieldName('name')?.text ?? '';
476
+ const type = child.childForFieldName('type')?.text?.trim();
477
+ params.push({ name, type: type || undefined, isOptional: false, defaultValue: undefined });
478
+ }
479
+ }
480
+ return params;
481
+ }
482
+ function extractJavaAnnotations(node) {
483
+ const annotations = [];
484
+ for (let i = 0; i < node.childCount; i++) {
485
+ const child = node.child(i);
486
+ if (child.type === 'modifiers') {
487
+ for (let j = 0; j < child.childCount; j++) {
488
+ const mod = child.child(j);
489
+ if (mod.type === 'marker_annotation' || mod.type === 'annotation') {
490
+ annotations.push(mod.text.trim());
491
+ }
492
+ }
493
+ }
494
+ }
495
+ return annotations;
496
+ }
497
+ function extractJavaClasses(nodes) {
498
+ return nodes.map(node => {
499
+ const name = node.childForFieldName('name')?.text ?? '';
500
+ const body = node.childForFieldName('body');
501
+ const modifiers = getModifiers(node);
502
+ const isPublic = modifiers.some(m => m.includes('public'));
503
+ // Extract extends/implements
504
+ const superclass = node.childForFieldName('superclass')?.text;
505
+ const interfaces = node.childForFieldName('interfaces');
506
+ const implementsList = [];
507
+ if (interfaces) {
508
+ for (let i = 0; i < interfaces.childCount; i++) {
509
+ const child = interfaces.child(i);
510
+ if (child.isNamed)
511
+ implementsList.push(child.text);
512
+ }
513
+ }
514
+ const methodNodes = body ? findChildren(body, ['method_declaration', 'constructor_declaration']) : [];
515
+ const methods = extractJavaFunctions(methodNodes);
516
+ const decorators = extractJavaAnnotations(node);
517
+ return {
518
+ name,
519
+ methods,
520
+ properties: extractProperties(body, 'java'),
521
+ isPublic,
522
+ implements: implementsList,
523
+ extends: superclass || undefined,
524
+ decorators,
525
+ startLine: node.startPosition.row + 1,
526
+ endLine: node.endPosition.row + 1,
527
+ };
528
+ });
529
+ }
530
+ function extractJavaImports(nodes) {
531
+ return nodes.map(node => {
532
+ const text = node.text.replace(/^\s*import\s+(static\s+)?/, '').replace(/;\s*$/, '').trim();
533
+ const parts = text.split('.');
534
+ const name = parts[parts.length - 1];
535
+ return {
536
+ module: text,
537
+ namedImports: name === '*' ? [] : [name],
538
+ isTypeOnly: false,
539
+ };
540
+ });
541
+ }
542
+ // --- C# ---
543
+ function extractCSharpFunctions(root) {
544
+ const methods = findDescendants(root, ['method_declaration', 'constructor_declaration']);
545
+ return methods.map(node => {
546
+ const name = node.childForFieldName('name')?.text ?? '';
547
+ const returnTypeNode = node.childForFieldName('type');
548
+ const paramsNode = node.childForFieldName('parameters');
549
+ const modifiers = getModifiers(node);
550
+ const isPublic = modifiers.some(m => m.includes('public'));
551
+ const isAsync = modifiers.some(m => m.includes('async')) || returnTypeNode?.text?.includes('Task') || false;
552
+ const decorators = extractCSharpAttributes(node);
553
+ return {
554
+ name,
555
+ parameters: parseCSharpParams(paramsNode),
556
+ returnType: returnTypeNode?.text === 'void' ? undefined : returnTypeNode?.text?.trim(),
557
+ isAsync,
558
+ isPublic,
559
+ complexity: computeComplexity(node.childForFieldName('body')),
560
+ decorators,
561
+ genericParams: [],
562
+ startLine: node.startPosition.row + 1,
563
+ endLine: node.endPosition.row + 1,
564
+ };
565
+ });
566
+ }
567
+ function parseCSharpParams(paramsNode) {
568
+ if (!paramsNode)
569
+ return [];
570
+ const params = [];
571
+ for (let i = 0; i < paramsNode.childCount; i++) {
572
+ const child = paramsNode.child(i);
573
+ if (child.type === 'parameter') {
574
+ const name = child.childForFieldName('name')?.text ?? '';
575
+ const type = child.childForFieldName('type')?.text?.trim();
576
+ params.push({
577
+ name,
578
+ type: type || undefined,
579
+ isOptional: type?.endsWith('?') || false,
580
+ defaultValue: undefined,
581
+ });
582
+ }
583
+ }
584
+ return params;
585
+ }
586
+ function extractCSharpAttributes(node) {
587
+ const attrs = [];
588
+ for (let i = 0; i < node.childCount; i++) {
589
+ const child = node.child(i);
590
+ if (child.type === 'attribute_list') {
591
+ attrs.push(child.text.trim());
592
+ }
593
+ }
594
+ return attrs;
595
+ }
596
+ function extractCSharpClasses(root) {
597
+ const classes = findDescendants(root, ['class_declaration', 'interface_declaration']);
598
+ return classes.map(node => {
599
+ const name = node.childForFieldName('name')?.text ?? '';
600
+ const body = node.childForFieldName('body');
601
+ const modifiers = getModifiers(node);
602
+ const isPublic = modifiers.some(m => m.includes('public'));
603
+ // Extract base list (extends/implements combined in C#)
604
+ const baseList = node.childForFieldName('bases');
605
+ const bases = [];
606
+ if (baseList) {
607
+ for (let i = 0; i < baseList.childCount; i++) {
608
+ const child = baseList.child(i);
609
+ if (child.isNamed)
610
+ bases.push(child.text);
611
+ }
612
+ }
613
+ const methodNodes = body ? findChildren(body, ['method_declaration', 'constructor_declaration']) : [];
614
+ const methods = extractJavaFunctions(methodNodes); // Same structure as Java
615
+ const decorators = extractCSharpAttributes(node);
616
+ return {
617
+ name,
618
+ methods,
619
+ properties: extractProperties(body, 'csharp'),
620
+ isPublic,
621
+ implements: bases.slice(1),
622
+ extends: bases[0] || undefined,
623
+ decorators,
624
+ startLine: node.startPosition.row + 1,
625
+ endLine: node.endPosition.row + 1,
626
+ };
627
+ });
628
+ }
629
+ function extractCSharpImports(root) {
630
+ const usings = findDescendants(root, ['using_directive']);
631
+ return usings.map(node => {
632
+ const text = node.text.replace(/^\s*using\s+(static\s+)?/, '').replace(/;\s*$/, '').trim();
633
+ return { module: text, namedImports: [], isTypeOnly: false };
634
+ });
635
+ }
636
+ // --- Rust ---
637
+ function extractRustFunctions(root, config) {
638
+ const functions = [];
639
+ // Top-level functions
640
+ const topFns = findChildren(root, config.nodeTypes.functionDecl);
641
+ functions.push(...topFns.map(parseRustFunction));
642
+ // Functions inside impl blocks
643
+ if (config.nodeTypes.implBlock) {
644
+ const implBlocks = findChildren(root, [config.nodeTypes.implBlock]);
645
+ for (const impl of implBlocks) {
646
+ const body = impl.childForFieldName('body');
647
+ if (body) {
648
+ const methods = findChildren(body, config.nodeTypes.functionDecl);
649
+ functions.push(...methods.map(parseRustFunction));
650
+ }
651
+ }
652
+ }
653
+ return functions;
654
+ }
655
+ function parseRustFunction(node) {
656
+ const name = node.childForFieldName('name')?.text ?? '';
657
+ const paramsNode = node.childForFieldName('parameters');
658
+ const returnTypeNode = node.childForFieldName('return_type');
659
+ const bodyNode = node.childForFieldName('body');
660
+ const isPub = hasModifier(node, 'pub');
661
+ const isAsync = node.text.trimStart().startsWith('pub async') || node.text.trimStart().startsWith('async');
662
+ const decorators = collectRustAttributes(node);
663
+ return {
664
+ name,
665
+ parameters: parseRustParams(paramsNode),
666
+ returnType: returnTypeNode?.text?.trim() || undefined,
667
+ isAsync,
668
+ isPublic: isPub,
669
+ complexity: computeComplexity(bodyNode),
670
+ decorators,
671
+ genericParams: [],
672
+ startLine: node.startPosition.row + 1,
673
+ endLine: node.endPosition.row + 1,
674
+ };
675
+ }
676
+ function parseRustParams(paramsNode) {
677
+ if (!paramsNode)
678
+ return [];
679
+ const params = [];
680
+ for (let i = 0; i < paramsNode.childCount; i++) {
681
+ const child = paramsNode.child(i);
682
+ if (child.type === 'parameter') {
683
+ const patternNode = child.childForFieldName('pattern');
684
+ const typeNode = child.childForFieldName('type');
685
+ const name = patternNode?.text ?? '';
686
+ const type = typeNode?.text?.trim();
687
+ params.push({ name, type: type || undefined, isOptional: false, defaultValue: undefined });
688
+ }
689
+ else if (child.type === 'self_parameter') {
690
+ // Skip &self, &mut self, self
691
+ continue;
692
+ }
693
+ }
694
+ return params;
695
+ }
696
+ function collectRustAttributes(node) {
697
+ const attrs = [];
698
+ // Attributes precede the function as siblings
699
+ let prev = node.previousNamedSibling;
700
+ while (prev && prev.type === 'attribute_item') {
701
+ attrs.unshift(prev.text.trim());
702
+ prev = prev.previousNamedSibling;
703
+ }
704
+ return attrs;
705
+ }
706
+ function extractRustStructs(root) {
707
+ const structs = [];
708
+ // Extract structs, enums, and traits as class-like entities
709
+ const structNodes = findChildren(root, ['struct_item', 'enum_item', 'trait_item']);
710
+ for (const node of structNodes) {
711
+ const name = node.childForFieldName('name')?.text ?? '';
712
+ const isPub = hasModifier(node, 'pub');
713
+ const decorators = collectRustAttributes(node);
714
+ const bodyNode = node.childForFieldName('body');
715
+ structs.push({
716
+ name,
717
+ methods: [],
718
+ properties: extractProperties(bodyNode, 'rust'),
719
+ isPublic: isPub,
720
+ implements: [],
721
+ extends: undefined,
722
+ decorators,
723
+ startLine: node.startPosition.row + 1,
724
+ endLine: node.endPosition.row + 1,
725
+ });
726
+ }
727
+ return structs;
728
+ }
729
+ function extractRustImports(root) {
730
+ const uses = findChildren(root, ['use_declaration']);
731
+ return uses.map(node => {
732
+ const arg = node.childForFieldName('argument');
733
+ const module = arg?.text ?? node.text.replace(/^\s*use\s+/, '').replace(/;\s*$/, '').trim();
734
+ return { module, namedImports: [], isTypeOnly: false };
735
+ });
736
+ }
737
+ // --- Swift ---
738
+ function extractSwiftFunctions(nodes) {
739
+ return nodes.map(node => {
740
+ // Swift uses 'name' field for the function identifier (simple_identifier)
741
+ let name = '';
742
+ const params = [];
743
+ let returnType;
744
+ const modifiers = getSwiftModifiers(node);
745
+ const isPublic = modifiers.includes('public') || modifiers.includes('open');
746
+ let isAsync = false;
747
+ for (let i = 0; i < node.childCount; i++) {
748
+ const child = node.child(i);
749
+ const fieldName = node.fieldNameForChild(i);
750
+ if (fieldName === 'name') {
751
+ if (child.type === 'simple_identifier') {
752
+ name = child.text;
753
+ }
754
+ else if (!name) {
755
+ // Return type may also use 'name' field in some tree-sitter-swift versions
756
+ returnType = child.text;
757
+ }
758
+ }
759
+ if (child.type === 'parameter') {
760
+ params.push(child);
761
+ }
762
+ if (child.type === 'async' || child.text === 'async') {
763
+ isAsync = true;
764
+ }
765
+ }
766
+ // If name was overwritten by return type, try first simple_identifier
767
+ if (!name) {
768
+ for (let i = 0; i < node.childCount; i++) {
769
+ if (node.child(i).type === 'simple_identifier') {
770
+ name = node.child(i).text;
771
+ break;
772
+ }
773
+ }
774
+ }
775
+ // Find body node for complexity
776
+ let bodyNode = null;
777
+ for (let i = 0; i < node.childCount; i++) {
778
+ if (node.child(i).type === 'function_body') {
779
+ bodyNode = node.child(i);
780
+ break;
781
+ }
782
+ }
783
+ return {
784
+ name,
785
+ parameters: parseSwiftParams(params),
786
+ returnType,
787
+ isAsync,
788
+ isPublic,
789
+ complexity: computeComplexity(bodyNode),
790
+ decorators: [],
791
+ genericParams: [],
792
+ startLine: node.startPosition.row + 1,
793
+ endLine: node.endPosition.row + 1,
794
+ };
795
+ });
796
+ }
797
+ function getSwiftModifiers(node) {
798
+ const mods = [];
799
+ for (let i = 0; i < node.childCount; i++) {
800
+ const child = node.child(i);
801
+ if (child.type === 'modifiers') {
802
+ for (let j = 0; j < child.childCount; j++) {
803
+ mods.push(child.child(j).text.trim());
804
+ }
805
+ }
806
+ }
807
+ return mods;
808
+ }
809
+ function parseSwiftParams(paramNodes) {
810
+ return paramNodes.map(p => {
811
+ const text = p.text;
812
+ const parts = text.split(':');
813
+ const labelAndName = parts[0]?.trim().split(/\s+/) ?? [];
814
+ const name = labelAndName[labelAndName.length - 1] || '';
815
+ const type = parts.slice(1).join(':').trim() || undefined;
816
+ return {
817
+ name,
818
+ type,
819
+ isOptional: type?.endsWith('?') || false,
820
+ defaultValue: undefined,
821
+ };
822
+ });
823
+ }
824
+ function extractSwiftClasses(root) {
825
+ const classTypes = ['class_declaration', 'struct_declaration', 'protocol_declaration'];
826
+ const classNodes = findChildren(root, classTypes);
827
+ return classNodes.map(node => {
828
+ const nameNode = node.childForFieldName('name');
829
+ const name = nameNode?.text ?? '';
830
+ const modifiers = getSwiftModifiers(node);
831
+ const isPublic = modifiers.includes('public') || modifiers.includes('open');
832
+ // Extract conformances from inheritance clause
833
+ const conformances = [];
834
+ for (let i = 0; i < node.childCount; i++) {
835
+ const child = node.child(i);
836
+ if (child.type === 'type_identifier' && child !== nameNode) {
837
+ conformances.push(child.text);
838
+ }
839
+ if (child.type === 'inheritance_specifier' || child.type === 'user_type') {
840
+ conformances.push(child.text);
841
+ }
842
+ }
843
+ // Extract methods from class body
844
+ const body = node.childForFieldName('body');
845
+ const methodNodes = body ? findDescendants(body, ['function_declaration'], 2) : [];
846
+ const methods = extractSwiftFunctions(methodNodes);
847
+ return {
848
+ name,
849
+ methods,
850
+ properties: extractProperties(body, 'swift'),
851
+ isPublic,
852
+ implements: conformances.slice(1),
853
+ extends: conformances[0] || undefined,
854
+ decorators: [],
855
+ startLine: node.startPosition.row + 1,
856
+ endLine: node.endPosition.row + 1,
857
+ };
858
+ });
859
+ }
860
+ function extractSwiftImports(root) {
861
+ const imports = findChildren(root, ['import_declaration']);
862
+ return imports.map(node => {
863
+ let module = '';
864
+ for (let i = 0; i < node.childCount; i++) {
865
+ const child = node.child(i);
866
+ if (child.type === 'identifier' || child.type === 'simple_identifier') {
867
+ module = child.text;
868
+ }
869
+ }
870
+ return { module, namedImports: [], isTypeOnly: false };
871
+ });
872
+ }
873
+ // ============================================================================
874
+ // TreeSitterWASMParser — ILanguageParser implementation
875
+ // ============================================================================
876
+ export class TreeSitterWASMParser {
877
+ language;
878
+ supportedExtensions;
879
+ constructor(language, extensions) {
880
+ this.language = language;
881
+ this.supportedExtensions = extensions;
882
+ }
883
+ async parseFile(content, filePath) {
884
+ const lang = await loadLanguage(this.language);
885
+ // Create a parser per call to avoid TOCTOU race conditions.
886
+ // Two concurrent parseFile() calls for different languages could otherwise
887
+ // corrupt each other via setLanguage() on a shared instance across await boundaries.
888
+ // Parser creation is ~μs; grammar loading (the expensive part) is already cached.
889
+ const parser = new treeSitterModule();
890
+ parser.setLanguage(lang);
891
+ const tree = parser.parse(content);
892
+ const root = tree.rootNode;
893
+ try {
894
+ const result = this.extractFromAST(root);
895
+ return {
896
+ ...result,
897
+ language: this.language,
898
+ filePath,
899
+ };
900
+ }
901
+ finally {
902
+ tree.delete();
903
+ parser.delete();
904
+ }
905
+ }
906
+ extractFromAST(root) {
907
+ const config = GRAMMAR_CONFIG[this.language];
908
+ switch (this.language) {
909
+ case 'python': {
910
+ // Collect top-level functions (not inside classes)
911
+ const allFuncNodes = findChildren(root, config.nodeTypes.functionDecl);
912
+ // Also check decorated definitions
913
+ const decoratedFuncs = findChildren(root, ['decorated_definition'])
914
+ .map(d => {
915
+ for (let i = 0; i < d.childCount; i++) {
916
+ if (config.nodeTypes.functionDecl.includes(d.child(i).type))
917
+ return d.child(i);
918
+ }
919
+ return null;
920
+ })
921
+ .filter(Boolean);
922
+ const funcNodes = [...allFuncNodes, ...decoratedFuncs];
923
+ const allClassNodes = findChildren(root, config.nodeTypes.classDecl);
924
+ const decoratedClasses = findChildren(root, ['decorated_definition'])
925
+ .map(d => {
926
+ for (let i = 0; i < d.childCount; i++) {
927
+ if (config.nodeTypes.classDecl.includes(d.child(i).type))
928
+ return d.child(i);
929
+ }
930
+ return null;
931
+ })
932
+ .filter(Boolean);
933
+ const classNodes = [...allClassNodes, ...decoratedClasses];
934
+ const importNodes = findChildren(root, config.nodeTypes.importDecl);
935
+ return {
936
+ functions: extractPythonFunctions(funcNodes),
937
+ classes: extractPythonClasses(classNodes),
938
+ imports: extractPythonImports(importNodes),
939
+ };
940
+ }
941
+ case 'java': {
942
+ const classNodes = findDescendants(root, config.nodeTypes.classDecl);
943
+ const importNodes = findChildren(root, config.nodeTypes.importDecl);
944
+ // Top-level method declarations (outside classes are rare in Java, but extract them)
945
+ const topFuncNodes = findChildren(root, config.nodeTypes.functionDecl);
946
+ // Also extract methods from all classes for flat function list
947
+ const allMethods = [...topFuncNodes];
948
+ for (const cls of classNodes) {
949
+ const body = cls.childForFieldName('body');
950
+ if (body) {
951
+ allMethods.push(...findChildren(body, config.nodeTypes.functionDecl));
952
+ }
953
+ }
954
+ return {
955
+ functions: extractJavaFunctions(allMethods),
956
+ classes: extractJavaClasses(classNodes),
957
+ imports: extractJavaImports(importNodes),
958
+ };
959
+ }
960
+ case 'csharp':
961
+ return {
962
+ functions: extractCSharpFunctions(root),
963
+ classes: extractCSharpClasses(root),
964
+ imports: extractCSharpImports(root),
965
+ };
966
+ case 'rust':
967
+ return {
968
+ functions: extractRustFunctions(root, config),
969
+ classes: extractRustStructs(root),
970
+ imports: extractRustImports(root),
971
+ };
972
+ case 'swift': {
973
+ // All function declarations at any depth (matching regex parser behavior)
974
+ const allFuncNodes = findDescendants(root, config.nodeTypes.functionDecl);
975
+ return {
976
+ functions: extractSwiftFunctions(allFuncNodes),
977
+ classes: extractSwiftClasses(root),
978
+ imports: extractSwiftImports(root),
979
+ };
980
+ }
981
+ default:
982
+ return { functions: [], classes: [], imports: [] };
983
+ }
984
+ }
985
+ }
986
+ // ============================================================================
987
+ // Factory: Create WASM parsers for supported languages
988
+ // ============================================================================
989
+ const WASM_LANGUAGE_EXTENSIONS = {
990
+ python: ['.py'],
991
+ java: ['.java'],
992
+ csharp: ['.cs'],
993
+ rust: ['.rs'],
994
+ swift: ['.swift'],
995
+ };
996
+ export function createWasmParsers() {
997
+ const parsers = new Map();
998
+ for (const [lang, exts] of Object.entries(WASM_LANGUAGE_EXTENSIONS)) {
999
+ parsers.set(lang, new TreeSitterWASMParser(lang, exts));
1000
+ }
1001
+ return parsers;
1002
+ }
1003
+ /**
1004
+ * Check if web-tree-sitter WASM is available in this environment.
1005
+ * Returns true if the dependency is installed; does NOT initialize WASM.
1006
+ */
1007
+ export function isWasmAvailable() {
1008
+ // Opt-out: set AQE_PARSER_REGEX_ONLY=1 to force regex parsers
1009
+ if (process.env.AQE_PARSER_REGEX_ONLY === '1' || process.env.AQE_PARSER_REGEX_ONLY === 'true') {
1010
+ return false;
1011
+ }
1012
+ try {
1013
+ // Check that web-tree-sitter runtime is installed
1014
+ const { createRequire } = Module;
1015
+ const req = createRequire(import.meta.url);
1016
+ req.resolve('web-tree-sitter');
1017
+ // Check that at least one bundled grammar exists
1018
+ resolveGrammarPath('tree-sitter-python.wasm');
1019
+ return true;
1020
+ }
1021
+ catch {
1022
+ return false;
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Reset internal state — for testing only.
1027
+ */
1028
+ export function _resetWasmState() {
1029
+ treeSitterModule = null;
1030
+ initPromise = null;
1031
+ initFailCount = 0;
1032
+ loadedLanguages.clear();
1033
+ }
1034
+ //# sourceMappingURL=tree-sitter-wasm-parser.js.map