homegraph 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +305 -268
  3. package/dist/bin/command-supervision.d.ts.map +1 -1
  4. package/dist/bin/command-supervision.js +7 -4
  5. package/dist/bin/command-supervision.js.map +1 -1
  6. package/dist/bin/homegraph.js +304 -81
  7. package/dist/bin/homegraph.js.map +1 -1
  8. package/dist/context/index.d.ts.map +1 -1
  9. package/dist/context/index.js +32 -11
  10. package/dist/context/index.js.map +1 -1
  11. package/dist/db/index.d.ts +143 -1
  12. package/dist/db/index.d.ts.map +1 -1
  13. package/dist/db/index.js +305 -28
  14. package/dist/db/index.js.map +1 -1
  15. package/dist/db/migrations.js +37 -37
  16. package/dist/db/queries.d.ts +43 -4
  17. package/dist/db/queries.d.ts.map +1 -1
  18. package/dist/db/queries.js +294 -170
  19. package/dist/db/queries.js.map +1 -1
  20. package/dist/db/schema.sql +203 -203
  21. package/dist/db/sqlite-adapter.d.ts +24 -17
  22. package/dist/db/sqlite-adapter.d.ts.map +1 -1
  23. package/dist/db/sqlite-adapter.js +292 -36
  24. package/dist/db/sqlite-adapter.js.map +1 -1
  25. package/dist/db/wal-valve.d.ts +15 -2
  26. package/dist/db/wal-valve.d.ts.map +1 -1
  27. package/dist/db/wal-valve.js +88 -6
  28. package/dist/db/wal-valve.js.map +1 -1
  29. package/dist/directory.js +5 -5
  30. package/dist/extraction/arkts-batch-worker.js +3 -2
  31. package/dist/extraction/arkts-batch-worker.js.map +1 -1
  32. package/dist/extraction/default-ignore.d.ts +39 -0
  33. package/dist/extraction/default-ignore.d.ts.map +1 -0
  34. package/dist/extraction/default-ignore.js +221 -0
  35. package/dist/extraction/default-ignore.js.map +1 -0
  36. package/dist/extraction/index.d.ts +9 -10
  37. package/dist/extraction/index.d.ts.map +1 -1
  38. package/dist/extraction/index.js +227 -323
  39. package/dist/extraction/index.js.map +1 -1
  40. package/dist/extraction/languages/arkts-viewtree.d.ts +2 -4
  41. package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
  42. package/dist/extraction/languages/arkts-viewtree.js +6 -21
  43. package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
  44. package/dist/extraction/languages/arkts.d.ts +100 -6
  45. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  46. package/dist/extraction/languages/arkts.js +1777 -173
  47. package/dist/extraction/languages/arkts.js.map +1 -1
  48. package/dist/extraction/store-worker.d.ts +20 -0
  49. package/dist/extraction/store-worker.d.ts.map +1 -0
  50. package/dist/extraction/store-worker.js +102 -0
  51. package/dist/extraction/store-worker.js.map +1 -0
  52. package/dist/extraction/store-writer.d.ts +48 -0
  53. package/dist/extraction/store-writer.d.ts.map +1 -0
  54. package/dist/extraction/store-writer.js +167 -0
  55. package/dist/extraction/store-writer.js.map +1 -0
  56. package/dist/extraction/tree-sitter.d.ts.map +1 -1
  57. package/dist/extraction/tree-sitter.js +47 -0
  58. package/dist/extraction/tree-sitter.js.map +1 -1
  59. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  60. package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  61. package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  62. package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  63. package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  64. package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  65. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  66. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  67. package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  68. package/dist/extraction/wasm-runtime-flags.d.ts +14 -4
  69. package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
  70. package/dist/extraction/wasm-runtime-flags.js +55 -7
  71. package/dist/extraction/wasm-runtime-flags.js.map +1 -1
  72. package/dist/index.d.ts +16 -5
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +135 -97
  75. package/dist/index.js.map +1 -1
  76. package/dist/installer/instructions-template.js +9 -9
  77. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  78. package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  79. package/dist/mcp/liveness-watchdog.js +185 -73
  80. package/dist/mcp/liveness-watchdog.js.map +1 -1
  81. package/dist/mcp/query-worker.d.ts +2 -2
  82. package/dist/mcp/query-worker.js +2 -2
  83. package/dist/mcp/server-instructions.js +47 -47
  84. package/dist/mcp/tools.d.ts.map +1 -1
  85. package/dist/mcp/tools.js +42 -26
  86. package/dist/mcp/tools.js.map +1 -1
  87. package/dist/reasoning/reasoner.js +32 -32
  88. package/dist/resolution/callback-synthesizer.d.ts +52 -16
  89. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  90. package/dist/resolution/callback-synthesizer.js +234 -180
  91. package/dist/resolution/callback-synthesizer.js.map +1 -1
  92. package/dist/resolution/cooperative-yield.d.ts +10 -2
  93. package/dist/resolution/cooperative-yield.d.ts.map +1 -1
  94. package/dist/resolution/cooperative-yield.js +6 -4
  95. package/dist/resolution/cooperative-yield.js.map +1 -1
  96. package/dist/resolution/frameworks/go.d.ts.map +1 -1
  97. package/dist/resolution/frameworks/go.js +29 -6
  98. package/dist/resolution/frameworks/go.js.map +1 -1
  99. package/dist/resolution/import-resolver.d.ts +2 -3
  100. package/dist/resolution/import-resolver.d.ts.map +1 -1
  101. package/dist/resolution/import-resolver.js +166 -7
  102. package/dist/resolution/import-resolver.js.map +1 -1
  103. package/dist/resolution/index.d.ts +87 -2
  104. package/dist/resolution/index.d.ts.map +1 -1
  105. package/dist/resolution/index.js +739 -131
  106. package/dist/resolution/index.js.map +1 -1
  107. package/dist/resolution/memory-budget.d.ts +48 -0
  108. package/dist/resolution/memory-budget.d.ts.map +1 -0
  109. package/dist/resolution/memory-budget.js +162 -0
  110. package/dist/resolution/memory-budget.js.map +1 -0
  111. package/dist/resolution/name-matcher.d.ts +12 -1
  112. package/dist/resolution/name-matcher.d.ts.map +1 -1
  113. package/dist/resolution/name-matcher.js +439 -97
  114. package/dist/resolution/name-matcher.js.map +1 -1
  115. package/dist/resolution/resolver-pool.d.ts +106 -0
  116. package/dist/resolution/resolver-pool.d.ts.map +1 -0
  117. package/dist/resolution/resolver-pool.js +344 -0
  118. package/dist/resolution/resolver-pool.js.map +1 -0
  119. package/dist/resolution/resolver-worker.d.ts +17 -0
  120. package/dist/resolution/resolver-worker.d.ts.map +1 -0
  121. package/dist/resolution/resolver-worker.js +141 -0
  122. package/dist/resolution/resolver-worker.js.map +1 -0
  123. package/dist/resolution/types.d.ts +3 -0
  124. package/dist/resolution/types.d.ts.map +1 -1
  125. package/dist/spec/build/diff-parser.d.ts +55 -0
  126. package/dist/spec/build/diff-parser.d.ts.map +1 -0
  127. package/dist/spec/build/diff-parser.js +205 -0
  128. package/dist/spec/build/diff-parser.js.map +1 -0
  129. package/dist/spec/build/pipeline.d.ts +54 -0
  130. package/dist/spec/build/pipeline.d.ts.map +1 -0
  131. package/dist/spec/build/pipeline.js +170 -0
  132. package/dist/spec/build/pipeline.js.map +1 -0
  133. package/dist/spec/build/scan.d.ts +48 -0
  134. package/dist/spec/build/scan.d.ts.map +1 -0
  135. package/dist/spec/build/scan.js +89 -0
  136. package/dist/spec/build/scan.js.map +1 -0
  137. package/dist/spec/build/scope-resolver.d.ts +50 -0
  138. package/dist/spec/build/scope-resolver.d.ts.map +1 -0
  139. package/dist/spec/build/scope-resolver.js +105 -0
  140. package/dist/spec/build/scope-resolver.js.map +1 -0
  141. package/dist/spec/build/spec-extractor.d.ts +74 -0
  142. package/dist/spec/build/spec-extractor.d.ts.map +1 -0
  143. package/dist/spec/build/spec-extractor.js +344 -0
  144. package/dist/spec/build/spec-extractor.js.map +1 -0
  145. package/dist/spec/config.d.ts +35 -1
  146. package/dist/spec/config.d.ts.map +1 -1
  147. package/dist/spec/config.js +30 -5
  148. package/dist/spec/config.js.map +1 -1
  149. package/dist/spec/db/commit-node.js +4 -4
  150. package/dist/spec/db/fragment-node.js +10 -10
  151. package/dist/spec/db/fts.d.ts.map +1 -1
  152. package/dist/spec/db/fts.js +27 -58
  153. package/dist/spec/db/fts.js.map +1 -1
  154. package/dist/spec/db/index.d.ts +5 -3
  155. package/dist/spec/db/index.d.ts.map +1 -1
  156. package/dist/spec/db/index.js +16 -1
  157. package/dist/spec/db/index.js.map +1 -1
  158. package/dist/spec/db/persist.d.ts +45 -0
  159. package/dist/spec/db/persist.d.ts.map +1 -0
  160. package/dist/spec/db/persist.js +66 -0
  161. package/dist/spec/db/persist.js.map +1 -0
  162. package/dist/spec/db/relations.d.ts +80 -1
  163. package/dist/spec/db/relations.d.ts.map +1 -1
  164. package/dist/spec/db/relations.js +218 -47
  165. package/dist/spec/db/relations.js.map +1 -1
  166. package/dist/spec/db/schema.d.ts +4 -0
  167. package/dist/spec/db/schema.d.ts.map +1 -1
  168. package/dist/spec/db/schema.js +10 -6
  169. package/dist/spec/db/schema.js.map +1 -1
  170. package/dist/spec/db/schema.sql +121 -117
  171. package/dist/spec/db/spec-node.d.ts +5 -0
  172. package/dist/spec/db/spec-node.d.ts.map +1 -1
  173. package/dist/spec/db/spec-node.js +15 -9
  174. package/dist/spec/db/spec-node.js.map +1 -1
  175. package/dist/spec/db/sql-utils.d.ts +11 -0
  176. package/dist/spec/db/sql-utils.d.ts.map +1 -0
  177. package/dist/spec/db/sql-utils.js +19 -0
  178. package/dist/spec/db/sql-utils.js.map +1 -0
  179. package/dist/spec/evolve/cluster-context.d.ts +30 -0
  180. package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
  181. package/dist/spec/evolve/cluster-context.js +78 -0
  182. package/dist/spec/evolve/cluster-context.js.map +1 -0
  183. package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
  184. package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
  185. package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
  186. package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
  187. package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
  188. package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
  189. package/dist/spec/evolve/commit-spec-persister.js +93 -0
  190. package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
  191. package/dist/spec/evolve/impact-locator.d.ts +23 -7
  192. package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
  193. package/dist/spec/evolve/impact-locator.js +58 -14
  194. package/dist/spec/evolve/impact-locator.js.map +1 -1
  195. package/dist/spec/evolve/pipeline.d.ts +62 -25
  196. package/dist/spec/evolve/pipeline.d.ts.map +1 -1
  197. package/dist/spec/evolve/pipeline.js +436 -457
  198. package/dist/spec/evolve/pipeline.js.map +1 -1
  199. package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
  200. package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
  201. package/dist/spec/evolve/spec-rewriter.js +45 -45
  202. package/dist/spec/evolve/spec-rewriter.js.map +1 -1
  203. package/dist/spec/git/commits.d.ts +85 -0
  204. package/dist/spec/git/commits.d.ts.map +1 -0
  205. package/dist/spec/git/commits.js +218 -0
  206. package/dist/spec/git/commits.js.map +1 -0
  207. package/dist/spec/git/exec.d.ts +13 -0
  208. package/dist/spec/git/exec.d.ts.map +1 -0
  209. package/dist/spec/git/exec.js +19 -0
  210. package/dist/spec/git/exec.js.map +1 -0
  211. package/dist/spec/git/index.d.ts +9 -0
  212. package/dist/spec/git/index.d.ts.map +1 -0
  213. package/dist/spec/git/index.js +22 -0
  214. package/dist/spec/git/index.js.map +1 -0
  215. package/dist/spec/graph/index.d.ts +8 -0
  216. package/dist/spec/graph/index.d.ts.map +1 -0
  217. package/dist/spec/graph/index.js +17 -0
  218. package/dist/spec/graph/index.js.map +1 -0
  219. package/dist/spec/graph/queries.d.ts +6 -35
  220. package/dist/spec/graph/queries.d.ts.map +1 -1
  221. package/dist/spec/graph/queries.js +71 -248
  222. package/dist/spec/graph/queries.js.map +1 -1
  223. package/dist/spec/llm/agent-client.d.ts +59 -0
  224. package/dist/spec/llm/agent-client.d.ts.map +1 -0
  225. package/dist/spec/llm/agent-client.js +213 -0
  226. package/dist/spec/llm/agent-client.js.map +1 -0
  227. package/dist/spec/llm/agents/claude-code.d.ts +32 -0
  228. package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
  229. package/dist/spec/llm/agents/claude-code.js +125 -0
  230. package/dist/spec/llm/agents/claude-code.js.map +1 -0
  231. package/dist/spec/llm/agents/codex.d.ts +32 -0
  232. package/dist/spec/llm/agents/codex.d.ts.map +1 -0
  233. package/dist/spec/llm/agents/codex.js +145 -0
  234. package/dist/spec/llm/agents/codex.js.map +1 -0
  235. package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
  236. package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
  237. package/dist/spec/llm/agents/detect-utils.js +91 -0
  238. package/dist/spec/llm/agents/detect-utils.js.map +1 -0
  239. package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
  240. package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
  241. package/dist/spec/llm/agents/deveco-code.js +165 -0
  242. package/dist/spec/llm/agents/deveco-code.js.map +1 -0
  243. package/dist/spec/llm/agents/index.d.ts +31 -0
  244. package/dist/spec/llm/agents/index.d.ts.map +1 -0
  245. package/dist/spec/llm/agents/index.js +65 -0
  246. package/dist/spec/llm/agents/index.js.map +1 -0
  247. package/dist/spec/llm/agents/types.d.ts +76 -0
  248. package/dist/spec/llm/agents/types.d.ts.map +1 -0
  249. package/dist/spec/llm/agents/types.js +15 -0
  250. package/dist/spec/llm/agents/types.js.map +1 -0
  251. package/dist/spec/llm/client.d.ts +31 -11
  252. package/dist/spec/llm/client.d.ts.map +1 -1
  253. package/dist/spec/llm/client.js +143 -81
  254. package/dist/spec/llm/client.js.map +1 -1
  255. package/dist/spec/llm/factory.d.ts +41 -0
  256. package/dist/spec/llm/factory.d.ts.map +1 -0
  257. package/dist/spec/llm/factory.js +80 -0
  258. package/dist/spec/llm/factory.js.map +1 -0
  259. package/dist/spec/llm/prompts.d.ts +24 -8
  260. package/dist/spec/llm/prompts.d.ts.map +1 -1
  261. package/dist/spec/llm/prompts.js +112 -62
  262. package/dist/spec/llm/prompts.js.map +1 -1
  263. package/dist/spec/llm/retry.d.ts +53 -0
  264. package/dist/spec/llm/retry.d.ts.map +1 -0
  265. package/dist/spec/llm/retry.js +153 -0
  266. package/dist/spec/llm/retry.js.map +1 -0
  267. package/dist/spec/mine/clustering/features.d.ts +38 -0
  268. package/dist/spec/mine/clustering/features.d.ts.map +1 -0
  269. package/dist/spec/mine/clustering/features.js +108 -0
  270. package/dist/spec/mine/clustering/features.js.map +1 -0
  271. package/dist/spec/mine/clustering/index.d.ts +62 -0
  272. package/dist/spec/mine/clustering/index.d.ts.map +1 -0
  273. package/dist/spec/mine/clustering/index.js +259 -0
  274. package/dist/spec/mine/clustering/index.js.map +1 -0
  275. package/dist/spec/mine/clustering/leiden.d.ts +61 -0
  276. package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
  277. package/dist/spec/mine/clustering/leiden.js +489 -0
  278. package/dist/spec/mine/clustering/leiden.js.map +1 -0
  279. package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
  280. package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
  281. package/dist/spec/mine/clustering/text-similarity.js +98 -0
  282. package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
  283. package/dist/spec/mine/generator.d.ts +54 -0
  284. package/dist/spec/mine/generator.d.ts.map +1 -0
  285. package/dist/spec/mine/generator.js +267 -0
  286. package/dist/spec/mine/generator.js.map +1 -0
  287. package/dist/spec/mine/persist.d.ts +37 -0
  288. package/dist/spec/mine/persist.d.ts.map +1 -0
  289. package/dist/spec/mine/persist.js +170 -0
  290. package/dist/spec/mine/persist.js.map +1 -0
  291. package/dist/spec/mine/pipeline.d.ts +41 -0
  292. package/dist/spec/mine/pipeline.d.ts.map +1 -0
  293. package/dist/spec/mine/pipeline.js +236 -0
  294. package/dist/spec/mine/pipeline.js.map +1 -0
  295. package/dist/spec/mine/scanner.d.ts +59 -0
  296. package/dist/spec/mine/scanner.d.ts.map +1 -0
  297. package/dist/spec/mine/scanner.js +383 -0
  298. package/dist/spec/mine/scanner.js.map +1 -0
  299. package/dist/spec/types.d.ts +32 -0
  300. package/dist/spec/types.d.ts.map +1 -1
  301. package/dist/spec/ui/index.d.ts +9 -0
  302. package/dist/spec/ui/index.d.ts.map +1 -0
  303. package/dist/spec/ui/index.js +16 -0
  304. package/dist/spec/ui/index.js.map +1 -0
  305. package/dist/spec/ui/progress-handler.d.ts +33 -0
  306. package/dist/spec/ui/progress-handler.d.ts.map +1 -0
  307. package/dist/spec/ui/progress-handler.js +132 -0
  308. package/dist/spec/ui/progress-handler.js.map +1 -0
  309. package/dist/spec/ui/progress.d.ts +24 -0
  310. package/dist/spec/ui/progress.d.ts.map +1 -0
  311. package/dist/spec/ui/progress.js +13 -0
  312. package/dist/spec/ui/progress.js.map +1 -0
  313. package/dist/spec/utils/fs.d.ts +45 -0
  314. package/dist/spec/utils/fs.d.ts.map +1 -0
  315. package/dist/spec/utils/fs.js +163 -0
  316. package/dist/spec/utils/fs.js.map +1 -0
  317. package/dist/spec/utils/index.d.ts +12 -0
  318. package/dist/spec/utils/index.d.ts.map +1 -0
  319. package/dist/spec/utils/index.js +26 -0
  320. package/dist/spec/utils/index.js.map +1 -0
  321. package/dist/spec/utils/meta.d.ts +32 -0
  322. package/dist/spec/utils/meta.d.ts.map +1 -0
  323. package/dist/spec/utils/meta.js +122 -0
  324. package/dist/spec/utils/meta.js.map +1 -0
  325. package/dist/spec/utils/truncate.d.ts +86 -0
  326. package/dist/spec/utils/truncate.d.ts.map +1 -0
  327. package/dist/spec/utils/truncate.js +172 -0
  328. package/dist/spec/utils/truncate.js.map +1 -0
  329. package/dist/sync/watcher.d.ts +25 -1
  330. package/dist/sync/watcher.d.ts.map +1 -1
  331. package/dist/sync/watcher.js +76 -3
  332. package/dist/sync/watcher.js.map +1 -1
  333. package/dist/telemetry/index.js +3 -3
  334. package/dist/telemetry/index.js.map +1 -1
  335. package/dist/types.d.ts +3 -0
  336. package/dist/types.d.ts.map +1 -1
  337. package/package.json +62 -58
  338. package/scripts/_tmp-cfwk-resolve.log +0 -0
  339. package/scripts/_tmp-cfwk-sig.log +0 -0
  340. package/scripts/_tmp-cfwk-vt.log +0 -0
  341. package/scripts/add-lang/bench.sh +60 -60
  342. package/scripts/add-lang/check-grammar.mjs +75 -75
  343. package/scripts/add-lang/dump-ast.mjs +103 -103
  344. package/scripts/add-lang/verify-extraction.mjs +70 -70
  345. package/scripts/agent-eval/ab-adoption.sh +91 -91
  346. package/scripts/agent-eval/ab-hook.sh +86 -86
  347. package/scripts/agent-eval/ab-impl.sh +78 -78
  348. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
  349. package/scripts/agent-eval/ab-sufficiency.sh +78 -78
  350. package/scripts/agent-eval/arms-F.sh +21 -21
  351. package/scripts/agent-eval/arms-matrix.sh +37 -37
  352. package/scripts/agent-eval/audit.sh +68 -68
  353. package/scripts/agent-eval/bench-readme.sh +28 -28
  354. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  355. package/scripts/agent-eval/block-read-hook.sh +19 -19
  356. package/scripts/agent-eval/hook-settings.json +15 -15
  357. package/scripts/agent-eval/itrun.sh +120 -120
  358. package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
  359. package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
  360. package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
  361. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
  362. package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
  363. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
  364. package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
  365. package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
  366. package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
  367. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
  368. package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
  369. package/scripts/agent-eval/offload-eval-setup.sh +24 -24
  370. package/scripts/agent-eval/offload-eval-styles.sh +71 -71
  371. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
  372. package/scripts/agent-eval/offload-eval.md +76 -76
  373. package/scripts/agent-eval/parse-arms.mjs +116 -116
  374. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  375. package/scripts/agent-eval/parse-run.mjs +45 -45
  376. package/scripts/agent-eval/parse-session.mjs +93 -93
  377. package/scripts/agent-eval/probe-context.mjs +21 -21
  378. package/scripts/agent-eval/probe-explore.mjs +40 -40
  379. package/scripts/agent-eval/probe-node.mjs +20 -20
  380. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  381. package/scripts/agent-eval/probe-trace.mjs +20 -20
  382. package/scripts/agent-eval/redirect-read-hook.sh +38 -38
  383. package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -119
  384. package/scripts/agent-eval/repro-daemon-clients.mjs +125 -125
  385. package/scripts/agent-eval/run-agent.sh +34 -34
  386. package/scripts/agent-eval/run-all.sh +75 -75
  387. package/scripts/agent-eval/run-arms.sh +56 -56
  388. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  389. package/scripts/bench-arkts-init-rss.log +0 -0
  390. package/scripts/build-bundle.sh +123 -123
  391. package/scripts/exp_boundary_eval/README.md +247 -247
  392. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  393. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
  394. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  395. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
  396. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
  397. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
  398. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
  399. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  400. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
  401. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  402. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
  403. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  404. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
  405. package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
  406. package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -78
  407. package/scripts/exp_boundary_eval/_test_stdin.py +8 -8
  408. package/scripts/exp_boundary_eval/_utils.py +1116 -1116
  409. package/scripts/exp_boundary_eval/analyze.py +1313 -1313
  410. package/scripts/exp_boundary_eval/deveco_arm.py +519 -519
  411. package/scripts/exp_boundary_eval/run_all.py +378 -378
  412. package/scripts/exp_boundary_eval/run_one.py +165 -165
  413. package/scripts/exp_boundary_eval/run_session.py +158 -158
  414. package/scripts/exp_boundary_eval/setup.py +120 -120
  415. package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -73
  416. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -36
  417. package/scripts/exp_boundary_eval/win_node_launcher.py +24 -24
  418. package/scripts/extract-release-notes.mjs +130 -130
  419. package/scripts/local-install.sh +41 -41
  420. package/scripts/npm-sdk.js +75 -75
  421. package/scripts/npm-shim.js +275 -275
  422. package/scripts/ohos-sdk-publish.mjs +133 -133
  423. package/scripts/pack-npm.sh +119 -119
  424. package/scripts/prepare-release.mjs +270 -270
  425. package/scripts/probe-arkts-mem-why-run.log +0 -0
  426. package/scripts/probe-banner-livecard-ir.log +0 -0
  427. package/scripts/probe-cfwk-ast.stderr.log +0 -0
  428. package/scripts/probe-cfwk-ast.stdout.log +0 -0
  429. package/scripts/probe-cfwk-attr-shape.log +0 -0
  430. package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
  431. package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
  432. package/scripts/probe-cfwk-cvc.stderr.log +0 -0
  433. package/scripts/probe-cfwk-cvc.stdout.log +0 -0
  434. package/scripts/probe-cfwk-diag2.log +0 -0
  435. package/scripts/probe-cfwk-diag3.log +0 -0
  436. package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
  437. package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
  438. package/scripts/probe-cfwk-fileresult.log +0 -0
  439. package/scripts/probe-cfwk-fix.stderr.log +0 -0
  440. package/scripts/probe-cfwk-fix.stdout.log +0 -0
  441. package/scripts/probe-cfwk-fix2.stderr.log +0 -0
  442. package/scripts/probe-cfwk-fix2.stdout.log +0 -0
  443. package/scripts/probe-cfwk-fix3.stderr.log +0 -0
  444. package/scripts/probe-cfwk-fix3.stdout.log +0 -0
  445. package/scripts/probe-cfwk-foreach.log +0 -0
  446. package/scripts/probe-cfwk-getmethod-throw.log +0 -0
  447. package/scripts/probe-cfwk-hg-extract.log +0 -0
  448. package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
  449. package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
  450. package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
  451. package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
  452. package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
  453. package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
  454. package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
  455. package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
  456. package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
  457. package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
  458. package/scripts/probe-cfwk-resolve-sim.log +0 -0
  459. package/scripts/probe-cfwk-tree-shape.log +0 -0
  460. package/scripts/probe-cfwk-walk-abort.log +0 -0
  461. package/scripts/probe-cfwk.log +0 -0
  462. package/scripts/probe-force-index.log +0 -0
  463. package/scripts/probe-no-force-index.log +0 -0
  464. package/scripts/probe-samefile-ir.stderr.log +0 -0
  465. package/scripts/probe-samefile-ir.stdout.log +224 -0
  466. package/scripts/probe-sdk-vs-project.log +0 -0
  467. package/scripts/probe-viewtree-downgrade.log +0 -0
  468. package/dist/arkts/ohos-api-index.d.ts +0 -15
  469. package/dist/arkts/ohos-api-index.d.ts.map +0 -1
  470. package/dist/arkts/ohos-api-index.js +0 -190
  471. package/dist/arkts/ohos-api-index.js.map +0 -1
  472. package/dist/arkts/ohos-sdk-input.d.ts +0 -36
  473. package/dist/arkts/ohos-sdk-input.d.ts.map +0 -1
  474. package/dist/arkts/ohos-sdk-input.js +0 -214
  475. package/dist/arkts/ohos-sdk-input.js.map +0 -1
  476. package/dist/extraction/languages/arkts-state-decorators.d.ts +0 -13
  477. package/dist/extraction/languages/arkts-state-decorators.d.ts.map +0 -1
  478. package/dist/extraction/languages/arkts-state-decorators.js +0 -26
  479. package/dist/extraction/languages/arkts-state-decorators.js.map +0 -1
  480. package/dist/extraction/languages/ohos-api-consumer.d.ts +0 -34
  481. package/dist/extraction/languages/ohos-api-consumer.d.ts.map +0 -1
  482. package/dist/extraction/languages/ohos-api-consumer.js +0 -283
  483. package/dist/extraction/languages/ohos-api-consumer.js.map +0 -1
@@ -1,75 +1,125 @@
1
1
  "use strict";
2
2
  /**
3
- * LLM prompt templates for spec self-evolution.
4
- *
5
- * Extracted from logic-checker.ts and spec-rewriter.ts so evolve modules
6
- * don't contain prompt strings directly.
3
+ * LLM prompt templates for the spec pipelines — spec self-evolution
4
+ * (cluster evaluation) and spec mining (spec generation from clusters).
7
5
  *
8
6
  * @module spec/llm/prompts
9
7
  */
10
8
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.SPEC_EVALUATION_SYSTEM_PROMPT = exports.LOGIC_CHECK_SYSTEM_PROMPT = void 0;
12
- exports.buildLogicCheckUserPrompt = buildLogicCheckUserPrompt;
13
- exports.buildSpecEvaluationUserPrompt = buildSpecEvaluationUserPrompt;
9
+ exports.SPEC_EVALUATION_CLUSTER_SYSTEM_PROMPT = exports.SPEC_GENERATION_SYSTEM_PROMPT = exports.DEFAULT_SPEC_TEMPLATE = void 0;
10
+ exports.buildClusterSpecEvaluationUserPrompt = buildClusterSpecEvaluationUserPrompt;
11
+ const utils_1 = require("../utils");
14
12
  // =============================================================================
15
- // Logic check prompt
13
+ // Spec generation prompt + template (mine pipeline)
16
14
  // =============================================================================
17
- exports.LOGIC_CHECK_SYSTEM_PROMPT = `You are a code review assistant. Your task is to determine whether a git commit represents a business-logic change (as opposed to purely cosmetic, formatting, comment-only, or test-only changes).
18
-
19
- A business-logic change includes:
20
- - Changes to algorithms, data structures, or control flow
21
- - Changes to business rules, validation logic, or domain behavior
22
- - Adding or removing functionality
23
- - Bug fixes that change behavior
24
-
25
- NOT business-logic changes:
26
- - Whitespace, formatting, or code style changes
27
- - Comment-only changes
28
- - Test-only changes (adding tests without changing production code)
29
- - Configuration changes that don't alter behavior
30
- - Package/dependency version bumps
31
-
32
- Respond with a JSON object:
33
- {
34
- "is_logic_change": true/false,
35
- "reason": "Brief explanation of why this is or is not a logic change"
36
- }`;
37
- function buildLogicCheckUserPrompt(commitMessage, truncatedDiff) {
38
- return `Analyze this commit:
39
-
40
- Commit Message: ${commitMessage}
41
-
42
- Diff:
43
- ${truncatedDiff}`;
44
- }
15
+ /** Default markdown template for generated spec documents. */
16
+ exports.DEFAULT_SPEC_TEMPLATE = `# Spec: {{title}}
17
+
18
+ ## Summary
19
+ {{summary}}
20
+
21
+ ## Motivation
22
+ {{motivation}}
23
+
24
+ ## Specification
25
+
26
+ ### Functional Requirements
27
+ {{functional_requirements}}
28
+
29
+ ### Acceptance Criteria (EARS format)
30
+ {{acceptance_criteria}}
31
+
32
+ ## Implementation Notes
33
+
34
+ ### Related Commits
35
+ {{commit_list}}
36
+
37
+ ### Affected Files
38
+ {{file_list}}
39
+
40
+ ### Key Symbols
41
+ {{symbol_list}}
42
+ `;
43
+ /** System prompt for LLM spec generation from a commit cluster. */
44
+ exports.SPEC_GENERATION_SYSTEM_PROMPT = `You are a technical documentation writer specializing in software design specifications. Given a cluster of related Git commits, generate a design specification in markdown format.
45
+
46
+ Guidelines:
47
+ - Focus on WHAT was built, not HOW it was implemented
48
+ - Use EARS (Easy Approach to Requirements Syntax) for acceptance criteria
49
+ - Be specific — reference real symbols, files, and commit messages
50
+ - Keep the spec concise but complete
51
+ - Output ONLY the spec document, no preamble or commentary
52
+
53
+ Output format — fill in the template exactly. Replace {{placeholders}} with real content. Do NOT include the placeholder braces in your output.`;
45
54
  // =============================================================================
46
- // Spec evaluation prompt
55
+ // Cluster spec evaluation prompt
47
56
  // =============================================================================
48
- exports.SPEC_EVALUATION_SYSTEM_PROMPT = `You are a technical documentation maintainer. Your task is to evaluate whether a git commit requires updating a software design specification (plan.md).
49
-
50
- Given the current plan content, the commit message, and the code diff, determine:
51
- 1. Whether the plan needs to be updated (UPDATE), deprecated (DEPRECATE), or left unchanged (UNCHANGED).
52
- 2. If UPDATE: provide the new title, subtitles (as an array of heading-preview strings), and full rewritten plan_content.
53
- 3. If DEPRECATE: provide a brief explanation in the plan_content field.
54
-
55
- Response format (JSON):
56
- {
57
- "action": "UPDATE" | "DEPRECATE" | "UNCHANGED",
58
- "title": "New spec title (for UPDATE)",
59
- "subtitles": ["heading1 → heading2 - preview", ...],
60
- "plan_content": "Full rewritten markdown content (for UPDATE) or deprecation reason (for DEPRECATE)"
57
+ /** Maximum characters for the current spec content in the user prompt
58
+ * (~16K tokens @ ~0.25 token/char). Exceedingly large spec documents are
59
+ * truncated to prevent context-window overflow. */
60
+ const MAX_SPEC_CONTENT_CHARS = 64000;
61
+ exports.SPEC_EVALUATION_CLUSTER_SYSTEM_PROMPT = `You are a technical documentation maintainer. Your task is to evaluate whether a GROUP of related git commits requires updating a software design specification.
62
+
63
+ Given the current content and a summary of multiple commits that affect this spec, determine:
64
+ 1. Whether the spec needs to be updated (UPDATE), deprecated (DEPRECATE), or left unchanged (UNCHANGED).
65
+ 2. If UPDATE: provide the new title, subtitles (as an array of heading-preview strings), and full rewritten spec_content that incorporates the changes from all commits.
66
+ 3. If DEPRECATE: provide a brief explanation in the spec_content field.
67
+
68
+ Key considerations for batch evaluation:
69
+ - Multiple commits may partially overlap in their changes — synthesize the combined impact.
70
+ - Some commits may be bug fixes that revert earlier changes — look for the net effect.
71
+ - If the combined changes fundamentally alter the spec's scope, prefer DEPRECATE over UPDATE.
72
+
73
+ Response format (JSON):
74
+ {
75
+ "action": "UPDATE" | "DEPRECATE" | "UNCHANGED",
76
+ "title": "New spec title (for UPDATE)",
77
+ "subtitles": ["heading1 → heading2 - preview", ...],
78
+ "spec_content": "Full rewritten markdown content (for UPDATE) or deprecation reason (for DEPRECATE)"
61
79
  }`;
62
- function buildSpecEvaluationUserPrompt(planContent, commitMessage, truncatedDiff, scheduleNextSpecs) {
63
- const scheduleStr = scheduleNextSpecs.length > 0 ? scheduleNextSpecs.join(', ') : 'none';
64
- return `Current Plan Content:
65
- ${planContent}
66
-
67
- Commit Message:
68
- ${commitMessage}
69
-
70
- Code Diff:
71
- ${truncatedDiff}
72
-
73
- Scheduled specs to be processed next (for context): ${scheduleStr}`;
80
+ /**
81
+ * Build the user prompt for cluster-based spec evaluation.
82
+ *
83
+ * Presents:
84
+ * 1. The current spec content.
85
+ * 2. A cluster overview (commit count, primary files).
86
+ * 3. Per-commit summaries (short hash, message, changed files, truncated diff).
87
+ *
88
+ * The prompt is designed to fit within a reasonable token budget for a
89
+ * single LLM call even with 5-10 commits in the cluster.
90
+ *
91
+ * @param specContent - Full current spec.md content.
92
+ * @param clusterContext - Pre-built cluster context from buildClusterContext.
93
+ * @returns Formatted user prompt string.
94
+ */
95
+ function buildClusterSpecEvaluationUserPrompt(specContent, clusterContext) {
96
+ const parts = [];
97
+ // 1. Current spec
98
+ const truncatedSpec = (0, utils_1.truncateText)(specContent, MAX_SPEC_CONTENT_CHARS);
99
+ parts.push('## Current Spec Content');
100
+ parts.push('');
101
+ parts.push(truncatedSpec);
102
+ parts.push('');
103
+ // 2. Cluster overview
104
+ parts.push('## Commit Cluster');
105
+ parts.push('');
106
+ parts.push(`- **Commits**: ${clusterContext.commitCount}`);
107
+ parts.push(`- **Primary files**: ${clusterContext.primaryFiles.join(', ') || '(none)'}`);
108
+ parts.push('');
109
+ // 3. Per-commit summaries
110
+ parts.push('## Commit Summaries');
111
+ parts.push('');
112
+ for (const cs of clusterContext.commitSummaries) {
113
+ parts.push(`### ${cs.shortHash} — ${cs.message}`);
114
+ parts.push(`Files: ${cs.changedFiles.join(', ')}`);
115
+ if (cs.truncatedDiff && cs.truncatedDiff.length > 0) {
116
+ parts.push('');
117
+ parts.push('```diff');
118
+ parts.push(cs.truncatedDiff);
119
+ parts.push('```');
120
+ }
121
+ parts.push('');
122
+ }
123
+ return parts.join('\n');
74
124
  }
75
125
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/spec/llm/prompts.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AA2BH,8DAUC;AAqBD,sEAmBC;AA3ED,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEnE,QAAA,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;;EAmBvC,CAAC;AAEH,SAAgB,yBAAyB,CACvC,aAAqB,EACrB,aAAqB;IAErB,OAAO;;kBAES,aAAa;;;EAG7B,aAAa,EAAE,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEnE,QAAA,6BAA6B,GAAG;;;;;;;;;;;;;EAa3C,CAAC;AAEH,SAAgB,6BAA6B,CAC3C,WAAmB,EACnB,aAAqB,EACrB,aAAqB,EACrB,iBAA2B;IAE3B,MAAM,WAAW,GACf,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAEvE,OAAO;EACP,WAAW;;;EAGX,aAAa;;;EAGb,aAAa;;sDAEuC,WAAW,EAAE,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/spec/llm/prompts.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA8FH,oFAsCC;AAjID,oCAAwC;AAExC,gFAAgF;AAChF,oDAAoD;AACpD,gFAAgF;AAEhF,8DAA8D;AACjD,QAAA,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BpC,CAAC;AAEF,mEAAmE;AACtD,QAAA,6BAA6B,GAAG;;;;;;;;;gJASmG,CAAC;AAEjJ,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF;;oDAEoD;AACpD,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAExB,QAAA,qCAAqC,GAAG;;;;;;;;;;;;;;;;;;EAkBnD,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,SAAgB,oCAAoC,CAClD,WAAmB,EACnB,cAA8B;IAE9B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,kBAAkB;IAClB,MAAM,aAAa,GAAG,IAAA,oBAAY,EAAC,WAAW,EAAE,sBAAsB,CAAC,CAAC;IACxE,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,sBAAsB;IACtB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CACR,wBAAwB,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CAC7E,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,0BAA0B;IAC1B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,MAAM,EAAE,IAAI,cAAc,CAAC,eAAe,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,EAAE,CAAC,aAAa,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * LLM retry helper — error classification and delay calculation.
3
+ *
4
+ * OpenAI SDK v4 throws typed `APIError` subclasses. This module classifies
5
+ * them as retryable (transient) or terminal (bad request, auth failure, etc.)
6
+ * and computes exponential-backoff delays with jitter and Retry-After support.
7
+ *
8
+ * @module spec/llm/retry
9
+ */
10
+ export interface RetryDecision {
11
+ /** Whether the error is safe to retry. */
12
+ retryable: boolean;
13
+ /**
14
+ * Recommended delay in milliseconds (from Retry-After header, if present).
15
+ * `undefined` means the caller should calculate backoff.
16
+ */
17
+ retryAfterMs?: number;
18
+ }
19
+ /**
20
+ * Classify an error thrown by the OpenAI SDK as retryable or terminal.
21
+ *
22
+ * Classification rules (first match wins):
23
+ *
24
+ * 1. Non-`Error` throwables → NOT retryable (safety).
25
+ * 2. `RateLimitError` (429) → RETRYABLE; parse Retry-After if available.
26
+ * 3. `InternalServerError` (500) → RETRYABLE.
27
+ * 4. Other `APIError` subclasses with status in `RETRYABLE_STATUSES` →
28
+ * RETRYABLE.
29
+ * 5. `APIConnectionError` / `APIConnectionTimeoutError` → RETRYABLE.
30
+ * 6. Generic `Error` with `.code` in `RETRYABLE_CODES` → RETRYABLE.
31
+ * 7. Everything else → NOT retryable (conservative).
32
+ */
33
+ export declare function classifyError(err: unknown): RetryDecision;
34
+ /**
35
+ * Compute the delay before the next retry attempt.
36
+ *
37
+ * Strategy:
38
+ * 1. If `retryAfterMs` is available from the server (429 Retry-After), use it
39
+ * as a minimum, then add jitter up to 25% of the computed backoff.
40
+ * 2. Otherwise: exponential backoff = `baseDelay * 2^attempt` with full-range
41
+ * random jitter (`random(0, backoff)`).
42
+ * 3. Cap at `maxDelay`.
43
+ *
44
+ * @param retryAfterMs - Server-suggested delay from Retry-After (optional).
45
+ * @param baseDelay - Base delay in ms for backoff calculation.
46
+ * @param maxDelay - Hard upper bound in ms.
47
+ * @param attempt - Zero-based retry attempt index.
48
+ * @returns Delay in milliseconds (integer).
49
+ */
50
+ export declare function computeDelay(retryAfterMs: number | undefined, baseDelay: number, maxDelay: number, attempt: number): number;
51
+ /** Promise-based sleep. */
52
+ export declare function sleep(ms: number): Promise<void>;
53
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAoBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAwCzD;AA0CD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,CAiBR;AAMD,2BAA2B;AAC3B,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ /**
3
+ * LLM retry helper — error classification and delay calculation.
4
+ *
5
+ * OpenAI SDK v4 throws typed `APIError` subclasses. This module classifies
6
+ * them as retryable (transient) or terminal (bad request, auth failure, etc.)
7
+ * and computes exponential-backoff delays with jitter and Retry-After support.
8
+ *
9
+ * @module spec/llm/retry
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.classifyError = classifyError;
16
+ exports.computeDelay = computeDelay;
17
+ exports.sleep = sleep;
18
+ const openai_1 = __importDefault(require("openai"));
19
+ // ---------------------------------------------------------------------------
20
+ // Error classification
21
+ // ---------------------------------------------------------------------------
22
+ /** HTTP status codes that indicate a transient server error. */
23
+ const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
24
+ /** Node.js error codes that indicate a transient network failure. */
25
+ const RETRYABLE_CODES = new Set([
26
+ 'ECONNRESET',
27
+ 'ETIMEDOUT',
28
+ 'ECONNREFUSED',
29
+ 'ENOTFOUND',
30
+ 'EPIPE',
31
+ 'EAI_AGAIN',
32
+ 'ERR_SOCKET_CONNECTION_TIMEOUT',
33
+ ]);
34
+ /**
35
+ * Classify an error thrown by the OpenAI SDK as retryable or terminal.
36
+ *
37
+ * Classification rules (first match wins):
38
+ *
39
+ * 1. Non-`Error` throwables → NOT retryable (safety).
40
+ * 2. `RateLimitError` (429) → RETRYABLE; parse Retry-After if available.
41
+ * 3. `InternalServerError` (500) → RETRYABLE.
42
+ * 4. Other `APIError` subclasses with status in `RETRYABLE_STATUSES` →
43
+ * RETRYABLE.
44
+ * 5. `APIConnectionError` / `APIConnectionTimeoutError` → RETRYABLE.
45
+ * 6. Generic `Error` with `.code` in `RETRYABLE_CODES` → RETRYABLE.
46
+ * 7. Everything else → NOT retryable (conservative).
47
+ */
48
+ function classifyError(err) {
49
+ if (!(err instanceof Error)) {
50
+ return { retryable: false };
51
+ }
52
+ // 1. RateLimitError (429)
53
+ if (err instanceof openai_1.default.RateLimitError) {
54
+ const retryAfterMs = parseRetryAfter(err.headers);
55
+ return { retryable: true, retryAfterMs };
56
+ }
57
+ // 2. InternalServerError (500)
58
+ if (err instanceof openai_1.default.InternalServerError) {
59
+ return { retryable: true };
60
+ }
61
+ // 3. Other APIError with known transient status
62
+ if (err instanceof openai_1.default.APIError) {
63
+ if (err.status !== undefined && RETRYABLE_STATUSES.has(err.status)) {
64
+ return { retryable: true };
65
+ }
66
+ // Explicit client errors (400, 401, 403, 404, 409, 422, etc.) → terminal
67
+ return { retryable: false };
68
+ }
69
+ // 4. Connection-level errors
70
+ if (err instanceof openai_1.default.APIConnectionError ||
71
+ err instanceof openai_1.default.APIConnectionTimeoutError) {
72
+ return { retryable: true };
73
+ }
74
+ // 5. Generic Node.js network errors
75
+ if (RETRYABLE_CODES.has(err.code ?? '')) {
76
+ return { retryable: true };
77
+ }
78
+ // 6. Everything else — don't guess, just fail
79
+ return { retryable: false };
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // Retry-After parsing
83
+ // ---------------------------------------------------------------------------
84
+ /**
85
+ * Parse a `Retry-After` header value to milliseconds.
86
+ *
87
+ * Supports both delta-seconds (`"5"`) and HTTP-date (`"Wed, 21 Oct 2015 ..."`).
88
+ * Returns `undefined` if the header is missing, unparseable, or unacceptably
89
+ * large (> 5 minutes to avoid hiding a systemic outage).
90
+ */
91
+ function parseRetryAfter(headers) {
92
+ if (!headers)
93
+ return undefined;
94
+ const raw = headers['retry-after'];
95
+ if (!raw || typeof raw !== 'string')
96
+ return undefined;
97
+ // Delta-seconds: "5" or "5.5"
98
+ const delta = Number(raw);
99
+ if (!isNaN(delta) && delta > 0) {
100
+ const ms = Math.round(delta * 1000);
101
+ return ms > 300_000 ? undefined : ms; // cap at 5 min
102
+ }
103
+ // HTTP-date
104
+ const date = new Date(raw).getTime();
105
+ if (!isNaN(date)) {
106
+ const ms = Math.max(0, date - Date.now());
107
+ return ms > 300_000 ? undefined : ms;
108
+ }
109
+ return undefined;
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Delay computation
113
+ // ---------------------------------------------------------------------------
114
+ /**
115
+ * Compute the delay before the next retry attempt.
116
+ *
117
+ * Strategy:
118
+ * 1. If `retryAfterMs` is available from the server (429 Retry-After), use it
119
+ * as a minimum, then add jitter up to 25% of the computed backoff.
120
+ * 2. Otherwise: exponential backoff = `baseDelay * 2^attempt` with full-range
121
+ * random jitter (`random(0, backoff)`).
122
+ * 3. Cap at `maxDelay`.
123
+ *
124
+ * @param retryAfterMs - Server-suggested delay from Retry-After (optional).
125
+ * @param baseDelay - Base delay in ms for backoff calculation.
126
+ * @param maxDelay - Hard upper bound in ms.
127
+ * @param attempt - Zero-based retry attempt index.
128
+ * @returns Delay in milliseconds (integer).
129
+ */
130
+ function computeDelay(retryAfterMs, baseDelay, maxDelay, attempt) {
131
+ const backoff = baseDelay * Math.pow(2, attempt);
132
+ let delay;
133
+ if (retryAfterMs !== undefined && retryAfterMs > 0) {
134
+ // Use Retry-After as floor, add up to 25% jitter
135
+ const jitter = Math.random() * Math.min(backoff * 0.25, 5000);
136
+ delay = retryAfterMs + jitter;
137
+ }
138
+ else {
139
+ // Full exponential backoff with jitter
140
+ delay = Math.random() * backoff;
141
+ }
142
+ // Clamp
143
+ delay = Math.max(0, Math.min(delay, maxDelay));
144
+ return Math.round(delay);
145
+ }
146
+ // ---------------------------------------------------------------------------
147
+ // Sleep
148
+ // ---------------------------------------------------------------------------
149
+ /** Promise-based sleep. */
150
+ function sleep(ms) {
151
+ return new Promise((resolve) => setTimeout(resolve, ms));
152
+ }
153
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/spec/llm/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Per-commit feature extraction for clustering — symbol names, file paths,
3
+ * directory prefixes, ticket references, change counts, and cohesion.
4
+ *
5
+ * @module spec/mine/clustering/features
6
+ */
7
+ import { CommitChange } from '../scanner';
8
+ /** Minimum number of changed symbols (added + removed + modified) required
9
+ * for a solo commit to be promoted into its own cluster. Commits below
10
+ * this threshold go to `unclustered` — they are too small to warrant a
11
+ * standalone spec document. */
12
+ export declare const MIN_SYMBOLS_FOR_SOLO_CLUSTER = 2;
13
+ /** Collect all symbol names across all file changes in a commit. */
14
+ export declare function collectSymbolNames(change: CommitChange): string[];
15
+ /** Collect all file paths changed in a commit. */
16
+ export declare function collectFilePaths(change: CommitChange): string[];
17
+ /** Collect directory prefixes (first 2 path segments) for module proximity.
18
+ * For single-segment paths (root-level files) the filename itself is used as
19
+ * the key — this prevents unrelated root-level files from falsely sharing an
20
+ * empty "directory" and being grouped together. */
21
+ export declare function collectDirectoryPrefixes(change: CommitChange): string[];
22
+ /** Count total changed symbols across all file changes in a commit. */
23
+ export declare function countChangedSymbols(change: CommitChange): number;
24
+ /** Compute the cohesion ratio for a commit — symbols changed per file touched.
25
+ * Low cohesion (< 1.0) suggests a mechanical refactor across many files;
26
+ * high cohesion (≥ 2.0) suggests concentrated feature work. */
27
+ export declare function computeCohesion(change: CommitChange): number;
28
+ /** Extract ticket references (e.g., PROJ-123, #456) from a commit message. */
29
+ export declare function extractTicketRefs(message: string): string[];
30
+ /**
31
+ * Fallback quality gate: true when a commit has at least one new file that
32
+ * is not a test file. Used when the symbol-level change count is below the
33
+ * solo-cluster threshold — a commit that adds non-test source files carries
34
+ * structural intent even when the extractor could not produce symbols
35
+ * (e.g. ArkTS files without an active extraction context).
36
+ */
37
+ export declare function hasNewNonTestFiles(change: CommitChange): boolean;
38
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../../src/spec/mine/clustering/features.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C;;;gCAGgC;AAChC,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAWjE;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAM/D;AAED;;;oDAGoD;AACpD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAWvE;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAQhE;AAED;;gEAEgE;AAChE,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAI5D;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAOhE"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * Per-commit feature extraction for clustering — symbol names, file paths,
4
+ * directory prefixes, ticket references, change counts, and cohesion.
5
+ *
6
+ * @module spec/mine/clustering/features
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.MIN_SYMBOLS_FOR_SOLO_CLUSTER = void 0;
10
+ exports.collectSymbolNames = collectSymbolNames;
11
+ exports.collectFilePaths = collectFilePaths;
12
+ exports.collectDirectoryPrefixes = collectDirectoryPrefixes;
13
+ exports.countChangedSymbols = countChangedSymbols;
14
+ exports.computeCohesion = computeCohesion;
15
+ exports.extractTicketRefs = extractTicketRefs;
16
+ exports.hasNewNonTestFiles = hasNewNonTestFiles;
17
+ const query_utils_1 = require("../../../search/query-utils");
18
+ /** Minimum number of changed symbols (added + removed + modified) required
19
+ * for a solo commit to be promoted into its own cluster. Commits below
20
+ * this threshold go to `unclustered` — they are too small to warrant a
21
+ * standalone spec document. */
22
+ exports.MIN_SYMBOLS_FOR_SOLO_CLUSTER = 2;
23
+ /** Collect all symbol names across all file changes in a commit. */
24
+ function collectSymbolNames(change) {
25
+ const names = new Set();
26
+ for (const fc of change.fileChanges) {
27
+ for (const s of fc.addedSymbols)
28
+ names.add(s.name);
29
+ for (const s of fc.removedSymbols)
30
+ names.add(s.name);
31
+ for (const m of fc.modifiedSymbols) {
32
+ names.add(m.old.name);
33
+ names.add(m.new.name);
34
+ }
35
+ }
36
+ return Array.from(names);
37
+ }
38
+ /** Collect all file paths changed in a commit. */
39
+ function collectFilePaths(change) {
40
+ const paths = new Set();
41
+ for (const fc of change.fileChanges) {
42
+ paths.add(fc.filePath);
43
+ }
44
+ return Array.from(paths);
45
+ }
46
+ /** Collect directory prefixes (first 2 path segments) for module proximity.
47
+ * For single-segment paths (root-level files) the filename itself is used as
48
+ * the key — this prevents unrelated root-level files from falsely sharing an
49
+ * empty "directory" and being grouped together. */
50
+ function collectDirectoryPrefixes(change) {
51
+ const dirs = new Set();
52
+ for (const fc of change.fileChanges) {
53
+ const parts = fc.filePath.split('/');
54
+ if (parts.length === 1) {
55
+ dirs.add(parts[0]);
56
+ }
57
+ else {
58
+ dirs.add(parts.slice(0, 2).join('/'));
59
+ }
60
+ }
61
+ return Array.from(dirs);
62
+ }
63
+ /** Count total changed symbols across all file changes in a commit. */
64
+ function countChangedSymbols(change) {
65
+ let count = 0;
66
+ for (const fc of change.fileChanges) {
67
+ count += fc.addedSymbols.length;
68
+ count += fc.removedSymbols.length;
69
+ count += fc.modifiedSymbols.length;
70
+ }
71
+ return count;
72
+ }
73
+ /** Compute the cohesion ratio for a commit — symbols changed per file touched.
74
+ * Low cohesion (< 1.0) suggests a mechanical refactor across many files;
75
+ * high cohesion (≥ 2.0) suggests concentrated feature work. */
76
+ function computeCohesion(change) {
77
+ const totalSymbols = countChangedSymbols(change);
78
+ const filesTouched = change.fileChanges.length || 1;
79
+ return totalSymbols / filesTouched;
80
+ }
81
+ /** Extract ticket references (e.g., PROJ-123, #456) from a commit message. */
82
+ function extractTicketRefs(message) {
83
+ const refs = [];
84
+ const jiraRe = /[A-Z]+-\d+/g;
85
+ const ghRe = /#\d+/g;
86
+ let m;
87
+ while ((m = jiraRe.exec(message)) !== null)
88
+ refs.push(m[0]);
89
+ while ((m = ghRe.exec(message)) !== null)
90
+ refs.push(m[0]);
91
+ return Array.from(new Set(refs));
92
+ }
93
+ /**
94
+ * Fallback quality gate: true when a commit has at least one new file that
95
+ * is not a test file. Used when the symbol-level change count is below the
96
+ * solo-cluster threshold — a commit that adds non-test source files carries
97
+ * structural intent even when the extractor could not produce symbols
98
+ * (e.g. ArkTS files without an active extraction context).
99
+ */
100
+ function hasNewNonTestFiles(change) {
101
+ for (const fc of change.fileChanges) {
102
+ if (fc.isNewFile && !(0, query_utils_1.isTestFile)(fc.filePath)) {
103
+ return true;
104
+ }
105
+ }
106
+ return false;
107
+ }
108
+ //# sourceMappingURL=features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../../../src/spec/mine/clustering/features.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAYH,gDAWC;AAGD,4CAMC;AAMD,4DAWC;AAGD,kDAQC;AAKD,0CAIC;AAGD,8CAQC;AASD,gDAOC;AA7FD,6DAAyD;AAEzD;;;gCAGgC;AACnB,QAAA,4BAA4B,GAAG,CAAC,CAAC;AAE9C,oEAAoE;AACpE,SAAgB,kBAAkB,CAAC,MAAoB;IACrD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,YAAY;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,cAAc;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,eAAe,EAAE,CAAC;YACnC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,kDAAkD;AAClD,SAAgB,gBAAgB,CAAC,MAAoB;IACnD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;;oDAGoD;AACpD,SAAgB,wBAAwB,CAAC,MAAoB;IAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,uEAAuE;AACvE,SAAgB,mBAAmB,CAAC,MAAoB;IACtD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;QAChC,KAAK,IAAI,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC;QAClC,KAAK,IAAI,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;gEAEgE;AAChE,SAAgB,eAAe,CAAC,MAAoB;IAClD,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC;IACpD,OAAO,YAAY,GAAG,YAAY,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,SAAgB,iBAAiB,CAAC,OAAe;IAC/C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,aAAa,CAAC;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC;IACrB,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,MAAoB;IACrD,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,IAAI,EAAE,CAAC,SAAS,IAAI,CAAC,IAAA,wBAAU,EAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Commit Clusterer — multi-signal graph clustering for the `spec mine` pipeline.
3
+ *
4
+ * Groups commits by structural (AST symbol overlap), file-path, temporal,
5
+ * and commit-message similarity. Pure TypeScript implementation — no native
6
+ * dependencies required.
7
+ *
8
+ * Orchestrates the pieces in this directory:
9
+ * - `text-similarity` — tokenize / Jaccard / cosine / TF-IDF
10
+ * - `features` — per-commit feature extraction
11
+ * - `leiden` — generic Leiden community detection + tuning
12
+ *
13
+ * @module spec/mine/clustering
14
+ */
15
+ import { CommitChange } from '../scanner';
16
+ /** A cluster of semantically-related commits. */
17
+ export interface CommitCluster {
18
+ id: number;
19
+ commits: CommitChange[];
20
+ primaryFiles: string[];
21
+ primarySymbols: string[];
22
+ summary: string;
23
+ timeRange: {
24
+ start: number;
25
+ end: number;
26
+ };
27
+ }
28
+ /** Full clustering result including unclustered outliers and stats. */
29
+ export interface ClusterResult {
30
+ clusters: CommitCluster[];
31
+ unclustered: CommitChange[];
32
+ stats: {
33
+ totalCommits: number;
34
+ clusteredCommits: number;
35
+ clusterCount: number;
36
+ };
37
+ }
38
+ /**
39
+ * Cluster commits using Leiden community detection on a multi-signal
40
+ * similarity graph, with recursive sub-splitting for large clusters.
41
+ *
42
+ * The pipeline:
43
+ * 1. Build a weighted similarity graph from AST symbol, file-path,
44
+ * commit-message TF-IDF, ticket-reference, and temporal signals.
45
+ * 2. Run Leiden community detection with auto-tuned resolution γ.
46
+ * 3. Greedy-merge if still too many communities.
47
+ * 4. Recursively split large clusters (≥ 4 commits) by running
48
+ * Leiden on their sub-graphs.
49
+ *
50
+ * Replaces the previous Louvain (no refinement) and connected-components
51
+ * (single-linkage chaining) approaches.
52
+ *
53
+ * @param changes - AST change data for each commit.
54
+ * @param threshold - Minimum similarity (0-1) for considering an edge.
55
+ * @param maxClusters - Desired maximum number of top-level clusters.
56
+ * The resolution parameter γ is auto-tuned to approach
57
+ * this target. Recursive splitting may produce more
58
+ * clusters at finer granularities.
59
+ * @returns Clustered result with stats.
60
+ */
61
+ export declare function clusterCommits(changes: CommitChange[], threshold: number, maxClusters: number): ClusterResult;
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/spec/mine/clustering/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAwB1C,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAoFD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,aAAa,CA0Mf"}