homegraph 1.5.1 → 1.5.2

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 (258) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +305 -305
  3. package/dist/bin/homegraph.js +9 -9
  4. package/dist/db/index.js +36 -36
  5. package/dist/db/migrations.js +37 -37
  6. package/dist/db/queries.js +156 -156
  7. package/dist/db/schema.sql +203 -203
  8. package/dist/directory.js +5 -5
  9. package/dist/extraction/index.d.ts +1 -1
  10. package/dist/extraction/index.d.ts.map +1 -1
  11. package/dist/extraction/index.js +54 -43
  12. package/dist/extraction/index.js.map +1 -1
  13. package/dist/extraction/languages/arkts.d.ts +53 -6
  14. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  15. package/dist/extraction/languages/arkts.js +565 -65
  16. package/dist/extraction/languages/arkts.js.map +1 -1
  17. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  18. package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  19. package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  20. package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  21. package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  22. package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  23. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  24. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  25. package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +3 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/installer/instructions-template.js +9 -9
  30. package/dist/mcp/diff-impact.d.ts +131 -0
  31. package/dist/mcp/diff-impact.d.ts.map +1 -0
  32. package/dist/mcp/diff-impact.js +385 -0
  33. package/dist/mcp/diff-impact.js.map +1 -0
  34. package/dist/mcp/liveness-watchdog.js +51 -51
  35. package/dist/mcp/server-instructions.d.ts +1 -1
  36. package/dist/mcp/server-instructions.d.ts.map +1 -1
  37. package/dist/mcp/server-instructions.js +49 -47
  38. package/dist/mcp/server-instructions.js.map +1 -1
  39. package/dist/mcp/tools.d.ts +21 -5
  40. package/dist/mcp/tools.d.ts.map +1 -1
  41. package/dist/mcp/tools.js +305 -55
  42. package/dist/mcp/tools.js.map +1 -1
  43. package/dist/resolution/callback-synthesizer.d.ts +2 -1
  44. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  45. package/dist/resolution/callback-synthesizer.js +153 -53
  46. package/dist/resolution/callback-synthesizer.js.map +1 -1
  47. package/dist/resolution/frameworks/arkts-entry.d.ts.map +1 -1
  48. package/dist/resolution/frameworks/arkts-entry.js +20 -9
  49. package/dist/resolution/frameworks/arkts-entry.js.map +1 -1
  50. package/dist/resolution/index.d.ts.map +1 -1
  51. package/dist/resolution/index.js +1 -1
  52. package/dist/resolution/index.js.map +1 -1
  53. package/dist/resolution/memory-budget.d.ts +33 -0
  54. package/dist/resolution/memory-budget.d.ts.map +1 -1
  55. package/dist/resolution/memory-budget.js +58 -0
  56. package/dist/resolution/memory-budget.js.map +1 -1
  57. package/dist/resolution/resolver-pool.d.ts +2 -0
  58. package/dist/resolution/resolver-pool.d.ts.map +1 -1
  59. package/dist/resolution/resolver-pool.js +4 -0
  60. package/dist/resolution/resolver-pool.js.map +1 -1
  61. package/dist/spec/db/commit-node.js +4 -4
  62. package/dist/spec/db/fragment-node.js +10 -10
  63. package/dist/spec/db/fts.js +8 -8
  64. package/dist/spec/db/relations.js +88 -88
  65. package/dist/spec/db/schema.js +6 -6
  66. package/dist/spec/db/schema.sql +121 -121
  67. package/dist/spec/db/spec-node.js +4 -4
  68. package/dist/spec/llm/prompts.js +53 -53
  69. package/dist/ui/shimmer-progress.d.ts.map +1 -1
  70. package/dist/ui/shimmer-progress.js +4 -1
  71. package/dist/ui/shimmer-progress.js.map +1 -1
  72. package/package.json +61 -62
  73. package/dist/extraction/languages/arkts-viewtree.d.ts +0 -22
  74. package/dist/extraction/languages/arkts-viewtree.d.ts.map +0 -1
  75. package/dist/extraction/languages/arkts-viewtree.js +0 -133
  76. package/dist/extraction/languages/arkts-viewtree.js.map +0 -1
  77. package/dist/reasoning/config.d.ts +0 -45
  78. package/dist/reasoning/config.d.ts.map +0 -1
  79. package/dist/reasoning/config.js +0 -171
  80. package/dist/reasoning/config.js.map +0 -1
  81. package/dist/reasoning/credentials.d.ts +0 -5
  82. package/dist/reasoning/credentials.d.ts.map +0 -1
  83. package/dist/reasoning/credentials.js +0 -83
  84. package/dist/reasoning/credentials.js.map +0 -1
  85. package/dist/reasoning/login.d.ts +0 -21
  86. package/dist/reasoning/login.d.ts.map +0 -1
  87. package/dist/reasoning/login.js +0 -85
  88. package/dist/reasoning/login.js.map +0 -1
  89. package/dist/reasoning/reasoner.d.ts +0 -43
  90. package/dist/reasoning/reasoner.d.ts.map +0 -1
  91. package/dist/reasoning/reasoner.js +0 -308
  92. package/dist/reasoning/reasoner.js.map +0 -1
  93. package/dist/spec/evolve/llm-client.d.ts +0 -50
  94. package/dist/spec/evolve/llm-client.d.ts.map +0 -1
  95. package/dist/spec/evolve/llm-client.js +0 -176
  96. package/dist/spec/evolve/llm-client.js.map +0 -1
  97. package/dist/spec/evolve/logic-checker.d.ts +0 -12
  98. package/dist/spec/evolve/logic-checker.d.ts.map +0 -1
  99. package/dist/spec/evolve/logic-checker.js +0 -24
  100. package/dist/spec/evolve/logic-checker.js.map +0 -1
  101. package/dist/spec/llm/index.d.ts +0 -3
  102. package/dist/spec/llm/index.d.ts.map +0 -1
  103. package/dist/spec/llm/index.js +0 -11
  104. package/dist/spec/llm/index.js.map +0 -1
  105. package/dist/spec/mining/diff-parser.d.ts +0 -33
  106. package/dist/spec/mining/diff-parser.d.ts.map +0 -1
  107. package/dist/spec/mining/diff-parser.js +0 -166
  108. package/dist/spec/mining/diff-parser.js.map +0 -1
  109. package/dist/spec/mining/git-scanner.d.ts +0 -103
  110. package/dist/spec/mining/git-scanner.d.ts.map +0 -1
  111. package/dist/spec/mining/git-scanner.js +0 -307
  112. package/dist/spec/mining/git-scanner.js.map +0 -1
  113. package/dist/spec/mining/pipeline.d.ts +0 -53
  114. package/dist/spec/mining/pipeline.d.ts.map +0 -1
  115. package/dist/spec/mining/pipeline.js +0 -178
  116. package/dist/spec/mining/pipeline.js.map +0 -1
  117. package/dist/spec/mining/scope-resolver.d.ts +0 -45
  118. package/dist/spec/mining/scope-resolver.d.ts.map +0 -1
  119. package/dist/spec/mining/scope-resolver.js +0 -103
  120. package/dist/spec/mining/scope-resolver.js.map +0 -1
  121. package/dist/spec/mining/spec-extractor.d.ts +0 -69
  122. package/dist/spec/mining/spec-extractor.d.ts.map +0 -1
  123. package/dist/spec/mining/spec-extractor.js +0 -369
  124. package/dist/spec/mining/spec-extractor.js.map +0 -1
  125. package/dist/spec/utils.d.ts +0 -167
  126. package/dist/spec/utils.d.ts.map +0 -1
  127. package/dist/spec/utils.js +0 -463
  128. package/dist/spec/utils.js.map +0 -1
  129. package/scripts/_tmp-cfwk-resolve.log +0 -0
  130. package/scripts/_tmp-cfwk-sig.log +0 -0
  131. package/scripts/_tmp-cfwk-vt.log +0 -0
  132. package/scripts/add-lang/bench.sh +0 -60
  133. package/scripts/add-lang/check-grammar.mjs +0 -75
  134. package/scripts/add-lang/dump-ast.mjs +0 -103
  135. package/scripts/add-lang/verify-extraction.mjs +0 -70
  136. package/scripts/agent-eval/ab-adoption.sh +0 -91
  137. package/scripts/agent-eval/ab-hook.sh +0 -86
  138. package/scripts/agent-eval/ab-impl.sh +0 -78
  139. package/scripts/agent-eval/ab-new-vs-baseline.sh +0 -102
  140. package/scripts/agent-eval/ab-sufficiency.sh +0 -78
  141. package/scripts/agent-eval/arms-F.sh +0 -21
  142. package/scripts/agent-eval/arms-matrix.sh +0 -37
  143. package/scripts/agent-eval/audit.sh +0 -68
  144. package/scripts/agent-eval/bench-readme.sh +0 -28
  145. package/scripts/agent-eval/bench-why-repo.sh +0 -22
  146. package/scripts/agent-eval/block-read-hook.sh +0 -19
  147. package/scripts/agent-eval/hook-settings.json +0 -15
  148. package/scripts/agent-eval/itrun.sh +0 -120
  149. package/scripts/agent-eval/offload-eval-3arm.sh +0 -72
  150. package/scripts/agent-eval/offload-eval-cost.mjs +0 -133
  151. package/scripts/agent-eval/offload-eval-effort.mjs +0 -108
  152. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +0 -25
  153. package/scripts/agent-eval/offload-eval-frontload.sh +0 -47
  154. package/scripts/agent-eval/offload-eval-ground-truth.json +0 -18
  155. package/scripts/agent-eval/offload-eval-hook.mjs +0 -84
  156. package/scripts/agent-eval/offload-eval-judge.mjs +0 -103
  157. package/scripts/agent-eval/offload-eval-matrix.sh +0 -20
  158. package/scripts/agent-eval/offload-eval-metrics.mjs +0 -94
  159. package/scripts/agent-eval/offload-eval-refs1.sh +0 -50
  160. package/scripts/agent-eval/offload-eval-setup.sh +0 -24
  161. package/scripts/agent-eval/offload-eval-styles.sh +0 -72
  162. package/scripts/agent-eval/offload-eval-summarize.mjs +0 -68
  163. package/scripts/agent-eval/offload-eval.md +0 -76
  164. package/scripts/agent-eval/parse-arms.mjs +0 -116
  165. package/scripts/agent-eval/parse-bench-readme.mjs +0 -84
  166. package/scripts/agent-eval/parse-run.mjs +0 -45
  167. package/scripts/agent-eval/parse-session.mjs +0 -93
  168. package/scripts/agent-eval/probe-context.mjs +0 -21
  169. package/scripts/agent-eval/probe-explore.mjs +0 -40
  170. package/scripts/agent-eval/probe-node.mjs +0 -20
  171. package/scripts/agent-eval/probe-sweep.mjs +0 -119
  172. package/scripts/agent-eval/probe-trace.mjs +0 -20
  173. package/scripts/agent-eval/redirect-read-hook.sh +0 -38
  174. package/scripts/agent-eval/repro-concurrent-explore.mjs +0 -119
  175. package/scripts/agent-eval/repro-daemon-clients.mjs +0 -125
  176. package/scripts/agent-eval/run-agent.sh +0 -34
  177. package/scripts/agent-eval/run-all.sh +0 -75
  178. package/scripts/agent-eval/run-arms.sh +0 -56
  179. package/scripts/agent-eval/seq-matrix.mjs +0 -137
  180. package/scripts/bench-arkts-init-rss.log +0 -0
  181. package/scripts/build-bundle.sh +0 -123
  182. package/scripts/exp_boundary_eval/README.md +0 -247
  183. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  184. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
  185. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  186. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
  187. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
  188. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
  189. package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
  190. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  191. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
  192. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  193. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
  194. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  195. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
  196. package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
  197. package/scripts/exp_boundary_eval/_test_mcp_chain.py +0 -78
  198. package/scripts/exp_boundary_eval/_test_stdin.py +0 -8
  199. package/scripts/exp_boundary_eval/_utils.py +0 -1116
  200. package/scripts/exp_boundary_eval/analyze.py +0 -1313
  201. package/scripts/exp_boundary_eval/deveco_arm.py +0 -519
  202. package/scripts/exp_boundary_eval/run_all.py +0 -378
  203. package/scripts/exp_boundary_eval/run_one.py +0 -165
  204. package/scripts/exp_boundary_eval/run_session.py +0 -158
  205. package/scripts/exp_boundary_eval/setup.py +0 -120
  206. package/scripts/exp_boundary_eval/win_mcp_launcher.py +0 -73
  207. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +0 -36
  208. package/scripts/exp_boundary_eval/win_node_launcher.py +0 -24
  209. package/scripts/extract-release-notes.mjs +0 -130
  210. package/scripts/local-install.sh +0 -41
  211. package/scripts/npm-sdk.js +0 -75
  212. package/scripts/npm-shim.js +0 -275
  213. package/scripts/ohos-sdk-publish.mjs +0 -133
  214. package/scripts/pack-npm.sh +0 -119
  215. package/scripts/prepare-release.mjs +0 -270
  216. package/scripts/probe-arkts-mem-why-run.log +0 -0
  217. package/scripts/probe-banner-livecard-ir.log +0 -0
  218. package/scripts/probe-cfwk-ast.stderr.log +0 -0
  219. package/scripts/probe-cfwk-ast.stdout.log +0 -0
  220. package/scripts/probe-cfwk-attr-shape.log +0 -0
  221. package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
  222. package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
  223. package/scripts/probe-cfwk-cvc.stderr.log +0 -0
  224. package/scripts/probe-cfwk-cvc.stdout.log +0 -0
  225. package/scripts/probe-cfwk-diag2.log +0 -0
  226. package/scripts/probe-cfwk-diag3.log +0 -0
  227. package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
  228. package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
  229. package/scripts/probe-cfwk-fileresult.log +0 -0
  230. package/scripts/probe-cfwk-fix.stderr.log +0 -0
  231. package/scripts/probe-cfwk-fix.stdout.log +0 -0
  232. package/scripts/probe-cfwk-fix2.stderr.log +0 -0
  233. package/scripts/probe-cfwk-fix2.stdout.log +0 -0
  234. package/scripts/probe-cfwk-fix3.stderr.log +0 -0
  235. package/scripts/probe-cfwk-fix3.stdout.log +0 -0
  236. package/scripts/probe-cfwk-foreach.log +0 -0
  237. package/scripts/probe-cfwk-getmethod-throw.log +0 -0
  238. package/scripts/probe-cfwk-hg-extract.log +0 -0
  239. package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
  240. package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
  241. package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
  242. package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
  243. package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
  244. package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
  245. package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
  246. package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
  247. package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
  248. package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
  249. package/scripts/probe-cfwk-resolve-sim.log +0 -0
  250. package/scripts/probe-cfwk-tree-shape.log +0 -0
  251. package/scripts/probe-cfwk-walk-abort.log +0 -0
  252. package/scripts/probe-cfwk.log +0 -0
  253. package/scripts/probe-force-index.log +0 -0
  254. package/scripts/probe-no-force-index.log +0 -0
  255. package/scripts/probe-samefile-ir.stderr.log +0 -0
  256. package/scripts/probe-samefile-ir.stdout.log +0 -224
  257. package/scripts/probe-sdk-vs-project.log +0 -0
  258. package/scripts/probe-viewtree-downgrade.log +0 -0
@@ -1,53 +0,0 @@
1
- /**
2
- * Mining pipeline orchestrator — main entry point for reverse-mining spec
3
- * knowledge from Git history.
4
- *
5
- * Replaces `commit4spec/reverse_engineer/pipeline.py`. Discovers spec↔commit
6
- * pairs via `scan()`, persists them into the SQLite knowledge graph, and
7
- * writes a `.homegraph/commit4spec/meta.json` anchor so the self-evolve pipeline can
8
- * pick up where mining left off.
9
- *
10
- * @module spec/mining/pipeline
11
- */
12
- import { SqliteDatabase } from '../../db/sqlite-adapter';
13
- import { SpecConfig } from '../config';
14
- export interface MiningResult {
15
- specsFound: number;
16
- commitsFound: number;
17
- fragmentsFound: number;
18
- relationsCreated: number;
19
- totalEntries: number;
20
- skippedEntries: Array<{
21
- specId: string;
22
- reason: string;
23
- }>;
24
- }
25
- /**
26
- * Run the full reverse-mining pipeline.
27
- *
28
- * Steps (ported from `pipeline.py:49-151`):
29
- *
30
- * 1. Initialise the spec knowledge-graph schema in the database.
31
- * 2. Discover all specs on disk (for the `totalEntries` count).
32
- * 3. Scan the repository for spec↔commit pairs.
33
- * 4. Sort pairs by commit timestamp ascending so that `INSERT OR REPLACE`
34
- * gives the most-recent commit the final word for each spec node.
35
- * 5. Process each pair:
36
- * - Insert a SpecNode (once per specId; deduplicated by commit timestamp).
37
- * - Insert a CommitNode (once per commit hash).
38
- * - Insert a SUMMARIZED_FROM relation.
39
- * - Parse the commit diff into code fragments and persist them.
40
- * 6. Build a list of specs discovered on disk but never matched to a commit.
41
- * 7. Write `.homegraph/commit4spec/meta.json`.
42
- * 8. Return the `MiningResult` with all counts.
43
- *
44
- * Edge cases:
45
- * - Empty pairs → zero counts, write meta anyway, return result.
46
- * - Pair with commit metadata but no spec metadata → commit and fragments
47
- * are still persisted; SpecNode and spec_commit_relation are skipped.
48
- * - Pair with spec metadata but no commit metadata → entire pair is skipped.
49
- * - Same spec in multiple pairs → only counted once in `specsFound`, but
50
- * every commit relation is created.
51
- */
52
- export declare function runMiningPipeline(repoPath: string, specStoragePath: string, db: SqliteDatabase, config?: SpecConfig): MiningResult;
53
- //# sourceMappingURL=pipeline.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/spec/mining/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAC;AAmBvD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3D;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,EAAE,EAAE,cAAc,EAClB,MAAM,CAAC,EAAE,UAAU,GAClB,YAAY,CAwId"}
@@ -1,178 +0,0 @@
1
- "use strict";
2
- /**
3
- * Mining pipeline orchestrator — main entry point for reverse-mining spec
4
- * knowledge from Git history.
5
- *
6
- * Replaces `commit4spec/reverse_engineer/pipeline.py`. Discovers spec↔commit
7
- * pairs via `scan()`, persists them into the SQLite knowledge graph, and
8
- * writes a `.homegraph/commit4spec/meta.json` anchor so the self-evolve pipeline can
9
- * pick up where mining left off.
10
- *
11
- * @module spec/mining/pipeline
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.runMiningPipeline = runMiningPipeline;
15
- const config_1 = require("../config");
16
- const utils_1 = require("../utils");
17
- const schema_1 = require("../db/schema");
18
- const spec_node_1 = require("../db/spec-node");
19
- const commit_node_1 = require("../db/commit-node");
20
- const fragment_node_1 = require("../db/fragment-node");
21
- const relations_1 = require("../db/relations");
22
- const child_process_1 = require("child_process");
23
- const git_scanner_1 = require("./git-scanner");
24
- const diff_parser_1 = require("./diff-parser");
25
- const errors_1 = require("../../errors");
26
- // ---------------------------------------------------------------------------
27
- // runMiningPipeline
28
- // ---------------------------------------------------------------------------
29
- /**
30
- * Run the full reverse-mining pipeline.
31
- *
32
- * Steps (ported from `pipeline.py:49-151`):
33
- *
34
- * 1. Initialise the spec knowledge-graph schema in the database.
35
- * 2. Discover all specs on disk (for the `totalEntries` count).
36
- * 3. Scan the repository for spec↔commit pairs.
37
- * 4. Sort pairs by commit timestamp ascending so that `INSERT OR REPLACE`
38
- * gives the most-recent commit the final word for each spec node.
39
- * 5. Process each pair:
40
- * - Insert a SpecNode (once per specId; deduplicated by commit timestamp).
41
- * - Insert a CommitNode (once per commit hash).
42
- * - Insert a SUMMARIZED_FROM relation.
43
- * - Parse the commit diff into code fragments and persist them.
44
- * 6. Build a list of specs discovered on disk but never matched to a commit.
45
- * 7. Write `.homegraph/commit4spec/meta.json`.
46
- * 8. Return the `MiningResult` with all counts.
47
- *
48
- * Edge cases:
49
- * - Empty pairs → zero counts, write meta anyway, return result.
50
- * - Pair with commit metadata but no spec metadata → commit and fragments
51
- * are still persisted; SpecNode and spec_commit_relation are skipped.
52
- * - Pair with spec metadata but no commit metadata → entire pair is skipped.
53
- * - Same spec in multiple pairs → only counted once in `specsFound`, but
54
- * every commit relation is created.
55
- */
56
- function runMiningPipeline(repoPath, specStoragePath, db, config) {
57
- // Resolve config once — guarantee a valid SpecConfig for downstream consumers.
58
- const resolvedConfig = config ?? (0, config_1.loadSpecConfig)(repoPath);
59
- // ---- Step 1: init schema ----
60
- (0, schema_1.initSpecSchema)(db);
61
- // ---- Step 2: discover specs (for totalEntries) ----
62
- const allEntries = (0, utils_1.discoverSpecs)(specStoragePath);
63
- const totalEntries = allEntries.length;
64
- // ---- Step 3: scan for pairs ----
65
- const pairs = (0, git_scanner_1.scan)(repoPath, specStoragePath, resolvedConfig);
66
- // ---- Step 4: sort by commit timestamp ascending (oldest first) ----
67
- // INSERT OR REPLACE is used for SpecNode — when the same spec appears
68
- // in multiple pairs, the LAST write (most-recent commit) naturally wins.
69
- pairs.sort((a, b) => {
70
- const aTs = a.commitMetadata?.timestamp ?? 0;
71
- const bTs = b.commitMetadata?.timestamp ?? 0;
72
- return aTs - bTs;
73
- });
74
- // ---- Step 5: process pairs ----
75
- const writtenSpecIds = new Set();
76
- const seenCommitHashes = new Set();
77
- let specsFound = 0;
78
- let commitsFound = 0;
79
- let fragmentsFound = 0;
80
- let relationsCreated = 0;
81
- for (const pair of pairs) {
82
- // Skip if no commit metadata (no data to insert).
83
- const cm = pair.commitMetadata;
84
- if (!cm) {
85
- continue;
86
- }
87
- const sm = pair.specMetadata;
88
- // Insert SpecNode if spec metadata is present.
89
- // INSERT OR REPLACE lets the most-recent commit (last in ascending
90
- // order) overwrite the timestamp. We still track writtenSpecIds to
91
- // correctly count distinct specs (not overwrites).
92
- if (sm) {
93
- (0, errors_1.logDebug)('Processing pair: inserting SpecNode', {
94
- specId: sm.specId,
95
- title: sm.title,
96
- });
97
- (0, spec_node_1.insertSpecNode)(db, {
98
- id: sm.specId,
99
- title: sm.title,
100
- subtitles: sm.subtitles,
101
- status: 'active',
102
- version: 1,
103
- filePath: sm.filePath,
104
- timestamp: cm.timestamp,
105
- });
106
- if (!writtenSpecIds.has(pair.specId)) {
107
- writtenSpecIds.add(pair.specId);
108
- specsFound++;
109
- }
110
- }
111
- // Insert CommitNode if not yet seen.
112
- if (!seenCommitHashes.has(cm.hash)) {
113
- (0, commit_node_1.insertCommitNode)(db, {
114
- hash: cm.hash,
115
- message: cm.message,
116
- author: cm.author,
117
- timestamp: cm.timestamp,
118
- });
119
- seenCommitHashes.add(cm.hash);
120
- commitsFound++;
121
- }
122
- // Insert spec_commit_relation (only when spec metadata exists).
123
- if (sm) {
124
- (0, relations_1.insertSpecCommitRelation)(db, pair.specId, cm.hash, 'SUMMARIZED_FROM');
125
- relationsCreated++;
126
- }
127
- // ---- Analyze diff and insert fragments ----
128
- const preFetchedDiff = (0, git_scanner_1.getCommitDiff)(repoPath, cm.hash);
129
- const fragments = (0, diff_parser_1.analyzeCommitDiff)(repoPath, cm.hash, preFetchedDiff);
130
- for (const frag of fragments) {
131
- // insertCodeFragment auto-generates an id when the `id` field is empty.
132
- const inserted = (0, fragment_node_1.insertCodeFragment)(db, {
133
- id: '',
134
- changeType: frag.changeType,
135
- filePath: frag.filePath,
136
- startLine: frag.startLine,
137
- endLine: frag.endLine,
138
- codeDiff: frag.codeDiff,
139
- });
140
- fragmentsFound++;
141
- (0, relations_1.insertCommitFragmentRelation)(db, cm.hash, inserted.id);
142
- relationsCreated++;
143
- }
144
- }
145
- // ---- Step 6: build skipped entries ----
146
- const skippedEntries = allEntries
147
- .filter((e) => !writtenSpecIds.has(e.specId))
148
- .map((e) => ({ specId: e.specId, reason: 'No matching commits found' }));
149
- for (const skipped of skippedEntries) {
150
- (0, errors_1.logWarn)('Spec discovered on disk but no matching commits found', {
151
- specId: skipped.specId,
152
- });
153
- }
154
- // ---- Step 7: write meta ----
155
- let headHash;
156
- try {
157
- headHash = (0, child_process_1.execFileSync)('git', ['rev-parse', 'HEAD'], {
158
- cwd: repoPath,
159
- encoding: 'utf8',
160
- stdio: ['ignore', 'pipe', 'ignore'],
161
- windowsHide: true,
162
- }).trim();
163
- }
164
- catch {
165
- headHash = undefined;
166
- }
167
- (0, utils_1.writeMeta)(repoPath, specStoragePath, headHash);
168
- // ---- Step 8: return result ----
169
- return {
170
- specsFound,
171
- commitsFound,
172
- fragmentsFound,
173
- relationsCreated,
174
- totalEntries,
175
- skippedEntries,
176
- };
177
- }
178
- //# sourceMappingURL=pipeline.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/spec/mining/pipeline.ts"],"names":[],"mappings":"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"}
@@ -1,45 +0,0 @@
1
- /**
2
- * Commit message scope parsing and resolution.
3
- *
4
- * Replaces `commit4spec/reverse_engineer/scope_resolver.py`.
5
- * Extracts conventional-commit scopes, normalizes them, and resolves them to
6
- * spec IDs found on disk.
7
- *
8
- * @module spec/mining/scope-resolver
9
- */
10
- import { SpecConfig } from '../config';
11
- /**
12
- * Extract a scope from a commit message using the configured regex.
13
- *
14
- * Only searches the **first line** of the commit message. Returns the
15
- * contents of the first capture group (the scope), or `null` when there is
16
- * no match or the regex has no capture group.
17
- */
18
- export declare function extractScope(message: string, scopeRegex: string): string | null;
19
- /**
20
- * Normalize a scope string.
21
- *
22
- * Steps applied in order:
23
- *
24
- * 1. **Strip prefixes** — for each prefix in `stripPrefixes`, if `scope`
25
- * starts with it, remove it and stop (only the first matching prefix is
26
- * stripped).
27
- * 2. **Lowercase** — if `lowercase` is `true`, convert to lower case.
28
- * 3. **Pad spec number** — if `padSpecNumber` is `true`, match the pattern
29
- * `/^spec(\d+)$/i` and zero-pad the numeric portion to 2 digits
30
- * (e.g. `spec3` → `spec03`).
31
- */
32
- export declare function normalizeScope(scope: string, config: {
33
- stripPrefixes: string[];
34
- lowercase: boolean;
35
- padSpecNumber: boolean;
36
- }): string;
37
- /**
38
- * Extract a scope from a commit message, normalize it, then check whether the
39
- * resulting spec ID exists on disk in `specStoragePath`.
40
- *
41
- * Returns the normalized spec ID when the scope resolves to an existing spec,
42
- * otherwise `null`.
43
- */
44
- export declare function resolveScopeToSpec(message: string, specStoragePath: string, config: SpecConfig): string | null;
45
- //# sourceMappingURL=scope-resolver.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scope-resolver.d.ts","sourceRoot":"","sources":["../../../src/spec/mining/scope-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAQvC;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkB/E;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,GAC9E,MAAM,CAyBR;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,UAAU,GACjB,MAAM,GAAG,IAAI,CAYf"}
@@ -1,103 +0,0 @@
1
- "use strict";
2
- /**
3
- * Commit message scope parsing and resolution.
4
- *
5
- * Replaces `commit4spec/reverse_engineer/scope_resolver.py`.
6
- * Extracts conventional-commit scopes, normalizes them, and resolves them to
7
- * spec IDs found on disk.
8
- *
9
- * @module spec/mining/scope-resolver
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.extractScope = extractScope;
13
- exports.normalizeScope = normalizeScope;
14
- exports.resolveScopeToSpec = resolveScopeToSpec;
15
- const utils_1 = require("../utils");
16
- const errors_1 = require("../../errors");
17
- // ---------------------------------------------------------------------------
18
- // extractScope
19
- // ---------------------------------------------------------------------------
20
- /**
21
- * Extract a scope from a commit message using the configured regex.
22
- *
23
- * Only searches the **first line** of the commit message. Returns the
24
- * contents of the first capture group (the scope), or `null` when there is
25
- * no match or the regex has no capture group.
26
- */
27
- function extractScope(message, scopeRegex) {
28
- const firstLine = message.split('\n', 1)[0] ?? '';
29
- let regex;
30
- try {
31
- regex = new RegExp(scopeRegex);
32
- }
33
- catch {
34
- (0, errors_1.logDebug)('extractScope: invalid regex from config, returning null', {
35
- scopeRegex,
36
- });
37
- return null;
38
- }
39
- const match = regex.exec(firstLine);
40
- if (match && match[1] !== undefined) {
41
- return match[1];
42
- }
43
- return null;
44
- }
45
- // ---------------------------------------------------------------------------
46
- // normalizeScope
47
- // ---------------------------------------------------------------------------
48
- /**
49
- * Normalize a scope string.
50
- *
51
- * Steps applied in order:
52
- *
53
- * 1. **Strip prefixes** — for each prefix in `stripPrefixes`, if `scope`
54
- * starts with it, remove it and stop (only the first matching prefix is
55
- * stripped).
56
- * 2. **Lowercase** — if `lowercase` is `true`, convert to lower case.
57
- * 3. **Pad spec number** — if `padSpecNumber` is `true`, match the pattern
58
- * `/^spec(\d+)$/i` and zero-pad the numeric portion to 2 digits
59
- * (e.g. `spec3` → `spec03`).
60
- */
61
- function normalizeScope(scope, config) {
62
- let normalized = scope;
63
- // Step 1: strip the first matching prefix
64
- for (const prefix of config.stripPrefixes) {
65
- if (normalized.startsWith(prefix)) {
66
- normalized = normalized.slice(prefix.length);
67
- break;
68
- }
69
- }
70
- // Step 2: lowercase
71
- if (config.lowercase) {
72
- normalized = normalized.toLowerCase();
73
- }
74
- // Step 3: pad spec number (e.g. spec3 → spec03)
75
- if (config.padSpecNumber) {
76
- const m = /^spec(\d+)$/i.exec(normalized);
77
- if (m && m[1] !== undefined) {
78
- normalized = `spec${m[1].padStart(2, '0')}`;
79
- }
80
- }
81
- return normalized;
82
- }
83
- // ---------------------------------------------------------------------------
84
- // resolveScopeToSpec
85
- // ---------------------------------------------------------------------------
86
- /**
87
- * Extract a scope from a commit message, normalize it, then check whether the
88
- * resulting spec ID exists on disk in `specStoragePath`.
89
- *
90
- * Returns the normalized spec ID when the scope resolves to an existing spec,
91
- * otherwise `null`.
92
- */
93
- function resolveScopeToSpec(message, specStoragePath, config) {
94
- const scope = extractScope(message, config.commitScope.scopeRegex);
95
- if (!scope) {
96
- return null;
97
- }
98
- const normalized = normalizeScope(scope, config.commitScope.normalize);
99
- const entries = (0, utils_1.discoverSpecs)(specStoragePath);
100
- const specIds = new Set(entries.map((e) => e.specId));
101
- return specIds.has(normalized) ? normalized : null;
102
- }
103
- //# sourceMappingURL=scope-resolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scope-resolver.js","sourceRoot":"","sources":["../../../src/spec/mining/scope-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAiBH,oCAkBC;AAmBD,wCA4BC;AAaD,gDAgBC;AA5GD,oCAAyC;AACzC,yCAAwC;AAExC,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAgB,YAAY,CAAC,OAAe,EAAE,UAAkB;IAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,IAAA,iBAAQ,EAAC,yDAAyD,EAAE;YAClE,UAAU;SACX,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEpC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,SAAgB,cAAc,CAC5B,KAAa,EACb,MAA+E;IAE/E,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,0CAA0C;IAC1C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1C,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM;QACR,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,gDAAgD;IAChD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5B,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,OAAe,EACf,eAAuB,EACvB,MAAkB;IAElB,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAEvE,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,eAAe,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtD,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC"}
@@ -1,69 +0,0 @@
1
- /**
2
- * Spec file discovery and metadata extraction.
3
- *
4
- * Replaces `commit4spec/reverse_engineer/spec_extractor.py`.
5
- * Discovers spec files in a storage directory and extracts structured
6
- * metadata (title, subtitles, commit hash from commit-info.md).
7
- *
8
- * @module spec/mining/spec-extractor
9
- */
10
- import { SpecConfig } from '../config';
11
- export interface SpecMetadata {
12
- specId: string;
13
- title: string;
14
- subtitles: string[];
15
- commitHash: string | null;
16
- filePath: string;
17
- type: 'directory' | 'flat-file';
18
- }
19
- export interface SupplementaryDoc {
20
- path: string;
21
- content: string;
22
- }
23
- /**
24
- * Parse ATX headings from markdown content and build breadcrumb-path strings
25
- * with content previews.
26
- *
27
- * Algorithm (ported from `spec_extractor.py:50-88`):
28
- *
29
- * 1. Find all `#` … `######` headings (ATX-style) and their line positions.
30
- * 2. Walk through headings, maintaining a breadcrumb stack — pop until the
31
- * stack is shorter than the current heading's level, then push the new
32
- * heading text.
33
- * 3. For each heading, collect the "direct content" lines — non-heading,
34
- * non-empty lines between this heading and the next heading of equal or
35
- * higher level (or EOF).
36
- * 4. Skip headings that have sub-headings but no direct content.
37
- * 5. Build a display string: `breadcrumb_path - first_direct_content_line`.
38
- * 6. Strip `SPEC` suffix from level-1 (root) breadcrumb parts.
39
- * 7. Truncate the preview to `maxContentLen` characters, appending `…`
40
- * when truncated.
41
- *
42
- * @param content - Raw markdown string.
43
- * @param maxContentLen - Max characters for the content preview (default 200).
44
- * @returns Array of formatted heading strings.
45
- */
46
- export declare function extractMarkdownHeadings(content: string, maxContentLen?: number): string[];
47
- /**
48
- * Discover and extract metadata for a single spec, given its storage location
49
- * and directory name.
50
- *
51
- * Ported from `spec_extractor.py:177-237`.
52
- *
53
- * Two discovery branches are attempted in order:
54
- *
55
- * - **Flat-file**: checks `{specStoragePath}/{specDirName}.md`. If it exists,
56
- * reads it and produces metadata with `type: 'flat-file'`.
57
- * - **Directory**: checks `{specStoragePath}/{specDirName}/`. If it exists,
58
- * searches for a primary document using `config.discovery.primaryDocCandidates`,
59
- * reads it, and produces metadata with `type: 'directory'`.
60
- *
61
- * Returns `null` when neither branch yields a readable spec.
62
- *
63
- * @param specStoragePath - Root directory where specs are stored.
64
- * @param specDirName - Name of the spec (e.g. "spec03", "auth-module").
65
- * @param config - Optional full `SpecConfig`; falls back to defaults
66
- * when omitted (discovery config resolved at call site).
67
- */
68
- export declare function extractSpecMetadata(specStoragePath: string, specDirName: string, config?: SpecConfig): SpecMetadata | null;
69
- //# sourceMappingURL=spec-extractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec-extractor.d.ts","sourceRoot":"","sources":["../../../src/spec/mining/spec-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAuC,MAAM,WAAW,CAAC;AAQ5E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,aAAa,GAAE,MAAY,GAC1B,MAAM,EAAE,CAyFV;AA0JD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,UAAU,GAClB,YAAY,GAAG,IAAI,CAiFrB"}