homegraph 1.5.0 → 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 (213) hide show
  1. package/dist/bin/command-supervision.d.ts.map +1 -1
  2. package/dist/bin/command-supervision.js +7 -4
  3. package/dist/bin/command-supervision.js.map +1 -1
  4. package/dist/extraction/index.d.ts +1 -1
  5. package/dist/extraction/index.d.ts.map +1 -1
  6. package/dist/extraction/index.js +54 -43
  7. package/dist/extraction/index.js.map +1 -1
  8. package/dist/extraction/languages/arkts.d.ts +69 -12
  9. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  10. package/dist/extraction/languages/arkts.js +739 -86
  11. package/dist/extraction/languages/arkts.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/mcp/diff-impact.d.ts +131 -0
  16. package/dist/mcp/diff-impact.d.ts.map +1 -0
  17. package/dist/mcp/diff-impact.js +385 -0
  18. package/dist/mcp/diff-impact.js.map +1 -0
  19. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  20. package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  21. package/dist/mcp/liveness-watchdog.js +134 -22
  22. package/dist/mcp/liveness-watchdog.js.map +1 -1
  23. package/dist/mcp/server-instructions.d.ts +1 -1
  24. package/dist/mcp/server-instructions.d.ts.map +1 -1
  25. package/dist/mcp/server-instructions.js +2 -0
  26. package/dist/mcp/server-instructions.js.map +1 -1
  27. package/dist/mcp/tools.d.ts +21 -5
  28. package/dist/mcp/tools.d.ts.map +1 -1
  29. package/dist/mcp/tools.js +305 -55
  30. package/dist/mcp/tools.js.map +1 -1
  31. package/dist/resolution/callback-synthesizer.d.ts +2 -1
  32. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  33. package/dist/resolution/callback-synthesizer.js +153 -53
  34. package/dist/resolution/callback-synthesizer.js.map +1 -1
  35. package/dist/resolution/frameworks/arkts-entry.d.ts.map +1 -1
  36. package/dist/resolution/frameworks/arkts-entry.js +20 -9
  37. package/dist/resolution/frameworks/arkts-entry.js.map +1 -1
  38. package/dist/resolution/index.d.ts.map +1 -1
  39. package/dist/resolution/index.js +1 -1
  40. package/dist/resolution/index.js.map +1 -1
  41. package/dist/resolution/memory-budget.d.ts +33 -0
  42. package/dist/resolution/memory-budget.d.ts.map +1 -1
  43. package/dist/resolution/memory-budget.js +58 -0
  44. package/dist/resolution/memory-budget.js.map +1 -1
  45. package/dist/resolution/resolver-pool.d.ts +2 -0
  46. package/dist/resolution/resolver-pool.d.ts.map +1 -1
  47. package/dist/resolution/resolver-pool.js +4 -0
  48. package/dist/resolution/resolver-pool.js.map +1 -1
  49. package/dist/ui/shimmer-progress.d.ts.map +1 -1
  50. package/dist/ui/shimmer-progress.js +4 -1
  51. package/dist/ui/shimmer-progress.js.map +1 -1
  52. package/package.json +4 -5
  53. package/dist/arkts/ohos-api-index.d.ts +0 -15
  54. package/dist/arkts/ohos-api-index.d.ts.map +0 -1
  55. package/dist/arkts/ohos-api-index.js +0 -190
  56. package/dist/arkts/ohos-api-index.js.map +0 -1
  57. package/dist/arkts/ohos-sdk-input.d.ts +0 -36
  58. package/dist/arkts/ohos-sdk-input.d.ts.map +0 -1
  59. package/dist/arkts/ohos-sdk-input.js +0 -214
  60. package/dist/arkts/ohos-sdk-input.js.map +0 -1
  61. package/dist/extraction/languages/arkts-state-decorators.d.ts +0 -13
  62. package/dist/extraction/languages/arkts-state-decorators.d.ts.map +0 -1
  63. package/dist/extraction/languages/arkts-state-decorators.js +0 -26
  64. package/dist/extraction/languages/arkts-state-decorators.js.map +0 -1
  65. package/dist/extraction/languages/arkts-viewtree.d.ts +0 -24
  66. package/dist/extraction/languages/arkts-viewtree.d.ts.map +0 -1
  67. package/dist/extraction/languages/arkts-viewtree.js +0 -148
  68. package/dist/extraction/languages/arkts-viewtree.js.map +0 -1
  69. package/dist/extraction/languages/ohos-api-consumer.d.ts +0 -34
  70. package/dist/extraction/languages/ohos-api-consumer.d.ts.map +0 -1
  71. package/dist/extraction/languages/ohos-api-consumer.js +0 -283
  72. package/dist/extraction/languages/ohos-api-consumer.js.map +0 -1
  73. package/dist/reasoning/config.d.ts +0 -45
  74. package/dist/reasoning/config.d.ts.map +0 -1
  75. package/dist/reasoning/config.js +0 -171
  76. package/dist/reasoning/config.js.map +0 -1
  77. package/dist/reasoning/credentials.d.ts +0 -5
  78. package/dist/reasoning/credentials.d.ts.map +0 -1
  79. package/dist/reasoning/credentials.js +0 -83
  80. package/dist/reasoning/credentials.js.map +0 -1
  81. package/dist/reasoning/login.d.ts +0 -21
  82. package/dist/reasoning/login.d.ts.map +0 -1
  83. package/dist/reasoning/login.js +0 -85
  84. package/dist/reasoning/login.js.map +0 -1
  85. package/dist/reasoning/reasoner.d.ts +0 -43
  86. package/dist/reasoning/reasoner.d.ts.map +0 -1
  87. package/dist/reasoning/reasoner.js +0 -308
  88. package/dist/reasoning/reasoner.js.map +0 -1
  89. package/dist/spec/build/git-scanner.d.ts +0 -93
  90. package/dist/spec/build/git-scanner.d.ts.map +0 -1
  91. package/dist/spec/build/git-scanner.js +0 -254
  92. package/dist/spec/build/git-scanner.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/git-utils.d.ts +0 -8
  102. package/dist/spec/git-utils.d.ts.map +0 -1
  103. package/dist/spec/git-utils.js +0 -14
  104. package/dist/spec/git-utils.js.map +0 -1
  105. package/dist/spec/llm/index.d.ts +0 -3
  106. package/dist/spec/llm/index.d.ts.map +0 -1
  107. package/dist/spec/llm/index.js +0 -11
  108. package/dist/spec/llm/index.js.map +0 -1
  109. package/dist/spec/mine/clusterer.d.ts +0 -63
  110. package/dist/spec/mine/clusterer.d.ts.map +0 -1
  111. package/dist/spec/mine/clusterer.js +0 -904
  112. package/dist/spec/mine/clusterer.js.map +0 -1
  113. package/dist/spec/mine/progress-handler.d.ts +0 -22
  114. package/dist/spec/mine/progress-handler.d.ts.map +0 -1
  115. package/dist/spec/mine/progress-handler.js +0 -108
  116. package/dist/spec/mine/progress-handler.js.map +0 -1
  117. package/dist/spec/mine/progress.d.ts +0 -23
  118. package/dist/spec/mine/progress.d.ts.map +0 -1
  119. package/dist/spec/mine/progress.js +0 -12
  120. package/dist/spec/mine/progress.js.map +0 -1
  121. package/dist/spec/mining/diff-parser.d.ts +0 -33
  122. package/dist/spec/mining/diff-parser.d.ts.map +0 -1
  123. package/dist/spec/mining/diff-parser.js +0 -166
  124. package/dist/spec/mining/diff-parser.js.map +0 -1
  125. package/dist/spec/mining/git-scanner.d.ts +0 -103
  126. package/dist/spec/mining/git-scanner.d.ts.map +0 -1
  127. package/dist/spec/mining/git-scanner.js +0 -307
  128. package/dist/spec/mining/git-scanner.js.map +0 -1
  129. package/dist/spec/mining/pipeline.d.ts +0 -53
  130. package/dist/spec/mining/pipeline.d.ts.map +0 -1
  131. package/dist/spec/mining/pipeline.js +0 -178
  132. package/dist/spec/mining/pipeline.js.map +0 -1
  133. package/dist/spec/mining/scope-resolver.d.ts +0 -45
  134. package/dist/spec/mining/scope-resolver.d.ts.map +0 -1
  135. package/dist/spec/mining/scope-resolver.js +0 -103
  136. package/dist/spec/mining/scope-resolver.js.map +0 -1
  137. package/dist/spec/mining/spec-extractor.d.ts +0 -69
  138. package/dist/spec/mining/spec-extractor.d.ts.map +0 -1
  139. package/dist/spec/mining/spec-extractor.js +0 -369
  140. package/dist/spec/mining/spec-extractor.js.map +0 -1
  141. package/dist/spec/utils.d.ts +0 -155
  142. package/dist/spec/utils.d.ts.map +0 -1
  143. package/dist/spec/utils.js +0 -411
  144. package/dist/spec/utils.js.map +0 -1
  145. package/scripts/add-lang/bench.sh +0 -60
  146. package/scripts/add-lang/check-grammar.mjs +0 -75
  147. package/scripts/add-lang/dump-ast.mjs +0 -103
  148. package/scripts/add-lang/verify-extraction.mjs +0 -70
  149. package/scripts/agent-eval/ab-adoption.sh +0 -91
  150. package/scripts/agent-eval/ab-hook.sh +0 -86
  151. package/scripts/agent-eval/ab-impl.sh +0 -78
  152. package/scripts/agent-eval/ab-new-vs-baseline.sh +0 -102
  153. package/scripts/agent-eval/ab-sufficiency.sh +0 -78
  154. package/scripts/agent-eval/arms-F.sh +0 -21
  155. package/scripts/agent-eval/arms-matrix.sh +0 -37
  156. package/scripts/agent-eval/audit.sh +0 -68
  157. package/scripts/agent-eval/bench-readme.sh +0 -28
  158. package/scripts/agent-eval/bench-why-repo.sh +0 -22
  159. package/scripts/agent-eval/block-read-hook.sh +0 -19
  160. package/scripts/agent-eval/hook-settings.json +0 -15
  161. package/scripts/agent-eval/itrun.sh +0 -120
  162. package/scripts/agent-eval/offload-eval-3arm.sh +0 -72
  163. package/scripts/agent-eval/offload-eval-cost.mjs +0 -133
  164. package/scripts/agent-eval/offload-eval-effort.mjs +0 -108
  165. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +0 -25
  166. package/scripts/agent-eval/offload-eval-frontload.sh +0 -47
  167. package/scripts/agent-eval/offload-eval-ground-truth.json +0 -18
  168. package/scripts/agent-eval/offload-eval-hook.mjs +0 -84
  169. package/scripts/agent-eval/offload-eval-judge.mjs +0 -103
  170. package/scripts/agent-eval/offload-eval-matrix.sh +0 -20
  171. package/scripts/agent-eval/offload-eval-metrics.mjs +0 -94
  172. package/scripts/agent-eval/offload-eval-refs1.sh +0 -50
  173. package/scripts/agent-eval/offload-eval-setup.sh +0 -24
  174. package/scripts/agent-eval/offload-eval-styles.sh +0 -72
  175. package/scripts/agent-eval/offload-eval-summarize.mjs +0 -68
  176. package/scripts/agent-eval/offload-eval.md +0 -76
  177. package/scripts/agent-eval/parse-arms.mjs +0 -116
  178. package/scripts/agent-eval/parse-bench-readme.mjs +0 -84
  179. package/scripts/agent-eval/parse-run.mjs +0 -45
  180. package/scripts/agent-eval/parse-session.mjs +0 -93
  181. package/scripts/agent-eval/probe-context.mjs +0 -21
  182. package/scripts/agent-eval/probe-explore.mjs +0 -40
  183. package/scripts/agent-eval/probe-node.mjs +0 -20
  184. package/scripts/agent-eval/probe-sweep.mjs +0 -119
  185. package/scripts/agent-eval/probe-trace.mjs +0 -20
  186. package/scripts/agent-eval/redirect-read-hook.sh +0 -38
  187. package/scripts/agent-eval/repro-concurrent-explore.mjs +0 -119
  188. package/scripts/agent-eval/repro-daemon-clients.mjs +0 -125
  189. package/scripts/agent-eval/run-agent.sh +0 -34
  190. package/scripts/agent-eval/run-all.sh +0 -75
  191. package/scripts/agent-eval/run-arms.sh +0 -56
  192. package/scripts/agent-eval/seq-matrix.mjs +0 -137
  193. package/scripts/build-bundle.sh +0 -123
  194. package/scripts/exp_boundary_eval/README.md +0 -247
  195. package/scripts/exp_boundary_eval/_test_mcp_chain.py +0 -78
  196. package/scripts/exp_boundary_eval/_test_stdin.py +0 -8
  197. package/scripts/exp_boundary_eval/_utils.py +0 -1116
  198. package/scripts/exp_boundary_eval/analyze.py +0 -1313
  199. package/scripts/exp_boundary_eval/deveco_arm.py +0 -519
  200. package/scripts/exp_boundary_eval/run_all.py +0 -378
  201. package/scripts/exp_boundary_eval/run_one.py +0 -165
  202. package/scripts/exp_boundary_eval/run_session.py +0 -158
  203. package/scripts/exp_boundary_eval/setup.py +0 -120
  204. package/scripts/exp_boundary_eval/win_mcp_launcher.py +0 -73
  205. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +0 -36
  206. package/scripts/exp_boundary_eval/win_node_launcher.py +0 -24
  207. package/scripts/extract-release-notes.mjs +0 -130
  208. package/scripts/local-install.sh +0 -41
  209. package/scripts/npm-sdk.js +0 -75
  210. package/scripts/npm-shim.js +0 -275
  211. package/scripts/ohos-sdk-publish.mjs +0 -133
  212. package/scripts/pack-npm.sh +0 -119
  213. package/scripts/prepare-release.mjs +0 -270
@@ -1,155 +0,0 @@
1
- /**
2
- * Spec utility functions — replaces `file_utils.py`, `meta.py`, and
3
- * `truncate.py` from Python Commit4Spec.
4
- *
5
- * Covers file I/O, meta.json read/write, text/diff truncation, and budget
6
- * computation. All functions are synchronous and use Node.js built-ins.
7
- *
8
- * @module spec/utils
9
- */
10
- export interface SpecEntry {
11
- specId: string;
12
- entryType: 'directory' | 'file';
13
- path: string;
14
- }
15
- export interface SpecMeta {
16
- repoPath: string;
17
- specStoragePath: string;
18
- currentCommitID?: string;
19
- createdAt?: string;
20
- updatedAt: string;
21
- }
22
- export interface BudgetProfile {
23
- tier: 'tiny' | 'small' | 'medium' | 'large' | 'vlarge';
24
- maxFragments: number;
25
- maxContents: number;
26
- contentBudget: number;
27
- }
28
- /** Root directory for spec data, relative to the repository root. */
29
- export declare const SPEC_DATA_DIR = ".homegraph/commit4spec";
30
- /**
31
- * Read a UTF-8 file synchronously.
32
- *
33
- * Returns `null` for ENOENT (not found), EISDIR (is a directory), or EACCES
34
- * (permission denied). Other errors propagate.
35
- */
36
- export declare function readFileContent(filePath: string): string | null;
37
- /**
38
- * Write a UTF-8 file synchronously, creating parent directories as needed.
39
- *
40
- * Parent directories are created with `fs.mkdirSync({ recursive: true })`.
41
- * If the parent exists but is not a directory the underlying error propagates.
42
- */
43
- export declare function writeFileContent(filePath: string, content: string): void;
44
- /**
45
- * Discover specs in a storage directory.
46
- *
47
- * A "spec" is any `.md` file OR any subdirectory. For `.md` files the
48
- * `specId` is the basename without the extension. For subdirectories the
49
- * `specId` is the directory name.
50
- *
51
- * Returns an empty array when `specStoragePath` does not exist or is not a
52
- * directory.
53
- */
54
- export declare function discoverSpecs(specStoragePath: string): SpecEntry[];
55
- /**
56
- * Resolve the database path.
57
- *
58
- * Priority:
59
- * 1. If `explicitDbPath` is given, return it as-is (no side effects).
60
- * 2. If `repoPath` is given, default to `{repoPath}/${SPEC_DATA_DIR}/commit4spec.db`
61
- * and ensure `${SPEC_DATA_DIR}/.gitignore` exists containing `"*"`.
62
- * 3. If neither is given, return `"./commit4spec.db"`.
63
- */
64
- export declare function resolveDbPath(repoPath?: string, explicitDbPath?: string): string;
65
- /**
66
- * Read `${SPEC_DATA_DIR}/meta.json` from `repoPath`.
67
- *
68
- * Returns `null` when the file is missing, unreadable, or contains invalid
69
- * JSON or a JSON value that is not a plain object.
70
- */
71
- export declare function readMeta(repoPath: string): SpecMeta | null;
72
- /**
73
- * Write `${SPEC_DATA_DIR}/meta.json` to `repoPath`.
74
- *
75
- * If existing meta has a `createdAt` field it is preserved; otherwise the
76
- * current time is used as the creation timestamp. `updatedAt` is always set
77
- * to the current time. The `${SPEC_DATA_DIR}` directory is created if it does
78
- * not exist.
79
- *
80
- * Returns the full `SpecMeta` that was written.
81
- */
82
- export declare function writeMeta(repoPath: string, specStoragePath: string, currentCommitID?: string): SpecMeta;
83
- /**
84
- * Truncate a unified diff at a sensible boundary.
85
- *
86
- * The algorithm prefers semantic boundaries to keep diffs readable:
87
- *
88
- * 1. If the diff is shorter than `maxChars` (default 3800), return it unchanged.
89
- * 2. Try: find the **last** `@@` hunk header in the trailing 50% portion of
90
- * the diff and cut right before it.
91
- * 3. Fallback: find the **last** newline in the trailing 80% portion and cut
92
- * after it.
93
- * 4. Hard fallback: cut exactly at `maxChars`.
94
- *
95
- * Always appends `" …(truncated)"` when truncation occurs.
96
- *
97
- * @param diff - The unified diff text to truncate.
98
- * @param maxChars - Maximum allowed characters (including suffix). Default 3800.
99
- * @returns The (possibly truncated) diff text.
100
- */
101
- export declare function truncateCodeDiff(diff: string, maxChars?: number): string;
102
- /**
103
- * Truncate plain text with newline-awareness.
104
- *
105
- * When the text is longer than `maxChars`, it is cut at the last newline
106
- * found before `maxChars` (minus the suffix length). If no suitable newline
107
- * exists, a hard cut is made.
108
- *
109
- * The suffix `" …(truncated)"` is appended only when truncation occurs.
110
- *
111
- * @param text - The text to truncate.
112
- * @param maxChars - Maximum allowed characters (including suffix).
113
- * @returns The (possibly truncated) text.
114
- */
115
- export declare function truncateText(text: string, maxChars: number): string;
116
- /**
117
- * Truncate a subtitles array.
118
- *
119
- * 1. If the array has more than `maxEntries`, it is sliced to `maxEntries`.
120
- * 2. Each remaining entry that exceeds `maxChars` is individually truncated
121
- * via `truncateText`.
122
- *
123
- * Entries that already fit within both limits are left unchanged.
124
- *
125
- * @param subtitles - Array of subtitle strings.
126
- * @param maxChars - Maximum characters per entry (including suffix).
127
- * @param maxEntries - Maximum number of entries to keep.
128
- * @returns The truncated subtitles array (always a new array).
129
- */
130
- export declare function truncateSubtitles(subtitles: string[], maxChars: number, maxEntries: number): string[];
131
- /**
132
- * Compute a budget profile based on spec and optional fragment counts.
133
- *
134
- * The profile determines how many fragments, contents, and characters the
135
- * pipeline should budget when building LLM prompts. Higher counts produce
136
- * tighter budgets to keep prompts manageable.
137
- *
138
- * Thresholds (matching `truncate.py:38-57`):
139
- *
140
- * | specCount | tier | maxFragments | maxContents | contentBudget |
141
- * |-----------|---------|--------------|-------------|---------------|
142
- * | ≤ 3 | tiny | 12 | 16 | 48000 |
143
- * | ≤ 8 | small | 10 | 14 | 40000 |
144
- * | ≤ 15 | medium | 8 | 12 | 32000 |
145
- * | ≤ 30 | large | 6 | 10 | 24000 |
146
- * | > 30 | vlarge | 0 | 0 | 16000 |
147
- *
148
- * The `vlarge` tier disables fragment/contents inclusion entirely (0 values).
149
- *
150
- * @param specCount - Number of specs in the knowledge graph.
151
- * @param fragmentCount - (Unused) reserved for future per-fragment weighting.
152
- * @returns The budget profile for the given scale.
153
- */
154
- export declare function computeBudgetProfile(specCount: number, _fragmentCount?: number): BudgetProfile;
155
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/spec/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,GAAG,MAAM,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,qEAAqE;AACrE,eAAO,MAAM,aAAa,2BAA2B,CAAC;AAStD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMxE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,CA6BlE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAiChF;AAMD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CA8C1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,MAAM,GACvB,QAAQ,CAsBV;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAa,GAAG,MAAM,CA6C9E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoBnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EAAE,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAMV;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,aAAa,CAcf"}
@@ -1,411 +0,0 @@
1
- "use strict";
2
- /**
3
- * Spec utility functions — replaces `file_utils.py`, `meta.py`, and
4
- * `truncate.py` from Python Commit4Spec.
5
- *
6
- * Covers file I/O, meta.json read/write, text/diff truncation, and budget
7
- * computation. All functions are synchronous and use Node.js built-ins.
8
- *
9
- * @module spec/utils
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.SPEC_DATA_DIR = void 0;
46
- exports.readFileContent = readFileContent;
47
- exports.writeFileContent = writeFileContent;
48
- exports.discoverSpecs = discoverSpecs;
49
- exports.resolveDbPath = resolveDbPath;
50
- exports.readMeta = readMeta;
51
- exports.writeMeta = writeMeta;
52
- exports.truncateCodeDiff = truncateCodeDiff;
53
- exports.truncateText = truncateText;
54
- exports.truncateSubtitles = truncateSubtitles;
55
- exports.computeBudgetProfile = computeBudgetProfile;
56
- const fs = __importStar(require("fs"));
57
- const path = __importStar(require("path"));
58
- const errors_1 = require("../errors");
59
- // =============================================================================
60
- // Constants
61
- // =============================================================================
62
- /** Root directory for spec data, relative to the repository root. */
63
- exports.SPEC_DATA_DIR = '.homegraph/commit4spec';
64
- const TRUNCATION_SUFFIX = ' …(truncated)';
65
- const TRUNCATION_SUFFIX_LENGTH = TRUNCATION_SUFFIX.length;
66
- // =============================================================================
67
- // File I/O
68
- // =============================================================================
69
- /**
70
- * Read a UTF-8 file synchronously.
71
- *
72
- * Returns `null` for ENOENT (not found), EISDIR (is a directory), or EACCES
73
- * (permission denied). Other errors propagate.
74
- */
75
- function readFileContent(filePath) {
76
- try {
77
- return fs.readFileSync(filePath, 'utf-8');
78
- }
79
- catch (err) {
80
- if (err.code === 'ENOENT' || err.code === 'EISDIR' || err.code === 'EACCES') {
81
- return null;
82
- }
83
- throw err;
84
- }
85
- }
86
- /**
87
- * Write a UTF-8 file synchronously, creating parent directories as needed.
88
- *
89
- * Parent directories are created with `fs.mkdirSync({ recursive: true })`.
90
- * If the parent exists but is not a directory the underlying error propagates.
91
- */
92
- function writeFileContent(filePath, content) {
93
- const dir = path.dirname(filePath);
94
- if (dir && dir !== '.') {
95
- fs.mkdirSync(dir, { recursive: true });
96
- }
97
- fs.writeFileSync(filePath, content, 'utf-8');
98
- }
99
- // =============================================================================
100
- // Spec discovery
101
- // =============================================================================
102
- /**
103
- * Discover specs in a storage directory.
104
- *
105
- * A "spec" is any `.md` file OR any subdirectory. For `.md` files the
106
- * `specId` is the basename without the extension. For subdirectories the
107
- * `specId` is the directory name.
108
- *
109
- * Returns an empty array when `specStoragePath` does not exist or is not a
110
- * directory.
111
- */
112
- function discoverSpecs(specStoragePath) {
113
- let entries;
114
- try {
115
- entries = fs.readdirSync(specStoragePath, { withFileTypes: true });
116
- }
117
- catch (err) {
118
- // Non-existent or not a directory → empty list
119
- return [];
120
- }
121
- const result = [];
122
- for (const entry of entries) {
123
- if (entry.isDirectory()) {
124
- result.push({
125
- specId: entry.name,
126
- entryType: 'directory',
127
- path: path.join(specStoragePath, entry.name),
128
- });
129
- }
130
- else if (entry.isFile() && entry.name.endsWith('.md')) {
131
- result.push({
132
- specId: entry.name.slice(0, -3), // strip ".md"
133
- entryType: 'file',
134
- path: path.join(specStoragePath, entry.name),
135
- });
136
- }
137
- // Symlinks, other file types, and dot-files are silently skipped.
138
- }
139
- return result;
140
- }
141
- // =============================================================================
142
- // Database path resolution
143
- // =============================================================================
144
- /**
145
- * Resolve the database path.
146
- *
147
- * Priority:
148
- * 1. If `explicitDbPath` is given, return it as-is (no side effects).
149
- * 2. If `repoPath` is given, default to `{repoPath}/${SPEC_DATA_DIR}/commit4spec.db`
150
- * and ensure `${SPEC_DATA_DIR}/.gitignore` exists containing `"*"`.
151
- * 3. If neither is given, return `"./commit4spec.db"`.
152
- */
153
- function resolveDbPath(repoPath, explicitDbPath) {
154
- if (explicitDbPath) {
155
- return explicitDbPath;
156
- }
157
- if (repoPath) {
158
- const commit4specDir = path.join(repoPath, exports.SPEC_DATA_DIR);
159
- const gitignorePath = path.join(commit4specDir, '.gitignore');
160
- const dbPath = path.join(commit4specDir, 'commit4spec.db');
161
- // Ensure ${SPEC_DATA_DIR} directory exists
162
- try {
163
- fs.mkdirSync(commit4specDir, { recursive: true });
164
- }
165
- catch {
166
- // Directory may already exist; ok.
167
- }
168
- // Write .gitignore if it doesn't exist
169
- if (!fs.existsSync(gitignorePath)) {
170
- try {
171
- fs.writeFileSync(gitignorePath, '*\n', 'utf-8');
172
- }
173
- catch (err) {
174
- (0, errors_1.logWarn)(`Failed to write ${exports.SPEC_DATA_DIR}/.gitignore`, {
175
- path: gitignorePath,
176
- error: err instanceof Error ? err.message : String(err),
177
- });
178
- }
179
- }
180
- return dbPath;
181
- }
182
- return './commit4spec.db';
183
- }
184
- // =============================================================================
185
- // Meta read / write
186
- // =============================================================================
187
- /**
188
- * Read `${SPEC_DATA_DIR}/meta.json` from `repoPath`.
189
- *
190
- * Returns `null` when the file is missing, unreadable, or contains invalid
191
- * JSON or a JSON value that is not a plain object.
192
- */
193
- function readMeta(repoPath) {
194
- const metaPath = path.join(repoPath, exports.SPEC_DATA_DIR, 'meta.json');
195
- let raw;
196
- try {
197
- raw = fs.readFileSync(metaPath, 'utf-8');
198
- }
199
- catch {
200
- return null;
201
- }
202
- let parsed;
203
- try {
204
- parsed = JSON.parse(raw);
205
- }
206
- catch {
207
- (0, errors_1.logWarn)(`Ignoring ${exports.SPEC_DATA_DIR}/meta.json: not valid JSON`, {
208
- path: metaPath,
209
- });
210
- return null;
211
- }
212
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
213
- (0, errors_1.logWarn)(`Ignoring ${exports.SPEC_DATA_DIR}/meta.json: top-level value must be a JSON object`, { path: metaPath });
214
- return null;
215
- }
216
- const obj = parsed;
217
- // Validate required string fields
218
- if (typeof obj.repoPath !== 'string' || typeof obj.specStoragePath !== 'string') {
219
- (0, errors_1.logWarn)(`Ignoring ${exports.SPEC_DATA_DIR}/meta.json: repoPath and specStoragePath must be strings`, { path: metaPath });
220
- return null;
221
- }
222
- return {
223
- repoPath: obj.repoPath,
224
- specStoragePath: obj.specStoragePath,
225
- currentCommitID: typeof obj.currentCommitID === 'string' ? obj.currentCommitID : undefined,
226
- createdAt: typeof obj.createdAt === 'string' ? obj.createdAt : undefined,
227
- updatedAt: typeof obj.updatedAt === 'string' ? obj.updatedAt : new Date().toISOString(),
228
- };
229
- }
230
- /**
231
- * Write `${SPEC_DATA_DIR}/meta.json` to `repoPath`.
232
- *
233
- * If existing meta has a `createdAt` field it is preserved; otherwise the
234
- * current time is used as the creation timestamp. `updatedAt` is always set
235
- * to the current time. The `${SPEC_DATA_DIR}` directory is created if it does
236
- * not exist.
237
- *
238
- * Returns the full `SpecMeta` that was written.
239
- */
240
- function writeMeta(repoPath, specStoragePath, currentCommitID) {
241
- const metaDir = path.join(repoPath, exports.SPEC_DATA_DIR);
242
- const metaPath = path.join(metaDir, 'meta.json');
243
- const now = new Date().toISOString();
244
- // Preserve createdAt from existing meta; use now for new files
245
- const existing = readMeta(repoPath);
246
- const createdAt = (existing?.createdAt) || now;
247
- const meta = {
248
- repoPath,
249
- specStoragePath,
250
- currentCommitID,
251
- createdAt,
252
- updatedAt: now,
253
- };
254
- fs.mkdirSync(metaDir, { recursive: true });
255
- fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2) + '\n', 'utf-8');
256
- return meta;
257
- }
258
- // =============================================================================
259
- // Truncation utilities
260
- // =============================================================================
261
- /**
262
- * Truncate a unified diff at a sensible boundary.
263
- *
264
- * The algorithm prefers semantic boundaries to keep diffs readable:
265
- *
266
- * 1. If the diff is shorter than `maxChars` (default 3800), return it unchanged.
267
- * 2. Try: find the **last** `@@` hunk header in the trailing 50% portion of
268
- * the diff and cut right before it.
269
- * 3. Fallback: find the **last** newline in the trailing 80% portion and cut
270
- * after it.
271
- * 4. Hard fallback: cut exactly at `maxChars`.
272
- *
273
- * Always appends `" …(truncated)"` when truncation occurs.
274
- *
275
- * @param diff - The unified diff text to truncate.
276
- * @param maxChars - Maximum allowed characters (including suffix). Default 3800.
277
- * @returns The (possibly truncated) diff text.
278
- */
279
- function truncateCodeDiff(diff, maxChars = 3800) {
280
- if (diff.length <= maxChars) {
281
- return diff;
282
- }
283
- const suffix = TRUNCATION_SUFFIX;
284
- const effectiveMax = maxChars - TRUNCATION_SUFFIX_LENGTH;
285
- if (effectiveMax <= 0) {
286
- return diff.slice(0, Math.max(0, maxChars - 1)) + suffix;
287
- }
288
- // Step 2: find last "@@" hunk header in trailing 50%
289
- const halfPoint = Math.floor(diff.length * 0.5);
290
- // We search for "\n@@" or "@@" at the very start. Use a regex that
291
- // matches a line starting with "@@" (after optional leading whitespace in
292
- // some edge cases, but standard diffs have "@@" at column 0).
293
- const hunkHeaderRe = /(^|\n)@@/g;
294
- let lastHunkHeaderPos = -1;
295
- let match;
296
- // Reset lastIndex and scan from the beginning; we only accept matches whose
297
- // index is >= halfPoint.
298
- hunkHeaderRe.lastIndex = 0;
299
- while ((match = hunkHeaderRe.exec(diff)) !== null) {
300
- const cap = match[1]; // the newline-or-start anchor
301
- const pos = match.index + (cap ? cap.length : 0); // position of "@@"
302
- if (pos >= halfPoint && pos <= effectiveMax) {
303
- lastHunkHeaderPos = pos;
304
- }
305
- }
306
- if (lastHunkHeaderPos > 0) {
307
- return diff.slice(0, lastHunkHeaderPos) + suffix;
308
- }
309
- // Step 3: find last "\n" in trailing 80%
310
- const eightyPoint = Math.floor(diff.length * 0.2);
311
- for (let i = effectiveMax - 1; i >= eightyPoint; i--) {
312
- if (diff[i] === '\n' && i < effectiveMax) {
313
- return diff.slice(0, i + 1) + suffix;
314
- }
315
- }
316
- // Step 4: hard cut
317
- return diff.slice(0, effectiveMax) + suffix;
318
- }
319
- /**
320
- * Truncate plain text with newline-awareness.
321
- *
322
- * When the text is longer than `maxChars`, it is cut at the last newline
323
- * found before `maxChars` (minus the suffix length). If no suitable newline
324
- * exists, a hard cut is made.
325
- *
326
- * The suffix `" …(truncated)"` is appended only when truncation occurs.
327
- *
328
- * @param text - The text to truncate.
329
- * @param maxChars - Maximum allowed characters (including suffix).
330
- * @returns The (possibly truncated) text.
331
- */
332
- function truncateText(text, maxChars) {
333
- if (text.length <= maxChars) {
334
- return text;
335
- }
336
- const suffix = TRUNCATION_SUFFIX;
337
- const effectiveMax = maxChars - TRUNCATION_SUFFIX_LENGTH;
338
- if (effectiveMax <= 0) {
339
- return text.slice(0, Math.max(0, maxChars - 1)) + suffix;
340
- }
341
- // Try to find the last newline within the budget
342
- for (let i = effectiveMax - 1; i >= 0; i--) {
343
- if (text[i] === '\n') {
344
- return text.slice(0, i) + suffix;
345
- }
346
- }
347
- // Hard cut
348
- return text.slice(0, effectiveMax) + suffix;
349
- }
350
- /**
351
- * Truncate a subtitles array.
352
- *
353
- * 1. If the array has more than `maxEntries`, it is sliced to `maxEntries`.
354
- * 2. Each remaining entry that exceeds `maxChars` is individually truncated
355
- * via `truncateText`.
356
- *
357
- * Entries that already fit within both limits are left unchanged.
358
- *
359
- * @param subtitles - Array of subtitle strings.
360
- * @param maxChars - Maximum characters per entry (including suffix).
361
- * @param maxEntries - Maximum number of entries to keep.
362
- * @returns The truncated subtitles array (always a new array).
363
- */
364
- function truncateSubtitles(subtitles, maxChars, maxEntries) {
365
- // Cap entry count
366
- const capped = subtitles.length > maxEntries ? subtitles.slice(0, maxEntries) : [...subtitles];
367
- // Truncate each entry
368
- return capped.map((entry) => truncateText(entry, maxChars));
369
- }
370
- // =============================================================================
371
- // Budget profile
372
- // =============================================================================
373
- /**
374
- * Compute a budget profile based on spec and optional fragment counts.
375
- *
376
- * The profile determines how many fragments, contents, and characters the
377
- * pipeline should budget when building LLM prompts. Higher counts produce
378
- * tighter budgets to keep prompts manageable.
379
- *
380
- * Thresholds (matching `truncate.py:38-57`):
381
- *
382
- * | specCount | tier | maxFragments | maxContents | contentBudget |
383
- * |-----------|---------|--------------|-------------|---------------|
384
- * | ≤ 3 | tiny | 12 | 16 | 48000 |
385
- * | ≤ 8 | small | 10 | 14 | 40000 |
386
- * | ≤ 15 | medium | 8 | 12 | 32000 |
387
- * | ≤ 30 | large | 6 | 10 | 24000 |
388
- * | > 30 | vlarge | 0 | 0 | 16000 |
389
- *
390
- * The `vlarge` tier disables fragment/contents inclusion entirely (0 values).
391
- *
392
- * @param specCount - Number of specs in the knowledge graph.
393
- * @param fragmentCount - (Unused) reserved for future per-fragment weighting.
394
- * @returns The budget profile for the given scale.
395
- */
396
- function computeBudgetProfile(specCount, _fragmentCount) {
397
- if (specCount <= 3) {
398
- return { tier: 'tiny', maxFragments: 12, maxContents: 16, contentBudget: 48000 };
399
- }
400
- if (specCount <= 8) {
401
- return { tier: 'small', maxFragments: 10, maxContents: 14, contentBudget: 40000 };
402
- }
403
- if (specCount <= 15) {
404
- return { tier: 'medium', maxFragments: 8, maxContents: 12, contentBudget: 32000 };
405
- }
406
- if (specCount <= 30) {
407
- return { tier: 'large', maxFragments: 6, maxContents: 10, contentBudget: 24000 };
408
- }
409
- return { tier: 'vlarge', maxFragments: 0, maxContents: 0, contentBudget: 16000 };
410
- }
411
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/spec/utils.ts"],"names":[],"mappings":"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"}
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Add-lang benchmark for ONE repo:
3
- # clone -> wipe+index (with the homegraph on PATH) -> verify extraction ->
4
- # with/without retrieval A/B (reuses scripts/agent-eval/run-all.sh).
5
- #
6
- # Assumes the homegraph dev build is already built + linked on PATH — the skill
7
- # runs `npm run build && ./scripts/local-install.sh` ONCE before looping repos.
8
- # The A/B is skipped if extraction fails its critical checks (don't burn $ on a
9
- # broken extractor); set FORCE_AB=1 to run it anyway.
10
- #
11
- # Usage: bench.sh <lang> <repo-name> <repo-url> "<question>" [headless|tmux|all]
12
- # Env: CORPUS corpus dir (default /tmp/homegraph-corpus, shared with agent-eval)
13
- set -uo pipefail
14
-
15
- LANG_TOKEN="${1:?usage: bench.sh <lang> <repo-name> <repo-url> \"<question>\" [mode]}"
16
- NAME="${2:?repo-name required}"
17
- URL="${3:?repo-url required}"
18
- Q="${4:?question required}"
19
- MODE="${5:-headless}"
20
-
21
- HARNESS="$(cd "$(dirname "$0")" && pwd)"
22
- AGENT_EVAL="$(cd "$HARNESS/../agent-eval" && pwd)"
23
- CORPUS="${CORPUS:-/tmp/homegraph-corpus}"
24
- REPO="$CORPUS/$NAME"
25
-
26
- command -v homegraph >/dev/null || { echo "no homegraph on PATH (build + ./scripts/local-install.sh first)"; exit 1; }
27
-
28
- echo "==================== add-lang bench: $NAME ($LANG_TOKEN) ===================="
29
- echo "homegraph: $(command -v homegraph) -> $(homegraph --version 2>/dev/null || echo '?')"
30
-
31
- # 1. Ensure the repo (shallow clone, reuse if present).
32
- mkdir -p "$CORPUS"
33
- if [ -d "$REPO/.git" ]; then
34
- echo "→ reusing checkout: $REPO"
35
- else
36
- echo "→ cloning $URL"
37
- git clone --depth 1 "$URL" "$REPO" || { echo "git clone failed"; exit 1; }
38
- fi
39
-
40
- # 2. Wipe + index with the binary under test.
41
- echo "→ wiping .homegraph and indexing"
42
- rm -rf "$REPO/.homegraph"
43
- ( cd "$REPO" && homegraph init -i ) || { echo "indexing failed"; exit 1; }
44
-
45
- # 3. Verify extraction (cheap guard before the paid A/B).
46
- echo "→ verifying extraction"
47
- node "$HARNESS/verify-extraction.mjs" "$REPO" "$LANG_TOKEN"
48
- VERIFY=$?
49
-
50
- # 4. Retrieval A/B (skipped if extraction is broken, unless FORCE_AB=1).
51
- if [ "$VERIFY" -ne 0 ] && [ "${FORCE_AB:-0}" != "1" ]; then
52
- echo "→ SKIPPING A/B — extraction failed critical checks (set FORCE_AB=1 to override)"
53
- else
54
- echo "→ retrieval A/B (mode=$MODE)"
55
- bash "$AGENT_EVAL/run-all.sh" "$REPO" "$Q" "$MODE"
56
- fi
57
-
58
- echo "==================== bench complete: $NAME (verify exit=$VERIFY) ===================="
59
- # Exit reflects extraction: 0 = pass/warn, 1 = critical fail, 2 = couldn't read status.
60
- exit "$VERIFY"