homegraph 0.9.10 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +243 -193
  3. package/dist/bin/fatal-handler.d.ts +20 -0
  4. package/dist/bin/fatal-handler.d.ts.map +1 -0
  5. package/dist/bin/fatal-handler.js +118 -0
  6. package/dist/bin/fatal-handler.js.map +1 -0
  7. package/dist/bin/homegraph.d.ts +6 -6
  8. package/dist/bin/homegraph.js +532 -109
  9. package/dist/bin/homegraph.js.map +1 -1
  10. package/dist/bin/node-version-check.d.ts +4 -4
  11. package/dist/bin/node-version-check.js +12 -12
  12. package/dist/bin/uninstall.d.ts +1 -1
  13. package/dist/bin/uninstall.js +1 -1
  14. package/dist/context/index.d.ts.map +1 -1
  15. package/dist/context/index.js +8 -1
  16. package/dist/context/index.js.map +1 -1
  17. package/dist/db/index.d.ts +22 -1
  18. package/dist/db/index.d.ts.map +1 -1
  19. package/dist/db/index.js +48 -2
  20. package/dist/db/index.js.map +1 -1
  21. package/dist/db/migrations.d.ts +1 -1
  22. package/dist/db/migrations.d.ts.map +1 -1
  23. package/dist/db/migrations.js +26 -17
  24. package/dist/db/migrations.js.map +1 -1
  25. package/dist/db/queries.d.ts +21 -1
  26. package/dist/db/queries.d.ts.map +1 -1
  27. package/dist/db/queries.js +180 -137
  28. package/dist/db/queries.js.map +1 -1
  29. package/dist/db/schema.sql +152 -151
  30. package/dist/db/sqlite-adapter.d.ts +1 -1
  31. package/dist/db/sqlite-adapter.js +3 -3
  32. package/dist/directory.d.ts +87 -6
  33. package/dist/directory.d.ts.map +1 -1
  34. package/dist/directory.js +319 -57
  35. package/dist/directory.js.map +1 -1
  36. package/dist/errors.d.ts +15 -15
  37. package/dist/errors.js +20 -20
  38. package/dist/extraction/astro-extractor.d.ts +79 -0
  39. package/dist/extraction/astro-extractor.d.ts.map +1 -0
  40. package/dist/extraction/astro-extractor.js +320 -0
  41. package/dist/extraction/astro-extractor.js.map +1 -0
  42. package/dist/extraction/context.d.ts +1 -1
  43. package/dist/extraction/context.js +1 -1
  44. package/dist/extraction/extraction-version.d.ts +2 -2
  45. package/dist/extraction/extraction-version.d.ts.map +1 -1
  46. package/dist/extraction/extraction-version.js +2 -2
  47. package/dist/extraction/extraction-version.js.map +1 -1
  48. package/dist/extraction/function-ref.d.ts +118 -0
  49. package/dist/extraction/function-ref.d.ts.map +1 -0
  50. package/dist/extraction/function-ref.js +727 -0
  51. package/dist/extraction/function-ref.js.map +1 -0
  52. package/dist/extraction/generated-detection.d.ts.map +1 -1
  53. package/dist/extraction/generated-detection.js +3 -0
  54. package/dist/extraction/generated-detection.js.map +1 -1
  55. package/dist/extraction/grammars.d.ts +15 -5
  56. package/dist/extraction/grammars.d.ts.map +1 -1
  57. package/dist/extraction/grammars.js +44 -10
  58. package/dist/extraction/grammars.js.map +1 -1
  59. package/dist/extraction/index.d.ts +37 -0
  60. package/dist/extraction/index.d.ts.map +1 -1
  61. package/dist/extraction/index.js +562 -70
  62. package/dist/extraction/index.js.map +1 -1
  63. package/dist/extraction/languages/arkts-viewtree.d.ts +22 -0
  64. package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -0
  65. package/dist/extraction/languages/arkts-viewtree.js +133 -0
  66. package/dist/extraction/languages/arkts-viewtree.js.map +1 -0
  67. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  68. package/dist/extraction/languages/arkts.js +211 -20
  69. package/dist/extraction/languages/arkts.js.map +1 -1
  70. package/dist/extraction/languages/c-cpp.d.ts +8 -0
  71. package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  72. package/dist/extraction/languages/c-cpp.js +104 -2
  73. package/dist/extraction/languages/c-cpp.js.map +1 -1
  74. package/dist/extraction/languages/csharp.d.ts.map +1 -1
  75. package/dist/extraction/languages/csharp.js +58 -3
  76. package/dist/extraction/languages/csharp.js.map +1 -1
  77. package/dist/extraction/languages/dart.d.ts.map +1 -1
  78. package/dist/extraction/languages/dart.js +183 -1
  79. package/dist/extraction/languages/dart.js.map +1 -1
  80. package/dist/extraction/languages/go.d.ts.map +1 -1
  81. package/dist/extraction/languages/go.js +37 -0
  82. package/dist/extraction/languages/go.js.map +1 -1
  83. package/dist/extraction/languages/index.d.ts.map +1 -1
  84. package/dist/extraction/languages/index.js +2 -0
  85. package/dist/extraction/languages/index.js.map +1 -1
  86. package/dist/extraction/languages/java.d.ts.map +1 -1
  87. package/dist/extraction/languages/java.js +241 -0
  88. package/dist/extraction/languages/java.js.map +1 -1
  89. package/dist/extraction/languages/javascript.d.ts.map +1 -1
  90. package/dist/extraction/languages/javascript.js +16 -0
  91. package/dist/extraction/languages/javascript.js.map +1 -1
  92. package/dist/extraction/languages/kotlin.d.ts.map +1 -1
  93. package/dist/extraction/languages/kotlin.js +94 -0
  94. package/dist/extraction/languages/kotlin.js.map +1 -1
  95. package/dist/extraction/languages/objc.d.ts.map +1 -1
  96. package/dist/extraction/languages/objc.js +42 -0
  97. package/dist/extraction/languages/objc.js.map +1 -1
  98. package/dist/extraction/languages/pascal.d.ts.map +1 -1
  99. package/dist/extraction/languages/pascal.js +11 -0
  100. package/dist/extraction/languages/pascal.js.map +1 -1
  101. package/dist/extraction/languages/php.d.ts.map +1 -1
  102. package/dist/extraction/languages/php.js +77 -1
  103. package/dist/extraction/languages/php.js.map +1 -1
  104. package/dist/extraction/languages/r.d.ts +3 -0
  105. package/dist/extraction/languages/r.d.ts.map +1 -0
  106. package/dist/extraction/languages/r.js +314 -0
  107. package/dist/extraction/languages/r.js.map +1 -0
  108. package/dist/extraction/languages/rust.d.ts.map +1 -1
  109. package/dist/extraction/languages/rust.js +29 -0
  110. package/dist/extraction/languages/rust.js.map +1 -1
  111. package/dist/extraction/languages/scala.d.ts.map +1 -1
  112. package/dist/extraction/languages/scala.js +44 -9
  113. package/dist/extraction/languages/scala.js.map +1 -1
  114. package/dist/extraction/languages/swift.d.ts.map +1 -1
  115. package/dist/extraction/languages/swift.js +61 -0
  116. package/dist/extraction/languages/swift.js.map +1 -1
  117. package/dist/extraction/languages/typescript.d.ts +13 -0
  118. package/dist/extraction/languages/typescript.d.ts.map +1 -1
  119. package/dist/extraction/languages/typescript.js +38 -0
  120. package/dist/extraction/languages/typescript.js.map +1 -1
  121. package/dist/extraction/liquid-extractor.d.ts.map +1 -1
  122. package/dist/extraction/liquid-extractor.js +4 -1
  123. package/dist/extraction/liquid-extractor.js.map +1 -1
  124. package/dist/extraction/parse-worker.js +4 -1
  125. package/dist/extraction/parse-worker.js.map +1 -1
  126. package/dist/extraction/svelte-extractor.d.ts.map +1 -1
  127. package/dist/extraction/svelte-extractor.js +6 -3
  128. package/dist/extraction/svelte-extractor.js.map +1 -1
  129. package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
  130. package/dist/extraction/tree-sitter-helpers.js +59 -10
  131. package/dist/extraction/tree-sitter-helpers.js.map +1 -1
  132. package/dist/extraction/tree-sitter-types.d.ts +29 -0
  133. package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  134. package/dist/extraction/tree-sitter.d.ts +192 -0
  135. package/dist/extraction/tree-sitter.d.ts.map +1 -1
  136. package/dist/extraction/tree-sitter.js +1553 -45
  137. package/dist/extraction/tree-sitter.js.map +1 -1
  138. package/dist/extraction/vue-extractor.d.ts.map +1 -1
  139. package/dist/extraction/vue-extractor.js +6 -3
  140. package/dist/extraction/vue-extractor.js.map +1 -1
  141. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  142. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  143. package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
  144. package/dist/graph/traversal.d.ts.map +1 -1
  145. package/dist/graph/traversal.js +11 -2
  146. package/dist/graph/traversal.js.map +1 -1
  147. package/dist/index.d.ts +64 -23
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +137 -41
  150. package/dist/index.js.map +1 -1
  151. package/dist/installer/config-writer.d.ts +1 -1
  152. package/dist/installer/config-writer.js +1 -1
  153. package/dist/installer/index.d.ts +4 -4
  154. package/dist/installer/index.d.ts.map +1 -1
  155. package/dist/installer/index.js +100 -73
  156. package/dist/installer/index.js.map +1 -1
  157. package/dist/installer/instructions-template.d.ts +34 -11
  158. package/dist/installer/instructions-template.d.ts.map +1 -1
  159. package/dist/installer/instructions-template.js +44 -12
  160. package/dist/installer/instructions-template.js.map +1 -1
  161. package/dist/installer/targets/antigravity.d.ts +6 -6
  162. package/dist/installer/targets/antigravity.js +14 -14
  163. package/dist/installer/targets/claude.d.ts +19 -13
  164. package/dist/installer/targets/claude.d.ts.map +1 -1
  165. package/dist/installer/targets/claude.js +97 -29
  166. package/dist/installer/targets/claude.js.map +1 -1
  167. package/dist/installer/targets/codebuddy.d.ts +17 -0
  168. package/dist/installer/targets/codebuddy.d.ts.map +1 -0
  169. package/dist/installer/targets/codebuddy.js +150 -0
  170. package/dist/installer/targets/codebuddy.js.map +1 -0
  171. package/dist/installer/targets/codex.js +5 -7
  172. package/dist/installer/targets/codex.js.map +1 -1
  173. package/dist/installer/targets/cursor.d.ts +1 -1
  174. package/dist/installer/targets/cursor.js +7 -7
  175. package/dist/installer/targets/deveco.d.ts +23 -0
  176. package/dist/installer/targets/deveco.d.ts.map +1 -0
  177. package/dist/installer/targets/deveco.js +217 -0
  178. package/dist/installer/targets/deveco.js.map +1 -0
  179. package/dist/installer/targets/gemini.js +5 -7
  180. package/dist/installer/targets/gemini.js.map +1 -1
  181. package/dist/installer/targets/hermes.js +15 -15
  182. package/dist/installer/targets/kiro.d.ts +1 -1
  183. package/dist/installer/targets/kiro.js +4 -4
  184. package/dist/installer/targets/opencode.d.ts +9 -1
  185. package/dist/installer/targets/opencode.d.ts.map +1 -1
  186. package/dist/installer/targets/opencode.js +92 -41
  187. package/dist/installer/targets/opencode.js.map +1 -1
  188. package/dist/installer/targets/registry.d.ts.map +1 -1
  189. package/dist/installer/targets/registry.js +4 -0
  190. package/dist/installer/targets/registry.js.map +1 -1
  191. package/dist/installer/targets/shared.d.ts +28 -4
  192. package/dist/installer/targets/shared.d.ts.map +1 -1
  193. package/dist/installer/targets/shared.js +32 -15
  194. package/dist/installer/targets/shared.js.map +1 -1
  195. package/dist/installer/targets/types.d.ts +9 -2
  196. package/dist/installer/targets/types.d.ts.map +1 -1
  197. package/dist/mcp/daemon-manager.d.ts +42 -0
  198. package/dist/mcp/daemon-manager.d.ts.map +1 -0
  199. package/dist/mcp/daemon-manager.js +129 -0
  200. package/dist/mcp/daemon-manager.js.map +1 -0
  201. package/dist/mcp/daemon-paths.d.ts +1 -1
  202. package/dist/mcp/daemon-paths.js +3 -3
  203. package/dist/mcp/daemon-registry.d.ts +47 -0
  204. package/dist/mcp/daemon-registry.d.ts.map +1 -0
  205. package/dist/mcp/daemon-registry.js +229 -0
  206. package/dist/mcp/daemon-registry.js.map +1 -0
  207. package/dist/mcp/daemon.d.ts.map +1 -1
  208. package/dist/mcp/daemon.js +27 -6
  209. package/dist/mcp/daemon.js.map +1 -1
  210. package/dist/mcp/dynamic-boundaries.d.ts +41 -0
  211. package/dist/mcp/dynamic-boundaries.d.ts.map +1 -0
  212. package/dist/mcp/dynamic-boundaries.js +359 -0
  213. package/dist/mcp/dynamic-boundaries.js.map +1 -0
  214. package/dist/mcp/engine.d.ts +4 -4
  215. package/dist/mcp/engine.d.ts.map +1 -1
  216. package/dist/mcp/engine.js +32 -24
  217. package/dist/mcp/engine.js.map +1 -1
  218. package/dist/mcp/index.d.ts +8 -7
  219. package/dist/mcp/index.d.ts.map +1 -1
  220. package/dist/mcp/index.js +39 -18
  221. package/dist/mcp/index.js.map +1 -1
  222. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  223. package/dist/mcp/liveness-watchdog.d.ts.map +1 -0
  224. package/dist/mcp/liveness-watchdog.js +207 -0
  225. package/dist/mcp/liveness-watchdog.js.map +1 -0
  226. package/dist/mcp/proxy.d.ts +6 -0
  227. package/dist/mcp/proxy.d.ts.map +1 -1
  228. package/dist/mcp/proxy.js +75 -18
  229. package/dist/mcp/proxy.js.map +1 -1
  230. package/dist/mcp/server-instructions.d.ts +22 -7
  231. package/dist/mcp/server-instructions.d.ts.map +1 -1
  232. package/dist/mcp/server-instructions.js +91 -59
  233. package/dist/mcp/server-instructions.js.map +1 -1
  234. package/dist/mcp/session.d.ts +3 -1
  235. package/dist/mcp/session.d.ts.map +1 -1
  236. package/dist/mcp/session.js +43 -7
  237. package/dist/mcp/session.js.map +1 -1
  238. package/dist/mcp/stdin-teardown.d.ts +27 -0
  239. package/dist/mcp/stdin-teardown.d.ts.map +1 -0
  240. package/dist/mcp/stdin-teardown.js +49 -0
  241. package/dist/mcp/stdin-teardown.js.map +1 -0
  242. package/dist/mcp/tools.d.ts +137 -16
  243. package/dist/mcp/tools.d.ts.map +1 -1
  244. package/dist/mcp/tools.js +1271 -219
  245. package/dist/mcp/tools.js.map +1 -1
  246. package/dist/mcp/transport.d.ts +1 -1
  247. package/dist/mcp/transport.d.ts.map +1 -1
  248. package/dist/mcp/transport.js +20 -4
  249. package/dist/mcp/transport.js.map +1 -1
  250. package/dist/mcp/version.d.ts +1 -1
  251. package/dist/mcp/version.js +2 -2
  252. package/dist/project-config.d.ts +36 -0
  253. package/dist/project-config.d.ts.map +1 -0
  254. package/dist/project-config.js +235 -0
  255. package/dist/project-config.js.map +1 -0
  256. package/dist/reasoning/config.d.ts +45 -0
  257. package/dist/reasoning/config.d.ts.map +1 -0
  258. package/dist/reasoning/config.js +171 -0
  259. package/dist/reasoning/config.js.map +1 -0
  260. package/dist/reasoning/credentials.d.ts +5 -0
  261. package/dist/reasoning/credentials.d.ts.map +1 -0
  262. package/dist/reasoning/credentials.js +83 -0
  263. package/dist/reasoning/credentials.js.map +1 -0
  264. package/dist/reasoning/login.d.ts +21 -0
  265. package/dist/reasoning/login.d.ts.map +1 -0
  266. package/dist/reasoning/login.js +85 -0
  267. package/dist/reasoning/login.js.map +1 -0
  268. package/dist/reasoning/reasoner.d.ts +43 -0
  269. package/dist/reasoning/reasoner.d.ts.map +1 -0
  270. package/dist/reasoning/reasoner.js +308 -0
  271. package/dist/reasoning/reasoner.js.map +1 -0
  272. package/dist/resolution/c-fnptr-synthesizer.d.ts +33 -0
  273. package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -0
  274. package/dist/resolution/c-fnptr-synthesizer.js +352 -0
  275. package/dist/resolution/c-fnptr-synthesizer.js.map +1 -0
  276. package/dist/resolution/callback-synthesizer.d.ts +6 -1
  277. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  278. package/dist/resolution/callback-synthesizer.js +1197 -1
  279. package/dist/resolution/callback-synthesizer.js.map +1 -1
  280. package/dist/resolution/frameworks/arkts-entry.d.ts +12 -0
  281. package/dist/resolution/frameworks/arkts-entry.d.ts.map +1 -0
  282. package/dist/resolution/frameworks/arkts-entry.js +214 -0
  283. package/dist/resolution/frameworks/arkts-entry.js.map +1 -0
  284. package/dist/resolution/frameworks/arkts-napi.d.ts +3 -0
  285. package/dist/resolution/frameworks/arkts-napi.d.ts.map +1 -0
  286. package/dist/resolution/frameworks/arkts-napi.js +166 -0
  287. package/dist/resolution/frameworks/arkts-napi.js.map +1 -0
  288. package/dist/resolution/frameworks/astro.d.ts +9 -0
  289. package/dist/resolution/frameworks/astro.d.ts.map +1 -0
  290. package/dist/resolution/frameworks/astro.js +169 -0
  291. package/dist/resolution/frameworks/astro.js.map +1 -0
  292. package/dist/resolution/frameworks/goframe.d.ts +41 -0
  293. package/dist/resolution/frameworks/goframe.d.ts.map +1 -0
  294. package/dist/resolution/frameworks/goframe.js +112 -0
  295. package/dist/resolution/frameworks/goframe.js.map +1 -0
  296. package/dist/resolution/frameworks/index.d.ts +3 -0
  297. package/dist/resolution/frameworks/index.d.ts.map +1 -1
  298. package/dist/resolution/frameworks/index.js +17 -1
  299. package/dist/resolution/frameworks/index.js.map +1 -1
  300. package/dist/resolution/frameworks/java.js +6 -1
  301. package/dist/resolution/frameworks/java.js.map +1 -1
  302. package/dist/resolution/frameworks/react.d.ts.map +1 -1
  303. package/dist/resolution/frameworks/react.js +32 -63
  304. package/dist/resolution/frameworks/react.js.map +1 -1
  305. package/dist/resolution/frameworks/svelte.js +6 -2
  306. package/dist/resolution/frameworks/svelte.js.map +1 -1
  307. package/dist/resolution/frameworks/vue.js +24 -27
  308. package/dist/resolution/frameworks/vue.js.map +1 -1
  309. package/dist/resolution/goframe-synthesizer.d.ts +28 -0
  310. package/dist/resolution/goframe-synthesizer.d.ts.map +1 -0
  311. package/dist/resolution/goframe-synthesizer.js +158 -0
  312. package/dist/resolution/goframe-synthesizer.js.map +1 -0
  313. package/dist/resolution/import-resolver.d.ts +10 -0
  314. package/dist/resolution/import-resolver.d.ts.map +1 -1
  315. package/dist/resolution/import-resolver.js +125 -2
  316. package/dist/resolution/import-resolver.js.map +1 -1
  317. package/dist/resolution/index.d.ts +37 -0
  318. package/dist/resolution/index.d.ts.map +1 -1
  319. package/dist/resolution/index.js +306 -3
  320. package/dist/resolution/index.js.map +1 -1
  321. package/dist/resolution/name-matcher.d.ts +41 -0
  322. package/dist/resolution/name-matcher.d.ts.map +1 -1
  323. package/dist/resolution/name-matcher.js +519 -14
  324. package/dist/resolution/name-matcher.js.map +1 -1
  325. package/dist/resolution/strip-comments.d.ts +1 -1
  326. package/dist/resolution/strip-comments.d.ts.map +1 -1
  327. package/dist/resolution/strip-comments.js +2 -0
  328. package/dist/resolution/strip-comments.js.map +1 -1
  329. package/dist/resolution/types.d.ts +20 -3
  330. package/dist/resolution/types.d.ts.map +1 -1
  331. package/dist/search/query-utils.d.ts +17 -1
  332. package/dist/search/query-utils.d.ts.map +1 -1
  333. package/dist/search/query-utils.js +79 -10
  334. package/dist/search/query-utils.js.map +1 -1
  335. package/dist/sync/git-hooks.d.ts +4 -4
  336. package/dist/sync/git-hooks.js +5 -5
  337. package/dist/sync/watcher.d.ts +69 -2
  338. package/dist/sync/watcher.d.ts.map +1 -1
  339. package/dist/sync/watcher.js +226 -21
  340. package/dist/sync/watcher.js.map +1 -1
  341. package/dist/sync/worktree.d.ts +3 -3
  342. package/dist/sync/worktree.js +5 -5
  343. package/dist/telemetry/index.d.ts +143 -0
  344. package/dist/telemetry/index.d.ts.map +1 -0
  345. package/dist/telemetry/index.js +541 -0
  346. package/dist/telemetry/index.js.map +1 -0
  347. package/dist/types.d.ts +18 -3
  348. package/dist/types.d.ts.map +1 -1
  349. package/dist/types.js +3 -1
  350. package/dist/types.js.map +1 -1
  351. package/dist/upgrade/index.d.ts.map +1 -1
  352. package/dist/upgrade/index.js +46 -10
  353. package/dist/upgrade/index.js.map +1 -1
  354. package/dist/utils.d.ts +46 -27
  355. package/dist/utils.d.ts.map +1 -1
  356. package/dist/utils.js +87 -53
  357. package/dist/utils.js.map +1 -1
  358. package/package.json +57 -57
  359. package/scripts/add-lang/bench.sh +60 -60
  360. package/scripts/add-lang/check-grammar.mjs +75 -75
  361. package/scripts/add-lang/dump-ast.mjs +103 -103
  362. package/scripts/add-lang/verify-extraction.mjs +70 -70
  363. package/scripts/agent-eval/ab-adoption.sh +91 -0
  364. package/scripts/agent-eval/ab-hook.sh +86 -0
  365. package/scripts/agent-eval/ab-impl.sh +78 -0
  366. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -0
  367. package/scripts/agent-eval/ab-sufficiency.sh +78 -0
  368. package/scripts/agent-eval/arms-F.sh +21 -21
  369. package/scripts/agent-eval/arms-matrix.sh +37 -37
  370. package/scripts/agent-eval/audit.sh +68 -68
  371. package/scripts/agent-eval/bench-readme.sh +28 -28
  372. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  373. package/scripts/agent-eval/block-read-hook.sh +19 -19
  374. package/scripts/agent-eval/hook-settings.json +15 -15
  375. package/scripts/agent-eval/itrun.sh +120 -120
  376. package/scripts/agent-eval/offload-eval-3arm.sh +72 -0
  377. package/scripts/agent-eval/offload-eval-cost.mjs +133 -0
  378. package/scripts/agent-eval/offload-eval-effort.mjs +108 -0
  379. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -0
  380. package/scripts/agent-eval/offload-eval-frontload.sh +47 -0
  381. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -0
  382. package/scripts/agent-eval/offload-eval-hook.mjs +84 -0
  383. package/scripts/agent-eval/offload-eval-judge.mjs +103 -0
  384. package/scripts/agent-eval/offload-eval-matrix.sh +20 -0
  385. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -0
  386. package/scripts/agent-eval/offload-eval-refs1.sh +50 -0
  387. package/scripts/agent-eval/offload-eval-setup.sh +24 -0
  388. package/scripts/agent-eval/offload-eval-styles.sh +72 -0
  389. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -0
  390. package/scripts/agent-eval/offload-eval.md +76 -0
  391. package/scripts/agent-eval/parse-arms.mjs +116 -116
  392. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  393. package/scripts/agent-eval/parse-run.mjs +45 -45
  394. package/scripts/agent-eval/parse-session.mjs +93 -93
  395. package/scripts/agent-eval/probe-context.mjs +21 -21
  396. package/scripts/agent-eval/probe-explore.mjs +40 -40
  397. package/scripts/agent-eval/probe-node.mjs +20 -20
  398. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  399. package/scripts/agent-eval/probe-trace.mjs +20 -20
  400. package/scripts/agent-eval/redirect-read-hook.sh +38 -0
  401. package/scripts/agent-eval/run-agent.sh +34 -34
  402. package/scripts/agent-eval/run-all.sh +69 -67
  403. package/scripts/agent-eval/run-arms.sh +56 -56
  404. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  405. package/scripts/build-bundle.sh +118 -118
  406. package/scripts/extract-release-notes.mjs +130 -130
  407. package/scripts/local-install.sh +41 -41
  408. package/scripts/npm-sdk.js +75 -75
  409. package/scripts/npm-shim.js +246 -246
  410. package/scripts/pack-npm.sh +119 -119
  411. package/scripts/prepare-release.mjs +270 -270
  412. package/scripts/qa_eval/README.md +400 -0
  413. package/scripts/qa_eval/agent_runner.py +526 -0
  414. package/scripts/qa_eval/data/.gitignore +4 -0
  415. package/scripts/qa_eval/data/test-set.jsonl +22 -0
  416. package/scripts/qa_eval/eval_metrics.py +233 -0
  417. package/scripts/qa_eval/external_agent.py +577 -0
  418. package/scripts/qa_eval/llm_config.py +92 -0
  419. package/scripts/qa_eval/memory_monitor.py +132 -0
  420. package/scripts/qa_eval/my_answer_accuracy.py +187 -0
  421. package/scripts/qa_eval/requirements.txt +2 -0
  422. package/scripts/qa_eval/run_pipeline.py +702 -0
  423. package/scripts/qa_eval/stats_efficiency.py +279 -0
  424. package/scripts/qa_eval/stats_scores.py +207 -0
  425. package/dist/bin/codegraph.d.ts +0 -26
  426. package/dist/bin/codegraph.d.ts.map +0 -1
  427. package/dist/bin/codegraph.js +0 -1572
  428. package/dist/bin/codegraph.js.map +0 -1
  429. package/dist/extraction/arkanalyzer-extractor.d.ts +0 -6
  430. package/dist/extraction/arkanalyzer-extractor.d.ts.map +0 -1
  431. package/dist/extraction/arkanalyzer-extractor.js +0 -11
  432. package/dist/extraction/arkanalyzer-extractor.js.map +0 -1
  433. package/dist/extraction/arkanalyzer-project.d.ts +0 -20
  434. package/dist/extraction/arkanalyzer-project.d.ts.map +0 -1
  435. package/dist/extraction/arkanalyzer-project.js +0 -596
  436. package/dist/extraction/arkanalyzer-project.js.map +0 -1
@@ -1,31 +1,112 @@
1
1
  /**
2
2
  * Directory Management
3
3
  *
4
- * Manages the .homegraph/ directory structure for CodeGraph data.
4
+ * Manages the .homegraph/ directory structure for HomeGraph data.
5
5
  */
6
6
  /**
7
- * CodeGraph directory name
7
+ * Resolve the per-project data directory name, honoring the `HOMEGRAPH_DIR`
8
+ * environment override (default `.homegraph`). The override is a single path
9
+ * segment that lives in the project root.
10
+ *
11
+ * Why this exists: two environments that share one working tree must NOT share
12
+ * one `.homegraph/` — most concretely Windows-native and WSL (issue #636). The
13
+ * daemon lockfile (`.homegraph/daemon.pid`) records a platform-specific pid and
14
+ * socket path (a Windows named pipe vs a WSL Unix socket), and SQLite file
15
+ * locking across the WSL2 ↔ Windows filesystem boundary is unreliable, so two
16
+ * daemons sharing one index risks corruption. Setting `HOMEGRAPH_DIR=.homegraph-win`
17
+ * on one side gives each environment its own index in the same tree.
18
+ *
19
+ * Read live (not captured at load) so it is both process-accurate and testable.
20
+ * An override that isn't a plain directory name — empty, containing a path
21
+ * separator, `.`, `..`/traversal, or absolute — is ignored (we keep the
22
+ * default) rather than risk writing the index outside the project or into the
23
+ * project root itself; we warn once to stderr so the misconfiguration is seen.
8
24
  */
25
+ export declare function homeGraphDirName(): string;
26
+ /** Default data directory name (also honors {@link homeGraphDirName} at runtime). */
9
27
  export declare const HOMEGRAPH_DIR = ".homegraph";
28
+ /**
29
+ * Is `name` (a single path segment) a HomeGraph data directory? Matches the
30
+ * default `.homegraph`, the active override, and any `.homegraph-*` sibling.
31
+ */
32
+ export declare function isHomeGraphDataDir(name: string): boolean;
10
33
  /**
11
34
  * Get the .homegraph directory path for a project
12
35
  */
13
- export declare function getCodeGraphDir(projectRoot: string): string;
36
+ export declare function getHomeGraphDir(projectRoot: string): string;
14
37
  /**
15
- * Check if a project has been initialized with CodeGraph
38
+ * Check if a project has been initialized with HomeGraph
16
39
  * Requires both .homegraph/ directory AND homegraph.db to exist
17
40
  */
18
41
  export declare function isInitialized(projectRoot: string): boolean;
19
42
  /**
20
43
  * Find the nearest parent directory containing .homegraph/
21
44
  *
22
- * Walks up from the given path to find a CodeGraph-initialized project,
45
+ * Walks up from the given path to find a HomeGraph-initialized project,
23
46
  * similar to how git finds .git/ directories.
24
47
  *
25
48
  * @param startPath - Directory to start searching from
26
49
  * @returns The project root containing .homegraph/, or null if not found
27
50
  */
28
- export declare function findNearestCodeGraphRoot(startPath: string): string | null;
51
+ /**
52
+ * Reason a directory is unsafe to use as an index ROOT, or null when it's fine.
53
+ *
54
+ * Indexing your home directory or a filesystem root drags in caches, `Library`,
55
+ * every other project, etc. — a multi-GB index, constant file-watcher churn, and
56
+ * (pre-1.0 on macOS) a file-descriptor blowup that exhausted `kern.maxfiles` and
57
+ * took unrelated apps / the whole machine down (#845). The classic trigger:
58
+ * running the installer or `homegraph init` from `$HOME`, which auto-indexes the
59
+ * current directory. These are never intended project roots, so the installer
60
+ * and `init`/`index` refuse them (overridable with `--force`).
61
+ *
62
+ * Pure-ish (reads only `os.homedir()` + realpath) so it's easy to unit-test.
63
+ * The returned string is a human phrase that slots into "… looks like {reason}".
64
+ */
65
+ export declare function unsafeIndexRootReason(projectRoot: string): string | null;
66
+ export declare function findNearestHomeGraphRoot(startPath: string): string | null;
67
+ /**
68
+ * Indexed sub-project roots beneath `root` (bounded breadth-first scan). For
69
+ * the monorepo case behind #964: the index lives in a CHILD
70
+ * (`packages/x/.homegraph/`), not at the workspace root the agent's cwd points
71
+ * at. Descent stops at the first indexed directory on a branch (a project's
72
+ * own sub-dirs aren't separate projects) and is bounded by depth + count so it
73
+ * never turns into a full-tree crawl on a large repo.
74
+ */
75
+ export declare function findIndexedSubprojectRoots(root: string, opts?: {
76
+ maxDepth?: number;
77
+ max?: number;
78
+ }): string[];
79
+ /**
80
+ * What the front-load hook should do for a prompt issued from a directory.
81
+ */
82
+ export interface FrontloadPlan {
83
+ /** Open + explore this project and inject its source as context. `null` when
84
+ * there's no single project to front-load (none indexed, or several indexed
85
+ * sub-projects with no clear match — see {@link nudgeProjects}). */
86
+ exploreRoot: string | null;
87
+ /** Indexed sub-projects to surface in a "pass `projectPath`" nudge: the rest
88
+ * of a monorepo's indexed projects alongside `exploreRoot`, or — when no one
89
+ * project clearly matches — the full list (with `exploreRoot` null). */
90
+ nudgeProjects: string[];
91
+ /** True when the plan came from scanning DOWN into sub-projects (cwd itself
92
+ * is not under any index) — the monorepo case, where a follow-up
93
+ * `homegraph_explore` needs an explicit `projectPath`. */
94
+ viaSubScan: boolean;
95
+ }
96
+ /**
97
+ * Decide what the front-load hook injects for a `prompt` issued from `cwd`,
98
+ * shaped by where the `.homegraph/` index(es) actually are:
99
+ * 1. **cwd (or an ancestor) is indexed** → front-load that project. The
100
+ * normal single-project / nested-file case.
101
+ * 2. **cwd isn't indexed but looks like a workspace root** → the indexes live
102
+ * in sub-projects (the monorepo case behind #964). One indexed
103
+ * sub-project → front-load it; several → front-load the one the prompt
104
+ * names (by relative path like `packages/api`, or package directory name)
105
+ * and nudge about the rest; several with no match → nudge the full list so
106
+ * the agent passes `projectPath`, rather than guessing wrong.
107
+ * 3. **nothing indexed reachable** → do nothing (the agent's own tools apply).
108
+ */
109
+ export declare function planFrontload(cwd: string, prompt: string): FrontloadPlan;
29
110
  /**
30
111
  * Create the .homegraph directory structure
31
112
  * Note: Only throws if homegraph.db already exists, not just if .homegraph/ exists.
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBzE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAyBzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAuBzD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+B5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAYlF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CA8BA"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAqBzC;AAED,qFAAqF;AACrF,eAAO,MAAM,aAAa,eAAwB,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAED;;;;;;;;GAQG;AACH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA8BxE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBzE;AA2BD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,MAAM,EAAE,CAmBV;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;yEAEqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;6EAEyE;IACzE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;+DAE2D;IAC3D,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAwCxE;AAyDD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAgBzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAuBzD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+B5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAYlF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CA6BA"}
package/dist/directory.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Directory Management
4
4
  *
5
- * Manages the .homegraph/ directory structure for CodeGraph data.
5
+ * Manages the .homegraph/ directory structure for HomeGraph data.
6
6
  */
7
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
8
  if (k2 === undefined) k2 = k;
@@ -39,9 +39,14 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  })();
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
41
  exports.HOMEGRAPH_DIR = void 0;
42
- exports.getCodeGraphDir = getCodeGraphDir;
42
+ exports.homeGraphDirName = homeGraphDirName;
43
+ exports.isHomeGraphDataDir = isHomeGraphDataDir;
44
+ exports.getHomeGraphDir = getHomeGraphDir;
43
45
  exports.isInitialized = isInitialized;
44
- exports.findNearestCodeGraphRoot = findNearestCodeGraphRoot;
46
+ exports.unsafeIndexRootReason = unsafeIndexRootReason;
47
+ exports.findNearestHomeGraphRoot = findNearestHomeGraphRoot;
48
+ exports.findIndexedSubprojectRoots = findIndexedSubprojectRoots;
49
+ exports.planFrontload = planFrontload;
45
50
  exports.createDirectory = createDirectory;
46
51
  exports.removeDirectory = removeDirectory;
47
52
  exports.listDirectoryContents = listDirectoryContents;
@@ -49,40 +54,133 @@ exports.getDirectorySize = getDirectorySize;
49
54
  exports.ensureSubdirectory = ensureSubdirectory;
50
55
  exports.validateDirectory = validateDirectory;
51
56
  const fs = __importStar(require("fs"));
57
+ const os = __importStar(require("os"));
52
58
  const path = __importStar(require("path"));
59
+ /** The default per-project data directory name. */
60
+ const DEFAULT_HOMEGRAPH_DIR = '.homegraph';
61
+ let warnedBadDirName = false;
53
62
  /**
54
- * CodeGraph directory name
63
+ * Resolve the per-project data directory name, honoring the `HOMEGRAPH_DIR`
64
+ * environment override (default `.homegraph`). The override is a single path
65
+ * segment that lives in the project root.
66
+ *
67
+ * Why this exists: two environments that share one working tree must NOT share
68
+ * one `.homegraph/` — most concretely Windows-native and WSL (issue #636). The
69
+ * daemon lockfile (`.homegraph/daemon.pid`) records a platform-specific pid and
70
+ * socket path (a Windows named pipe vs a WSL Unix socket), and SQLite file
71
+ * locking across the WSL2 ↔ Windows filesystem boundary is unreliable, so two
72
+ * daemons sharing one index risks corruption. Setting `HOMEGRAPH_DIR=.homegraph-win`
73
+ * on one side gives each environment its own index in the same tree.
74
+ *
75
+ * Read live (not captured at load) so it is both process-accurate and testable.
76
+ * An override that isn't a plain directory name — empty, containing a path
77
+ * separator, `.`, `..`/traversal, or absolute — is ignored (we keep the
78
+ * default) rather than risk writing the index outside the project or into the
79
+ * project root itself; we warn once to stderr so the misconfiguration is seen.
80
+ */
81
+ function homeGraphDirName() {
82
+ const raw = process.env.HOMEGRAPH_DIR?.trim();
83
+ if (!raw)
84
+ return DEFAULT_HOMEGRAPH_DIR;
85
+ const invalid = raw === '.' ||
86
+ raw.includes('..') ||
87
+ raw.includes('/') ||
88
+ raw.includes('\\') ||
89
+ path.isAbsolute(raw);
90
+ if (invalid) {
91
+ if (!warnedBadDirName) {
92
+ warnedBadDirName = true;
93
+ // stderr only — stdout is the MCP protocol channel.
94
+ console.warn(`[homegraph] Ignoring invalid HOMEGRAPH_DIR="${raw}" — it must be a plain ` +
95
+ `directory name (no path separators, no "..", not absolute). Using "${DEFAULT_HOMEGRAPH_DIR}".`);
96
+ }
97
+ return DEFAULT_HOMEGRAPH_DIR;
98
+ }
99
+ return raw;
100
+ }
101
+ /** Default data directory name (also honors {@link homeGraphDirName} at runtime). */
102
+ exports.HOMEGRAPH_DIR = DEFAULT_HOMEGRAPH_DIR;
103
+ /**
104
+ * Is `name` (a single path segment) a HomeGraph data directory? Matches the
105
+ * default `.homegraph`, the active override, and any `.homegraph-*` sibling.
55
106
  */
56
- exports.HOMEGRAPH_DIR = '.homegraph';
107
+ function isHomeGraphDataDir(name) {
108
+ const active = homeGraphDirName();
109
+ return (name === DEFAULT_HOMEGRAPH_DIR ||
110
+ name === active ||
111
+ name.startsWith(DEFAULT_HOMEGRAPH_DIR + '-'));
112
+ }
57
113
  /**
58
114
  * Get the .homegraph directory path for a project
59
115
  */
60
- function getCodeGraphDir(projectRoot) {
61
- return path.join(projectRoot, exports.HOMEGRAPH_DIR);
116
+ function getHomeGraphDir(projectRoot) {
117
+ return path.join(projectRoot, homeGraphDirName());
62
118
  }
63
119
  /**
64
- * Check if a project has been initialized with CodeGraph
120
+ * Check if a project has been initialized with HomeGraph
65
121
  * Requires both .homegraph/ directory AND homegraph.db to exist
66
122
  */
67
123
  function isInitialized(projectRoot) {
68
- const codegraphDir = getCodeGraphDir(projectRoot);
69
- if (!fs.existsSync(codegraphDir) || !fs.statSync(codegraphDir).isDirectory()) {
124
+ const homegraphDir = getHomeGraphDir(projectRoot);
125
+ if (!fs.existsSync(homegraphDir) || !fs.statSync(homegraphDir).isDirectory()) {
70
126
  return false;
71
127
  }
72
128
  // Must have homegraph.db, not just .homegraph folder
73
- const dbPath = path.join(codegraphDir, 'homegraph.db');
129
+ const dbPath = path.join(homegraphDir, 'homegraph.db');
74
130
  return fs.existsSync(dbPath);
75
131
  }
76
132
  /**
77
133
  * Find the nearest parent directory containing .homegraph/
78
134
  *
79
- * Walks up from the given path to find a CodeGraph-initialized project,
135
+ * Walks up from the given path to find a HomeGraph-initialized project,
80
136
  * similar to how git finds .git/ directories.
81
137
  *
82
138
  * @param startPath - Directory to start searching from
83
139
  * @returns The project root containing .homegraph/, or null if not found
84
140
  */
85
- function findNearestCodeGraphRoot(startPath) {
141
+ /**
142
+ * Reason a directory is unsafe to use as an index ROOT, or null when it's fine.
143
+ *
144
+ * Indexing your home directory or a filesystem root drags in caches, `Library`,
145
+ * every other project, etc. — a multi-GB index, constant file-watcher churn, and
146
+ * (pre-1.0 on macOS) a file-descriptor blowup that exhausted `kern.maxfiles` and
147
+ * took unrelated apps / the whole machine down (#845). The classic trigger:
148
+ * running the installer or `homegraph init` from `$HOME`, which auto-indexes the
149
+ * current directory. These are never intended project roots, so the installer
150
+ * and `init`/`index` refuse them (overridable with `--force`).
151
+ *
152
+ * Pure-ish (reads only `os.homedir()` + realpath) so it's easy to unit-test.
153
+ * The returned string is a human phrase that slots into "… looks like {reason}".
154
+ */
155
+ function unsafeIndexRootReason(projectRoot) {
156
+ const resolve = (p) => {
157
+ try {
158
+ return fs.realpathSync(path.resolve(p));
159
+ }
160
+ catch {
161
+ return path.resolve(p);
162
+ }
163
+ };
164
+ const resolved = resolve(projectRoot);
165
+ // Filesystem root: `/` on POSIX, a drive root like `C:\` on Windows.
166
+ if (path.parse(resolved).root === resolved) {
167
+ return 'the filesystem root';
168
+ }
169
+ const home = resolve(os.homedir());
170
+ // Case-insensitive on macOS/Windows (case-preserving but case-insensitive FS).
171
+ const norm = (p) => process.platform === 'darwin' || process.platform === 'win32' ? p.toLowerCase() : p;
172
+ const r = norm(resolved);
173
+ const h = norm(home);
174
+ if (r === h) {
175
+ return 'your home directory';
176
+ }
177
+ // An ancestor of home (e.g. `/Users`, `/home`) — even broader than home.
178
+ if (h.startsWith(r + path.sep)) {
179
+ return 'a parent of your home directory';
180
+ }
181
+ return null;
182
+ }
183
+ function findNearestHomeGraphRoot(startPath) {
86
184
  let current = path.resolve(startPath);
87
185
  const root = path.parse(current).root;
88
186
  while (current !== root) {
@@ -100,61 +198,227 @@ function findNearestCodeGraphRoot(startPath) {
100
198
  }
101
199
  return null;
102
200
  }
201
+ /** Heavy/irrelevant directory names the sub-project scan never descends into. */
202
+ const SUBPROJECT_SCAN_SKIP = new Set([
203
+ 'node_modules', '.git', '.svn', '.hg', 'dist', 'build', 'out', 'target',
204
+ 'vendor', 'bin', 'obj', '.next', '.nuxt', '.svelte-kit', '.cache', 'coverage',
205
+ '.venv', 'venv', '__pycache__', '.turbo', '.idea', '.vscode', 'tmp', 'temp',
206
+ ]);
207
+ /** Manifests that mark a directory as a project/workspace root. The down-scan
208
+ * is gated on one of these so a non-project cwd (e.g. `$HOME`) is a cheap
209
+ * no-op instead of a deep filesystem crawl. */
210
+ const WORKSPACE_ROOT_MANIFESTS = [
211
+ 'package.json', 'pnpm-workspace.yaml', 'lerna.json', 'nx.json', 'turbo.json',
212
+ 'go.work', 'go.mod', 'Cargo.toml', 'pom.xml', 'build.gradle', 'build.gradle.kts',
213
+ 'settings.gradle', 'pyproject.toml', 'composer.json', 'Gemfile', 'rush.json',
214
+ 'WORKSPACE', 'WORKSPACE.bazel',
215
+ ];
216
+ function looksLikeProjectRoot(dir) {
217
+ return WORKSPACE_ROOT_MANIFESTS.some((m) => fs.existsSync(path.join(dir, m)));
218
+ }
219
+ function escapeRegExp(s) {
220
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
221
+ }
222
+ /**
223
+ * Indexed sub-project roots beneath `root` (bounded breadth-first scan). For
224
+ * the monorepo case behind #964: the index lives in a CHILD
225
+ * (`packages/x/.homegraph/`), not at the workspace root the agent's cwd points
226
+ * at. Descent stops at the first indexed directory on a branch (a project's
227
+ * own sub-dirs aren't separate projects) and is bounded by depth + count so it
228
+ * never turns into a full-tree crawl on a large repo.
229
+ */
230
+ function findIndexedSubprojectRoots(root, opts = {}) {
231
+ const maxDepth = opts.maxDepth ?? 4;
232
+ const max = opts.max ?? 64;
233
+ const out = [];
234
+ const walk = (dir, depth) => {
235
+ if (out.length >= max || depth > maxDepth)
236
+ return;
237
+ let entries;
238
+ try {
239
+ entries = fs.readdirSync(dir, { withFileTypes: true });
240
+ }
241
+ catch {
242
+ return;
243
+ }
244
+ for (const e of entries) {
245
+ if (out.length >= max)
246
+ return;
247
+ if (!e.isDirectory())
248
+ continue;
249
+ if (e.name.startsWith('.') || SUBPROJECT_SCAN_SKIP.has(e.name))
250
+ continue;
251
+ const child = path.join(dir, e.name);
252
+ if (isInitialized(child)) {
253
+ out.push(child);
254
+ continue;
255
+ } // don't descend into an indexed project
256
+ walk(child, depth + 1);
257
+ }
258
+ };
259
+ walk(root, 1);
260
+ return out;
261
+ }
262
+ /**
263
+ * Decide what the front-load hook injects for a `prompt` issued from `cwd`,
264
+ * shaped by where the `.homegraph/` index(es) actually are:
265
+ * 1. **cwd (or an ancestor) is indexed** → front-load that project. The
266
+ * normal single-project / nested-file case.
267
+ * 2. **cwd isn't indexed but looks like a workspace root** → the indexes live
268
+ * in sub-projects (the monorepo case behind #964). One indexed
269
+ * sub-project → front-load it; several → front-load the one the prompt
270
+ * names (by relative path like `packages/api`, or package directory name)
271
+ * and nudge about the rest; several with no match → nudge the full list so
272
+ * the agent passes `projectPath`, rather than guessing wrong.
273
+ * 3. **nothing indexed reachable** → do nothing (the agent's own tools apply).
274
+ */
275
+ function planFrontload(cwd, prompt) {
276
+ const none = { exploreRoot: null, nudgeProjects: [], viaSubScan: false };
277
+ // 1. up-walk — nearest indexed ancestor (incl. cwd). Cheap; covers the common
278
+ // single-project case without a down-scan.
279
+ let dir = path.resolve(cwd);
280
+ for (let i = 0; i < 6; i++) {
281
+ if (isInitialized(dir))
282
+ return { exploreRoot: dir, nudgeProjects: [], viaSubScan: false };
283
+ const parent = path.dirname(dir);
284
+ if (parent === dir)
285
+ break;
286
+ dir = parent;
287
+ }
288
+ // 2. down-scan — only from something that looks like a workspace root, so a
289
+ // non-project cwd (e.g. $HOME) is a cheap no-op, not a deep crawl.
290
+ const base = path.resolve(cwd);
291
+ if (!looksLikeProjectRoot(base))
292
+ return none;
293
+ const subs = findIndexedSubprojectRoots(base);
294
+ if (subs.length === 0)
295
+ return none;
296
+ if (subs.length === 1)
297
+ return { exploreRoot: subs[0], nudgeProjects: [], viaSubScan: true };
298
+ // Several indexed sub-projects — pick the one the prompt points at, if any.
299
+ const p = prompt.toLowerCase();
300
+ let best = null;
301
+ for (const s of subs) {
302
+ const rel = path.relative(base, s);
303
+ const relLc = rel.split(path.sep).join('/').toLowerCase();
304
+ const name = path.basename(s).toLowerCase();
305
+ let score = 0;
306
+ if (relLc && p.includes(relLc))
307
+ score = 10; // "packages/api"
308
+ else if (name.length >= 3 && new RegExp(`\\b${escapeRegExp(name)}\\b`).test(p))
309
+ score = 5; // "api"
310
+ if (score > 0 && (!best || score > best.score || (score === best.score && rel.length < best.relLen))) {
311
+ best = { root: s, score, relLen: rel.length };
312
+ }
313
+ }
314
+ if (best) {
315
+ return { exploreRoot: best.root, nudgeProjects: subs.filter((s) => s !== best.root), viaSubScan: true };
316
+ }
317
+ // No clear match — nudge the full list rather than front-load a guess.
318
+ return { exploreRoot: null, nudgeProjects: subs, viaSubScan: true };
319
+ }
320
+ /**
321
+ * Contents of `.homegraph/.gitignore`. A single wildcard ignore keeps every
322
+ * transient file in the index dir — the database, `daemon.pid`, the socket,
323
+ * logs, cache, and anything future versions add — out of git, without having
324
+ * to enumerate each name (issues #788, #492, #484). Older versions wrote an
325
+ * explicit allowlist that never listed `daemon.pid` or the socket, so those
326
+ * runtime files were silently committed.
327
+ */
328
+ const GITIGNORE_CONTENT = `# HomeGraph data files — local to each machine, not for committing.
329
+ # Ignore everything in .homegraph/ except this file itself, so transient
330
+ # files (the database, daemon.pid, sockets, logs) never show up in git.
331
+ *
332
+ !.gitignore
333
+ `;
334
+ /** Header line that prefixes every .gitignore HomeGraph has auto-generated. */
335
+ const GITIGNORE_MARKER = '# HomeGraph data files';
336
+ /**
337
+ * Is `content` a stale HomeGraph-generated `.gitignore` that should be
338
+ * regenerated in place? True when it carries our header but predates the
339
+ * wildcard ignore (it has no bare `*` line) — i.e. one of the old explicit
340
+ * allowlists (`*.db`, `cache/`, `.dirty`, …) that never ignored `daemon.pid`
341
+ * or the socket (issue #788). A file WITHOUT our header is user-authored and
342
+ * is left untouched; one that already has the wildcard is current. Matching
343
+ * on the header (not a byte-exact list of past defaults) heals every old
344
+ * variant — v0.7.x through 0.9.9 — and is idempotent once upgraded.
345
+ */
346
+ function isStaleDefaultGitignore(content) {
347
+ if (!content.trimStart().startsWith(GITIGNORE_MARKER))
348
+ return false;
349
+ return !content.split('\n').some((line) => line.trim() === '*');
350
+ }
351
+ /**
352
+ * Write `.homegraph/.gitignore` if it's absent, or upgrade a stale
353
+ * HomeGraph-generated default in place; a user-customized file is left alone.
354
+ * Best-effort — returns `false` only if a needed write failed.
355
+ */
356
+ function ensureGitignore(gitignorePath) {
357
+ let existing;
358
+ try {
359
+ existing = fs.readFileSync(gitignorePath, 'utf-8');
360
+ }
361
+ catch {
362
+ existing = null; // absent (ENOENT) or unreadable — (re)create below
363
+ }
364
+ // Current default or a user-authored file: nothing to do.
365
+ if (existing !== null && !isStaleDefaultGitignore(existing))
366
+ return true;
367
+ try {
368
+ fs.writeFileSync(gitignorePath, GITIGNORE_CONTENT, 'utf-8');
369
+ return true;
370
+ }
371
+ catch {
372
+ return false;
373
+ }
374
+ }
103
375
  /**
104
376
  * Create the .homegraph directory structure
105
377
  * Note: Only throws if homegraph.db already exists, not just if .homegraph/ exists.
106
378
  */
107
379
  function createDirectory(projectRoot) {
108
- const codegraphDir = getCodeGraphDir(projectRoot);
109
- const dbPath = path.join(codegraphDir, 'homegraph.db');
110
- // Only throw if CodeGraph is actually initialized (db exists)
380
+ const homegraphDir = getHomeGraphDir(projectRoot);
381
+ const dbPath = path.join(homegraphDir, 'homegraph.db');
382
+ // Only throw if HomeGraph is actually initialized (db exists)
111
383
  // .homegraph/ folder alone is fine
112
384
  if (fs.existsSync(dbPath)) {
113
- throw new Error(`CodeGraph already initialized in ${projectRoot}`);
385
+ throw new Error(`HomeGraph already initialized in ${projectRoot}`);
114
386
  }
115
387
  // Create main directory (if it doesn't exist)
116
- fs.mkdirSync(codegraphDir, { recursive: true });
117
- // Create .gitignore inside .homegraph (if it doesn't exist)
118
- const gitignorePath = path.join(codegraphDir, '.gitignore');
119
- if (!fs.existsSync(gitignorePath)) {
120
- const gitignoreContent = `# CodeGraph data files — local to each machine, not for committing.
121
- # Ignore everything in .homegraph/ except this file itself, so transient
122
- # files (the database, daemon.pid, sockets, logs) never show up in git.
123
- *
124
- !.gitignore
125
- `;
126
- fs.writeFileSync(gitignorePath, gitignoreContent, 'utf-8');
127
- }
388
+ fs.mkdirSync(homegraphDir, { recursive: true });
389
+ // Write .gitignore inside .homegraph (create if absent, upgrade a stale
390
+ // pre-wildcard default left by an older version — issue #788).
391
+ ensureGitignore(path.join(homegraphDir, '.gitignore'));
128
392
  }
129
393
  /**
130
394
  * Remove the .homegraph directory
131
395
  */
132
396
  function removeDirectory(projectRoot) {
133
- const codegraphDir = getCodeGraphDir(projectRoot);
134
- if (!fs.existsSync(codegraphDir)) {
397
+ const homegraphDir = getHomeGraphDir(projectRoot);
398
+ if (!fs.existsSync(homegraphDir)) {
135
399
  return;
136
400
  }
137
401
  // Verify .homegraph is a real directory, not a symlink pointing elsewhere
138
- const lstat = fs.lstatSync(codegraphDir);
402
+ const lstat = fs.lstatSync(homegraphDir);
139
403
  if (lstat.isSymbolicLink()) {
140
404
  // Only remove the symlink itself, never follow it for recursive delete
141
- fs.unlinkSync(codegraphDir);
405
+ fs.unlinkSync(homegraphDir);
142
406
  return;
143
407
  }
144
408
  if (!lstat.isDirectory()) {
145
409
  // Not a directory - remove the single file
146
- fs.unlinkSync(codegraphDir);
410
+ fs.unlinkSync(homegraphDir);
147
411
  return;
148
412
  }
149
413
  // Recursively remove directory
150
- fs.rmSync(codegraphDir, { recursive: true, force: true });
414
+ fs.rmSync(homegraphDir, { recursive: true, force: true });
151
415
  }
152
416
  /**
153
417
  * Get all files in the .homegraph directory
154
418
  */
155
419
  function listDirectoryContents(projectRoot) {
156
- const codegraphDir = getCodeGraphDir(projectRoot);
157
- if (!fs.existsSync(codegraphDir)) {
420
+ const homegraphDir = getHomeGraphDir(projectRoot);
421
+ if (!fs.existsSync(homegraphDir)) {
158
422
  return [];
159
423
  }
160
424
  const files = [];
@@ -174,15 +438,15 @@ function listDirectoryContents(projectRoot) {
174
438
  }
175
439
  }
176
440
  }
177
- walkDir(codegraphDir);
441
+ walkDir(homegraphDir);
178
442
  return files;
179
443
  }
180
444
  /**
181
445
  * Get the total size of the .homegraph directory in bytes
182
446
  */
183
447
  function getDirectorySize(projectRoot) {
184
- const codegraphDir = getCodeGraphDir(projectRoot);
185
- if (!fs.existsSync(codegraphDir)) {
448
+ const homegraphDir = getHomeGraphDir(projectRoot);
449
+ if (!fs.existsSync(homegraphDir)) {
186
450
  return 0;
187
451
  }
188
452
  let totalSize = 0;
@@ -203,7 +467,7 @@ function getDirectorySize(projectRoot) {
203
467
  }
204
468
  }
205
469
  }
206
- walkDir(codegraphDir);
470
+ walkDir(homegraphDir);
207
471
  return totalSize;
208
472
  }
209
473
  /**
@@ -213,7 +477,7 @@ function ensureSubdirectory(projectRoot, subdirName) {
213
477
  if (subdirName.includes('..') || subdirName.includes(path.sep) || subdirName.includes('/')) {
214
478
  throw new Error(`Invalid subdirectory name: ${subdirName}`);
215
479
  }
216
- const subdirPath = path.join(getCodeGraphDir(projectRoot), subdirName);
480
+ const subdirPath = path.join(getHomeGraphDir(projectRoot), subdirName);
217
481
  if (!fs.existsSync(subdirPath)) {
218
482
  fs.mkdirSync(subdirPath, { recursive: true });
219
483
  }
@@ -224,26 +488,24 @@ function ensureSubdirectory(projectRoot, subdirName) {
224
488
  */
225
489
  function validateDirectory(projectRoot) {
226
490
  const errors = [];
227
- const codegraphDir = getCodeGraphDir(projectRoot);
228
- if (!fs.existsSync(codegraphDir)) {
229
- errors.push('CodeGraph directory does not exist');
491
+ const homegraphDir = getHomeGraphDir(projectRoot);
492
+ if (!fs.existsSync(homegraphDir)) {
493
+ errors.push('HomeGraph directory does not exist');
230
494
  return { valid: false, errors };
231
495
  }
232
- if (!fs.statSync(codegraphDir).isDirectory()) {
496
+ if (!fs.statSync(homegraphDir).isDirectory()) {
233
497
  errors.push('.homegraph exists but is not a directory');
234
498
  return { valid: false, errors };
235
499
  }
236
- // Auto-repair missing .gitignore (non-critical file)
237
- const gitignorePath = path.join(codegraphDir, '.gitignore');
238
- if (!fs.existsSync(gitignorePath)) {
239
- try {
240
- const gitignoreContent = `# CodeGraph data files — local to each machine, not for committing.\n# Ignore everything in .homegraph/ except this file itself, so transient\n# files (the database, daemon.pid, sockets, logs) never show up in git.\n*\n!.gitignore\n`;
241
- fs.writeFileSync(gitignorePath, gitignoreContent, 'utf-8');
242
- }
243
- catch {
244
- // Non-fatal: warn but don't block
245
- errors.push('.gitignore missing in .homegraph directory and could not be created');
246
- }
500
+ // Auto-repair / upgrade .gitignore (non-critical file). A missing one is
501
+ // recreated; a stale pre-wildcard default that never ignored daemon.pid is
502
+ // regenerated in place (issue #788); a user-authored file is left alone.
503
+ const gitignorePath = path.join(homegraphDir, '.gitignore');
504
+ const existedBefore = fs.existsSync(gitignorePath);
505
+ if (!ensureGitignore(gitignorePath) && !existedBefore) {
506
+ // Only a missing-and-uncreatable file is surfaced; a failed in-place
507
+ // upgrade of an existing file is non-fatal — the index still works.
508
+ errors.push('.gitignore missing in .homegraph directory and could not be created');
247
509
  }
248
510
  return {
249
511
  valid: errors.length === 0,