homegraph 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/README.md +48 -11
  2. package/dist/bin/homegraph.js +298 -72
  3. package/dist/bin/homegraph.js.map +1 -1
  4. package/dist/context/index.d.ts.map +1 -1
  5. package/dist/context/index.js +117 -11
  6. package/dist/context/index.js.map +1 -1
  7. package/dist/db/index.d.ts +207 -6
  8. package/dist/db/index.d.ts.map +1 -1
  9. package/dist/db/index.js +461 -20
  10. package/dist/db/index.js.map +1 -1
  11. package/dist/db/migrations.d.ts +1 -1
  12. package/dist/db/migrations.d.ts.map +1 -1
  13. package/dist/db/migrations.js +19 -1
  14. package/dist/db/migrations.js.map +1 -1
  15. package/dist/db/queries.d.ts +157 -3
  16. package/dist/db/queries.d.ts.map +1 -1
  17. package/dist/db/queries.js +426 -9
  18. package/dist/db/queries.js.map +1 -1
  19. package/dist/db/schema.sql +32 -1
  20. package/dist/db/sqlite-adapter.d.ts +24 -17
  21. package/dist/db/sqlite-adapter.d.ts.map +1 -1
  22. package/dist/db/sqlite-adapter.js +292 -36
  23. package/dist/db/sqlite-adapter.js.map +1 -1
  24. package/dist/db/wal-valve.d.ts +119 -0
  25. package/dist/db/wal-valve.d.ts.map +1 -0
  26. package/dist/db/wal-valve.js +290 -0
  27. package/dist/db/wal-valve.js.map +1 -0
  28. package/dist/directory.d.ts +9 -5
  29. package/dist/directory.d.ts.map +1 -1
  30. package/dist/directory.js +210 -19
  31. package/dist/directory.js.map +1 -1
  32. package/dist/extraction/arkts-batch-worker.js +3 -2
  33. package/dist/extraction/arkts-batch-worker.js.map +1 -1
  34. package/dist/extraction/cfml-extractor.d.ts +107 -0
  35. package/dist/extraction/cfml-extractor.d.ts.map +1 -0
  36. package/dist/extraction/cfml-extractor.js +494 -0
  37. package/dist/extraction/cfml-extractor.js.map +1 -0
  38. package/dist/extraction/default-ignore.d.ts +39 -0
  39. package/dist/extraction/default-ignore.d.ts.map +1 -0
  40. package/dist/extraction/default-ignore.js +221 -0
  41. package/dist/extraction/default-ignore.js.map +1 -0
  42. package/dist/extraction/grammars.d.ts +25 -1
  43. package/dist/extraction/grammars.d.ts.map +1 -1
  44. package/dist/extraction/grammars.js +177 -24
  45. package/dist/extraction/grammars.js.map +1 -1
  46. package/dist/extraction/index.d.ts +52 -14
  47. package/dist/extraction/index.d.ts.map +1 -1
  48. package/dist/extraction/index.js +521 -314
  49. package/dist/extraction/index.js.map +1 -1
  50. package/dist/extraction/languages/arkts.d.ts +90 -6
  51. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  52. package/dist/extraction/languages/arkts.js +1579 -128
  53. package/dist/extraction/languages/arkts.js.map +1 -1
  54. package/dist/extraction/languages/c-cpp.d.ts +42 -0
  55. package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  56. package/dist/extraction/languages/c-cpp.js +369 -4
  57. package/dist/extraction/languages/c-cpp.js.map +1 -1
  58. package/dist/extraction/languages/cfquery.d.ts +12 -0
  59. package/dist/extraction/languages/cfquery.d.ts.map +1 -0
  60. package/dist/extraction/languages/cfquery.js +28 -0
  61. package/dist/extraction/languages/cfquery.js.map +1 -0
  62. package/dist/extraction/languages/cfscript.d.ts +3 -0
  63. package/dist/extraction/languages/cfscript.d.ts.map +1 -0
  64. package/dist/extraction/languages/cfscript.js +73 -0
  65. package/dist/extraction/languages/cfscript.js.map +1 -0
  66. package/dist/extraction/languages/cobol.d.ts +33 -0
  67. package/dist/extraction/languages/cobol.d.ts.map +1 -0
  68. package/dist/extraction/languages/cobol.js +499 -0
  69. package/dist/extraction/languages/cobol.js.map +1 -0
  70. package/dist/extraction/languages/erlang.d.ts +3 -0
  71. package/dist/extraction/languages/erlang.d.ts.map +1 -0
  72. package/dist/extraction/languages/erlang.js +350 -0
  73. package/dist/extraction/languages/erlang.js.map +1 -0
  74. package/dist/extraction/languages/index.d.ts.map +1 -1
  75. package/dist/extraction/languages/index.js +16 -0
  76. package/dist/extraction/languages/index.js.map +1 -1
  77. package/dist/extraction/languages/nix.d.ts +3 -0
  78. package/dist/extraction/languages/nix.d.ts.map +1 -0
  79. package/dist/extraction/languages/nix.js +294 -0
  80. package/dist/extraction/languages/nix.js.map +1 -0
  81. package/dist/extraction/languages/solidity.d.ts +3 -0
  82. package/dist/extraction/languages/solidity.d.ts.map +1 -0
  83. package/dist/extraction/languages/solidity.js +293 -0
  84. package/dist/extraction/languages/solidity.js.map +1 -0
  85. package/dist/extraction/languages/terraform.d.ts +3 -0
  86. package/dist/extraction/languages/terraform.d.ts.map +1 -0
  87. package/dist/extraction/languages/terraform.js +641 -0
  88. package/dist/extraction/languages/terraform.js.map +1 -0
  89. package/dist/extraction/languages/vbnet.d.ts +11 -0
  90. package/dist/extraction/languages/vbnet.d.ts.map +1 -0
  91. package/dist/extraction/languages/vbnet.js +141 -0
  92. package/dist/extraction/languages/vbnet.js.map +1 -0
  93. package/dist/extraction/mybatis-extractor.d.ts +30 -10
  94. package/dist/extraction/mybatis-extractor.d.ts.map +1 -1
  95. package/dist/extraction/mybatis-extractor.js +140 -38
  96. package/dist/extraction/mybatis-extractor.js.map +1 -1
  97. package/dist/extraction/parse-pool.d.ts +27 -1
  98. package/dist/extraction/parse-pool.d.ts.map +1 -1
  99. package/dist/extraction/parse-pool.js +75 -7
  100. package/dist/extraction/parse-pool.js.map +1 -1
  101. package/dist/extraction/parse-worker.js +9 -2
  102. package/dist/extraction/parse-worker.js.map +1 -1
  103. package/dist/extraction/store-worker.d.ts +20 -0
  104. package/dist/extraction/store-worker.d.ts.map +1 -0
  105. package/dist/extraction/store-worker.js +102 -0
  106. package/dist/extraction/store-worker.js.map +1 -0
  107. package/dist/extraction/store-writer.d.ts +48 -0
  108. package/dist/extraction/store-writer.d.ts.map +1 -0
  109. package/dist/extraction/store-writer.js +167 -0
  110. package/dist/extraction/store-writer.js.map +1 -0
  111. package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
  112. package/dist/extraction/tree-sitter-helpers.js +1 -0
  113. package/dist/extraction/tree-sitter-helpers.js.map +1 -1
  114. package/dist/extraction/tree-sitter-types.d.ts +3 -1
  115. package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  116. package/dist/extraction/tree-sitter.d.ts +38 -0
  117. package/dist/extraction/tree-sitter.d.ts.map +1 -1
  118. package/dist/extraction/tree-sitter.js +801 -10
  119. package/dist/extraction/tree-sitter.js.map +1 -1
  120. package/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
  121. package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  122. package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  123. package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  124. package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  125. package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  126. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  127. package/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
  128. package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  129. package/dist/extraction/wasm-runtime-flags.d.ts +14 -4
  130. package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
  131. package/dist/extraction/wasm-runtime-flags.js +55 -7
  132. package/dist/extraction/wasm-runtime-flags.js.map +1 -1
  133. package/dist/graph/traversal.d.ts.map +1 -1
  134. package/dist/graph/traversal.js +1 -1
  135. package/dist/graph/traversal.js.map +1 -1
  136. package/dist/index.d.ts +74 -5
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +436 -55
  139. package/dist/index.js.map +1 -1
  140. package/dist/installer/index.d.ts +42 -0
  141. package/dist/installer/index.d.ts.map +1 -1
  142. package/dist/installer/index.js +97 -2
  143. package/dist/installer/index.js.map +1 -1
  144. package/dist/mcp/daemon.d.ts +25 -3
  145. package/dist/mcp/daemon.d.ts.map +1 -1
  146. package/dist/mcp/daemon.js +62 -8
  147. package/dist/mcp/daemon.js.map +1 -1
  148. package/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
  149. package/dist/mcp/dynamic-boundaries.js +2 -1
  150. package/dist/mcp/dynamic-boundaries.js.map +1 -1
  151. package/dist/mcp/early-ppid.d.ts +26 -0
  152. package/dist/mcp/early-ppid.d.ts.map +1 -0
  153. package/dist/mcp/early-ppid.js +29 -0
  154. package/dist/mcp/early-ppid.js.map +1 -0
  155. package/dist/mcp/engine.d.ts +4 -5
  156. package/dist/mcp/engine.d.ts.map +1 -1
  157. package/dist/mcp/engine.js +27 -1
  158. package/dist/mcp/engine.js.map +1 -1
  159. package/dist/mcp/index.d.ts.map +1 -1
  160. package/dist/mcp/index.js +41 -6
  161. package/dist/mcp/index.js.map +1 -1
  162. package/dist/mcp/liveness-watchdog.d.ts +18 -1
  163. package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  164. package/dist/mcp/liveness-watchdog.js +73 -13
  165. package/dist/mcp/liveness-watchdog.js.map +1 -1
  166. package/dist/mcp/memory-budget.d.ts +30 -0
  167. package/dist/mcp/memory-budget.d.ts.map +1 -0
  168. package/dist/mcp/memory-budget.js +123 -0
  169. package/dist/mcp/memory-budget.js.map +1 -0
  170. package/dist/mcp/proxy.d.ts.map +1 -1
  171. package/dist/mcp/proxy.js +88 -4
  172. package/dist/mcp/proxy.js.map +1 -1
  173. package/dist/mcp/query-cache.d.ts +35 -4
  174. package/dist/mcp/query-cache.d.ts.map +1 -1
  175. package/dist/mcp/query-cache.js +89 -19
  176. package/dist/mcp/query-cache.js.map +1 -1
  177. package/dist/mcp/query-pool.d.ts +46 -12
  178. package/dist/mcp/query-pool.d.ts.map +1 -1
  179. package/dist/mcp/query-pool.js +100 -23
  180. package/dist/mcp/query-pool.js.map +1 -1
  181. package/dist/mcp/query-worker.d.ts +2 -2
  182. package/dist/mcp/query-worker.js +2 -2
  183. package/dist/mcp/server-instructions.d.ts +4 -27
  184. package/dist/mcp/server-instructions.d.ts.map +1 -1
  185. package/dist/mcp/server-instructions.js +39 -84
  186. package/dist/mcp/server-instructions.js.map +1 -1
  187. package/dist/mcp/session.d.ts +14 -0
  188. package/dist/mcp/session.d.ts.map +1 -1
  189. package/dist/mcp/session.js +28 -1
  190. package/dist/mcp/session.js.map +1 -1
  191. package/dist/mcp/startup-handshake.d.ts +44 -0
  192. package/dist/mcp/startup-handshake.d.ts.map +1 -0
  193. package/dist/mcp/startup-handshake.js +73 -0
  194. package/dist/mcp/startup-handshake.js.map +1 -0
  195. package/dist/mcp/tools.d.ts +104 -4
  196. package/dist/mcp/tools.d.ts.map +1 -1
  197. package/dist/mcp/tools.js +2432 -217
  198. package/dist/mcp/tools.js.map +1 -1
  199. package/dist/mcp/transport.d.ts.map +1 -1
  200. package/dist/mcp/transport.js +18 -0
  201. package/dist/mcp/transport.js.map +1 -1
  202. package/dist/project-config.d.ts +38 -0
  203. package/dist/project-config.d.ts.map +1 -1
  204. package/dist/project-config.js +101 -2
  205. package/dist/project-config.js.map +1 -1
  206. package/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
  207. package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
  208. package/dist/resolution/c-fnptr-synthesizer.js +178 -146
  209. package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
  210. package/dist/resolution/callback-synthesizer.d.ts +54 -10
  211. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  212. package/dist/resolution/callback-synthesizer.js +1299 -257
  213. package/dist/resolution/callback-synthesizer.js.map +1 -1
  214. package/dist/resolution/cooperative-yield.d.ts +10 -2
  215. package/dist/resolution/cooperative-yield.d.ts.map +1 -1
  216. package/dist/resolution/cooperative-yield.js +6 -4
  217. package/dist/resolution/cooperative-yield.js.map +1 -1
  218. package/dist/resolution/frameworks/cics.d.ts +20 -0
  219. package/dist/resolution/frameworks/cics.d.ts.map +1 -0
  220. package/dist/resolution/frameworks/cics.js +90 -0
  221. package/dist/resolution/frameworks/cics.js.map +1 -0
  222. package/dist/resolution/frameworks/go.d.ts.map +1 -1
  223. package/dist/resolution/frameworks/go.js +29 -6
  224. package/dist/resolution/frameworks/go.js.map +1 -1
  225. package/dist/resolution/frameworks/index.d.ts.map +1 -1
  226. package/dist/resolution/frameworks/index.js +3 -0
  227. package/dist/resolution/frameworks/index.js.map +1 -1
  228. package/dist/resolution/frameworks/java.d.ts.map +1 -1
  229. package/dist/resolution/frameworks/java.js +14 -6
  230. package/dist/resolution/frameworks/java.js.map +1 -1
  231. package/dist/resolution/frameworks/terraform.d.ts +38 -0
  232. package/dist/resolution/frameworks/terraform.d.ts.map +1 -0
  233. package/dist/resolution/frameworks/terraform.js +277 -0
  234. package/dist/resolution/frameworks/terraform.js.map +1 -0
  235. package/dist/resolution/goframe-synthesizer.d.ts +2 -1
  236. package/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
  237. package/dist/resolution/goframe-synthesizer.js +8 -3
  238. package/dist/resolution/goframe-synthesizer.js.map +1 -1
  239. package/dist/resolution/import-resolver.d.ts +9 -3
  240. package/dist/resolution/import-resolver.d.ts.map +1 -1
  241. package/dist/resolution/import-resolver.js +295 -11
  242. package/dist/resolution/import-resolver.js.map +1 -1
  243. package/dist/resolution/index.d.ts +146 -8
  244. package/dist/resolution/index.d.ts.map +1 -1
  245. package/dist/resolution/index.js +1089 -131
  246. package/dist/resolution/index.js.map +1 -1
  247. package/dist/resolution/memory-budget.d.ts +48 -0
  248. package/dist/resolution/memory-budget.d.ts.map +1 -0
  249. package/dist/resolution/memory-budget.js +162 -0
  250. package/dist/resolution/memory-budget.js.map +1 -0
  251. package/dist/resolution/name-matcher.d.ts +12 -4
  252. package/dist/resolution/name-matcher.d.ts.map +1 -1
  253. package/dist/resolution/name-matcher.js +793 -130
  254. package/dist/resolution/name-matcher.js.map +1 -1
  255. package/dist/resolution/resolver-pool.d.ts +106 -0
  256. package/dist/resolution/resolver-pool.d.ts.map +1 -0
  257. package/dist/resolution/resolver-pool.js +344 -0
  258. package/dist/resolution/resolver-pool.js.map +1 -0
  259. package/dist/resolution/resolver-worker.d.ts +17 -0
  260. package/dist/resolution/resolver-worker.d.ts.map +1 -0
  261. package/dist/resolution/resolver-worker.js +141 -0
  262. package/dist/resolution/resolver-worker.js.map +1 -0
  263. package/dist/resolution/strip-comments.d.ts +1 -1
  264. package/dist/resolution/strip-comments.d.ts.map +1 -1
  265. package/dist/resolution/strip-comments.js +49 -0
  266. package/dist/resolution/strip-comments.js.map +1 -1
  267. package/dist/resolution/types.d.ts +32 -0
  268. package/dist/resolution/types.d.ts.map +1 -1
  269. package/dist/resolution/workspace-packages.d.ts +10 -0
  270. package/dist/resolution/workspace-packages.d.ts.map +1 -1
  271. package/dist/resolution/workspace-packages.js +142 -4
  272. package/dist/resolution/workspace-packages.js.map +1 -1
  273. package/dist/search/identifier-segments.d.ts +60 -0
  274. package/dist/search/identifier-segments.d.ts.map +1 -0
  275. package/dist/search/identifier-segments.js +176 -0
  276. package/dist/search/identifier-segments.js.map +1 -0
  277. package/dist/search/query-utils.d.ts +201 -0
  278. package/dist/search/query-utils.d.ts.map +1 -1
  279. package/dist/search/query-utils.js +919 -2
  280. package/dist/search/query-utils.js.map +1 -1
  281. package/dist/spec/build/diff-parser.d.ts +55 -0
  282. package/dist/spec/build/diff-parser.d.ts.map +1 -0
  283. package/dist/spec/build/diff-parser.js +205 -0
  284. package/dist/spec/build/diff-parser.js.map +1 -0
  285. package/dist/spec/build/git-scanner.d.ts +93 -0
  286. package/dist/spec/build/git-scanner.d.ts.map +1 -0
  287. package/dist/spec/build/git-scanner.js +254 -0
  288. package/dist/spec/build/git-scanner.js.map +1 -0
  289. package/dist/spec/build/pipeline.d.ts +54 -0
  290. package/dist/spec/build/pipeline.d.ts.map +1 -0
  291. package/dist/spec/build/pipeline.js +170 -0
  292. package/dist/spec/build/pipeline.js.map +1 -0
  293. package/dist/spec/build/scan.d.ts +48 -0
  294. package/dist/spec/build/scan.d.ts.map +1 -0
  295. package/dist/spec/build/scan.js +89 -0
  296. package/dist/spec/build/scan.js.map +1 -0
  297. package/dist/spec/build/scope-resolver.d.ts +50 -0
  298. package/dist/spec/build/scope-resolver.d.ts.map +1 -0
  299. package/dist/spec/build/scope-resolver.js +105 -0
  300. package/dist/spec/build/scope-resolver.js.map +1 -0
  301. package/dist/spec/build/spec-extractor.d.ts +74 -0
  302. package/dist/spec/build/spec-extractor.d.ts.map +1 -0
  303. package/dist/spec/build/spec-extractor.js +344 -0
  304. package/dist/spec/build/spec-extractor.js.map +1 -0
  305. package/dist/spec/config.d.ts +35 -1
  306. package/dist/spec/config.d.ts.map +1 -1
  307. package/dist/spec/config.js +30 -5
  308. package/dist/spec/config.js.map +1 -1
  309. package/dist/spec/db/fts.d.ts.map +1 -1
  310. package/dist/spec/db/fts.js +19 -50
  311. package/dist/spec/db/fts.js.map +1 -1
  312. package/dist/spec/db/index.d.ts +5 -3
  313. package/dist/spec/db/index.d.ts.map +1 -1
  314. package/dist/spec/db/index.js +16 -1
  315. package/dist/spec/db/index.js.map +1 -1
  316. package/dist/spec/db/persist.d.ts +45 -0
  317. package/dist/spec/db/persist.d.ts.map +1 -0
  318. package/dist/spec/db/persist.js +66 -0
  319. package/dist/spec/db/persist.js.map +1 -0
  320. package/dist/spec/db/relations.d.ts +80 -1
  321. package/dist/spec/db/relations.d.ts.map +1 -1
  322. package/dist/spec/db/relations.js +175 -4
  323. package/dist/spec/db/relations.js.map +1 -1
  324. package/dist/spec/db/schema.d.ts +4 -0
  325. package/dist/spec/db/schema.d.ts.map +1 -1
  326. package/dist/spec/db/schema.js +4 -0
  327. package/dist/spec/db/schema.js.map +1 -1
  328. package/dist/spec/db/schema.sql +5 -1
  329. package/dist/spec/db/spec-node.d.ts +5 -0
  330. package/dist/spec/db/spec-node.d.ts.map +1 -1
  331. package/dist/spec/db/spec-node.js +11 -5
  332. package/dist/spec/db/spec-node.js.map +1 -1
  333. package/dist/spec/db/sql-utils.d.ts +11 -0
  334. package/dist/spec/db/sql-utils.d.ts.map +1 -0
  335. package/dist/spec/db/sql-utils.js +19 -0
  336. package/dist/spec/db/sql-utils.js.map +1 -0
  337. package/dist/spec/evolve/cluster-context.d.ts +30 -0
  338. package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
  339. package/dist/spec/evolve/cluster-context.js +78 -0
  340. package/dist/spec/evolve/cluster-context.js.map +1 -0
  341. package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
  342. package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
  343. package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
  344. package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
  345. package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
  346. package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
  347. package/dist/spec/evolve/commit-spec-persister.js +93 -0
  348. package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
  349. package/dist/spec/evolve/impact-locator.d.ts +23 -7
  350. package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
  351. package/dist/spec/evolve/impact-locator.js +58 -14
  352. package/dist/spec/evolve/impact-locator.js.map +1 -1
  353. package/dist/spec/evolve/pipeline.d.ts +62 -25
  354. package/dist/spec/evolve/pipeline.d.ts.map +1 -1
  355. package/dist/spec/evolve/pipeline.js +436 -457
  356. package/dist/spec/evolve/pipeline.js.map +1 -1
  357. package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
  358. package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
  359. package/dist/spec/evolve/spec-rewriter.js +45 -45
  360. package/dist/spec/evolve/spec-rewriter.js.map +1 -1
  361. package/dist/spec/git/commits.d.ts +85 -0
  362. package/dist/spec/git/commits.d.ts.map +1 -0
  363. package/dist/spec/git/commits.js +218 -0
  364. package/dist/spec/git/commits.js.map +1 -0
  365. package/dist/spec/git/exec.d.ts +13 -0
  366. package/dist/spec/git/exec.d.ts.map +1 -0
  367. package/dist/spec/git/exec.js +19 -0
  368. package/dist/spec/git/exec.js.map +1 -0
  369. package/dist/spec/git/index.d.ts +9 -0
  370. package/dist/spec/git/index.d.ts.map +1 -0
  371. package/dist/spec/git/index.js +22 -0
  372. package/dist/spec/git/index.js.map +1 -0
  373. package/dist/spec/git-utils.d.ts +8 -0
  374. package/dist/spec/git-utils.d.ts.map +1 -0
  375. package/dist/spec/git-utils.js +14 -0
  376. package/dist/spec/git-utils.js.map +1 -0
  377. package/dist/spec/graph/index.d.ts +8 -0
  378. package/dist/spec/graph/index.d.ts.map +1 -0
  379. package/dist/spec/graph/index.js +17 -0
  380. package/dist/spec/graph/index.js.map +1 -0
  381. package/dist/spec/graph/queries.d.ts +6 -35
  382. package/dist/spec/graph/queries.d.ts.map +1 -1
  383. package/dist/spec/graph/queries.js +71 -248
  384. package/dist/spec/graph/queries.js.map +1 -1
  385. package/dist/spec/llm/agent-client.d.ts +59 -0
  386. package/dist/spec/llm/agent-client.d.ts.map +1 -0
  387. package/dist/spec/llm/agent-client.js +213 -0
  388. package/dist/spec/llm/agent-client.js.map +1 -0
  389. package/dist/spec/llm/agents/claude-code.d.ts +32 -0
  390. package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
  391. package/dist/spec/llm/agents/claude-code.js +125 -0
  392. package/dist/spec/llm/agents/claude-code.js.map +1 -0
  393. package/dist/spec/llm/agents/codex.d.ts +32 -0
  394. package/dist/spec/llm/agents/codex.d.ts.map +1 -0
  395. package/dist/spec/llm/agents/codex.js +145 -0
  396. package/dist/spec/llm/agents/codex.js.map +1 -0
  397. package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
  398. package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
  399. package/dist/spec/llm/agents/detect-utils.js +91 -0
  400. package/dist/spec/llm/agents/detect-utils.js.map +1 -0
  401. package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
  402. package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
  403. package/dist/spec/llm/agents/deveco-code.js +165 -0
  404. package/dist/spec/llm/agents/deveco-code.js.map +1 -0
  405. package/dist/spec/llm/agents/index.d.ts +31 -0
  406. package/dist/spec/llm/agents/index.d.ts.map +1 -0
  407. package/dist/spec/llm/agents/index.js +65 -0
  408. package/dist/spec/llm/agents/index.js.map +1 -0
  409. package/dist/spec/llm/agents/types.d.ts +76 -0
  410. package/dist/spec/llm/agents/types.d.ts.map +1 -0
  411. package/dist/spec/llm/agents/types.js +15 -0
  412. package/dist/spec/llm/agents/types.js.map +1 -0
  413. package/dist/spec/llm/client.d.ts +31 -11
  414. package/dist/spec/llm/client.d.ts.map +1 -1
  415. package/dist/spec/llm/client.js +143 -81
  416. package/dist/spec/llm/client.js.map +1 -1
  417. package/dist/spec/llm/factory.d.ts +41 -0
  418. package/dist/spec/llm/factory.d.ts.map +1 -0
  419. package/dist/spec/llm/factory.js +80 -0
  420. package/dist/spec/llm/factory.js.map +1 -0
  421. package/dist/spec/llm/prompts.d.ts +24 -8
  422. package/dist/spec/llm/prompts.d.ts.map +1 -1
  423. package/dist/spec/llm/prompts.js +100 -50
  424. package/dist/spec/llm/prompts.js.map +1 -1
  425. package/dist/spec/llm/retry.d.ts +53 -0
  426. package/dist/spec/llm/retry.d.ts.map +1 -0
  427. package/dist/spec/llm/retry.js +153 -0
  428. package/dist/spec/llm/retry.js.map +1 -0
  429. package/dist/spec/mine/clusterer.d.ts +63 -0
  430. package/dist/spec/mine/clusterer.d.ts.map +1 -0
  431. package/dist/spec/mine/clusterer.js +904 -0
  432. package/dist/spec/mine/clusterer.js.map +1 -0
  433. package/dist/spec/mine/clustering/features.d.ts +38 -0
  434. package/dist/spec/mine/clustering/features.d.ts.map +1 -0
  435. package/dist/spec/mine/clustering/features.js +108 -0
  436. package/dist/spec/mine/clustering/features.js.map +1 -0
  437. package/dist/spec/mine/clustering/index.d.ts +62 -0
  438. package/dist/spec/mine/clustering/index.d.ts.map +1 -0
  439. package/dist/spec/mine/clustering/index.js +259 -0
  440. package/dist/spec/mine/clustering/index.js.map +1 -0
  441. package/dist/spec/mine/clustering/leiden.d.ts +61 -0
  442. package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
  443. package/dist/spec/mine/clustering/leiden.js +489 -0
  444. package/dist/spec/mine/clustering/leiden.js.map +1 -0
  445. package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
  446. package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
  447. package/dist/spec/mine/clustering/text-similarity.js +98 -0
  448. package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
  449. package/dist/spec/mine/generator.d.ts +54 -0
  450. package/dist/spec/mine/generator.d.ts.map +1 -0
  451. package/dist/spec/mine/generator.js +267 -0
  452. package/dist/spec/mine/generator.js.map +1 -0
  453. package/dist/spec/mine/persist.d.ts +37 -0
  454. package/dist/spec/mine/persist.d.ts.map +1 -0
  455. package/dist/spec/mine/persist.js +170 -0
  456. package/dist/spec/mine/persist.js.map +1 -0
  457. package/dist/spec/mine/pipeline.d.ts +41 -0
  458. package/dist/spec/mine/pipeline.d.ts.map +1 -0
  459. package/dist/spec/mine/pipeline.js +236 -0
  460. package/dist/spec/mine/pipeline.js.map +1 -0
  461. package/dist/spec/mine/progress-handler.d.ts +22 -0
  462. package/dist/spec/mine/progress-handler.d.ts.map +1 -0
  463. package/dist/spec/mine/progress-handler.js +108 -0
  464. package/dist/spec/mine/progress-handler.js.map +1 -0
  465. package/dist/spec/mine/progress.d.ts +23 -0
  466. package/dist/spec/mine/progress.d.ts.map +1 -0
  467. package/dist/spec/mine/progress.js +12 -0
  468. package/dist/spec/mine/progress.js.map +1 -0
  469. package/dist/spec/mine/scanner.d.ts +59 -0
  470. package/dist/spec/mine/scanner.d.ts.map +1 -0
  471. package/dist/spec/mine/scanner.js +383 -0
  472. package/dist/spec/mine/scanner.js.map +1 -0
  473. package/dist/spec/types.d.ts +32 -0
  474. package/dist/spec/types.d.ts.map +1 -1
  475. package/dist/spec/ui/index.d.ts +9 -0
  476. package/dist/spec/ui/index.d.ts.map +1 -0
  477. package/dist/spec/ui/index.js +16 -0
  478. package/dist/spec/ui/index.js.map +1 -0
  479. package/dist/spec/ui/progress-handler.d.ts +33 -0
  480. package/dist/spec/ui/progress-handler.d.ts.map +1 -0
  481. package/dist/spec/ui/progress-handler.js +132 -0
  482. package/dist/spec/ui/progress-handler.js.map +1 -0
  483. package/dist/spec/ui/progress.d.ts +24 -0
  484. package/dist/spec/ui/progress.d.ts.map +1 -0
  485. package/dist/spec/ui/progress.js +13 -0
  486. package/dist/spec/ui/progress.js.map +1 -0
  487. package/dist/spec/utils/fs.d.ts +45 -0
  488. package/dist/spec/utils/fs.d.ts.map +1 -0
  489. package/dist/spec/utils/fs.js +163 -0
  490. package/dist/spec/utils/fs.js.map +1 -0
  491. package/dist/spec/utils/index.d.ts +12 -0
  492. package/dist/spec/utils/index.d.ts.map +1 -0
  493. package/dist/spec/utils/index.js +26 -0
  494. package/dist/spec/utils/index.js.map +1 -0
  495. package/dist/spec/utils/meta.d.ts +32 -0
  496. package/dist/spec/utils/meta.d.ts.map +1 -0
  497. package/dist/spec/utils/meta.js +122 -0
  498. package/dist/spec/utils/meta.js.map +1 -0
  499. package/dist/spec/utils/truncate.d.ts +86 -0
  500. package/dist/spec/utils/truncate.d.ts.map +1 -0
  501. package/dist/spec/utils/truncate.js +172 -0
  502. package/dist/spec/utils/truncate.js.map +1 -0
  503. package/dist/spec/utils.d.ts +4 -16
  504. package/dist/spec/utils.d.ts.map +1 -1
  505. package/dist/spec/utils.js +6 -58
  506. package/dist/spec/utils.js.map +1 -1
  507. package/dist/sync/git-hooks.d.ts.map +1 -1
  508. package/dist/sync/git-hooks.js +2 -0
  509. package/dist/sync/git-hooks.js.map +1 -1
  510. package/dist/sync/watcher.d.ts +35 -6
  511. package/dist/sync/watcher.d.ts.map +1 -1
  512. package/dist/sync/watcher.js +127 -17
  513. package/dist/sync/watcher.js.map +1 -1
  514. package/dist/sync/worktree.d.ts.map +1 -1
  515. package/dist/sync/worktree.js +5 -0
  516. package/dist/sync/worktree.js.map +1 -1
  517. package/dist/telemetry/index.js +3 -3
  518. package/dist/telemetry/index.js.map +1 -1
  519. package/dist/types.d.ts +22 -1
  520. package/dist/types.d.ts.map +1 -1
  521. package/dist/types.js +10 -0
  522. package/dist/types.js.map +1 -1
  523. package/dist/upgrade/index.d.ts +32 -0
  524. package/dist/upgrade/index.d.ts.map +1 -1
  525. package/dist/upgrade/index.js +162 -14
  526. package/dist/upgrade/index.js.map +1 -1
  527. package/dist/upgrade/remove-binary.d.ts +87 -0
  528. package/dist/upgrade/remove-binary.d.ts.map +1 -0
  529. package/dist/upgrade/remove-binary.js +289 -0
  530. package/dist/upgrade/remove-binary.js.map +1 -0
  531. package/dist/upgrade/update-check.d.ts +92 -0
  532. package/dist/upgrade/update-check.d.ts.map +1 -0
  533. package/dist/upgrade/update-check.js +258 -0
  534. package/dist/upgrade/update-check.js.map +1 -0
  535. package/package.json +6 -2
  536. package/scripts/agent-eval/run-all.sh +6 -0
  537. package/scripts/build-bundle.sh +5 -0
  538. package/scripts/npm-shim.js +8 -1
  539. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  540. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  541. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
  542. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  543. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  544. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  545. package/scripts/exp_boundary_eval/data/agents.json +0 -109
  546. package/scripts/exp_boundary_eval/data/experiments.json +0 -140
  547. package/scripts/qa_eval/README.md +0 -407
  548. package/scripts/qa_eval/_test_deveco_probe.py +0 -41
  549. package/scripts/qa_eval/agent_runner.py +0 -526
  550. package/scripts/qa_eval/data/.gitignore +0 -4
  551. package/scripts/qa_eval/data/test-set.jsonl +0 -2
  552. package/scripts/qa_eval/eval_metrics.py +0 -274
  553. package/scripts/qa_eval/external_agent.py +0 -976
  554. package/scripts/qa_eval/llm_config.py +0 -92
  555. package/scripts/qa_eval/memory_monitor.py +0 -132
  556. package/scripts/qa_eval/my_answer_accuracy.py +0 -187
  557. package/scripts/qa_eval/requirements.txt +0 -2
  558. package/scripts/qa_eval/run_pipeline.py +0 -804
  559. package/scripts/qa_eval/stats_efficiency.py +0 -279
  560. package/scripts/qa_eval/stats_scores.py +0 -207
@@ -60,8 +60,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
60
60
  const commander_1 = require("commander");
61
61
  const path = __importStar(require("path"));
62
62
  const fs = __importStar(require("fs"));
63
- const directory_1 = require("../directory");
64
63
  const utils_1 = require("../spec/utils");
64
+ const config_1 = require("../spec/config");
65
+ const directory_1 = require("../directory");
65
66
  const worktree_1 = require("../sync/worktree");
66
67
  const shimmer_progress_1 = require("../ui/shimmer-progress");
67
68
  const glyphs_1 = require("../ui/glyphs");
@@ -426,9 +427,9 @@ function main() {
426
427
  if (arktsDegraded.length > 0) {
427
428
  clack.log.warn('ArkTS index quality notice — see details below.');
428
429
  clack.note(`${arktsDegraded[0].message}\n\n` +
429
- 'Large ArkTS repos on Windows use an isolated indexer with enableMethodBodyBuild=true.\n' +
430
- 'If indexing failed, set HOMEGRAPH_ARKTS_STACK_SIZES_KB=65536,131072,262144 and retry:\n' +
431
- ' node --stack-size=65536 dist/bin/homegraph.js index <path>', 'ArkTS quality notice');
430
+ 'ArkTS Scene builds run in-process by default (fastest). If the indexer\n' +
431
+ 'exits with a Windows stack overflow on a huge repo, opt into the isolated\n' +
432
+ 'worker: HOMEGRAPH_ARKTS_ISOLATED=1 (optional HOMEGRAPH_ARKTS_STACK_SIZES_KB).', 'ArkTS quality notice');
432
433
  }
433
434
  }
434
435
  /**
@@ -793,6 +794,7 @@ function main() {
793
794
  const journalMode = cg.getJournalMode();
794
795
  const buildInfo = cg.getIndexBuildInfo();
795
796
  const reindexRecommended = cg.isIndexStale();
797
+ const indexState = cg.getIndexState();
796
798
  const ohosApi = cg.getOhosApiBinding();
797
799
  // JSON output mode
798
800
  if (options.json) {
@@ -823,6 +825,7 @@ function main() {
823
825
  ? { version: ohosApi.version, packageName: ohosApi.packageName, dbPath: ohosApi.dbPath }
824
826
  : null,
825
827
  index: {
828
+ state: indexState,
826
829
  builtWithVersion: buildInfo.version,
827
830
  builtWithExtractionVersion: buildInfo.extractionVersion,
828
831
  currentExtractionVersion: extraction_version_1.EXTRACTION_VERSION,
@@ -845,14 +848,11 @@ function main() {
845
848
  console.log(` Nodes: ${formatNumber(stats.nodeCount)}`);
846
849
  console.log(` Edges: ${formatNumber(stats.edgeCount)}`);
847
850
  console.log(` DB Size: ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
848
- // Surface the active SQLite backend (node:sqlite Node's built-in real
849
- // SQLite, full WAL + FTS5, no native build).
850
- const backendLabel = chalk.green(`node:sqlite ${(0, glyphs_1.getGlyphs)().dash} built-in (full WAL)`);
851
+ // Prefer node:sqlite better-sqlite3; wasm is last-resort (no WAL).
852
+ const backendLabel = backend === 'node-sqlite' ? chalk.green('node-sqlite')
853
+ : backend === 'native' ? chalk.green('native (better-sqlite3)')
854
+ : chalk.yellow(`wasm ${(0, glyphs_1.getGlyphs)().dash} slower fallback; use Node 22.5+ or \`npm rebuild better-sqlite3\``);
851
855
  console.log(` Backend: ${backendLabel}`);
852
- // Effective journal mode: 'wal' means concurrent reads never block on a
853
- // writer; anything else means they can ("database is locked"). node:sqlite
854
- // supports WAL everywhere, so a non-wal mode means the filesystem can't
855
- // (network mounts, WSL2 /mnt). See issue #238.
856
856
  const journalLabel = journalMode === 'wal'
857
857
  ? chalk.green('wal')
858
858
  : chalk.yellow(`${journalMode || 'unknown'} ${(0, glyphs_1.getGlyphs)().dash} WAL inactive; reads can block on writes`);
@@ -2006,27 +2006,27 @@ function main() {
2006
2006
  // =============================================================================
2007
2007
  const specCommand = program
2008
2008
  .command('spec')
2009
- .description('Manage spec knowledge graph (reverse-mining, search, self-evolve)');
2009
+ .description('Manage spec knowledge graph (build, mine, search, self-evolve)');
2010
2010
  /**
2011
- * homegraph spec mine
2011
+ * homegraph spec build
2012
2012
  */
2013
2013
  specCommand
2014
- .command('mine')
2015
- .description('Reverse-mine spec knowledge from Git history')
2014
+ .command('build')
2015
+ .description('Build spec knowledge graph from scanned Git history')
2016
2016
  .option('-p, --path <path>', 'Path to the repository')
2017
- .option('--spec-storage-path <path>', 'Path to the .spec directory')
2018
- .option('--db-path <path>', 'Path to the SQLite database file')
2017
+ .option('--spec-dir <path>', 'Path to the .spec directory')
2019
2018
  .option('-v, --verbose', 'Show detailed output')
2020
2019
  .option('-j, --json', 'Output as JSON')
2021
2020
  .action(async (options) => {
2022
2021
  try {
2023
2022
  const repoPath = path.resolve(options.path || process.cwd());
2024
- const specStoragePath = options.specStoragePath ?? path.join(repoPath, '.spec');
2023
+ const specStoragePath = path.resolve(repoPath, options.specDir || '.spec');
2025
2024
  const { createDatabase } = await Promise.resolve().then(() => __importStar(require('../db/sqlite-adapter')));
2026
- const { runMiningPipeline } = await Promise.resolve().then(() => __importStar(require('../spec/mining/pipeline')));
2027
- const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/mining/git-scanner')));
2025
+ const { runBuildPipeline } = await Promise.resolve().then(() => __importStar(require('../spec/build/pipeline')));
2026
+ const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/git')));
2028
2027
  const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2029
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2028
+ const { createBuildProgressHandler } = await Promise.resolve().then(() => __importStar(require('../spec/ui')));
2029
+ const dbPath = resolveDbPath(repoPath);
2030
2030
  if (!isGitRepo(repoPath)) {
2031
2031
  error(`Not a git repository: ${repoPath}`);
2032
2032
  process.exit(1);
@@ -2036,8 +2036,25 @@ function main() {
2036
2036
  info(`Spec storage: ${specStoragePath}`);
2037
2037
  info(`Database: ${dbPath}`);
2038
2038
  }
2039
+ // Progress reporting (mirrors `spec mine`):
2040
+ // - JSON mode: no progress output (only final JSON).
2041
+ // - Verbose mode: plain-text lines with timestamps.
2042
+ // - TTY (default): ANSI progress bar with phase + item details.
2043
+ // - Pipe / non-TTY: fall back to verbose (5 % stepping).
2044
+ const onProgress = options.json
2045
+ ? undefined
2046
+ : createBuildProgressHandler(options.verbose ? 'verbose' : process.stdout.isTTY ? 'bar' : 'verbose');
2039
2047
  const { db } = createDatabase(dbPath);
2040
- const result = runMiningPipeline(repoPath, specStoragePath, db);
2048
+ const result = runBuildPipeline(repoPath, specStoragePath, db, onProgress);
2049
+ if (result.upToDate) {
2050
+ if (options.json) {
2051
+ console.log(JSON.stringify(result, null, 2));
2052
+ }
2053
+ else {
2054
+ info('Spec knowledge graph is up to date — nothing to build.');
2055
+ }
2056
+ return;
2057
+ }
2041
2058
  if (options.json) {
2042
2059
  console.log(JSON.stringify(result, null, 2));
2043
2060
  }
@@ -2060,6 +2077,168 @@ function main() {
2060
2077
  process.exit(1);
2061
2078
  }
2062
2079
  });
2080
+ /**
2081
+ * homegraph spec mine
2082
+ *
2083
+ * Mine design specs from Git history using AST analysis and LLM
2084
+ */
2085
+ specCommand
2086
+ .command('mine')
2087
+ .description('Mine design specs from Git history using AST analysis and LLM')
2088
+ .option('-p, --path <path>', 'Path to the repository')
2089
+ .option('--limit <number>', 'Maximum commits to scan', '100')
2090
+ .option('--output <path>', 'Output directory for generated specs', '.spec')
2091
+ .option('--threshold <number>', 'Clustering similarity threshold (0-1)', '0.25')
2092
+ .option('--max-cluster <number>', 'Maximum number of clusters', '10')
2093
+ .option('--template <path>', 'Path to a spec template markdown file')
2094
+ .option('--skip-llm', 'Skip LLM generation — only output clusters')
2095
+ .option('-v, --verbose', 'Show detailed output')
2096
+ .option('-j, --json', 'Output as JSON')
2097
+ .action(async (options) => {
2098
+ try {
2099
+ const repoPath = path.resolve(options.path || process.cwd());
2100
+ const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/git')));
2101
+ const { loadSpecConfig } = await Promise.resolve().then(() => __importStar(require('../spec/config')));
2102
+ const { runMinePipeline } = await Promise.resolve().then(() => __importStar(require('../spec/mine/pipeline')));
2103
+ const { createDatabase } = await Promise.resolve().then(() => __importStar(require('../db/sqlite-adapter')));
2104
+ const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2105
+ const { createMineProgressHandler } = await Promise.resolve().then(() => __importStar(require('../spec/ui')));
2106
+ if (!isGitRepo(repoPath)) {
2107
+ error(`Not a git repository: ${repoPath}`);
2108
+ process.exit(1);
2109
+ }
2110
+ // Parse numeric options
2111
+ const limit = parseInt(options.limit || '100', 10);
2112
+ if (isNaN(limit) || limit < 1 || limit > 1000) {
2113
+ error('--limit must be an integer between 1 and 1000');
2114
+ process.exit(1);
2115
+ }
2116
+ const threshold = parseFloat(options.threshold || '0.25');
2117
+ if (isNaN(threshold) || threshold < 0 || threshold > 1) {
2118
+ error('--threshold must be a number between 0 and 1');
2119
+ process.exit(1);
2120
+ }
2121
+ const maxCluster = parseInt(options.maxCluster || '10', 10);
2122
+ if (isNaN(maxCluster) || maxCluster < 1 || maxCluster > 50) {
2123
+ error('--max-cluster must be an integer between 1 and 50');
2124
+ process.exit(1);
2125
+ }
2126
+ // Resolve output directory: if meta.json exists, reuse its specStoragePath;
2127
+ // otherwise fall back to --output option, then default '.spec'.
2128
+ // All paths are resolved relative to repoPath so that relative values
2129
+ // (e.g. '.spec', or a relative specStoragePath from meta.json) are
2130
+ // anchored correctly regardless of cwd; absolute paths pass through unchanged.
2131
+ const existingMeta = (0, utils_1.readMeta)(repoPath);
2132
+ const outputDir = existingMeta
2133
+ ? path.resolve(repoPath, existingMeta.specStoragePath)
2134
+ : path.resolve(repoPath, options.output || '.spec');
2135
+ // Load spec config for LLM setup
2136
+ const specConfig = loadSpecConfig(repoPath);
2137
+ const llmConfig = specConfig.llm;
2138
+ const { resolveAgent } = await Promise.resolve().then(() => __importStar(require('../spec/llm/agents')));
2139
+ const codingAgent = options.skipLlm ? null : resolveAgent();
2140
+ if (!options.skipLlm && !llmConfig && !codingAgent) {
2141
+ info('No coding agent (Claude Code / Codex / DevEco Code) detected and no LLM configuration found.\n' +
2142
+ 'Set up "llm" in .homegraph/commit4spec/configs.json.\n' +
2143
+ '\n' +
2144
+ 'All available options (fields marked * are required):\n' +
2145
+ '{\n' +
2146
+ ' "llm": {\n' +
2147
+ ' "provider": "openai", // * "openai" or "anthropic"\n' +
2148
+ ' "apiKey": "sk-...", // * API key string (plain text)\n' +
2149
+ ' "apiKeyEnv": "OPENAI_API_KEY", // or read from env var (takes precedence)\n' +
2150
+ ' "model": "gpt-4o", // * model name (e.g. gpt-4o, claude-3-5-sonnet)\n' +
2151
+ ' "baseUrl": "https://...", // custom endpoint (proxies / local models)\n' +
2152
+ ' "temperature": 0.2, // creativity control (default: 0.2)\n' +
2153
+ ' "maxTokens": 20000 // max output tokens (default: 20000)\n' +
2154
+ ' }\n' +
2155
+ '}\n' +
2156
+ '\n' +
2157
+ 'Continuing with --skip-llm (clustering only).');
2158
+ }
2159
+ else if (!options.skipLlm && !llmConfig && codingAgent) {
2160
+ info(`Using ${codingAgent.displayName} (headless) for spec generation — no LLM configuration needed.`);
2161
+ }
2162
+ else if (!options.skipLlm && llmConfig && codingAgent) {
2163
+ info(`Using ${codingAgent.displayName} (headless) for spec generation — configured LLM is kept as fallback.`);
2164
+ }
2165
+ const mineConfig = (0, config_1.createMineConfig)({
2166
+ limit,
2167
+ threshold,
2168
+ maxCluster,
2169
+ outputDir,
2170
+ template: options.template,
2171
+ skipLlm: !!options.skipLlm,
2172
+ }, !!llmConfig || codingAgent !== null);
2173
+ if (options.verbose) {
2174
+ info(`Repository: ${repoPath}`);
2175
+ info(`Limit: ${limit === 100 ? '100 (default)' : limit}`);
2176
+ info(`Threshold: ${threshold}`);
2177
+ info(`Max clusters: ${maxCluster}`);
2178
+ info(`Output: ${outputDir}`);
2179
+ info(`Skip LLM: ${mineConfig.skipLlm}`);
2180
+ if (options.template) {
2181
+ info(`Template: ${options.template}`);
2182
+ }
2183
+ }
2184
+ // Open knowledge graph database for persistence
2185
+ let db;
2186
+ try {
2187
+ const dbPath = resolveDbPath(repoPath);
2188
+ const created = createDatabase(dbPath);
2189
+ db = created.db;
2190
+ }
2191
+ catch (err) {
2192
+ // Non-fatal — spec generation and file output still work without DB
2193
+ if (options.verbose) {
2194
+ warn(`Failed to open commit4spec.db: ${err instanceof Error ? err.message : String(err)}`);
2195
+ }
2196
+ }
2197
+ // Wire up progress reporting.
2198
+ // - JSON mode: no progress output (only final JSON).
2199
+ // - Verbose mode: plain-text lines with timestamps.
2200
+ // - TTY (default): ANSI progress bar with phase + item details.
2201
+ // - Pipe / non-TTY: fall back to verbose (5 % stepping).
2202
+ let onProgress;
2203
+ if (!options.json) {
2204
+ onProgress = createMineProgressHandler(options.verbose ? 'verbose' : process.stdout.isTTY ? 'bar' : 'verbose');
2205
+ }
2206
+ let result;
2207
+ try {
2208
+ result = await runMinePipeline(repoPath, mineConfig, llmConfig, db, onProgress);
2209
+ }
2210
+ finally {
2211
+ // Close database even if pipeline throws
2212
+ try {
2213
+ db?.close();
2214
+ }
2215
+ catch { /* best effort */ }
2216
+ }
2217
+ if (options.json) {
2218
+ console.log(JSON.stringify(result, null, 2));
2219
+ }
2220
+ else {
2221
+ success(`Scanned ${result.commitsScanned} commits, ` +
2222
+ `${result.changesFound} with structural changes, ` +
2223
+ `${result.clusters} clusters found.`);
2224
+ if (result.specsGenerated > 0) {
2225
+ success(`${result.specsGenerated} specs generated in ${outputDir}/`);
2226
+ }
2227
+ if (result.specsWritten > 0) {
2228
+ info(`${result.specsWritten} spec(s), ${result.commitsWritten} commit(s), ${result.fragmentsWritten} fragment(s) written to commit4spec.db`);
2229
+ }
2230
+ if (result.errors.length > 0) {
2231
+ for (const err of result.errors) {
2232
+ warn(err);
2233
+ }
2234
+ }
2235
+ }
2236
+ }
2237
+ catch (err) {
2238
+ error(`Reverse pipeline failed: ${err instanceof Error ? err.message : String(err)}`);
2239
+ process.exit(1);
2240
+ }
2241
+ });
2063
2242
  /**
2064
2243
  * homegraph spec match <text>
2065
2244
  */
@@ -2067,7 +2246,6 @@ function main() {
2067
2246
  .command('match <text>')
2068
2247
  .description('Search the spec knowledge graph for a term or phrase')
2069
2248
  .option('-p, --path <path>', 'Path to the repository')
2070
- .option('--db-path <path>', 'Path to the SQLite database file')
2071
2249
  .option('--top-k <number>', 'Number of results to return', '5')
2072
2250
  .option('--no-fragments', 'Exclude code fragments from results')
2073
2251
  .option('-j, --json', 'Output as JSON')
@@ -2078,9 +2256,9 @@ function main() {
2078
2256
  const { createDatabase } = await Promise.resolve().then(() => __importStar(require('../db/sqlite-adapter')));
2079
2257
  const { resolveDbPath, computeBudgetProfile } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2080
2258
  const { searchAndGetContext } = await Promise.resolve().then(() => __importStar(require('../spec/graph/queries')));
2081
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2259
+ const dbPath = resolveDbPath(repoPath);
2082
2260
  if (!fs.existsSync(dbPath)) {
2083
- error(`Database not found at ${dbPath}. Run 'homegraph spec mine' first.`);
2261
+ error(`Database not found at ${dbPath}. Run 'homegraph spec build/mine' first.`);
2084
2262
  process.exit(1);
2085
2263
  }
2086
2264
  const created = createDatabase(dbPath);
@@ -2152,7 +2330,6 @@ function main() {
2152
2330
  .command('find <filePath>')
2153
2331
  .description('Find specs related to the given file path via code-fragment matching')
2154
2332
  .option('-p, --path <path>', 'Path to the repository')
2155
- .option('--db-path <path>', 'Path to the SQLite database file')
2156
2333
  .option('-j, --json', 'Output as JSON')
2157
2334
  .action(async (filePath, options) => {
2158
2335
  let db;
@@ -2161,9 +2338,9 @@ function main() {
2161
2338
  const { createDatabase } = await Promise.resolve().then(() => __importStar(require('../db/sqlite-adapter')));
2162
2339
  const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2163
2340
  const { findSpecsByFilePath } = await Promise.resolve().then(() => __importStar(require('../spec/graph/queries')));
2164
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2341
+ const dbPath = resolveDbPath(repoPath);
2165
2342
  if (!fs.existsSync(dbPath)) {
2166
- error(`Database not found at ${dbPath}. Run 'homegraph spec mine' first.`);
2343
+ error(`Database not found at ${dbPath}. Run 'homegraph spec build/mine' first.`);
2167
2344
  process.exit(1);
2168
2345
  }
2169
2346
  const created = createDatabase(dbPath);
@@ -2212,7 +2389,6 @@ function main() {
2212
2389
  .option('-f, --file <path>', 'File path for symbol disambiguation')
2213
2390
  .option('-l, --line <number>', 'Line number for symbol disambiguation')
2214
2391
  .option('-p, --path <path>', 'Path to the repository')
2215
- .option('--db-path <path>', 'Path to the SQLite database file')
2216
2392
  .option('--top-k <number>', 'Number of results to return', '10')
2217
2393
  .option('-j, --json', 'Output as JSON')
2218
2394
  .action(async (symbol, options) => {
@@ -2302,9 +2478,9 @@ function main() {
2302
2478
  const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2303
2479
  const { findSpecsByCodeSymbol } = await Promise.resolve().then(() => __importStar(require('../spec/graph/queries')));
2304
2480
  const { initSpecSchema, runSpecMigrations, getCurrentSpecVersion, CURRENT_SPEC_SCHEMA_VERSION } = await Promise.resolve().then(() => __importStar(require('../spec/db/schema')));
2305
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2481
+ const dbPath = resolveDbPath(repoPath);
2306
2482
  if (!fs.existsSync(dbPath)) {
2307
- console.log(chalk.yellow(`Database not found at ${dbPath}. Run 'homegraph spec mine' first.`));
2483
+ console.log(chalk.yellow(`Database not found at ${dbPath}. Run 'homegraph spec build/mine' first.`));
2308
2484
  return;
2309
2485
  }
2310
2486
  const created = createDatabase(dbPath);
@@ -2392,7 +2568,6 @@ function main() {
2392
2568
  .command('stats')
2393
2569
  .description('Show statistics about the spec knowledge graph')
2394
2570
  .option('-p, --path <path>', 'Path to the repository')
2395
- .option('--db-path <path>', 'Path to the SQLite database file')
2396
2571
  .option('-j, --json', 'Output as JSON')
2397
2572
  .action(async (options) => {
2398
2573
  let db;
@@ -2401,9 +2576,9 @@ function main() {
2401
2576
  const { createDatabase } = await Promise.resolve().then(() => __importStar(require('../db/sqlite-adapter')));
2402
2577
  const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2403
2578
  const { getSpecStats } = await Promise.resolve().then(() => __importStar(require('../spec/graph/queries')));
2404
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2579
+ const dbPath = resolveDbPath(repoPath);
2405
2580
  if (!fs.existsSync(dbPath)) {
2406
- error(`Database not found at ${dbPath}. Run 'homegraph spec mine' first.`);
2581
+ error(`Database not found at ${dbPath}. Run 'homegraph spec build/mine' first.`);
2407
2582
  process.exit(1);
2408
2583
  }
2409
2584
  const created = createDatabase(dbPath);
@@ -2422,7 +2597,7 @@ function main() {
2422
2597
  console.log(` Relations: ${stats.relationCount}`);
2423
2598
  console.log();
2424
2599
  if (stats.specCount === 0) {
2425
- info("No specs yet. Run 'homegraph spec mine' to build the knowledge graph.");
2600
+ info("No specs yet. Run 'homegraph spec build/mine' to build the knowledge graph.");
2426
2601
  }
2427
2602
  }
2428
2603
  }
@@ -2451,10 +2626,19 @@ function main() {
2451
2626
  .description('Install a git post-commit hook that triggers spec evolution')
2452
2627
  .option('-p, --path <path>', 'Path to the repository')
2453
2628
  .option('-f, --force', 'Overwrite existing hook without prompting')
2629
+ .option('-t, --commit-threshold <n>', 'Number of pending commits to accumulate before triggering evolve', (v) => {
2630
+ const n = parseInt(v, 10);
2631
+ if (isNaN(n) || n < 1) {
2632
+ error('--commit-threshold must be a positive integer');
2633
+ process.exit(1);
2634
+ }
2635
+ return n;
2636
+ }, 3)
2454
2637
  .action(async (options) => {
2455
2638
  try {
2456
2639
  const repoPath = resolveSpecProjectPath(options.path);
2457
- const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/mining/git-scanner')));
2640
+ const commitThreshold = options.commitThreshold ?? 3;
2641
+ const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/git')));
2458
2642
  if (!isGitRepo(repoPath)) {
2459
2643
  error(`Not a git repository: ${repoPath}`);
2460
2644
  process.exit(1);
@@ -2507,14 +2691,47 @@ function main() {
2507
2691
  const MARKER_END = '# <<< homegraph spec evolve hook <<<';
2508
2692
  const hookBlock = [
2509
2693
  MARKER_BEGIN,
2510
- '# Triggers spec self-evolution after each commit. Runs in background.',
2694
+ '# Triggers spec self-evolution after N commits have accumulated.',
2695
+ '# Default threshold: 3 commits (configurable via --commit-threshold).',
2511
2696
  '# Installed by: homegraph spec evolve install',
2512
2697
  `# Logs: ${utils_1.SPEC_DATA_DIR}/logs/evolve-hook.log`,
2698
+ '',
2699
+ `THRESHOLD=${commitThreshold}`,
2700
+ `LOGS_DIR="${utils_1.SPEC_DATA_DIR}/logs"`,
2701
+ `META_FILE="${utils_1.SPEC_DATA_DIR}/meta.json"`,
2702
+ '',
2703
+ '# Ensure logs directory exists',
2704
+ 'mkdir -p "$LOGS_DIR"',
2705
+ '',
2706
+ '# Read currentCommitID from meta.json',
2707
+ 'if [ -f "$META_FILE" ]; then',
2708
+ ' CURRENT=$(sed -n \'s/.*"currentCommitID"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p\' "$META_FILE")',
2709
+ 'else',
2710
+ ' echo "[$(date -Iseconds)] meta.json not found — run \'homegraph spec build\' or \'homegraph spec mine\' first" \\',
2711
+ ' >> "$LOGS_DIR"/evolve-hook.log',
2712
+ ' exit 0',
2713
+ 'fi',
2714
+ '',
2715
+ '# Count pending commits since last evolved commit',
2716
+ 'if [ -z "$CURRENT" ] || ! git rev-parse --quiet --verify "$CURRENT^{commit}" >/dev/null 2>&1; then',
2717
+ ' # First run or anchor commit no longer exists — trigger immediately',
2718
+ ' PENDING=$THRESHOLD',
2719
+ 'else',
2720
+ ' PENDING=$(git rev-list --count "${CURRENT}..HEAD" 2>/dev/null || echo 0)',
2721
+ 'fi',
2722
+ '',
2723
+ 'if [ "$PENDING" -lt "$THRESHOLD" ]; then',
2724
+ ' echo "[$(date -Iseconds)] Pending: $PENDING/$THRESHOLD — skipping" \\',
2725
+ ' >> "$LOGS_DIR"/evolve-hook.log',
2726
+ ' exit 0',
2727
+ 'fi',
2728
+ '',
2729
+ '# Threshold reached — trigger evolution (async, non-blocking)',
2513
2730
  '# Runtime guard: skip if homegraph is not available',
2514
2731
  `HOMEGRAPH_BIN="${homegraphBin}"`,
2515
2732
  'if [ -x "$HOMEGRAPH_BIN" ] || command -v homegraph >/dev/null 2>&1; then',
2516
2733
  ' "${HOMEGRAPH_BIN:-homegraph}" spec evolve process --path "$(pwd)" --json \\',
2517
- ` >> ${utils_1.SPEC_DATA_DIR}/logs/evolve-hook.log 2>&1 &`,
2734
+ ` >> "$LOGS_DIR"/evolve-hook.log 2>&1 &`,
2518
2735
  'fi',
2519
2736
  MARKER_END,
2520
2737
  ].join('\n');
@@ -2549,6 +2766,7 @@ function main() {
2549
2766
  fs.writeFileSync(hookPath, content);
2550
2767
  fs.chmodSync(hookPath, 0o755);
2551
2768
  success(`Post-commit hook installed at ${hookPath}`);
2769
+ info(`Threshold: ${commitThreshold} commit(s) — evolution triggers when pending commits reach this count`);
2552
2770
  info(`Logs written to ${utils_1.SPEC_DATA_DIR}/logs/evolve-hook.log`);
2553
2771
  }
2554
2772
  catch (err) {
@@ -2566,7 +2784,7 @@ function main() {
2566
2784
  .action(async (options) => {
2567
2785
  try {
2568
2786
  const repoPath = resolveSpecProjectPath(options.path);
2569
- const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/mining/git-scanner')));
2787
+ const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/git')));
2570
2788
  if (!isGitRepo(repoPath)) {
2571
2789
  error(`Not a git repository: ${repoPath}`);
2572
2790
  process.exit(1);
@@ -2634,7 +2852,6 @@ function main() {
2634
2852
  .command('process')
2635
2853
  .description('Process commits through the spec self-evolve pipeline since last evolve')
2636
2854
  .option('-p, --path <path>', 'Path to the repository')
2637
- .option('--db-path <path>', 'Path to the SQLite database file')
2638
2855
  .option('-j, --json', 'Output as JSON')
2639
2856
  .action(async (options) => {
2640
2857
  let db;
@@ -2644,50 +2861,61 @@ function main() {
2644
2861
  const { resolveDbPath } = await Promise.resolve().then(() => __importStar(require('../spec/utils')));
2645
2862
  const { initSpecSchema } = await Promise.resolve().then(() => __importStar(require('../spec/db/schema')));
2646
2863
  const { loadSpecConfig } = await Promise.resolve().then(() => __importStar(require('../spec/config')));
2647
- const { runBatchEvolvePipeline } = await Promise.resolve().then(() => __importStar(require('../spec/evolve/pipeline')));
2648
- const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/mining/git-scanner')));
2864
+ const { runEvolvePipeline } = await Promise.resolve().then(() => __importStar(require('../spec/evolve/pipeline')));
2865
+ const { isGitRepo } = await Promise.resolve().then(() => __importStar(require('../spec/git')));
2649
2866
  if (!isGitRepo(repoPath)) {
2650
2867
  error(`Not a git repository: ${repoPath}`);
2651
2868
  process.exit(1);
2652
2869
  }
2653
- const dbPath = resolveDbPath(repoPath, options.dbPath);
2870
+ const dbPath = resolveDbPath(repoPath);
2654
2871
  const created = createDatabase(dbPath);
2655
2872
  db = created.db;
2656
2873
  initSpecSchema(db);
2657
2874
  const config = loadSpecConfig(repoPath);
2658
- const llmConfig = config.llm;
2659
- if (!llmConfig) {
2660
- warn('LLM not configured — Path B (LLM-based spec evolution) will be skipped.');
2661
- warn('Only Path A (commit message scope GENERATE) will be processed.');
2875
+ const { resolveAgent } = await Promise.resolve().then(() => __importStar(require('../spec/llm/agents')));
2876
+ const codingAgent = resolveAgent();
2877
+ if (!config.llm && !codingAgent) {
2878
+ warn('No coding agent (Claude Code / Codex / DevEco Code) detected and LLM not configured — phase 3 (LLM-based spec evolution) will be skipped.');
2879
+ warn('Phase 1 (commit-spec graph construction) will still run.');
2662
2880
  warn('Configure LLM in .homegraph/commit4spec/configs.json for full functionality:\n' +
2663
2881
  '{\n' +
2664
2882
  ' "llm": {\n' +
2665
- ' "provider": "openai",\n' +
2666
- ' "apiKeyEnv": "OPENAI_API_KEY",\n' +
2667
- ' "model": "gpt-4o"\n' +
2883
+ ' "provider": "openai", // * "openai" or "anthropic"\n' +
2884
+ ' "apiKey": "sk-...", // * API key string (plain text)\n' +
2885
+ ' "apiKeyEnv": "OPENAI_API_KEY", // or read from env var (takes precedence)\n' +
2886
+ ' "model": "gpt-4o", // * model name\n' +
2887
+ ' "baseUrl": "https://...", // custom endpoint\n' +
2888
+ ' "temperature": 0.2, // creativity control (default: 0.2)\n' +
2889
+ ' "maxTokens": 20000 // max output tokens (default: 20000)\n' +
2668
2890
  ' }\n' +
2669
2891
  '}');
2670
2892
  }
2671
- const result = await runBatchEvolvePipeline(repoPath, db, llmConfig ?? undefined);
2893
+ else if (!config.llm && codingAgent) {
2894
+ info(`Using ${codingAgent.displayName} (headless) for phase 3 spec evolution — no LLM configuration needed.`);
2895
+ }
2896
+ else if (config.llm && codingAgent) {
2897
+ info(`Using ${codingAgent.displayName} (headless) for phase 3 spec evolution — configured LLM is kept as fallback.`);
2898
+ }
2899
+ const result = await runEvolvePipeline(repoPath, db, config);
2672
2900
  if (options.json) {
2673
2901
  console.log(JSON.stringify(result, null, 2));
2674
2902
  }
2675
2903
  else {
2676
- if (result.commitsProcessed === 0) {
2904
+ if (result.commitsScanned === 0) {
2677
2905
  console.log(chalk.green('No new commits to evolve.'));
2678
2906
  console.log(`Last evolved commit: ${result.fromCommit ? result.fromCommit.slice(0, 7) : 'none'}`);
2679
2907
  console.log(`Current HEAD: ${result.toCommit.slice(0, 7)}`);
2680
2908
  }
2681
2909
  else {
2682
- console.log(chalk.bold(`Evolve complete: ${result.commitsProcessed} commit(s) processed`));
2683
- console.log(`Range: ${result.fromCommit ? result.fromCommit.slice(0, 7) : 'none'} → ${result.toCommit.slice(0, 7)}`);
2910
+ console.log(chalk.bold(`Evolve complete: ${result.commitsScanned} commit(s) processed`));
2911
+ console.log(`Evolved to: ${result.toCommit.slice(0, 7)}`);
2684
2912
  if (result.metaUpdated) {
2685
2913
  console.log(chalk.green(`meta.json updated (currentCommitID = ${result.toCommit.slice(0, 7)})`));
2686
2914
  }
2687
- else if (result.failures > 0) {
2688
- console.log(chalk.yellow(`⚠ meta.json NOT updated — ${result.failures} commit(s) failed`));
2915
+ else if (result.phaseOneFailures > 0) {
2916
+ console.log(chalk.yellow(`⚠ meta.json NOT updated — ${result.phaseOneFailures} commit(s) failed`));
2689
2917
  }
2690
- else if (result.skippedCommits > 0) {
2918
+ else if (result.phaseOneSkipped > 0) {
2691
2919
  console.log(chalk.yellow('⚠ meta.json NOT updated — all commits were skipped (no Path A match, no LLM)'));
2692
2920
  }
2693
2921
  else {
@@ -2696,34 +2924,31 @@ function main() {
2696
2924
  // Show per-commit summary
2697
2925
  for (const r of result.perCommitResults) {
2698
2926
  let prefix;
2699
- if (r.skipped) {
2927
+ if (r.phaseOneSkipped) {
2700
2928
  prefix = chalk.yellow(' ⚠');
2701
2929
  }
2702
2930
  else {
2703
- prefix = r.persisted ? chalk.green(' ✓') : chalk.red(' ✗');
2931
+ prefix = r.matched ? chalk.green(' ✓') : chalk.red(' ✗');
2704
2932
  }
2705
2933
  console.log(`${prefix} ${r.commitHash.slice(0, 7)}`);
2706
- if (r.skipped) {
2707
- console.log(` skipped: ${r.skipReason}`);
2708
- }
2709
- if (r.isLogicChange) {
2710
- console.log(` logic change: ${r.logicCheckReason}`);
2934
+ if (r.phaseOneSkipped) {
2935
+ console.log(` skipped: ${r.phaseOneSkipReason}`);
2711
2936
  }
2712
- if (r.generateSpecId) {
2713
- console.log(` Path A - GENERATE ${r.generateSpecId}`);
2937
+ if (r.matchedSpecId) {
2938
+ console.log(` Path A - GENERATE ${r.matchedSpecId}`);
2714
2939
  }
2715
2940
  for (const ev of r.evolvedSpecs) {
2716
2941
  console.log(` ${ev.specId}: ${ev.action}`);
2717
2942
  }
2718
2943
  }
2719
2944
  // Aggregate summary
2720
- const totalFragments = result.perCommitResults.reduce((s, r) => s + r.fragmentsCount, 0);
2945
+ const totalFragments = result.perCommitResults.reduce((s, r) => s + r.fragmentsInserted, 0);
2721
2946
  const totalRelations = result.perCommitResults.reduce((s, r) => s + r.relationsCreated, 0);
2722
- if (result.skippedCommits > 0) {
2723
- console.log(chalk.yellow(`${result.skippedCommits} commit(s) skipped — no LLM configured, did not match Path A`));
2947
+ if (result.phaseOneSkipped > 0) {
2948
+ console.log(chalk.yellow(`${result.phaseOneSkipped} commit(s) skipped — no LLM configured, did not match Path A`));
2724
2949
  }
2725
- if (result.failures > 0) {
2726
- console.log(chalk.red(`${result.failures} commit(s) failed — see details above`));
2950
+ if (result.phaseOneFailures > 0) {
2951
+ console.log(chalk.red(`${result.phaseOneFailures} commit(s) failed — see details above`));
2727
2952
  }
2728
2953
  console.log(`Summary: fragments=${totalFragments}, relations=${totalRelations}`);
2729
2954
  }
@@ -2732,7 +2957,7 @@ function main() {
2732
2957
  catch (err) {
2733
2958
  const message = err instanceof Error ? err.message : String(err);
2734
2959
  if (message.includes('No meta.json found')) {
2735
- error("No meta.json found. Run 'homegraph spec mine' first.");
2960
+ error("No meta.json found. Run 'homegraph spec build/mine' first.");
2736
2961
  }
2737
2962
  else {
2738
2963
  error(`Evolve failed: ${message}`);
@@ -2867,6 +3092,7 @@ function main() {
2867
3092
  method,
2868
3093
  resolveLatest: () => up.resolveLatestVersion(),
2869
3094
  run: up.defaultRun,
3095
+ capture: up.defaultCapture,
2870
3096
  hasCommand: up.hasCommand,
2871
3097
  log: (m) => console.log(m),
2872
3098
  warn: (m) => warn(m),