homegraph 1.5.7 → 1.5.8

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 (550) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -2
  3. package/dist/bin/homegraph.js +16 -14
  4. package/dist/db/index.d.ts +1 -1
  5. package/dist/db/index.js +11 -25
  6. package/dist/db/queries.d.ts +5 -1
  7. package/dist/db/queries.js +31 -2
  8. package/dist/db/sqlite-adapter.d.ts +6 -12
  9. package/dist/db/sqlite-adapter.js +13 -41
  10. package/dist/directory.d.ts +1 -1
  11. package/dist/directory.js +25 -1
  12. package/dist/extraction/grammars.d.ts +2 -0
  13. package/dist/extraction/grammars.js +7 -7
  14. package/dist/graph/evidence-paths.d.ts +63 -0
  15. package/dist/graph/evidence-paths.js +245 -0
  16. package/dist/index.d.ts +6 -1
  17. package/dist/index.js +55 -17
  18. package/dist/mcp/arkts-evidence-packs.d.ts +67 -0
  19. package/dist/mcp/arkts-evidence-packs.js +352 -0
  20. package/dist/mcp/daemon.js +1 -1
  21. package/dist/mcp/engine.d.ts +20 -7
  22. package/dist/mcp/engine.js +113 -106
  23. package/dist/mcp/index-availability.d.ts +23 -0
  24. package/dist/mcp/index-availability.js +78 -0
  25. package/dist/mcp/index.js +5 -4
  26. package/dist/mcp/query-cache.d.ts +1 -1
  27. package/dist/mcp/query-cache.js +6 -2
  28. package/dist/mcp/query-worker.d.ts +1 -1
  29. package/dist/mcp/query-worker.js +1 -1
  30. package/dist/mcp/server-instructions.d.ts +4 -9
  31. package/dist/mcp/server-instructions.js +34 -74
  32. package/dist/mcp/session.js +12 -4
  33. package/dist/mcp/source-slice-identity.d.ts +3 -0
  34. package/dist/mcp/source-slice-identity.js +11 -0
  35. package/dist/mcp/tools.d.ts +24 -6
  36. package/dist/mcp/tools.js +201 -80
  37. package/dist/spec/llm/client.js +3 -15
  38. package/dist/spec/llm/openai-sdk.d.ts +14 -0
  39. package/dist/spec/llm/openai-sdk.js +37 -0
  40. package/dist/spec/llm/retry.js +8 -9
  41. package/dist/utils.d.ts +5 -0
  42. package/dist/utils.js +24 -0
  43. package/package.json +3 -5
  44. package/dist/addons/dynamic-import.d.ts.map +0 -1
  45. package/dist/addons/dynamic-import.js.map +0 -1
  46. package/dist/addons/init-template.d.ts.map +0 -1
  47. package/dist/addons/init-template.js.map +0 -1
  48. package/dist/addons/loader.d.ts.map +0 -1
  49. package/dist/addons/loader.js.map +0 -1
  50. package/dist/addons/manager.d.ts.map +0 -1
  51. package/dist/addons/manager.js.map +0 -1
  52. package/dist/addons/paths.d.ts.map +0 -1
  53. package/dist/addons/paths.js.map +0 -1
  54. package/dist/addons/registry.d.ts.map +0 -1
  55. package/dist/addons/registry.js.map +0 -1
  56. package/dist/addons/semver.d.ts.map +0 -1
  57. package/dist/addons/semver.js.map +0 -1
  58. package/dist/addons/types.d.ts.map +0 -1
  59. package/dist/addons/types.js.map +0 -1
  60. package/dist/addons/validate.d.ts.map +0 -1
  61. package/dist/addons/validate.js.map +0 -1
  62. package/dist/arkui/index.d.ts.map +0 -1
  63. package/dist/arkui/index.js.map +0 -1
  64. package/dist/arkui/migrate-passage.d.ts.map +0 -1
  65. package/dist/arkui/migrate-passage.js.map +0 -1
  66. package/dist/arkui/migrate-semantics.d.ts.map +0 -1
  67. package/dist/arkui/migrate-semantics.js.map +0 -1
  68. package/dist/arkui/migrate-snapshot.d.ts.map +0 -1
  69. package/dist/arkui/migrate-snapshot.js.map +0 -1
  70. package/dist/bin/addon-commands.d.ts.map +0 -1
  71. package/dist/bin/addon-commands.js.map +0 -1
  72. package/dist/bin/command-supervision.d.ts.map +0 -1
  73. package/dist/bin/command-supervision.js.map +0 -1
  74. package/dist/bin/fatal-handler.d.ts.map +0 -1
  75. package/dist/bin/fatal-handler.js.map +0 -1
  76. package/dist/bin/homegraph.d.ts.map +0 -1
  77. package/dist/bin/homegraph.js.map +0 -1
  78. package/dist/bin/node-version-check.d.ts.map +0 -1
  79. package/dist/bin/node-version-check.js.map +0 -1
  80. package/dist/bin/uninstall.d.ts.map +0 -1
  81. package/dist/bin/uninstall.js.map +0 -1
  82. package/dist/context/formatter.d.ts.map +0 -1
  83. package/dist/context/formatter.js.map +0 -1
  84. package/dist/context/index.d.ts.map +0 -1
  85. package/dist/context/index.js.map +0 -1
  86. package/dist/context/markers.d.ts.map +0 -1
  87. package/dist/context/markers.js.map +0 -1
  88. package/dist/db/index.d.ts.map +0 -1
  89. package/dist/db/index.js.map +0 -1
  90. package/dist/db/migrations.d.ts.map +0 -1
  91. package/dist/db/migrations.js.map +0 -1
  92. package/dist/db/queries.d.ts.map +0 -1
  93. package/dist/db/queries.js.map +0 -1
  94. package/dist/db/sqlite-adapter.d.ts.map +0 -1
  95. package/dist/db/sqlite-adapter.js.map +0 -1
  96. package/dist/db/wal-valve.d.ts.map +0 -1
  97. package/dist/db/wal-valve.js.map +0 -1
  98. package/dist/directory.d.ts.map +0 -1
  99. package/dist/directory.js.map +0 -1
  100. package/dist/errors.d.ts.map +0 -1
  101. package/dist/errors.js.map +0 -1
  102. package/dist/extraction/arkts-batch-worker.d.ts.map +0 -1
  103. package/dist/extraction/arkts-batch-worker.js.map +0 -1
  104. package/dist/extraction/astro-extractor.d.ts.map +0 -1
  105. package/dist/extraction/astro-extractor.js.map +0 -1
  106. package/dist/extraction/cfml-extractor.d.ts.map +0 -1
  107. package/dist/extraction/cfml-extractor.js.map +0 -1
  108. package/dist/extraction/context.d.ts.map +0 -1
  109. package/dist/extraction/context.js.map +0 -1
  110. package/dist/extraction/default-ignore.d.ts.map +0 -1
  111. package/dist/extraction/default-ignore.js.map +0 -1
  112. package/dist/extraction/dfm-extractor.d.ts.map +0 -1
  113. package/dist/extraction/dfm-extractor.js.map +0 -1
  114. package/dist/extraction/extraction-version.d.ts.map +0 -1
  115. package/dist/extraction/extraction-version.js.map +0 -1
  116. package/dist/extraction/function-ref.d.ts.map +0 -1
  117. package/dist/extraction/function-ref.js.map +0 -1
  118. package/dist/extraction/generated-detection.d.ts.map +0 -1
  119. package/dist/extraction/generated-detection.js.map +0 -1
  120. package/dist/extraction/grammars.d.ts.map +0 -1
  121. package/dist/extraction/grammars.js.map +0 -1
  122. package/dist/extraction/index.d.ts.map +0 -1
  123. package/dist/extraction/index.js.map +0 -1
  124. package/dist/extraction/languages/arkts.d.ts.map +0 -1
  125. package/dist/extraction/languages/arkts.js.map +0 -1
  126. package/dist/extraction/languages/c-cpp.d.ts.map +0 -1
  127. package/dist/extraction/languages/c-cpp.js.map +0 -1
  128. package/dist/extraction/languages/cfquery.d.ts.map +0 -1
  129. package/dist/extraction/languages/cfquery.js.map +0 -1
  130. package/dist/extraction/languages/cfscript.d.ts.map +0 -1
  131. package/dist/extraction/languages/cfscript.js.map +0 -1
  132. package/dist/extraction/languages/cobol.d.ts.map +0 -1
  133. package/dist/extraction/languages/cobol.js.map +0 -1
  134. package/dist/extraction/languages/csharp.d.ts.map +0 -1
  135. package/dist/extraction/languages/csharp.js.map +0 -1
  136. package/dist/extraction/languages/dart.d.ts.map +0 -1
  137. package/dist/extraction/languages/dart.js.map +0 -1
  138. package/dist/extraction/languages/erlang.d.ts.map +0 -1
  139. package/dist/extraction/languages/erlang.js.map +0 -1
  140. package/dist/extraction/languages/go.d.ts.map +0 -1
  141. package/dist/extraction/languages/go.js.map +0 -1
  142. package/dist/extraction/languages/index.d.ts.map +0 -1
  143. package/dist/extraction/languages/index.js.map +0 -1
  144. package/dist/extraction/languages/java.d.ts.map +0 -1
  145. package/dist/extraction/languages/java.js.map +0 -1
  146. package/dist/extraction/languages/javascript.d.ts.map +0 -1
  147. package/dist/extraction/languages/javascript.js.map +0 -1
  148. package/dist/extraction/languages/kotlin.d.ts.map +0 -1
  149. package/dist/extraction/languages/kotlin.js.map +0 -1
  150. package/dist/extraction/languages/lua.d.ts.map +0 -1
  151. package/dist/extraction/languages/lua.js.map +0 -1
  152. package/dist/extraction/languages/luau.d.ts.map +0 -1
  153. package/dist/extraction/languages/luau.js.map +0 -1
  154. package/dist/extraction/languages/nix.d.ts.map +0 -1
  155. package/dist/extraction/languages/nix.js.map +0 -1
  156. package/dist/extraction/languages/objc.d.ts.map +0 -1
  157. package/dist/extraction/languages/objc.js.map +0 -1
  158. package/dist/extraction/languages/pascal.d.ts.map +0 -1
  159. package/dist/extraction/languages/pascal.js.map +0 -1
  160. package/dist/extraction/languages/php.d.ts.map +0 -1
  161. package/dist/extraction/languages/php.js.map +0 -1
  162. package/dist/extraction/languages/python.d.ts.map +0 -1
  163. package/dist/extraction/languages/python.js.map +0 -1
  164. package/dist/extraction/languages/r.d.ts.map +0 -1
  165. package/dist/extraction/languages/r.js.map +0 -1
  166. package/dist/extraction/languages/ruby.d.ts.map +0 -1
  167. package/dist/extraction/languages/ruby.js.map +0 -1
  168. package/dist/extraction/languages/rust.d.ts.map +0 -1
  169. package/dist/extraction/languages/rust.js.map +0 -1
  170. package/dist/extraction/languages/scala.d.ts.map +0 -1
  171. package/dist/extraction/languages/scala.js.map +0 -1
  172. package/dist/extraction/languages/solidity.d.ts.map +0 -1
  173. package/dist/extraction/languages/solidity.js.map +0 -1
  174. package/dist/extraction/languages/swift.d.ts.map +0 -1
  175. package/dist/extraction/languages/swift.js.map +0 -1
  176. package/dist/extraction/languages/terraform.d.ts.map +0 -1
  177. package/dist/extraction/languages/terraform.js.map +0 -1
  178. package/dist/extraction/languages/typescript.d.ts.map +0 -1
  179. package/dist/extraction/languages/typescript.js.map +0 -1
  180. package/dist/extraction/languages/vbnet.d.ts.map +0 -1
  181. package/dist/extraction/languages/vbnet.js.map +0 -1
  182. package/dist/extraction/liquid-extractor.d.ts.map +0 -1
  183. package/dist/extraction/liquid-extractor.js.map +0 -1
  184. package/dist/extraction/mybatis-extractor.d.ts.map +0 -1
  185. package/dist/extraction/mybatis-extractor.js.map +0 -1
  186. package/dist/extraction/parse-pool.d.ts.map +0 -1
  187. package/dist/extraction/parse-pool.js.map +0 -1
  188. package/dist/extraction/parse-worker.d.ts.map +0 -1
  189. package/dist/extraction/parse-worker.js.map +0 -1
  190. package/dist/extraction/razor-extractor.d.ts.map +0 -1
  191. package/dist/extraction/razor-extractor.js.map +0 -1
  192. package/dist/extraction/store-worker.d.ts.map +0 -1
  193. package/dist/extraction/store-worker.js.map +0 -1
  194. package/dist/extraction/store-writer.d.ts.map +0 -1
  195. package/dist/extraction/store-writer.js.map +0 -1
  196. package/dist/extraction/svelte-extractor.d.ts.map +0 -1
  197. package/dist/extraction/svelte-extractor.js.map +0 -1
  198. package/dist/extraction/tree-sitter-helpers.d.ts.map +0 -1
  199. package/dist/extraction/tree-sitter-helpers.js.map +0 -1
  200. package/dist/extraction/tree-sitter-types.d.ts.map +0 -1
  201. package/dist/extraction/tree-sitter-types.js.map +0 -1
  202. package/dist/extraction/tree-sitter.d.ts.map +0 -1
  203. package/dist/extraction/tree-sitter.js.map +0 -1
  204. package/dist/extraction/vue-extractor.d.ts.map +0 -1
  205. package/dist/extraction/vue-extractor.js.map +0 -1
  206. package/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
  207. package/dist/extraction/wasm-runtime-flags.d.ts.map +0 -1
  208. package/dist/extraction/wasm-runtime-flags.js.map +0 -1
  209. package/dist/graph/index.d.ts.map +0 -1
  210. package/dist/graph/index.js.map +0 -1
  211. package/dist/graph/queries.d.ts.map +0 -1
  212. package/dist/graph/queries.js.map +0 -1
  213. package/dist/graph/traversal.d.ts.map +0 -1
  214. package/dist/graph/traversal.js.map +0 -1
  215. package/dist/graph-sources.d.ts.map +0 -1
  216. package/dist/graph-sources.js.map +0 -1
  217. package/dist/index.d.ts.map +0 -1
  218. package/dist/index.js.map +0 -1
  219. package/dist/installer/config-writer.d.ts.map +0 -1
  220. package/dist/installer/config-writer.js.map +0 -1
  221. package/dist/installer/index.d.ts.map +0 -1
  222. package/dist/installer/index.js.map +0 -1
  223. package/dist/installer/instructions-template.d.ts.map +0 -1
  224. package/dist/installer/instructions-template.js.map +0 -1
  225. package/dist/installer/targets/antigravity.d.ts.map +0 -1
  226. package/dist/installer/targets/antigravity.js.map +0 -1
  227. package/dist/installer/targets/claude.d.ts.map +0 -1
  228. package/dist/installer/targets/claude.js.map +0 -1
  229. package/dist/installer/targets/codebuddy.d.ts.map +0 -1
  230. package/dist/installer/targets/codebuddy.js.map +0 -1
  231. package/dist/installer/targets/codex.d.ts.map +0 -1
  232. package/dist/installer/targets/codex.js.map +0 -1
  233. package/dist/installer/targets/cursor.d.ts.map +0 -1
  234. package/dist/installer/targets/cursor.js.map +0 -1
  235. package/dist/installer/targets/deveco.d.ts.map +0 -1
  236. package/dist/installer/targets/deveco.js.map +0 -1
  237. package/dist/installer/targets/gemini.d.ts.map +0 -1
  238. package/dist/installer/targets/gemini.js.map +0 -1
  239. package/dist/installer/targets/hermes.d.ts.map +0 -1
  240. package/dist/installer/targets/hermes.js.map +0 -1
  241. package/dist/installer/targets/kiro.d.ts.map +0 -1
  242. package/dist/installer/targets/kiro.js.map +0 -1
  243. package/dist/installer/targets/opencode.d.ts.map +0 -1
  244. package/dist/installer/targets/opencode.js.map +0 -1
  245. package/dist/installer/targets/registry.d.ts.map +0 -1
  246. package/dist/installer/targets/registry.js.map +0 -1
  247. package/dist/installer/targets/shared.d.ts.map +0 -1
  248. package/dist/installer/targets/shared.js.map +0 -1
  249. package/dist/installer/targets/toml.d.ts.map +0 -1
  250. package/dist/installer/targets/toml.js.map +0 -1
  251. package/dist/installer/targets/types.d.ts.map +0 -1
  252. package/dist/installer/targets/types.js.map +0 -1
  253. package/dist/mcp/daemon-manager.d.ts.map +0 -1
  254. package/dist/mcp/daemon-manager.js.map +0 -1
  255. package/dist/mcp/daemon-paths.d.ts.map +0 -1
  256. package/dist/mcp/daemon-paths.js.map +0 -1
  257. package/dist/mcp/daemon-registry.d.ts.map +0 -1
  258. package/dist/mcp/daemon-registry.js.map +0 -1
  259. package/dist/mcp/daemon.d.ts.map +0 -1
  260. package/dist/mcp/daemon.js.map +0 -1
  261. package/dist/mcp/diff-impact.d.ts.map +0 -1
  262. package/dist/mcp/diff-impact.js.map +0 -1
  263. package/dist/mcp/dynamic-boundaries.d.ts.map +0 -1
  264. package/dist/mcp/dynamic-boundaries.js.map +0 -1
  265. package/dist/mcp/early-ppid.d.ts.map +0 -1
  266. package/dist/mcp/early-ppid.js.map +0 -1
  267. package/dist/mcp/engine.d.ts.map +0 -1
  268. package/dist/mcp/engine.js.map +0 -1
  269. package/dist/mcp/evidence-rendering.d.ts.map +0 -1
  270. package/dist/mcp/evidence-rendering.js.map +0 -1
  271. package/dist/mcp/explore-dedup.d.ts.map +0 -1
  272. package/dist/mcp/explore-dedup.js.map +0 -1
  273. package/dist/mcp/explore-repeat-guard.d.ts.map +0 -1
  274. package/dist/mcp/explore-repeat-guard.js.map +0 -1
  275. package/dist/mcp/explore-session-state.d.ts.map +0 -1
  276. package/dist/mcp/explore-session-state.js.map +0 -1
  277. package/dist/mcp/index.d.ts.map +0 -1
  278. package/dist/mcp/index.js.map +0 -1
  279. package/dist/mcp/liveness-watchdog.d.ts.map +0 -1
  280. package/dist/mcp/liveness-watchdog.js.map +0 -1
  281. package/dist/mcp/memory-budget.d.ts.map +0 -1
  282. package/dist/mcp/memory-budget.js.map +0 -1
  283. package/dist/mcp/ppid-watchdog.d.ts.map +0 -1
  284. package/dist/mcp/ppid-watchdog.js.map +0 -1
  285. package/dist/mcp/proxy.d.ts.map +0 -1
  286. package/dist/mcp/proxy.js.map +0 -1
  287. package/dist/mcp/query-cache.d.ts.map +0 -1
  288. package/dist/mcp/query-cache.js.map +0 -1
  289. package/dist/mcp/query-pool.d.ts.map +0 -1
  290. package/dist/mcp/query-pool.js.map +0 -1
  291. package/dist/mcp/query-worker.d.ts.map +0 -1
  292. package/dist/mcp/query-worker.js.map +0 -1
  293. package/dist/mcp/server-instructions.d.ts.map +0 -1
  294. package/dist/mcp/server-instructions.js.map +0 -1
  295. package/dist/mcp/session.d.ts.map +0 -1
  296. package/dist/mcp/session.js.map +0 -1
  297. package/dist/mcp/startup-handshake.d.ts.map +0 -1
  298. package/dist/mcp/startup-handshake.js.map +0 -1
  299. package/dist/mcp/stdin-teardown.d.ts.map +0 -1
  300. package/dist/mcp/stdin-teardown.js.map +0 -1
  301. package/dist/mcp/tools.d.ts.map +0 -1
  302. package/dist/mcp/tools.js.map +0 -1
  303. package/dist/mcp/transport.d.ts.map +0 -1
  304. package/dist/mcp/transport.js.map +0 -1
  305. package/dist/mcp/version.d.ts.map +0 -1
  306. package/dist/mcp/version.js.map +0 -1
  307. package/dist/project-config.d.ts.map +0 -1
  308. package/dist/project-config.js.map +0 -1
  309. package/dist/project-map/index.d.ts.map +0 -1
  310. package/dist/project-map/index.js.map +0 -1
  311. package/dist/resolution/c-fnptr-synthesizer.d.ts.map +0 -1
  312. package/dist/resolution/c-fnptr-synthesizer.js.map +0 -1
  313. package/dist/resolution/callback-synthesizer.d.ts.map +0 -1
  314. package/dist/resolution/callback-synthesizer.js.map +0 -1
  315. package/dist/resolution/cooperative-yield.d.ts.map +0 -1
  316. package/dist/resolution/cooperative-yield.js.map +0 -1
  317. package/dist/resolution/frameworks/arkts-entry.d.ts.map +0 -1
  318. package/dist/resolution/frameworks/arkts-entry.js.map +0 -1
  319. package/dist/resolution/frameworks/arkts-napi.d.ts.map +0 -1
  320. package/dist/resolution/frameworks/arkts-napi.js.map +0 -1
  321. package/dist/resolution/frameworks/astro.d.ts.map +0 -1
  322. package/dist/resolution/frameworks/astro.js.map +0 -1
  323. package/dist/resolution/frameworks/cargo-workspace.d.ts.map +0 -1
  324. package/dist/resolution/frameworks/cargo-workspace.js.map +0 -1
  325. package/dist/resolution/frameworks/cics.d.ts.map +0 -1
  326. package/dist/resolution/frameworks/cics.js.map +0 -1
  327. package/dist/resolution/frameworks/csharp.d.ts.map +0 -1
  328. package/dist/resolution/frameworks/csharp.js.map +0 -1
  329. package/dist/resolution/frameworks/drupal.d.ts.map +0 -1
  330. package/dist/resolution/frameworks/drupal.js.map +0 -1
  331. package/dist/resolution/frameworks/expo-modules.d.ts.map +0 -1
  332. package/dist/resolution/frameworks/expo-modules.js.map +0 -1
  333. package/dist/resolution/frameworks/express.d.ts.map +0 -1
  334. package/dist/resolution/frameworks/express.js.map +0 -1
  335. package/dist/resolution/frameworks/fabric.d.ts.map +0 -1
  336. package/dist/resolution/frameworks/fabric.js.map +0 -1
  337. package/dist/resolution/frameworks/go.d.ts.map +0 -1
  338. package/dist/resolution/frameworks/go.js.map +0 -1
  339. package/dist/resolution/frameworks/goframe.d.ts.map +0 -1
  340. package/dist/resolution/frameworks/goframe.js.map +0 -1
  341. package/dist/resolution/frameworks/index.d.ts.map +0 -1
  342. package/dist/resolution/frameworks/index.js.map +0 -1
  343. package/dist/resolution/frameworks/java.d.ts.map +0 -1
  344. package/dist/resolution/frameworks/java.js.map +0 -1
  345. package/dist/resolution/frameworks/laravel.d.ts.map +0 -1
  346. package/dist/resolution/frameworks/laravel.js.map +0 -1
  347. package/dist/resolution/frameworks/nestjs.d.ts.map +0 -1
  348. package/dist/resolution/frameworks/nestjs.js.map +0 -1
  349. package/dist/resolution/frameworks/play.d.ts.map +0 -1
  350. package/dist/resolution/frameworks/play.js.map +0 -1
  351. package/dist/resolution/frameworks/python.d.ts.map +0 -1
  352. package/dist/resolution/frameworks/python.js.map +0 -1
  353. package/dist/resolution/frameworks/react-native.d.ts.map +0 -1
  354. package/dist/resolution/frameworks/react-native.js.map +0 -1
  355. package/dist/resolution/frameworks/react.d.ts.map +0 -1
  356. package/dist/resolution/frameworks/react.js.map +0 -1
  357. package/dist/resolution/frameworks/ruby.d.ts.map +0 -1
  358. package/dist/resolution/frameworks/ruby.js.map +0 -1
  359. package/dist/resolution/frameworks/rust.d.ts.map +0 -1
  360. package/dist/resolution/frameworks/rust.js.map +0 -1
  361. package/dist/resolution/frameworks/svelte.d.ts.map +0 -1
  362. package/dist/resolution/frameworks/svelte.js.map +0 -1
  363. package/dist/resolution/frameworks/swift-objc.d.ts.map +0 -1
  364. package/dist/resolution/frameworks/swift-objc.js.map +0 -1
  365. package/dist/resolution/frameworks/swift.d.ts.map +0 -1
  366. package/dist/resolution/frameworks/swift.js.map +0 -1
  367. package/dist/resolution/frameworks/terraform.d.ts.map +0 -1
  368. package/dist/resolution/frameworks/terraform.js.map +0 -1
  369. package/dist/resolution/frameworks/vue.d.ts.map +0 -1
  370. package/dist/resolution/frameworks/vue.js.map +0 -1
  371. package/dist/resolution/go-module.d.ts.map +0 -1
  372. package/dist/resolution/go-module.js.map +0 -1
  373. package/dist/resolution/goframe-synthesizer.d.ts.map +0 -1
  374. package/dist/resolution/goframe-synthesizer.js.map +0 -1
  375. package/dist/resolution/import-resolver.d.ts.map +0 -1
  376. package/dist/resolution/import-resolver.js.map +0 -1
  377. package/dist/resolution/index.d.ts.map +0 -1
  378. package/dist/resolution/index.js.map +0 -1
  379. package/dist/resolution/lru-cache.d.ts.map +0 -1
  380. package/dist/resolution/lru-cache.js.map +0 -1
  381. package/dist/resolution/memory-budget.d.ts.map +0 -1
  382. package/dist/resolution/memory-budget.js.map +0 -1
  383. package/dist/resolution/name-matcher.d.ts.map +0 -1
  384. package/dist/resolution/name-matcher.js.map +0 -1
  385. package/dist/resolution/path-aliases.d.ts.map +0 -1
  386. package/dist/resolution/path-aliases.js.map +0 -1
  387. package/dist/resolution/resolver-pool.d.ts.map +0 -1
  388. package/dist/resolution/resolver-pool.js.map +0 -1
  389. package/dist/resolution/resolver-worker.d.ts.map +0 -1
  390. package/dist/resolution/resolver-worker.js.map +0 -1
  391. package/dist/resolution/strip-comments.d.ts.map +0 -1
  392. package/dist/resolution/strip-comments.js.map +0 -1
  393. package/dist/resolution/swift-objc-bridge.d.ts.map +0 -1
  394. package/dist/resolution/swift-objc-bridge.js.map +0 -1
  395. package/dist/resolution/types.d.ts.map +0 -1
  396. package/dist/resolution/types.js.map +0 -1
  397. package/dist/resolution/workspace-packages.d.ts.map +0 -1
  398. package/dist/resolution/workspace-packages.js.map +0 -1
  399. package/dist/search/identifier-segments.d.ts.map +0 -1
  400. package/dist/search/identifier-segments.js.map +0 -1
  401. package/dist/search/literal-evidence.d.ts.map +0 -1
  402. package/dist/search/literal-evidence.js.map +0 -1
  403. package/dist/search/query-parser.d.ts.map +0 -1
  404. package/dist/search/query-parser.js.map +0 -1
  405. package/dist/search/query-plan-provider.d.ts.map +0 -1
  406. package/dist/search/query-plan-provider.js.map +0 -1
  407. package/dist/search/query-plan.d.ts.map +0 -1
  408. package/dist/search/query-plan.js.map +0 -1
  409. package/dist/search/query-utils.d.ts.map +0 -1
  410. package/dist/search/query-utils.js.map +0 -1
  411. package/dist/spec/build/diff-parser.d.ts.map +0 -1
  412. package/dist/spec/build/diff-parser.js.map +0 -1
  413. package/dist/spec/build/pipeline.d.ts.map +0 -1
  414. package/dist/spec/build/pipeline.js.map +0 -1
  415. package/dist/spec/build/scan.d.ts.map +0 -1
  416. package/dist/spec/build/scan.js.map +0 -1
  417. package/dist/spec/build/scope-resolver.d.ts.map +0 -1
  418. package/dist/spec/build/scope-resolver.js.map +0 -1
  419. package/dist/spec/build/spec-extractor.d.ts.map +0 -1
  420. package/dist/spec/build/spec-extractor.js.map +0 -1
  421. package/dist/spec/config.d.ts.map +0 -1
  422. package/dist/spec/config.js.map +0 -1
  423. package/dist/spec/db/commit-node.d.ts.map +0 -1
  424. package/dist/spec/db/commit-node.js.map +0 -1
  425. package/dist/spec/db/fragment-node.d.ts.map +0 -1
  426. package/dist/spec/db/fragment-node.js.map +0 -1
  427. package/dist/spec/db/fts.d.ts.map +0 -1
  428. package/dist/spec/db/fts.js.map +0 -1
  429. package/dist/spec/db/index.d.ts.map +0 -1
  430. package/dist/spec/db/index.js.map +0 -1
  431. package/dist/spec/db/persist.d.ts.map +0 -1
  432. package/dist/spec/db/persist.js.map +0 -1
  433. package/dist/spec/db/relations.d.ts.map +0 -1
  434. package/dist/spec/db/relations.js.map +0 -1
  435. package/dist/spec/db/schema.d.ts.map +0 -1
  436. package/dist/spec/db/schema.js.map +0 -1
  437. package/dist/spec/db/spec-node.d.ts.map +0 -1
  438. package/dist/spec/db/spec-node.js.map +0 -1
  439. package/dist/spec/db/sql-utils.d.ts.map +0 -1
  440. package/dist/spec/db/sql-utils.js.map +0 -1
  441. package/dist/spec/evolve/cluster-context.d.ts.map +0 -1
  442. package/dist/spec/evolve/cluster-context.js.map +0 -1
  443. package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +0 -1
  444. package/dist/spec/evolve/commit-spec-analyzer.js.map +0 -1
  445. package/dist/spec/evolve/commit-spec-persister.d.ts.map +0 -1
  446. package/dist/spec/evolve/commit-spec-persister.js.map +0 -1
  447. package/dist/spec/evolve/impact-locator.d.ts.map +0 -1
  448. package/dist/spec/evolve/impact-locator.js.map +0 -1
  449. package/dist/spec/evolve/pipeline.d.ts.map +0 -1
  450. package/dist/spec/evolve/pipeline.js.map +0 -1
  451. package/dist/spec/evolve/spec-rewriter.d.ts.map +0 -1
  452. package/dist/spec/evolve/spec-rewriter.js.map +0 -1
  453. package/dist/spec/git/commits.d.ts.map +0 -1
  454. package/dist/spec/git/commits.js.map +0 -1
  455. package/dist/spec/git/exec.d.ts.map +0 -1
  456. package/dist/spec/git/exec.js.map +0 -1
  457. package/dist/spec/git/index.d.ts.map +0 -1
  458. package/dist/spec/git/index.js.map +0 -1
  459. package/dist/spec/graph/index.d.ts.map +0 -1
  460. package/dist/spec/graph/index.js.map +0 -1
  461. package/dist/spec/graph/queries.d.ts.map +0 -1
  462. package/dist/spec/graph/queries.js.map +0 -1
  463. package/dist/spec/llm/agent-client.d.ts.map +0 -1
  464. package/dist/spec/llm/agent-client.js.map +0 -1
  465. package/dist/spec/llm/agents/claude-code.d.ts.map +0 -1
  466. package/dist/spec/llm/agents/claude-code.js.map +0 -1
  467. package/dist/spec/llm/agents/codex.d.ts.map +0 -1
  468. package/dist/spec/llm/agents/codex.js.map +0 -1
  469. package/dist/spec/llm/agents/detect-utils.d.ts.map +0 -1
  470. package/dist/spec/llm/agents/detect-utils.js.map +0 -1
  471. package/dist/spec/llm/agents/deveco-code.d.ts.map +0 -1
  472. package/dist/spec/llm/agents/deveco-code.js.map +0 -1
  473. package/dist/spec/llm/agents/index.d.ts.map +0 -1
  474. package/dist/spec/llm/agents/index.js.map +0 -1
  475. package/dist/spec/llm/agents/types.d.ts.map +0 -1
  476. package/dist/spec/llm/agents/types.js.map +0 -1
  477. package/dist/spec/llm/client.d.ts.map +0 -1
  478. package/dist/spec/llm/client.js.map +0 -1
  479. package/dist/spec/llm/factory.d.ts.map +0 -1
  480. package/dist/spec/llm/factory.js.map +0 -1
  481. package/dist/spec/llm/prompts.d.ts.map +0 -1
  482. package/dist/spec/llm/prompts.js.map +0 -1
  483. package/dist/spec/llm/retry.d.ts.map +0 -1
  484. package/dist/spec/llm/retry.js.map +0 -1
  485. package/dist/spec/mine/addon/adapter.d.ts.map +0 -1
  486. package/dist/spec/mine/addon/adapter.js.map +0 -1
  487. package/dist/spec/mine/addon/render.d.ts.map +0 -1
  488. package/dist/spec/mine/addon/render.js.map +0 -1
  489. package/dist/spec/mine/addon/types.d.ts.map +0 -1
  490. package/dist/spec/mine/addon/types.js.map +0 -1
  491. package/dist/spec/mine/clustering/features.d.ts.map +0 -1
  492. package/dist/spec/mine/clustering/features.js.map +0 -1
  493. package/dist/spec/mine/clustering/index.d.ts.map +0 -1
  494. package/dist/spec/mine/clustering/index.js.map +0 -1
  495. package/dist/spec/mine/clustering/leiden.d.ts.map +0 -1
  496. package/dist/spec/mine/clustering/leiden.js.map +0 -1
  497. package/dist/spec/mine/clustering/text-similarity.d.ts.map +0 -1
  498. package/dist/spec/mine/clustering/text-similarity.js.map +0 -1
  499. package/dist/spec/mine/generator.d.ts.map +0 -1
  500. package/dist/spec/mine/generator.js.map +0 -1
  501. package/dist/spec/mine/persist.d.ts.map +0 -1
  502. package/dist/spec/mine/persist.js.map +0 -1
  503. package/dist/spec/mine/pipeline.d.ts.map +0 -1
  504. package/dist/spec/mine/pipeline.js.map +0 -1
  505. package/dist/spec/mine/scanner.d.ts.map +0 -1
  506. package/dist/spec/mine/scanner.js.map +0 -1
  507. package/dist/spec/types.d.ts.map +0 -1
  508. package/dist/spec/types.js.map +0 -1
  509. package/dist/spec/ui/index.d.ts.map +0 -1
  510. package/dist/spec/ui/index.js.map +0 -1
  511. package/dist/spec/ui/progress-handler.d.ts.map +0 -1
  512. package/dist/spec/ui/progress-handler.js.map +0 -1
  513. package/dist/spec/ui/progress.d.ts.map +0 -1
  514. package/dist/spec/ui/progress.js.map +0 -1
  515. package/dist/spec/utils/fs.d.ts.map +0 -1
  516. package/dist/spec/utils/fs.js.map +0 -1
  517. package/dist/spec/utils/index.d.ts.map +0 -1
  518. package/dist/spec/utils/index.js.map +0 -1
  519. package/dist/spec/utils/meta.d.ts.map +0 -1
  520. package/dist/spec/utils/meta.js.map +0 -1
  521. package/dist/spec/utils/truncate.d.ts.map +0 -1
  522. package/dist/spec/utils/truncate.js.map +0 -1
  523. package/dist/sync/git-hooks.d.ts.map +0 -1
  524. package/dist/sync/git-hooks.js.map +0 -1
  525. package/dist/sync/index.d.ts.map +0 -1
  526. package/dist/sync/index.js.map +0 -1
  527. package/dist/sync/watch-policy.d.ts.map +0 -1
  528. package/dist/sync/watch-policy.js.map +0 -1
  529. package/dist/sync/watcher.d.ts.map +0 -1
  530. package/dist/sync/watcher.js.map +0 -1
  531. package/dist/sync/worktree.d.ts.map +0 -1
  532. package/dist/sync/worktree.js.map +0 -1
  533. package/dist/types.d.ts.map +0 -1
  534. package/dist/types.js.map +0 -1
  535. package/dist/ui/glyphs.d.ts.map +0 -1
  536. package/dist/ui/glyphs.js.map +0 -1
  537. package/dist/ui/shimmer-progress.d.ts.map +0 -1
  538. package/dist/ui/shimmer-progress.js.map +0 -1
  539. package/dist/ui/shimmer-worker.d.ts.map +0 -1
  540. package/dist/ui/shimmer-worker.js.map +0 -1
  541. package/dist/ui/types.d.ts.map +0 -1
  542. package/dist/ui/types.js.map +0 -1
  543. package/dist/upgrade/index.d.ts.map +0 -1
  544. package/dist/upgrade/index.js.map +0 -1
  545. package/dist/upgrade/remove-binary.d.ts.map +0 -1
  546. package/dist/upgrade/remove-binary.js.map +0 -1
  547. package/dist/upgrade/update-check.d.ts.map +0 -1
  548. package/dist/upgrade/update-check.js.map +0 -1
  549. package/dist/utils.d.ts.map +0 -1
  550. package/dist/utils.js.map +0 -1
package/dist/mcp/tools.js CHANGED
@@ -21,9 +21,13 @@ exports.queryAsBareSymbolInventory = queryAsBareSymbolInventory;
21
21
  exports.hasPositiveAnswerNowDirective = hasPositiveAnswerNowDirective;
22
22
  exports.reconcilePartialAnswerNow = reconcilePartialAnswerNow;
23
23
  const query_pool_1 = require("./query-pool");
24
+ const source_slice_identity_1 = require("./source-slice-identity");
24
25
  const evidence_rendering_1 = require("./evidence-rendering");
26
+ const arkts_evidence_packs_1 = require("./arkts-evidence-packs");
27
+ const evidence_paths_1 = require("../graph/evidence-paths");
25
28
  const query_plan_1 = require("../search/query-plan");
26
29
  const memory_budget_1 = require("./memory-budget");
30
+ const index_availability_1 = require("./index-availability");
27
31
  const directory_1 = require("../directory");
28
32
  // Lazy-load the heavy HomeGraph chain off the MCP startup path — see the same
29
33
  // helper in engine.ts. ToolHandler must load to answer tools/list (static
@@ -657,7 +661,7 @@ exports.tools = [
657
661
  {
658
662
  name: 'homegraph_search',
659
663
  description: 'LAST RESORT spelling lookup — locations only, no source. Required: `query` (e.g. "signIn"). ' +
660
- 'Prefer explore/callers/node when names are known. ' +
664
+ 'Use ordinary scoped search/read when names or paths are known; use graph tools only for missing structural evidence. ' +
661
665
  'DO NOT call for topic file-lists, concept compares, or SDK/@kit feature catalogs (those return Skip guidance). ' +
662
666
  'Also skip literal string/pattern greps — use Grep instead. ' +
663
667
  'Bare-name search may return a compact explore result instead of locations.',
@@ -687,7 +691,7 @@ exports.tools = [
687
691
  {
688
692
  name: 'homegraph_callers',
689
693
  description: 'Compact caller list for one NAMED in-repo symbol (no bodies). Required: `symbol` (e.g. "authenticate"). ' +
690
- 'Cheaper than explore when you only need who-calls-X. For multi-file flows use homegraph_explore. ' +
694
+ 'Cheaper than explore when you only need who-calls-X. For an unresolved cross-symbol flow, consider homegraph_explore. ' +
691
695
  'DO NOT call for SDK catalogs, topic file-lists, concept compares, or hypothetics.',
692
696
  inputSchema: {
693
697
  type: 'object',
@@ -714,7 +718,7 @@ exports.tools = [
714
718
  {
715
719
  name: 'homegraph_callees',
716
720
  description: 'Compact callee list for one NAMED in-repo symbol (no bodies). Required: `symbol` (e.g. "authenticate"). ' +
717
- 'Cheaper than explore when you only need what-X-calls. For multi-file flows use homegraph_explore. ' +
721
+ 'Cheaper than explore when you only need what-X-calls. For an unresolved cross-symbol flow, consider homegraph_explore. ' +
718
722
  'DO NOT use for out-of-repo SDK catalogs or counterfactual analysis.',
719
723
  inputSchema: {
720
724
  type: 'object',
@@ -815,9 +819,9 @@ exports.tools = [
815
819
  'Cheaper than explore when you already know the name and only need one body. ' +
816
820
  'FILE: `file` only → line-numbered source + dependents. ' +
817
821
  'SYMBOL: body via includeCode + short trail; overloads return every body. ' +
818
- 'DO NOT call after explore already returned that symbol/file (multiplies tokens). ' +
819
- 'DO NOT crawl a feature with repeated node calls (prefer one explore for flows). ' +
820
- 'Treat returned source as already Read.',
822
+ 'Reuse complete unchanged source ranges already returned by any tool; refresh missing, truncated or edited ranges. ' +
823
+ 'Avoid repeated node calls over the same evidence; use explore only for an unresolved cross-symbol flow. ' +
824
+ 'Treat complete returned source ranges as already Read, not an entire file inferred from an excerpt.',
821
825
  inputSchema: {
822
826
  type: 'object',
823
827
  properties: {
@@ -860,7 +864,7 @@ exports.tools = [
860
864
  },
861
865
  {
862
866
  name: 'homegraph_usages',
863
- description: 'PRIMARY first tool for a narrow WHERE-USED question about one named API, `.member`, ALL_CAPS constant, field, or mutex. ' +
867
+ description: 'Optional focused tool for an unresolved WHERE-USED question about one named API, `.member`, ALL_CAPS constant, field, or mutex. ' +
864
868
  'Choose this instead of homegraph_explore when the requested answer is usage/reference locations. ' +
865
869
  'Required: `query`. Returns usage files/lines only; it does not build a general flow or source dump. ' +
866
870
  '`homegraph_explore` auto-routes equivalent high-confidence queries here only for compatibility.',
@@ -879,7 +883,7 @@ exports.tools = [
879
883
  },
880
884
  {
881
885
  name: 'homegraph_modules',
882
- description: 'PRIMARY first tool for a narrow DEPENDENCY/CYCLE question about named path modules or `*common` / `*service` / `*component` / `*constants` modules. ' +
886
+ description: 'Optional focused tool for an unresolved DEPENDENCY/CYCLE question about named path modules or `*common` / `*service` / `*component` / `*constants` modules. ' +
883
887
  'Choose this instead of homegraph_explore when the requested answer is module topology. ' +
884
888
  'Required: `query`. It does not build a general code flow or scan unrelated survey families. ' +
885
889
  '`homegraph_explore` auto-routes equivalent high-confidence dependency questions here only for compatibility.',
@@ -898,7 +902,7 @@ exports.tools = [
898
902
  },
899
903
  {
900
904
  name: 'homegraph_native',
901
- description: 'PRIMARY first tool for a narrow NAPI/NATIVE EXPORT or registration question about one named path or Type. ' +
905
+ description: 'Optional focused tool for an unresolved NAPI/NATIVE EXPORT or registration question about one named path or Type. ' +
902
906
  'Choose this instead of homegraph_explore when the requested answer is the ArkTS↔native export surface. Required: `query`. ' +
903
907
  'Returns indexed export descriptors/registration sites without a general domain file dump. ' +
904
908
  '`homegraph_explore` auto-routes equivalent high-confidence NAPI/export questions here only for compatibility.',
@@ -917,26 +921,16 @@ exports.tools = [
917
921
  },
918
922
  {
919
923
  name: 'homegraph_explore',
920
- description: 'GENERAL PRIMARY entry for understanding THIS repo before you edit or answer structural questions. ' +
921
- 'For an explicit narrow where-used, named module dependency/cycle, or NAPI/native export inventory, choose ' +
922
- 'homegraph_usages, homegraph_modules, or homegraph_native instead; this tool keeps conservative auto-routing only for compatibility. ' +
923
- 'Returns call paths + compact line-numbered source for the relevant symbols. Required: `query`. ' +
924
- 'CALL FIRST (alone, no parallel Grep/Read) when you will change an existing codebase — pass the user task or domain keywords ' +
925
- '(page/module/feature/component words); locate where to edit before writing code. Also CALL FIRST for how/wired questions, ' +
926
- 'named Type/Component/Page/Dialog, Type.member, click→handler, inheritance/subtypes, declaration/attribute sites, ' +
927
- 'or a cross-symbol mechanism/flow. Use the named focused tools for exact usage, module-topology, or native-export inventories. ' +
928
- 'PascalCase names optional when domain keywords suffice. ' +
929
- 'For edits preserve the requested action, target product/module and exclusions; taskContext may carry the full task. ' +
930
- 'Prefer callers/node when one named symbol is already enough. ' +
931
- 'DO NOT call for topic file-lists with no Type/file, literal copy hunts / pure existence compares with no anchors, ' +
932
- 'official-docs-only asks, empty-project-from-scratch scaffolds, git history, or media/binary asset inventories — those return Skip. ' +
933
- '@kit / OHOS API questions ARE in scope when the SDK API graph is available — exact where-used → homegraph_usages; ' +
934
- 'mechanism/API-symbol flow → homegraph_explore. ' +
935
- 'Literal string/pattern hunts → Grep; media assets → Glob; git history → git. ' +
936
- 'One explore; then answer or edit from Source + trail — do not re-grep/node/read the same symbols. ' +
937
- 'Overlapping paraphrase explores are refused (name a new Type/file/@kit to continue). ' +
938
- 'Busy/partial → retry ONCE with the named Next anchor or ONE narrow Grep — not a Grep/node storm '
939
- + '(session refuses further explore / depth fan-out after Partial).',
924
+ description: 'Optional graph evidence for a concrete unresolved cross-symbol mechanism in THIS repo. Required: `query`. ' +
925
+ 'Use ordinary bash/search/read for paths, symbols, literal strings and local changes; continue editing when that evidence suffices. ' +
926
+ 'Do not call for routine pre-edit orientation or merely because implementation is difficult. ' +
927
+ 'For a missing usage, dependency/cycle or native-registration relation, use ' +
928
+ 'homegraph_usages, homegraph_modules, or homegraph_native instead. ' +
929
+ 'Returns call paths and compact line-numbered source. ArkTS symbol evidence uses complete declarations and bounded directed paths with intermediate source dependencies; explicit Gaps and stop reasons name omitted or unverified evidence. Qualify ambiguous symbols by owning type or file. State the missing relation with known anchors, requested action, scope and constraints; taskContext can carry the full task. ' +
930
+ 'Reuse unchanged complete ranges; refresh missing, edited or truncated evidence. ' +
931
+ 'No new evidence → change to a targeted source inspection, not a paraphrased explore. ' +
932
+ 'Partial/busy → at most one focused recovery for the named gap; budgets are ceilings, not required calls. ' +
933
+ 'Retrieval completion is not task completion: continue implementation and required validation.',
940
934
  inputSchema: {
941
935
  type: 'object',
942
936
  properties: {
@@ -1015,7 +1009,7 @@ exports.tools = [
1015
1009
  {
1016
1010
  name: 'homegraph_files',
1017
1011
  description: 'Indexed directory tree (paths and symbol counts only — NO source). ' +
1018
- 'Only for coarse folder layout when explore cannot help. For where/what/how code questions use homegraph_explore.',
1012
+ 'Optional coarse folder inventory; prefer ordinary file listing for known paths. Use graph tools only for missing structural evidence.',
1019
1013
  inputSchema: {
1020
1014
  type: 'object',
1021
1015
  properties: {
@@ -1483,7 +1477,6 @@ class ToolHandler {
1483
1477
  return withRequiredProjectPath(visible);
1484
1478
  try {
1485
1479
  const stats = this.cg.getStats();
1486
- const budget = getExploreBudget(stats.fileCount);
1487
1480
  // Tiny-repo tool gating: on projects under TINY_REPO_FILE_THRESHOLD
1488
1481
  // files, only expose the core trio (search, node, explore) — one
1489
1482
  // below even the 4-tool default: at this scale callers, too, reduces
@@ -1524,7 +1517,7 @@ class ToolHandler {
1524
1517
  if (tool.name === 'homegraph_explore') {
1525
1518
  return {
1526
1519
  ...tool,
1527
- description: `${tool.description} Budget: make at most ${budget} calls for this project (${stats.fileCount.toLocaleString()} files indexed).`,
1520
+ description: `${tool.description} ${this.exploreSuffix(stats.fileCount)}`,
1528
1521
  };
1529
1522
  }
1530
1523
  return tool;
@@ -1534,6 +1527,53 @@ class ToolHandler {
1534
1527
  return visible;
1535
1528
  }
1536
1529
  }
1530
+ /**
1531
+ * Per-repo suffix appended to homegraph_explore's description (Spec 0027).
1532
+ *
1533
+ * fileCount === 0 must not read as "this project is empty": hosts snapshot
1534
+ * tools/list once at connect (#964), and an auto-init that is still building
1535
+ * reports 0 at that instant. Field evidence (DevEco Code bench, 3 sessions,
1536
+ * zero homegraph calls): agents read "make at most 1 calls for this project
1537
+ * (0 files indexed)" as terminal — "homegraph isn't indexed for this
1538
+ * project" — and permanently fell back to Read/Grep even though the index
1539
+ * completed seconds later. Mirror maybeDeepToolPhaseGate's success-shaped
1540
+ * guidance so the frozen description and the live call-time response tell
1541
+ * the same story: failed build → say so (indexing is the user's call, so
1542
+ * the agent relays it); still building → point at homegraph_project and
1543
+ * retry; genuinely empty → honest empty note. Only fileCount > 0 carries a
1544
+ * call budget — there is nothing to budget over an unbuilt index.
1545
+ */
1546
+ exploreSuffix(fileCount) {
1547
+ if (fileCount > 0) {
1548
+ return `Budget: make at most ${getExploreBudget(fileCount)} calls for this project (${fileCount.toLocaleString()} files indexed).`;
1549
+ }
1550
+ const cg = this.cg;
1551
+ if (cg) {
1552
+ try {
1553
+ // Failed check comes first: a failed full build rolls build_phase back
1554
+ // to 'fast' (startBackgroundFullBuild catch), so the building branch
1555
+ // below would otherwise mask the failure.
1556
+ if (cg.getQueryBuilder().getMetadata('index_state') === 'failed') {
1557
+ return 'The last full index build for this project failed, so results will be empty. Tell the user to re-run `homegraph index`.';
1558
+ }
1559
+ const state = (0, index_availability_1.resolveProductIndexState)(cg);
1560
+ if (state === 'empty') {
1561
+ return (0, index_availability_1.productIndexGuidance)('empty');
1562
+ }
1563
+ if (state === 'fast' || state === 'syncing') {
1564
+ // Keep the Spec 0027 "still building → homegraph_project" story for
1565
+ // frozen tools/list descriptions (hosts snapshot once at connect).
1566
+ return state === 'syncing'
1567
+ ? (0, index_availability_1.productIndexGuidance)('syncing')
1568
+ : "HomeGraph is still building this project's index. A call right now returns build-progress guidance; use `homegraph_project` for the module/file map, then retry once indexing finishes.";
1569
+ }
1570
+ }
1571
+ catch {
1572
+ /* metadata is advisory — fall through to the empty note */
1573
+ }
1574
+ }
1575
+ return 'No files are indexed for this project; results will be empty until an index is built.';
1576
+ }
1537
1577
  /**
1538
1578
  * Get HomeGraph instance for a project
1539
1579
  *
@@ -1913,7 +1953,7 @@ class ToolHandler {
1913
1953
  async execute(toolName, args, sessionState) {
1914
1954
  const requestStartedAt = Date.now();
1915
1955
  args = { ...args };
1916
- for (const key of [QUERY_PLAN_ARG, QUERY_DEADLINE_ARG, QUERY_STARTED_ARG, QUERY_INDEX_STATE_ARG, QUERY_FAST_ATTEMPTED_ARG])
1956
+ for (const key of [QUERY_PLAN_ARG, QUERY_DEADLINE_ARG, QUERY_STARTED_ARG, QUERY_INDEX_STATE_ARG, QUERY_FAST_ATTEMPTED_ARG, '_hgEvidenceMaxChars'])
1917
1957
  delete args[key];
1918
1958
  try {
1919
1959
  // Block the first tool call on the engine's post-open reconcile so we
@@ -2023,7 +2063,10 @@ class ToolHandler {
2023
2063
  }
2024
2064
  cacheKey = (0, query_cache_1.buildMcpQueryCacheKey)(toolName, args, fileCount);
2025
2065
  const cached = cacheIndex.getEntry(cacheQueries, cacheKey);
2026
- if (cached) {
2066
+ const packMeta = cached?._meta?.homegraphEvidencePacks;
2067
+ const cachedFiles = cached?._meta?.homegraphEvidence?.files;
2068
+ if (cached && (!packMeta || (packMeta.status === 'complete'
2069
+ && this.areEvidenceFilesCurrent(cachedFiles ?? [], cacheCg.getProjectRoot())))) {
2027
2070
  const diagnosed = this.withQueryPlanDiagnostics(cached, args, true);
2028
2071
  const withWorktree = this.withWorktreeNotice(diagnosed, projectPath);
2029
2072
  return this.withStalenessNotice(withWorktree, projectPath);
@@ -2082,8 +2125,8 @@ class ToolHandler {
2082
2125
  // Fast explore must still file Partial/ANSWER meta into the session
2083
2126
  // so explore + depth fuses see it (textResult-only paths used to skip).
2084
2127
  let served = fast;
2085
- if (toolName === 'homegraph_explore' && sessionState) {
2086
- served = this.takeExploreEmission(this.ensureExploreEmission(fast, rootFast, q), sessionState);
2128
+ if ((toolName === 'homegraph_explore' && sessionState) || fast._meta?.homegraphEvidencePacks) {
2129
+ served = this.takeExploreEmission(this.ensureExploreEmission(fast, rootFast, q), toolName === 'homegraph_explore' ? sessionState : undefined);
2087
2130
  }
2088
2131
  served = this.withQueryPlanDiagnostics(served, args);
2089
2132
  if (cacheEnabled && cacheKey && cacheQueries && cacheIndex && !served.isError) {
@@ -2137,7 +2180,11 @@ class ToolHandler {
2137
2180
  if (err instanceof PathRefusalError) {
2138
2181
  return this.errorResult(err.message);
2139
2182
  }
2140
- return this.errorResult(`Tool execution failed: ${err instanceof Error ? err.message : String(err)}. ` +
2183
+ const msg = err instanceof Error ? err.message : String(err);
2184
+ if ((0, index_availability_1.isSqliteBusyMessage)(msg)) {
2185
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
2186
+ }
2187
+ return this.errorResult(`Tool execution failed: ${msg}. ` +
2141
2188
  'This is an internal homegraph error — retry the call once; if it persists, ' +
2142
2189
  'continue without homegraph for this task.');
2143
2190
  }
@@ -2193,6 +2240,10 @@ class ToolHandler {
2193
2240
  if (decision.reason !== 'overlap')
2194
2241
  return true;
2195
2242
  const files = decision.matched?.files.filter((file) => file.bytes > 0 && file.ranges.length > 0) ?? [];
2243
+ return this.areEvidenceFilesCurrent(files, projectRoot);
2244
+ }
2245
+ /** Same bounded fingerprint check for repeat protection and cached source packs. */
2246
+ areEvidenceFilesCurrent(files, projectRoot) {
2196
2247
  if (files.length === 0 || files.length > 24)
2197
2248
  return false;
2198
2249
  let remainingBytes = 2 * 1024 * 1024;
@@ -2406,7 +2457,11 @@ class ToolHandler {
2406
2457
  if (err instanceof PathRefusalError) {
2407
2458
  return this.errorResult(err.message);
2408
2459
  }
2409
- return this.errorResult(`Tool execution failed: ${err instanceof Error ? err.message : String(err)}. ` +
2460
+ const msg = err instanceof Error ? err.message : String(err);
2461
+ if ((0, index_availability_1.isSqliteBusyMessage)(msg)) {
2462
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
2463
+ }
2464
+ return this.errorResult(`Tool execution failed: ${msg}. ` +
2410
2465
  'This is an internal homegraph error — retry the call once; if it persists, ' +
2411
2466
  'continue without homegraph for this task.');
2412
2467
  }
@@ -2449,34 +2504,31 @@ class ToolHandler {
2449
2504
  }
2450
2505
  }
2451
2506
  /**
2452
- * Gate symbol/graph tools while auto-init is still on the fast map or
2453
- * background full index (and no nodes exist yet). Success-shaped guidance —
2454
- * never isError — so agents keep using HomeGraph.
2507
+ * Gate symbol/graph tools by product index state (Spec 0032).
2508
+ * Success-shaped guidance — never isError — so agents keep using HomeGraph.
2455
2509
  */
2456
2510
  maybeDeepToolPhaseGate(cg, _toolName) {
2457
- const phase = cg.getBuildPhase();
2458
- if (phase === 'full')
2511
+ const state = (0, index_availability_1.resolveProductIndexState)(cg);
2512
+ if (state === 'full')
2459
2513
  return null;
2514
+ if (state === 'syncing') {
2515
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
2516
+ }
2517
+ if (state === 'empty') {
2518
+ return this.textResult((0, index_availability_1.productIndexGuidance)('empty'));
2519
+ }
2520
+ // fast: allow deep tools once some symbols exist (partial index).
2460
2521
  try {
2461
2522
  if (cg.getStats().nodeCount > 0)
2462
2523
  return null;
2463
2524
  }
2464
- catch {
2465
- /* ignore */
2466
- }
2467
- if (phase === 'fast' || phase === 'indexing') {
2468
- return this.textResult([
2469
- `Full symbol index is still building (phase=${phase}).`,
2470
- 'Use `homegraph_project` for the module/file map now, then retry this tool once indexing finishes.',
2471
- ].join('\n'));
2472
- }
2473
- if (phase === 'building_fast' || phase === 'none') {
2474
- return this.textResult([
2475
- 'HomeGraph is still preparing the project map.',
2476
- 'Retry in a few seconds, or call `homegraph_project` once the fast build completes.',
2477
- ].join('\n'));
2525
+ catch (err) {
2526
+ const msg = err instanceof Error ? err.message : String(err);
2527
+ if ((0, index_availability_1.isSqliteBusyMessage)(msg)) {
2528
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
2529
+ }
2478
2530
  }
2479
- return null;
2531
+ return this.textResult((0, index_availability_1.productIndexGuidance)('fast'));
2480
2532
  }
2481
2533
  async handleSearch(args) {
2482
2534
  const query = this.validateString(args.query, 'query');
@@ -5339,7 +5391,7 @@ class ToolHandler {
5339
5391
  } } };
5340
5392
  }
5341
5393
  /** Select once; legacy section builders consume the same canonical query/features. */
5342
- tryPlannedFastPath(cg, plan, root) {
5394
+ tryPlannedFastPath(cg, plan, root, evidenceMaxChars) {
5343
5395
  const query = plan.canonicalQuery;
5344
5396
  if (plan.route === 'usages' || plan.route === 'modules' || plan.route === 'native') {
5345
5397
  return this.runSpecializedExploreRoute(plan.route, cg, query, root, plan);
@@ -5350,8 +5402,8 @@ class ToolHandler {
5350
5402
  if (plan.source === 'llm' && (plan.intent === 'general' || plan.intent === 'flow'))
5351
5403
  return null;
5352
5404
  return this.tryFastInventoryExplore(cg, query, root, plan)
5353
- ?? this.tryLightMechanismExplore(cg, query, root, plan)
5354
- ?? this.tryCompactLocalSymbolExplore(cg, query, root, plan);
5405
+ ?? this.tryLightMechanismExplore(cg, query, root, plan, evidenceMaxChars)
5406
+ ?? this.tryCompactLocalSymbolExplore(cg, query, root, plan, evidenceMaxChars);
5355
5407
  }
5356
5408
  /** Internal execution only: no recursive MCP calls, model requests or new deadline. */
5357
5409
  async executePlannedStep(args, plan) {
@@ -5385,7 +5437,7 @@ class ToolHandler {
5385
5437
  return served;
5386
5438
  }
5387
5439
  const fast = args[QUERY_FAST_ATTEMPTED_ARG] === true && plan.source === 'rules'
5388
- ? null : this.tryPlannedFastPath(cg, plan, cg.getProjectRoot());
5440
+ ? null : this.tryPlannedFastPath(cg, plan, cg.getProjectRoot(), args._hgEvidenceMaxChars);
5389
5441
  if (fast)
5390
5442
  return fast;
5391
5443
  return this.handleExplore({ ...args, query, [QUERY_PLAN_ARG]: plan });
@@ -5448,7 +5500,10 @@ class ToolHandler {
5448
5500
  }
5449
5501
  seenQueries.add(`${compiled.intent}:${compiled.canonicalQuery}`);
5450
5502
  try {
5451
- const result = await this.executePlannedStep({ ...args, [QUERY_DEADLINE_ARG]: deadline }, compiled);
5503
+ const stepCap = Math.max(0, Math.floor((outputBudget - used) / Math.max(1, plan.steps.length - diagnostics.length + 1)) - 100);
5504
+ const result = await this.executePlannedStep({ ...args, [QUERY_DEADLINE_ARG]: deadline,
5505
+ ...(multi ? { _hgEvidenceMaxChars: Math.max(0, stepCap - Math.min(1600, Math.floor(stepCap / 2)) - 2) } : {}),
5506
+ }, compiled);
5452
5507
  const body = result.content.map((part) => part.text).join('\n');
5453
5508
  const candidates = result.isError ? [] : this.locatedPlanBindings(cg, result, resolved);
5454
5509
  const childEmission = result[explore_session_state_1.EXPLORE_EMISSION_KEY];
@@ -5491,7 +5546,16 @@ class ToolHandler {
5491
5546
  bindings.set(step.id, visibleBindings);
5492
5547
  const bodyCap = Math.max(0, cap - receipt.length - 2);
5493
5548
  const trimmed = neutralBody.length > bodyCap;
5494
- const kept = (0, evidence_rendering_1.trimEvidenceAtLine)(neutralBody, bodyCap);
5549
+ const atomic = !!result._meta?.homegraphEvidencePacks;
5550
+ const kept = atomic && trimmed
5551
+ ? '[Partial source: complete evidence pack omitted by the shared output budget.]'.slice(0, bodyCap)
5552
+ : atomic ? neutralBody : (0, evidence_rendering_1.trimEvidenceAtLine)(neutralBody, bodyCap);
5553
+ if (atomic && trimmed) {
5554
+ receipt = '';
5555
+ diagnostic.locatedNodes = [];
5556
+ diagnostic.resolvedAnchors = [];
5557
+ bindings.set(step.id, []);
5558
+ }
5495
5559
  if (trimmed)
5496
5560
  diagnostic.status = 'partial';
5497
5561
  else
@@ -6185,9 +6249,29 @@ class ToolHandler {
6185
6249
  }
6186
6250
  return finishCompact('Inventory sections above are complete for this query. **ANSWER NOW.**');
6187
6251
  }
6188
- /**
6189
- * Render a compact symbol-bounded slice of one file (lightweight mechanism path).
6190
- */
6252
+ /** Pack already-located ArkTS evidence before legacy windowing can cut it. */
6253
+ tryArktsEvidenceExplore(cg, query, projectRoot, nodes, focusIds, maxChars, maxFiles, plan) {
6254
+ if (process.env.HOMEGRAPH_ARKTS_EVIDENCE_PACKS === '0')
6255
+ return null;
6256
+ if (!nodes.some(n => /\.ets$/i.test(n.filePath) && !n.filePath.startsWith('ohos-sdk:')))
6257
+ return null;
6258
+ const budget = getExploreOutputBudget(cg.getStats().fileCount);
6259
+ const queryPaths = process.env.HOMEGRAPH_ARKTS_QUERY_PATHS !== '0';
6260
+ if (queryPaths)
6261
+ nodes = (0, evidence_paths_1.completeEvidencePathCandidates)(query, nodes, (name, limit) => cg.getQueryBuilder().getNodesByQualifiedNameExact(name, limit), plan);
6262
+ const pathSearch = !queryPaths ? undefined : (0, evidence_paths_1.searchEvidencePaths)({
6263
+ getNode: id => cg.getNode(id),
6264
+ getEdges: (id, direction, kinds, limit, preferred) => cg.getQueryBuilder().getEvidenceEdges(id, direction, kinds, limit, preferred),
6265
+ }, (0, evidence_paths_1.resolveEvidencePathGoal)(query, nodes, focusIds, plan));
6266
+ const result = (0, arkts_evidence_packs_1.buildArktsEvidencePacks)(cg, { projectRoot, query, nodes, focusIds,
6267
+ maxChars: Math.min(budget.maxOutputChars, maxChars ?? budget.maxOutputChars), maxFiles, pathSearch });
6268
+ if (!result)
6269
+ return null;
6270
+ // The pack renderer already supplies neutral guidance and exact source bytes.
6271
+ return { content: [{ type: 'text', text: result.text }], [explore_session_state_1.EXPLORE_EMISSION_KEY]: result.emission,
6272
+ _meta: { homegraphEvidencePacks: result.metadata } };
6273
+ }
6274
+ /** Render a compact symbol-bounded slice on the legacy mechanism path. */
6191
6275
  renderLightMechanismSource(projectRoot, filePath, nodes, maxChars) {
6192
6276
  const absPath = (0, utils_1.validatePathWithinRoot)(projectRoot, filePath);
6193
6277
  if (!absPath || !(0, fs_1.existsSync)(absPath))
@@ -6223,7 +6307,7 @@ class ToolHandler {
6223
6307
  * findRelevantContext. Fast enough for MCP budget; complete enough to avoid
6224
6308
  * agent grep/read loops (token savings).
6225
6309
  */
6226
- tryLightMechanismExplore(cg, query, projectRoot, plan) {
6310
+ tryLightMechanismExplore(cg, query, projectRoot, plan, evidenceMaxChars) {
6227
6311
  if (!planFeature(plan, 'shouldTryLightMechanismExplore', query, query_utils_1.shouldTryLightMechanismExplore))
6228
6312
  return null;
6229
6313
  const STRUCTURE_KINDS = new Set(['class', 'struct', 'interface', 'component', 'method', 'function']);
@@ -6394,6 +6478,9 @@ class ToolHandler {
6394
6478
  const seeds = (0, query_utils_1.extractMechanismEntrySeeds)(query);
6395
6479
  const flow = this.buildFlowFromNamedSymbols(cg, `${query} ${seeds.join(' ')}`);
6396
6480
  const hasFlowPath = flow.pathNodeIds.size > 1;
6481
+ const evidence = this.tryArktsEvidenceExplore(cg, query, projectRoot, [...fileNodes.values()].flat().concat([...flow.pathNodeIds].flatMap(id => { const n = cg.getNode(id); return n ? [n] : []; })), new Set([...seedIds, ...flow.pathNodeIds]), evidenceMaxChars, undefined, plan);
6482
+ if (evidence)
6483
+ return evidence;
6397
6484
  const managerSection = this.formatDomainRoleInventory(managerHits.length > 0
6398
6485
  ? managerHits
6399
6486
  : [...seedIds].map((id) => cg.getNode(id)).filter((n) => !!n && (0, query_utils_1.isDomainRoleSymbol)(n.name, n.filePath, domainPathTokens)));
@@ -6861,7 +6948,7 @@ class ToolHandler {
6861
6948
  * Compact explore for local-symbol behavior questions — skips findRelevantContext
6862
6949
  * and caps to 1–2 defining files (avoids the ~24K related-file dump).
6863
6950
  */
6864
- tryCompactLocalSymbolExplore(cg, query, projectRoot, plan) {
6951
+ tryCompactLocalSymbolExplore(cg, query, projectRoot, plan, evidenceMaxChars) {
6865
6952
  // Inventory runs *before* this on the call sites. Do not refuse compact
6866
6953
  // merely because inventory *intent* matched — empty inventory must fall
6867
6954
  // through here (bare callbacks like OnSurfaceChangedCB).
@@ -7041,6 +7128,9 @@ class ToolHandler {
7041
7128
  }
7042
7129
  if (seedIds.size === 0)
7043
7130
  return null;
7131
+ const evidence = this.tryArktsEvidenceExplore(cg, query, projectRoot, [...fileNodes.values()].flat(), seedIds, evidenceMaxChars, undefined, plan);
7132
+ if (evidence)
7133
+ return evidence;
7044
7134
  const pathAffinity = (seedPath, otherPath) => {
7045
7135
  const a = seedPath.replace(/\\/g, '/').split('/');
7046
7136
  const b = otherPath.replace(/\\/g, '/').split('/');
@@ -10312,6 +10402,13 @@ class ToolHandler {
10312
10402
  }
10313
10403
  const flow = this.buildFlowFromNamedSymbols(cg, flowQuery);
10314
10404
  const hasFlowPath = flow.pathNodeIds.size > 0;
10405
+ // Keep literal/resource and specialized inventory rendering intact. This
10406
+ // first batch changes symbol-grounded structural evidence only.
10407
+ if ((hasFlowPath || flow.text.length > 0 || plan?.intent === 'flow') && !subgraph.literalEvidence?.hits.length) {
10408
+ const evidence = this.tryArktsEvidenceExplore(cg, query, projectRoot, [...subgraph.nodes.values()].concat([...flow.pathNodeIds].flatMap(id => { const n = cg.getNode(id); return n ? [n] : []; })), new Set([...subgraph.roots, ...flow.namedNodeIds, ...flow.pathNodeIds]), args._hgEvidenceMaxChars, explicitMaxFiles ? maxFiles : undefined, plan);
10409
+ if (evidence)
10410
+ return evidence;
10411
+ }
10315
10412
  budget = tightenExploreBudgetForQuery(budget, query, { hasFlowPath });
10316
10413
  // Honor an explicit maxFiles from the caller — budget.defaultMaxFiles is only
10317
10414
  // a default when the agent didn't ask for more (adaptive sibling tests pass 12).
@@ -11980,21 +12077,18 @@ class ToolHandler {
11980
12077
  lines.push(`**Build phase:** ${cg.getBuildPhase()}`, `**Files indexed:** ${stats.fileCount}`, `**Total nodes:** ${stats.nodeCount}`, `**Total edges:** ${stats.edgeCount}`, `**Database size:** ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`, ...(stats.walSizeBytes > 0
11981
12078
  ? [`**WAL size:** ${(stats.walSizeBytes / 1024 / 1024).toFixed(2)} MB`]
11982
12079
  : []), `**Graph sources:** ${cg.getGraphSources()}`);
11983
- // Surface the active SQLite backend: node:sqlite → better-sqlite3 → wasm.
12080
+ // Surface the active SQLite backend: node:sqlite → wasm.
11984
12081
  const backend = cg.getBackend();
11985
12082
  if (backend === 'node-sqlite') {
11986
12083
  lines.push(`**Backend:** node-sqlite (built-in)`);
11987
12084
  }
11988
- else if (backend === 'native') {
11989
- lines.push(`**Backend:** native (better-sqlite3)`);
11990
- }
11991
12085
  else {
11992
12086
  lines.push(`**Backend:** ⚠ wasm (no WAL backend available) — ` +
11993
12087
  `5-10x slower than WAL. Fix: ${sqlite_adapter_1.WASM_FALLBACK_FIX_RECIPE}`);
11994
12088
  }
11995
12089
  // Effective journal mode. 'wal' ⇒ concurrent reads never block on a writer;
11996
- // anything else ⇒ they can ("database is locked"). node:sqlite / native
11997
- // support WAL; wasm remaps to DELETE.
12090
+ // anything else ⇒ they can ("database is locked"). node:sqlite supports WAL;
12091
+ // wasm remaps to DELETE.
11998
12092
  const journalMode = cg.getJournalMode();
11999
12093
  if (journalMode === 'wal') {
12000
12094
  lines.push(`**Journal mode:** wal (concurrent reads safe)`);
@@ -12047,10 +12141,27 @@ class ToolHandler {
12047
12141
  */
12048
12142
  async handleProject(args) {
12049
12143
  const cg = this.getHomeGraph(args.projectPath);
12050
- const phase = cg.getBuildPhase();
12051
- if (phase === 'building_fast') {
12052
- return this.textResult('Fast project map is still building — retry in a few seconds.');
12144
+ const state = (0, index_availability_1.resolveProductIndexState)(cg);
12145
+ if (state === 'empty') {
12146
+ return this.textResult((0, index_availability_1.productIndexGuidance)('empty'));
12147
+ }
12148
+ if (state === 'syncing') {
12149
+ // Prefer returning the map when readable; only hard-stop if phase has no map.
12150
+ try {
12151
+ const peek = cg.getProjectMap({ includeFiles: false });
12152
+ if (peek.modules.length === 0) {
12153
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
12154
+ }
12155
+ }
12156
+ catch (err) {
12157
+ const msg = err instanceof Error ? err.message : String(err);
12158
+ if ((0, index_availability_1.isSqliteBusyMessage)(msg)) {
12159
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
12160
+ }
12161
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
12162
+ }
12053
12163
  }
12164
+ const phase = cg.getBuildPhase();
12054
12165
  let map = cg.getProjectMap({
12055
12166
  module: typeof args.module === 'string' ? args.module : undefined,
12056
12167
  includeFiles: args.includeFiles !== false,
@@ -12069,6 +12180,9 @@ class ToolHandler {
12069
12180
  }
12070
12181
  catch (err) {
12071
12182
  const message = err instanceof Error ? err.message : String(err);
12183
+ if ((0, index_availability_1.isSqliteBusyMessage)(message)) {
12184
+ return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
12185
+ }
12072
12186
  return this.textResult(`Failed to build project map: ${message}`);
12073
12187
  }
12074
12188
  }
@@ -12076,14 +12190,18 @@ class ToolHandler {
12076
12190
  return this.textResult('No modules found in the project map.');
12077
12191
  }
12078
12192
  const FILE_CAP = 80;
12193
+ const productState = (0, index_availability_1.resolveProductIndexState)(cg);
12079
12194
  const lines = [
12080
- `**Project map** (phase=${map.phase})`,
12195
+ `**Project map** (status=${productState}, phase=${map.phase})`,
12081
12196
  `modules: ${map.modules.length} · files: ${map.fileCount}`,
12082
12197
  '',
12083
12198
  ];
12084
- if (map.phase === 'fast' || map.phase === 'indexing') {
12199
+ if (productState === 'fast' || map.phase === 'fast' || map.phase === 'indexing') {
12085
12200
  lines.push('_Full symbol index still building — this map has modules/files only (no call graph)._', '');
12086
12201
  }
12202
+ if (productState === 'syncing') {
12203
+ lines.push('_Index write in progress — map may be briefly stale._', '');
12204
+ }
12087
12205
  for (const m of map.modules) {
12088
12206
  const rootLabel = m.rootPath || '.';
12089
12207
  lines.push(`### ${m.name} (\`${rootLabel}\`) · ${m.kind} · ${m.fileCount} files`);
@@ -12979,6 +13097,9 @@ class ToolHandler {
12979
13097
  // Line-numbered (cat -n style, like homegraph_explore and Read) so the
12980
13098
  // agent can cite/edit exact lines without re-Reading the file for them.
12981
13099
  const numbered = node.startLine ? numberSourceLines(code, node.startLine) : code;
13100
+ if (node.startLine && process.env.HOMEGRAPH_SOURCE_RECEIPTS === '1') {
13101
+ lines.push('', (0, source_slice_identity_1.sourceSliceIdentity)(node.filePath, node.startLine, code));
13102
+ }
12982
13103
  lines.push('', '```' + node.language, numbered, '```');
12983
13104
  }
12984
13105
  return lines.join('\n');
@@ -1,23 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.OpenAiLlmClient = void 0;
7
4
  exports.parseJsonResponse = parseJsonResponse;
8
- /**
9
- * Provider-agnostic LLM client for spec
10
- *
11
- * Supports OpenAI-compatible chat completions API with automatic retry on
12
- * transient errors (rate limits, server errors, network failures). No mock
13
- * mode — callers that need test doubles inject their own stubs implementing
14
- * the interface.
15
- *
16
- * @module spec/llm/client
17
- */
18
- const openai_1 = __importDefault(require("openai"));
19
5
  const errors_1 = require("../../errors");
20
6
  const retry_1 = require("./retry");
7
+ const openai_sdk_1 = require("./openai-sdk");
21
8
  // =============================================================================
22
9
  // Shared JSON extraction
23
10
  // =============================================================================
@@ -102,7 +89,8 @@ class OpenAiLlmClient {
102
89
  * we handle retries ourselves with proper visibility).
103
90
  */
104
91
  buildClient() {
105
- return new openai_1.default({
92
+ const OpenAI = (0, openai_sdk_1.loadOpenAI)();
93
+ return new OpenAI({
106
94
  apiKey: this.config.apiKey,
107
95
  baseURL: this.resolveBaseURL(),
108
96
  maxRetries: 0, // disable SDK retry
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Lazy load of the optional `openai` package (Spec 0031).
3
+ *
4
+ * MCP `serve mcp` must start without it. Spec LLM commands require
5
+ * `npm install openai`.
6
+ *
7
+ * @module spec/llm/openai-sdk
8
+ */
9
+ export declare const OPENAI_INSTALL_HINT = "The openai package is not installed. Spec LLM calls need it: npm install openai";
10
+ /** Default export of `openai` — the client constructor plus `RateLimitError` etc. */
11
+ export type OpenAIClientCtor = typeof import('openai').default;
12
+ export declare function loadOpenAI(): OpenAIClientCtor;
13
+ export declare function tryLoadOpenAI(): OpenAIClientCtor | undefined;
14
+ //# sourceMappingURL=openai-sdk.d.ts.map