homegraph 1.5.6 → 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 (560) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +12 -6
  3. package/dist/bin/homegraph.js +16 -14
  4. package/dist/context/index.js +120 -15
  5. package/dist/db/index.d.ts +1 -1
  6. package/dist/db/index.js +11 -25
  7. package/dist/db/queries.d.ts +5 -1
  8. package/dist/db/queries.js +31 -2
  9. package/dist/db/sqlite-adapter.d.ts +6 -12
  10. package/dist/db/sqlite-adapter.js +13 -41
  11. package/dist/directory.d.ts +1 -1
  12. package/dist/directory.js +25 -1
  13. package/dist/extraction/grammars.d.ts +2 -0
  14. package/dist/extraction/grammars.js +7 -7
  15. package/dist/extraction/languages/arkts.d.ts +25 -3
  16. package/dist/extraction/languages/arkts.js +184 -22
  17. package/dist/graph/evidence-paths.d.ts +63 -0
  18. package/dist/graph/evidence-paths.js +245 -0
  19. package/dist/index.d.ts +6 -1
  20. package/dist/index.js +55 -17
  21. package/dist/mcp/arkts-evidence-packs.d.ts +67 -0
  22. package/dist/mcp/arkts-evidence-packs.js +352 -0
  23. package/dist/mcp/daemon.js +1 -1
  24. package/dist/mcp/engine.d.ts +20 -7
  25. package/dist/mcp/engine.js +113 -106
  26. package/dist/mcp/evidence-rendering.d.ts +10 -0
  27. package/dist/mcp/evidence-rendering.js +71 -0
  28. package/dist/mcp/explore-repeat-guard.d.ts +8 -13
  29. package/dist/mcp/explore-repeat-guard.js +54 -114
  30. package/dist/mcp/explore-session-state.d.ts +26 -4
  31. package/dist/mcp/explore-session-state.js +50 -4
  32. package/dist/mcp/index-availability.d.ts +23 -0
  33. package/dist/mcp/index-availability.js +78 -0
  34. package/dist/mcp/index.js +5 -4
  35. package/dist/mcp/query-cache.d.ts +1 -1
  36. package/dist/mcp/query-cache.js +90 -3
  37. package/dist/mcp/query-worker.d.ts +1 -1
  38. package/dist/mcp/query-worker.js +1 -1
  39. package/dist/mcp/server-instructions.d.ts +4 -9
  40. package/dist/mcp/server-instructions.js +34 -61
  41. package/dist/mcp/session.js +12 -4
  42. package/dist/mcp/source-slice-identity.d.ts +3 -0
  43. package/dist/mcp/source-slice-identity.js +11 -0
  44. package/dist/mcp/tools.d.ts +43 -9
  45. package/dist/mcp/tools.js +859 -155
  46. package/dist/search/literal-evidence.d.ts +44 -0
  47. package/dist/search/literal-evidence.js +278 -0
  48. package/dist/search/query-plan-provider.d.ts +6 -0
  49. package/dist/search/query-plan-provider.js +289 -0
  50. package/dist/search/query-plan.d.ts +98 -0
  51. package/dist/search/query-plan.js +334 -0
  52. package/dist/search/query-utils.d.ts +6 -1
  53. package/dist/search/query-utils.js +64 -5
  54. package/dist/spec/llm/client.js +3 -15
  55. package/dist/spec/llm/openai-sdk.d.ts +14 -0
  56. package/dist/spec/llm/openai-sdk.js +37 -0
  57. package/dist/spec/llm/retry.js +8 -9
  58. package/dist/types.d.ts +17 -0
  59. package/dist/utils.d.ts +5 -0
  60. package/dist/utils.js +24 -0
  61. package/package.json +3 -5
  62. package/dist/addons/dynamic-import.d.ts.map +0 -1
  63. package/dist/addons/dynamic-import.js.map +0 -1
  64. package/dist/addons/init-template.d.ts.map +0 -1
  65. package/dist/addons/init-template.js.map +0 -1
  66. package/dist/addons/loader.d.ts.map +0 -1
  67. package/dist/addons/loader.js.map +0 -1
  68. package/dist/addons/manager.d.ts.map +0 -1
  69. package/dist/addons/manager.js.map +0 -1
  70. package/dist/addons/paths.d.ts.map +0 -1
  71. package/dist/addons/paths.js.map +0 -1
  72. package/dist/addons/registry.d.ts.map +0 -1
  73. package/dist/addons/registry.js.map +0 -1
  74. package/dist/addons/semver.d.ts.map +0 -1
  75. package/dist/addons/semver.js.map +0 -1
  76. package/dist/addons/types.d.ts.map +0 -1
  77. package/dist/addons/types.js.map +0 -1
  78. package/dist/addons/validate.d.ts.map +0 -1
  79. package/dist/addons/validate.js.map +0 -1
  80. package/dist/arkui/index.d.ts.map +0 -1
  81. package/dist/arkui/index.js.map +0 -1
  82. package/dist/arkui/migrate-passage.d.ts.map +0 -1
  83. package/dist/arkui/migrate-passage.js.map +0 -1
  84. package/dist/arkui/migrate-semantics.d.ts.map +0 -1
  85. package/dist/arkui/migrate-semantics.js.map +0 -1
  86. package/dist/arkui/migrate-snapshot.d.ts.map +0 -1
  87. package/dist/arkui/migrate-snapshot.js.map +0 -1
  88. package/dist/bin/addon-commands.d.ts.map +0 -1
  89. package/dist/bin/addon-commands.js.map +0 -1
  90. package/dist/bin/command-supervision.d.ts.map +0 -1
  91. package/dist/bin/command-supervision.js.map +0 -1
  92. package/dist/bin/fatal-handler.d.ts.map +0 -1
  93. package/dist/bin/fatal-handler.js.map +0 -1
  94. package/dist/bin/homegraph.d.ts.map +0 -1
  95. package/dist/bin/homegraph.js.map +0 -1
  96. package/dist/bin/node-version-check.d.ts.map +0 -1
  97. package/dist/bin/node-version-check.js.map +0 -1
  98. package/dist/bin/uninstall.d.ts.map +0 -1
  99. package/dist/bin/uninstall.js.map +0 -1
  100. package/dist/context/formatter.d.ts.map +0 -1
  101. package/dist/context/formatter.js.map +0 -1
  102. package/dist/context/index.d.ts.map +0 -1
  103. package/dist/context/index.js.map +0 -1
  104. package/dist/context/markers.d.ts.map +0 -1
  105. package/dist/context/markers.js.map +0 -1
  106. package/dist/db/index.d.ts.map +0 -1
  107. package/dist/db/index.js.map +0 -1
  108. package/dist/db/migrations.d.ts.map +0 -1
  109. package/dist/db/migrations.js.map +0 -1
  110. package/dist/db/queries.d.ts.map +0 -1
  111. package/dist/db/queries.js.map +0 -1
  112. package/dist/db/sqlite-adapter.d.ts.map +0 -1
  113. package/dist/db/sqlite-adapter.js.map +0 -1
  114. package/dist/db/wal-valve.d.ts.map +0 -1
  115. package/dist/db/wal-valve.js.map +0 -1
  116. package/dist/directory.d.ts.map +0 -1
  117. package/dist/directory.js.map +0 -1
  118. package/dist/errors.d.ts.map +0 -1
  119. package/dist/errors.js.map +0 -1
  120. package/dist/extraction/arkts-batch-worker.d.ts.map +0 -1
  121. package/dist/extraction/arkts-batch-worker.js.map +0 -1
  122. package/dist/extraction/astro-extractor.d.ts.map +0 -1
  123. package/dist/extraction/astro-extractor.js.map +0 -1
  124. package/dist/extraction/cfml-extractor.d.ts.map +0 -1
  125. package/dist/extraction/cfml-extractor.js.map +0 -1
  126. package/dist/extraction/context.d.ts.map +0 -1
  127. package/dist/extraction/context.js.map +0 -1
  128. package/dist/extraction/default-ignore.d.ts.map +0 -1
  129. package/dist/extraction/default-ignore.js.map +0 -1
  130. package/dist/extraction/dfm-extractor.d.ts.map +0 -1
  131. package/dist/extraction/dfm-extractor.js.map +0 -1
  132. package/dist/extraction/extraction-version.d.ts.map +0 -1
  133. package/dist/extraction/extraction-version.js.map +0 -1
  134. package/dist/extraction/function-ref.d.ts.map +0 -1
  135. package/dist/extraction/function-ref.js.map +0 -1
  136. package/dist/extraction/generated-detection.d.ts.map +0 -1
  137. package/dist/extraction/generated-detection.js.map +0 -1
  138. package/dist/extraction/grammars.d.ts.map +0 -1
  139. package/dist/extraction/grammars.js.map +0 -1
  140. package/dist/extraction/index.d.ts.map +0 -1
  141. package/dist/extraction/index.js.map +0 -1
  142. package/dist/extraction/languages/arkts.d.ts.map +0 -1
  143. package/dist/extraction/languages/arkts.js.map +0 -1
  144. package/dist/extraction/languages/c-cpp.d.ts.map +0 -1
  145. package/dist/extraction/languages/c-cpp.js.map +0 -1
  146. package/dist/extraction/languages/cfquery.d.ts.map +0 -1
  147. package/dist/extraction/languages/cfquery.js.map +0 -1
  148. package/dist/extraction/languages/cfscript.d.ts.map +0 -1
  149. package/dist/extraction/languages/cfscript.js.map +0 -1
  150. package/dist/extraction/languages/cobol.d.ts.map +0 -1
  151. package/dist/extraction/languages/cobol.js.map +0 -1
  152. package/dist/extraction/languages/csharp.d.ts.map +0 -1
  153. package/dist/extraction/languages/csharp.js.map +0 -1
  154. package/dist/extraction/languages/dart.d.ts.map +0 -1
  155. package/dist/extraction/languages/dart.js.map +0 -1
  156. package/dist/extraction/languages/erlang.d.ts.map +0 -1
  157. package/dist/extraction/languages/erlang.js.map +0 -1
  158. package/dist/extraction/languages/go.d.ts.map +0 -1
  159. package/dist/extraction/languages/go.js.map +0 -1
  160. package/dist/extraction/languages/index.d.ts.map +0 -1
  161. package/dist/extraction/languages/index.js.map +0 -1
  162. package/dist/extraction/languages/java.d.ts.map +0 -1
  163. package/dist/extraction/languages/java.js.map +0 -1
  164. package/dist/extraction/languages/javascript.d.ts.map +0 -1
  165. package/dist/extraction/languages/javascript.js.map +0 -1
  166. package/dist/extraction/languages/kotlin.d.ts.map +0 -1
  167. package/dist/extraction/languages/kotlin.js.map +0 -1
  168. package/dist/extraction/languages/lua.d.ts.map +0 -1
  169. package/dist/extraction/languages/lua.js.map +0 -1
  170. package/dist/extraction/languages/luau.d.ts.map +0 -1
  171. package/dist/extraction/languages/luau.js.map +0 -1
  172. package/dist/extraction/languages/nix.d.ts.map +0 -1
  173. package/dist/extraction/languages/nix.js.map +0 -1
  174. package/dist/extraction/languages/objc.d.ts.map +0 -1
  175. package/dist/extraction/languages/objc.js.map +0 -1
  176. package/dist/extraction/languages/pascal.d.ts.map +0 -1
  177. package/dist/extraction/languages/pascal.js.map +0 -1
  178. package/dist/extraction/languages/php.d.ts.map +0 -1
  179. package/dist/extraction/languages/php.js.map +0 -1
  180. package/dist/extraction/languages/python.d.ts.map +0 -1
  181. package/dist/extraction/languages/python.js.map +0 -1
  182. package/dist/extraction/languages/r.d.ts.map +0 -1
  183. package/dist/extraction/languages/r.js.map +0 -1
  184. package/dist/extraction/languages/ruby.d.ts.map +0 -1
  185. package/dist/extraction/languages/ruby.js.map +0 -1
  186. package/dist/extraction/languages/rust.d.ts.map +0 -1
  187. package/dist/extraction/languages/rust.js.map +0 -1
  188. package/dist/extraction/languages/scala.d.ts.map +0 -1
  189. package/dist/extraction/languages/scala.js.map +0 -1
  190. package/dist/extraction/languages/solidity.d.ts.map +0 -1
  191. package/dist/extraction/languages/solidity.js.map +0 -1
  192. package/dist/extraction/languages/swift.d.ts.map +0 -1
  193. package/dist/extraction/languages/swift.js.map +0 -1
  194. package/dist/extraction/languages/terraform.d.ts.map +0 -1
  195. package/dist/extraction/languages/terraform.js.map +0 -1
  196. package/dist/extraction/languages/typescript.d.ts.map +0 -1
  197. package/dist/extraction/languages/typescript.js.map +0 -1
  198. package/dist/extraction/languages/vbnet.d.ts.map +0 -1
  199. package/dist/extraction/languages/vbnet.js.map +0 -1
  200. package/dist/extraction/liquid-extractor.d.ts.map +0 -1
  201. package/dist/extraction/liquid-extractor.js.map +0 -1
  202. package/dist/extraction/mybatis-extractor.d.ts.map +0 -1
  203. package/dist/extraction/mybatis-extractor.js.map +0 -1
  204. package/dist/extraction/parse-pool.d.ts.map +0 -1
  205. package/dist/extraction/parse-pool.js.map +0 -1
  206. package/dist/extraction/parse-worker.d.ts.map +0 -1
  207. package/dist/extraction/parse-worker.js.map +0 -1
  208. package/dist/extraction/razor-extractor.d.ts.map +0 -1
  209. package/dist/extraction/razor-extractor.js.map +0 -1
  210. package/dist/extraction/store-worker.d.ts.map +0 -1
  211. package/dist/extraction/store-worker.js.map +0 -1
  212. package/dist/extraction/store-writer.d.ts.map +0 -1
  213. package/dist/extraction/store-writer.js.map +0 -1
  214. package/dist/extraction/svelte-extractor.d.ts.map +0 -1
  215. package/dist/extraction/svelte-extractor.js.map +0 -1
  216. package/dist/extraction/tree-sitter-helpers.d.ts.map +0 -1
  217. package/dist/extraction/tree-sitter-helpers.js.map +0 -1
  218. package/dist/extraction/tree-sitter-types.d.ts.map +0 -1
  219. package/dist/extraction/tree-sitter-types.js.map +0 -1
  220. package/dist/extraction/tree-sitter.d.ts.map +0 -1
  221. package/dist/extraction/tree-sitter.js.map +0 -1
  222. package/dist/extraction/vue-extractor.d.ts.map +0 -1
  223. package/dist/extraction/vue-extractor.js.map +0 -1
  224. package/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
  225. package/dist/extraction/wasm-runtime-flags.d.ts.map +0 -1
  226. package/dist/extraction/wasm-runtime-flags.js.map +0 -1
  227. package/dist/graph/index.d.ts.map +0 -1
  228. package/dist/graph/index.js.map +0 -1
  229. package/dist/graph/queries.d.ts.map +0 -1
  230. package/dist/graph/queries.js.map +0 -1
  231. package/dist/graph/traversal.d.ts.map +0 -1
  232. package/dist/graph/traversal.js.map +0 -1
  233. package/dist/graph-sources.d.ts.map +0 -1
  234. package/dist/graph-sources.js.map +0 -1
  235. package/dist/index.d.ts.map +0 -1
  236. package/dist/index.js.map +0 -1
  237. package/dist/installer/config-writer.d.ts.map +0 -1
  238. package/dist/installer/config-writer.js.map +0 -1
  239. package/dist/installer/index.d.ts.map +0 -1
  240. package/dist/installer/index.js.map +0 -1
  241. package/dist/installer/instructions-template.d.ts.map +0 -1
  242. package/dist/installer/instructions-template.js.map +0 -1
  243. package/dist/installer/targets/antigravity.d.ts.map +0 -1
  244. package/dist/installer/targets/antigravity.js.map +0 -1
  245. package/dist/installer/targets/claude.d.ts.map +0 -1
  246. package/dist/installer/targets/claude.js.map +0 -1
  247. package/dist/installer/targets/codebuddy.d.ts.map +0 -1
  248. package/dist/installer/targets/codebuddy.js.map +0 -1
  249. package/dist/installer/targets/codex.d.ts.map +0 -1
  250. package/dist/installer/targets/codex.js.map +0 -1
  251. package/dist/installer/targets/cursor.d.ts.map +0 -1
  252. package/dist/installer/targets/cursor.js.map +0 -1
  253. package/dist/installer/targets/deveco.d.ts.map +0 -1
  254. package/dist/installer/targets/deveco.js.map +0 -1
  255. package/dist/installer/targets/gemini.d.ts.map +0 -1
  256. package/dist/installer/targets/gemini.js.map +0 -1
  257. package/dist/installer/targets/hermes.d.ts.map +0 -1
  258. package/dist/installer/targets/hermes.js.map +0 -1
  259. package/dist/installer/targets/kiro.d.ts.map +0 -1
  260. package/dist/installer/targets/kiro.js.map +0 -1
  261. package/dist/installer/targets/opencode.d.ts.map +0 -1
  262. package/dist/installer/targets/opencode.js.map +0 -1
  263. package/dist/installer/targets/registry.d.ts.map +0 -1
  264. package/dist/installer/targets/registry.js.map +0 -1
  265. package/dist/installer/targets/shared.d.ts.map +0 -1
  266. package/dist/installer/targets/shared.js.map +0 -1
  267. package/dist/installer/targets/toml.d.ts.map +0 -1
  268. package/dist/installer/targets/toml.js.map +0 -1
  269. package/dist/installer/targets/types.d.ts.map +0 -1
  270. package/dist/installer/targets/types.js.map +0 -1
  271. package/dist/mcp/daemon-manager.d.ts.map +0 -1
  272. package/dist/mcp/daemon-manager.js.map +0 -1
  273. package/dist/mcp/daemon-paths.d.ts.map +0 -1
  274. package/dist/mcp/daemon-paths.js.map +0 -1
  275. package/dist/mcp/daemon-registry.d.ts.map +0 -1
  276. package/dist/mcp/daemon-registry.js.map +0 -1
  277. package/dist/mcp/daemon.d.ts.map +0 -1
  278. package/dist/mcp/daemon.js.map +0 -1
  279. package/dist/mcp/diff-impact.d.ts.map +0 -1
  280. package/dist/mcp/diff-impact.js.map +0 -1
  281. package/dist/mcp/dynamic-boundaries.d.ts.map +0 -1
  282. package/dist/mcp/dynamic-boundaries.js.map +0 -1
  283. package/dist/mcp/early-ppid.d.ts.map +0 -1
  284. package/dist/mcp/early-ppid.js.map +0 -1
  285. package/dist/mcp/engine.d.ts.map +0 -1
  286. package/dist/mcp/engine.js.map +0 -1
  287. package/dist/mcp/explore-dedup.d.ts.map +0 -1
  288. package/dist/mcp/explore-dedup.js.map +0 -1
  289. package/dist/mcp/explore-repeat-guard.d.ts.map +0 -1
  290. package/dist/mcp/explore-repeat-guard.js.map +0 -1
  291. package/dist/mcp/explore-session-state.d.ts.map +0 -1
  292. package/dist/mcp/explore-session-state.js.map +0 -1
  293. package/dist/mcp/index.d.ts.map +0 -1
  294. package/dist/mcp/index.js.map +0 -1
  295. package/dist/mcp/liveness-watchdog.d.ts.map +0 -1
  296. package/dist/mcp/liveness-watchdog.js.map +0 -1
  297. package/dist/mcp/memory-budget.d.ts.map +0 -1
  298. package/dist/mcp/memory-budget.js.map +0 -1
  299. package/dist/mcp/ppid-watchdog.d.ts.map +0 -1
  300. package/dist/mcp/ppid-watchdog.js.map +0 -1
  301. package/dist/mcp/proxy.d.ts.map +0 -1
  302. package/dist/mcp/proxy.js.map +0 -1
  303. package/dist/mcp/query-cache.d.ts.map +0 -1
  304. package/dist/mcp/query-cache.js.map +0 -1
  305. package/dist/mcp/query-pool.d.ts.map +0 -1
  306. package/dist/mcp/query-pool.js.map +0 -1
  307. package/dist/mcp/query-worker.d.ts.map +0 -1
  308. package/dist/mcp/query-worker.js.map +0 -1
  309. package/dist/mcp/server-instructions.d.ts.map +0 -1
  310. package/dist/mcp/server-instructions.js.map +0 -1
  311. package/dist/mcp/session.d.ts.map +0 -1
  312. package/dist/mcp/session.js.map +0 -1
  313. package/dist/mcp/startup-handshake.d.ts.map +0 -1
  314. package/dist/mcp/startup-handshake.js.map +0 -1
  315. package/dist/mcp/stdin-teardown.d.ts.map +0 -1
  316. package/dist/mcp/stdin-teardown.js.map +0 -1
  317. package/dist/mcp/tools.d.ts.map +0 -1
  318. package/dist/mcp/tools.js.map +0 -1
  319. package/dist/mcp/transport.d.ts.map +0 -1
  320. package/dist/mcp/transport.js.map +0 -1
  321. package/dist/mcp/version.d.ts.map +0 -1
  322. package/dist/mcp/version.js.map +0 -1
  323. package/dist/project-config.d.ts.map +0 -1
  324. package/dist/project-config.js.map +0 -1
  325. package/dist/project-map/index.d.ts.map +0 -1
  326. package/dist/project-map/index.js.map +0 -1
  327. package/dist/resolution/c-fnptr-synthesizer.d.ts.map +0 -1
  328. package/dist/resolution/c-fnptr-synthesizer.js.map +0 -1
  329. package/dist/resolution/callback-synthesizer.d.ts.map +0 -1
  330. package/dist/resolution/callback-synthesizer.js.map +0 -1
  331. package/dist/resolution/cooperative-yield.d.ts.map +0 -1
  332. package/dist/resolution/cooperative-yield.js.map +0 -1
  333. package/dist/resolution/frameworks/arkts-entry.d.ts.map +0 -1
  334. package/dist/resolution/frameworks/arkts-entry.js.map +0 -1
  335. package/dist/resolution/frameworks/arkts-napi.d.ts.map +0 -1
  336. package/dist/resolution/frameworks/arkts-napi.js.map +0 -1
  337. package/dist/resolution/frameworks/astro.d.ts.map +0 -1
  338. package/dist/resolution/frameworks/astro.js.map +0 -1
  339. package/dist/resolution/frameworks/cargo-workspace.d.ts.map +0 -1
  340. package/dist/resolution/frameworks/cargo-workspace.js.map +0 -1
  341. package/dist/resolution/frameworks/cics.d.ts.map +0 -1
  342. package/dist/resolution/frameworks/cics.js.map +0 -1
  343. package/dist/resolution/frameworks/csharp.d.ts.map +0 -1
  344. package/dist/resolution/frameworks/csharp.js.map +0 -1
  345. package/dist/resolution/frameworks/drupal.d.ts.map +0 -1
  346. package/dist/resolution/frameworks/drupal.js.map +0 -1
  347. package/dist/resolution/frameworks/expo-modules.d.ts.map +0 -1
  348. package/dist/resolution/frameworks/expo-modules.js.map +0 -1
  349. package/dist/resolution/frameworks/express.d.ts.map +0 -1
  350. package/dist/resolution/frameworks/express.js.map +0 -1
  351. package/dist/resolution/frameworks/fabric.d.ts.map +0 -1
  352. package/dist/resolution/frameworks/fabric.js.map +0 -1
  353. package/dist/resolution/frameworks/go.d.ts.map +0 -1
  354. package/dist/resolution/frameworks/go.js.map +0 -1
  355. package/dist/resolution/frameworks/goframe.d.ts.map +0 -1
  356. package/dist/resolution/frameworks/goframe.js.map +0 -1
  357. package/dist/resolution/frameworks/index.d.ts.map +0 -1
  358. package/dist/resolution/frameworks/index.js.map +0 -1
  359. package/dist/resolution/frameworks/java.d.ts.map +0 -1
  360. package/dist/resolution/frameworks/java.js.map +0 -1
  361. package/dist/resolution/frameworks/laravel.d.ts.map +0 -1
  362. package/dist/resolution/frameworks/laravel.js.map +0 -1
  363. package/dist/resolution/frameworks/nestjs.d.ts.map +0 -1
  364. package/dist/resolution/frameworks/nestjs.js.map +0 -1
  365. package/dist/resolution/frameworks/play.d.ts.map +0 -1
  366. package/dist/resolution/frameworks/play.js.map +0 -1
  367. package/dist/resolution/frameworks/python.d.ts.map +0 -1
  368. package/dist/resolution/frameworks/python.js.map +0 -1
  369. package/dist/resolution/frameworks/react-native.d.ts.map +0 -1
  370. package/dist/resolution/frameworks/react-native.js.map +0 -1
  371. package/dist/resolution/frameworks/react.d.ts.map +0 -1
  372. package/dist/resolution/frameworks/react.js.map +0 -1
  373. package/dist/resolution/frameworks/ruby.d.ts.map +0 -1
  374. package/dist/resolution/frameworks/ruby.js.map +0 -1
  375. package/dist/resolution/frameworks/rust.d.ts.map +0 -1
  376. package/dist/resolution/frameworks/rust.js.map +0 -1
  377. package/dist/resolution/frameworks/svelte.d.ts.map +0 -1
  378. package/dist/resolution/frameworks/svelte.js.map +0 -1
  379. package/dist/resolution/frameworks/swift-objc.d.ts.map +0 -1
  380. package/dist/resolution/frameworks/swift-objc.js.map +0 -1
  381. package/dist/resolution/frameworks/swift.d.ts.map +0 -1
  382. package/dist/resolution/frameworks/swift.js.map +0 -1
  383. package/dist/resolution/frameworks/terraform.d.ts.map +0 -1
  384. package/dist/resolution/frameworks/terraform.js.map +0 -1
  385. package/dist/resolution/frameworks/vue.d.ts.map +0 -1
  386. package/dist/resolution/frameworks/vue.js.map +0 -1
  387. package/dist/resolution/go-module.d.ts.map +0 -1
  388. package/dist/resolution/go-module.js.map +0 -1
  389. package/dist/resolution/goframe-synthesizer.d.ts.map +0 -1
  390. package/dist/resolution/goframe-synthesizer.js.map +0 -1
  391. package/dist/resolution/import-resolver.d.ts.map +0 -1
  392. package/dist/resolution/import-resolver.js.map +0 -1
  393. package/dist/resolution/index.d.ts.map +0 -1
  394. package/dist/resolution/index.js.map +0 -1
  395. package/dist/resolution/lru-cache.d.ts.map +0 -1
  396. package/dist/resolution/lru-cache.js.map +0 -1
  397. package/dist/resolution/memory-budget.d.ts.map +0 -1
  398. package/dist/resolution/memory-budget.js.map +0 -1
  399. package/dist/resolution/name-matcher.d.ts.map +0 -1
  400. package/dist/resolution/name-matcher.js.map +0 -1
  401. package/dist/resolution/path-aliases.d.ts.map +0 -1
  402. package/dist/resolution/path-aliases.js.map +0 -1
  403. package/dist/resolution/resolver-pool.d.ts.map +0 -1
  404. package/dist/resolution/resolver-pool.js.map +0 -1
  405. package/dist/resolution/resolver-worker.d.ts.map +0 -1
  406. package/dist/resolution/resolver-worker.js.map +0 -1
  407. package/dist/resolution/strip-comments.d.ts.map +0 -1
  408. package/dist/resolution/strip-comments.js.map +0 -1
  409. package/dist/resolution/swift-objc-bridge.d.ts.map +0 -1
  410. package/dist/resolution/swift-objc-bridge.js.map +0 -1
  411. package/dist/resolution/types.d.ts.map +0 -1
  412. package/dist/resolution/types.js.map +0 -1
  413. package/dist/resolution/workspace-packages.d.ts.map +0 -1
  414. package/dist/resolution/workspace-packages.js.map +0 -1
  415. package/dist/search/identifier-segments.d.ts.map +0 -1
  416. package/dist/search/identifier-segments.js.map +0 -1
  417. package/dist/search/query-parser.d.ts.map +0 -1
  418. package/dist/search/query-parser.js.map +0 -1
  419. package/dist/search/query-utils.d.ts.map +0 -1
  420. package/dist/search/query-utils.js.map +0 -1
  421. package/dist/spec/build/diff-parser.d.ts.map +0 -1
  422. package/dist/spec/build/diff-parser.js.map +0 -1
  423. package/dist/spec/build/pipeline.d.ts.map +0 -1
  424. package/dist/spec/build/pipeline.js.map +0 -1
  425. package/dist/spec/build/scan.d.ts.map +0 -1
  426. package/dist/spec/build/scan.js.map +0 -1
  427. package/dist/spec/build/scope-resolver.d.ts.map +0 -1
  428. package/dist/spec/build/scope-resolver.js.map +0 -1
  429. package/dist/spec/build/spec-extractor.d.ts.map +0 -1
  430. package/dist/spec/build/spec-extractor.js.map +0 -1
  431. package/dist/spec/config.d.ts.map +0 -1
  432. package/dist/spec/config.js.map +0 -1
  433. package/dist/spec/db/commit-node.d.ts.map +0 -1
  434. package/dist/spec/db/commit-node.js.map +0 -1
  435. package/dist/spec/db/fragment-node.d.ts.map +0 -1
  436. package/dist/spec/db/fragment-node.js.map +0 -1
  437. package/dist/spec/db/fts.d.ts.map +0 -1
  438. package/dist/spec/db/fts.js.map +0 -1
  439. package/dist/spec/db/index.d.ts.map +0 -1
  440. package/dist/spec/db/index.js.map +0 -1
  441. package/dist/spec/db/persist.d.ts.map +0 -1
  442. package/dist/spec/db/persist.js.map +0 -1
  443. package/dist/spec/db/relations.d.ts.map +0 -1
  444. package/dist/spec/db/relations.js.map +0 -1
  445. package/dist/spec/db/schema.d.ts.map +0 -1
  446. package/dist/spec/db/schema.js.map +0 -1
  447. package/dist/spec/db/spec-node.d.ts.map +0 -1
  448. package/dist/spec/db/spec-node.js.map +0 -1
  449. package/dist/spec/db/sql-utils.d.ts.map +0 -1
  450. package/dist/spec/db/sql-utils.js.map +0 -1
  451. package/dist/spec/evolve/cluster-context.d.ts.map +0 -1
  452. package/dist/spec/evolve/cluster-context.js.map +0 -1
  453. package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +0 -1
  454. package/dist/spec/evolve/commit-spec-analyzer.js.map +0 -1
  455. package/dist/spec/evolve/commit-spec-persister.d.ts.map +0 -1
  456. package/dist/spec/evolve/commit-spec-persister.js.map +0 -1
  457. package/dist/spec/evolve/impact-locator.d.ts.map +0 -1
  458. package/dist/spec/evolve/impact-locator.js.map +0 -1
  459. package/dist/spec/evolve/pipeline.d.ts.map +0 -1
  460. package/dist/spec/evolve/pipeline.js.map +0 -1
  461. package/dist/spec/evolve/spec-rewriter.d.ts.map +0 -1
  462. package/dist/spec/evolve/spec-rewriter.js.map +0 -1
  463. package/dist/spec/git/commits.d.ts.map +0 -1
  464. package/dist/spec/git/commits.js.map +0 -1
  465. package/dist/spec/git/exec.d.ts.map +0 -1
  466. package/dist/spec/git/exec.js.map +0 -1
  467. package/dist/spec/git/index.d.ts.map +0 -1
  468. package/dist/spec/git/index.js.map +0 -1
  469. package/dist/spec/graph/index.d.ts.map +0 -1
  470. package/dist/spec/graph/index.js.map +0 -1
  471. package/dist/spec/graph/queries.d.ts.map +0 -1
  472. package/dist/spec/graph/queries.js.map +0 -1
  473. package/dist/spec/llm/agent-client.d.ts.map +0 -1
  474. package/dist/spec/llm/agent-client.js.map +0 -1
  475. package/dist/spec/llm/agents/claude-code.d.ts.map +0 -1
  476. package/dist/spec/llm/agents/claude-code.js.map +0 -1
  477. package/dist/spec/llm/agents/codex.d.ts.map +0 -1
  478. package/dist/spec/llm/agents/codex.js.map +0 -1
  479. package/dist/spec/llm/agents/detect-utils.d.ts.map +0 -1
  480. package/dist/spec/llm/agents/detect-utils.js.map +0 -1
  481. package/dist/spec/llm/agents/deveco-code.d.ts.map +0 -1
  482. package/dist/spec/llm/agents/deveco-code.js.map +0 -1
  483. package/dist/spec/llm/agents/index.d.ts.map +0 -1
  484. package/dist/spec/llm/agents/index.js.map +0 -1
  485. package/dist/spec/llm/agents/types.d.ts.map +0 -1
  486. package/dist/spec/llm/agents/types.js.map +0 -1
  487. package/dist/spec/llm/client.d.ts.map +0 -1
  488. package/dist/spec/llm/client.js.map +0 -1
  489. package/dist/spec/llm/factory.d.ts.map +0 -1
  490. package/dist/spec/llm/factory.js.map +0 -1
  491. package/dist/spec/llm/prompts.d.ts.map +0 -1
  492. package/dist/spec/llm/prompts.js.map +0 -1
  493. package/dist/spec/llm/retry.d.ts.map +0 -1
  494. package/dist/spec/llm/retry.js.map +0 -1
  495. package/dist/spec/mine/addon/adapter.d.ts.map +0 -1
  496. package/dist/spec/mine/addon/adapter.js.map +0 -1
  497. package/dist/spec/mine/addon/render.d.ts.map +0 -1
  498. package/dist/spec/mine/addon/render.js.map +0 -1
  499. package/dist/spec/mine/addon/types.d.ts.map +0 -1
  500. package/dist/spec/mine/addon/types.js.map +0 -1
  501. package/dist/spec/mine/clustering/features.d.ts.map +0 -1
  502. package/dist/spec/mine/clustering/features.js.map +0 -1
  503. package/dist/spec/mine/clustering/index.d.ts.map +0 -1
  504. package/dist/spec/mine/clustering/index.js.map +0 -1
  505. package/dist/spec/mine/clustering/leiden.d.ts.map +0 -1
  506. package/dist/spec/mine/clustering/leiden.js.map +0 -1
  507. package/dist/spec/mine/clustering/text-similarity.d.ts.map +0 -1
  508. package/dist/spec/mine/clustering/text-similarity.js.map +0 -1
  509. package/dist/spec/mine/generator.d.ts.map +0 -1
  510. package/dist/spec/mine/generator.js.map +0 -1
  511. package/dist/spec/mine/persist.d.ts.map +0 -1
  512. package/dist/spec/mine/persist.js.map +0 -1
  513. package/dist/spec/mine/pipeline.d.ts.map +0 -1
  514. package/dist/spec/mine/pipeline.js.map +0 -1
  515. package/dist/spec/mine/scanner.d.ts.map +0 -1
  516. package/dist/spec/mine/scanner.js.map +0 -1
  517. package/dist/spec/types.d.ts.map +0 -1
  518. package/dist/spec/types.js.map +0 -1
  519. package/dist/spec/ui/index.d.ts.map +0 -1
  520. package/dist/spec/ui/index.js.map +0 -1
  521. package/dist/spec/ui/progress-handler.d.ts.map +0 -1
  522. package/dist/spec/ui/progress-handler.js.map +0 -1
  523. package/dist/spec/ui/progress.d.ts.map +0 -1
  524. package/dist/spec/ui/progress.js.map +0 -1
  525. package/dist/spec/utils/fs.d.ts.map +0 -1
  526. package/dist/spec/utils/fs.js.map +0 -1
  527. package/dist/spec/utils/index.d.ts.map +0 -1
  528. package/dist/spec/utils/index.js.map +0 -1
  529. package/dist/spec/utils/meta.d.ts.map +0 -1
  530. package/dist/spec/utils/meta.js.map +0 -1
  531. package/dist/spec/utils/truncate.d.ts.map +0 -1
  532. package/dist/spec/utils/truncate.js.map +0 -1
  533. package/dist/sync/git-hooks.d.ts.map +0 -1
  534. package/dist/sync/git-hooks.js.map +0 -1
  535. package/dist/sync/index.d.ts.map +0 -1
  536. package/dist/sync/index.js.map +0 -1
  537. package/dist/sync/watch-policy.d.ts.map +0 -1
  538. package/dist/sync/watch-policy.js.map +0 -1
  539. package/dist/sync/watcher.d.ts.map +0 -1
  540. package/dist/sync/watcher.js.map +0 -1
  541. package/dist/sync/worktree.d.ts.map +0 -1
  542. package/dist/sync/worktree.js.map +0 -1
  543. package/dist/types.d.ts.map +0 -1
  544. package/dist/types.js.map +0 -1
  545. package/dist/ui/glyphs.d.ts.map +0 -1
  546. package/dist/ui/glyphs.js.map +0 -1
  547. package/dist/ui/shimmer-progress.d.ts.map +0 -1
  548. package/dist/ui/shimmer-progress.js.map +0 -1
  549. package/dist/ui/shimmer-worker.d.ts.map +0 -1
  550. package/dist/ui/shimmer-worker.js.map +0 -1
  551. package/dist/ui/types.d.ts.map +0 -1
  552. package/dist/ui/types.js.map +0 -1
  553. package/dist/upgrade/index.d.ts.map +0 -1
  554. package/dist/upgrade/index.js.map +0 -1
  555. package/dist/upgrade/remove-binary.d.ts.map +0 -1
  556. package/dist/upgrade/remove-binary.js.map +0 -1
  557. package/dist/upgrade/update-check.d.ts.map +0 -1
  558. package/dist/upgrade/update-check.js.map +0 -1
  559. package/dist/utils.d.ts.map +0 -1
  560. package/dist/utils.js.map +0 -1
@@ -0,0 +1,98 @@
1
+ export declare const QUERY_PLAN_VERSION: 2;
2
+ export type QueryIntent = 'general' | 'usages' | 'modules' | 'native' | 'flow' | 'overview';
3
+ export type QueryRoute = 'general' | 'usages' | 'modules' | 'native' | 'inventory' | 'mechanism' | 'compact' | 'project';
4
+ export declare const QUERY_RELATIONS: readonly ["incoming_references", "registration_sites", "outgoing_calls", "module_imports", "module_cycles"];
5
+ export declare const QUERY_SOURCE_SCOPES: readonly ["local", "sdk", "all"];
6
+ export type QueryRelation = typeof QUERY_RELATIONS[number];
7
+ export type QuerySourceScope = typeof QUERY_SOURCE_SCOPES[number];
8
+ export interface QueryPlanningDecision {
9
+ eligible: boolean;
10
+ reason: 'planner_disabled' | 'builtin_tool' | 'exact_symbol_or_path' | 'task_context_requires_planning' | 'existing_shape_route' | 'focused_query' | 'ambiguous_or_compound';
11
+ /** Preserve the rule route even if a model later selects another route. */
12
+ ruleRoute: QueryRoute;
13
+ }
14
+ export interface QueryPlanStep {
15
+ id: string;
16
+ query: string;
17
+ intent: QueryIntent;
18
+ /** Code-shaped mentions / exact index matches, not completed-step evidence. */
19
+ anchors: string[];
20
+ /** Optional per-step semantic terms; omitted by older planner responses. */
21
+ searchTerms?: string[];
22
+ /** Verbatim user-supplied UI/resource values; never translated symbol names. */
23
+ literalTexts?: string[];
24
+ relation?: QueryRelation;
25
+ sourceScope?: QuerySourceScope;
26
+ dependsOn: string[];
27
+ }
28
+ /** Exact predecessor evidence supplied by the executor, never by the planner. */
29
+ export interface QueryPlanBinding {
30
+ id: string;
31
+ name: string;
32
+ qualifiedName?: string;
33
+ filePath: string;
34
+ startLine: number;
35
+ }
36
+ export interface QueryPlan {
37
+ version: typeof QUERY_PLAN_VERSION;
38
+ originalQuery: string;
39
+ /** Bounded user-supplied task constraints; never repository evidence. */
40
+ taskContext?: string;
41
+ canonicalQuery: string;
42
+ intent: QueryIntent;
43
+ route: QueryRoute;
44
+ anchors: string[];
45
+ searchTerms: string[];
46
+ literalTexts?: string[];
47
+ relation?: QueryRelation;
48
+ sourceScope?: QuerySourceScope;
49
+ bindings?: QueryPlanBinding[];
50
+ steps: QueryPlanStep[];
51
+ features: Record<string, boolean>;
52
+ source: 'rules' | 'llm';
53
+ confidence: number;
54
+ telemetry: {
55
+ durationMs: number;
56
+ requestCount?: number;
57
+ inputTokens?: number;
58
+ outputTokens?: number;
59
+ fallbackReason?: string;
60
+ decision?: QueryPlanningDecision;
61
+ };
62
+ }
63
+ export interface QueryPlanOptions {
64
+ /** Absolute request deadline. Planning consumes, rather than resets, this budget. */
65
+ deadlineAt: number;
66
+ /** Original task used to retain scope across narrower retrieval queries. */
67
+ taskContext?: string;
68
+ /** Only return true for an exact, current repository symbol/path match. */
69
+ validateAnchor?: (anchor: string) => boolean;
70
+ }
71
+ /** One shared bound for provider input, transferred plans and cache identity. */
72
+ export declare function normalizeQueryPlanTaskContext(value?: string): string | undefined;
73
+ /** A host's original task cannot be replaced by an agent's abbreviated focus. */
74
+ export declare function mergeQueryPlanTaskContext(original?: string, focus?: string): string | undefined;
75
+ /** Only the supplied request, never a generated retrieval cue, may authorize a map. */
76
+ export declare function queryExplicitlyRequestsProjectMap(query: string): boolean;
77
+ export declare function queryPlanFeatures(query: string): Record<string, boolean>;
78
+ /** Keep this identical to the legacy ALL_CAPS-only compatibility gate. */
79
+ export declare function queryAsPlannedBareSymbolInventory(query: string): boolean;
80
+ /** These are textual hints only. Extraction does not certify that an anchor exists. */
81
+ export declare function extractQueryPlanAnchors(query: string): string[];
82
+ /** Preserve explicit user text during provider failure, without translating it. */
83
+ export declare function extractQueryPlanLiteralTexts(query: string): string[];
84
+ export declare function buildRuleQueryPlan(query: string, originalTaskContext?: string): QueryPlan;
85
+ /** Eligibility is separate from provider availability, actual requests and plan acceptance. */
86
+ export declare function getModelQueryPlanningDecision(plan: QueryPlan): QueryPlanningDecision;
87
+ /** Compatibility boolean for callers that do not need the diagnostic reason. */
88
+ export declare function shouldUseModelQueryPlan(plan: QueryPlan): boolean;
89
+ /** Relation direction is explicit data, not guessed from a dependency word. */
90
+ export declare function intentForQueryRelation(intent: QueryIntent, relation?: QueryRelation): QueryIntent;
91
+ /** Add verified/name hints for every intent, including the general retrieval path. */
92
+ export declare function adaptQueryPlanQuery(query: string, intent: QueryIntent, anchors: string[], relation?: QueryRelation): string;
93
+ export declare function routeForQueryIntent(intent: QueryIntent, canonicalQuery: string, originalQuery?: string): QueryRoute;
94
+ /** Rebind only exact symbols resolved by the executor, never prose scraped from tool output. */
95
+ export declare function compileQueryPlanStep(plan: QueryPlan, step: QueryPlanStep, resolvedAnchors?: string[]): QueryPlan;
96
+ /** Remote planning is lazy, opt-in and has no provider/credential discovery. */
97
+ export declare function planQuery(query: string, options: QueryPlanOptions): Promise<QueryPlan>;
98
+ //# sourceMappingURL=query-plan.d.ts.map
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.QUERY_SOURCE_SCOPES = exports.QUERY_RELATIONS = exports.QUERY_PLAN_VERSION = void 0;
37
+ exports.normalizeQueryPlanTaskContext = normalizeQueryPlanTaskContext;
38
+ exports.mergeQueryPlanTaskContext = mergeQueryPlanTaskContext;
39
+ exports.queryExplicitlyRequestsProjectMap = queryExplicitlyRequestsProjectMap;
40
+ exports.queryPlanFeatures = queryPlanFeatures;
41
+ exports.queryAsPlannedBareSymbolInventory = queryAsPlannedBareSymbolInventory;
42
+ exports.extractQueryPlanAnchors = extractQueryPlanAnchors;
43
+ exports.extractQueryPlanLiteralTexts = extractQueryPlanLiteralTexts;
44
+ exports.buildRuleQueryPlan = buildRuleQueryPlan;
45
+ exports.getModelQueryPlanningDecision = getModelQueryPlanningDecision;
46
+ exports.shouldUseModelQueryPlan = shouldUseModelQueryPlan;
47
+ exports.intentForQueryRelation = intentForQueryRelation;
48
+ exports.adaptQueryPlanQuery = adaptQueryPlanQuery;
49
+ exports.routeForQueryIntent = routeForQueryIntent;
50
+ exports.compileQueryPlanStep = compileQueryPlanStep;
51
+ exports.planQuery = planQuery;
52
+ /** Versioned retrieval intent, not a replacement for the user's question or graph evidence. */
53
+ const shape = __importStar(require("./query-utils"));
54
+ exports.QUERY_PLAN_VERSION = 2;
55
+ exports.QUERY_RELATIONS = ['incoming_references', 'registration_sites', 'outgoing_calls', 'module_imports', 'module_cycles'];
56
+ exports.QUERY_SOURCE_SCOPES = ['local', 'sdk', 'all'];
57
+ /** One shared bound for provider input, transferred plans and cache identity. */
58
+ function normalizeQueryPlanTaskContext(value) {
59
+ return typeof value === 'string' ? value.trim().slice(0, 4000) || undefined : undefined;
60
+ }
61
+ function withTaskContext(query, taskContext) {
62
+ // This string reaches lexical retrieval. Framework prose such as "code evidence"
63
+ // would become unrelated symbol seeds, so concatenate only the supplied data.
64
+ return taskContext && taskContext !== query ? `${query}\n${taskContext}` : query;
65
+ }
66
+ /** A host's original task cannot be replaced by an agent's abbreviated focus. */
67
+ function mergeQueryPlanTaskContext(original, focus) {
68
+ const parts = [normalizeQueryPlanTaskContext(original), normalizeQueryPlanTaskContext(focus)]
69
+ .filter((part) => !!part);
70
+ return normalizeQueryPlanTaskContext([...new Set(parts)].join('\n'));
71
+ }
72
+ /** Only the supplied request, never a generated retrieval cue, may authorize a map. */
73
+ function queryExplicitlyRequestsProjectMap(query) {
74
+ // Map/overview can be part of a UI control's name, not the requested output.
75
+ if (/\b(?:overview|map|structure|architecture|layout)\s+(?:button|component|handler|widget|view|screen|page)\b|(?:概览|总览|地图|结构)(?:按钮|组件|控件|页面|点击|事件)/i.test(query))
76
+ return false;
77
+ if (/(?:不要|无需|不用|不是|不需要|排除).{0,20}(?:项目|工程|仓库|模块|目录|文件).{0,12}(?:概览|总览|结构|架构|地图)|\b(?:not|no|without|exclude)\b.{0,28}\b(?:project|repo(?:sitory)?|module|directory|file)\b.{0,20}\b(?:overview|map|structure|architecture|layout)\b|\b(?:not|no|without|exclude)\b.{0,16}\b(?:overview|map|structure|architecture|layout)\b.{0,24}\b(?:project|repo(?:sitory)?|module|directory|file)\b/i.test(query))
78
+ return false;
79
+ return /(?:项目|工程|仓库|代码库|模块|目录|文件)\s*(?:整体|总体)?\s*(?:结构|架构|概览|总览|地图|组织|划分)|(?:整体|总体|全局)\s*(?:架构|目录树)|\b(?:project|repo(?:sitory)?|codebase|modules?|director(?:y|ies)|files?)\s+(?:overall\s+)?(?:structure|architecture|overview|map|layout|organization)\b|\b(?:overview|map|architecture|structure|layout|organization)\s+(?:(?:of|for)\s+)?(?:(?:the|this|our|entire|whole|overall)\s+)*(?:project|repo(?:sitory)?|codebase|modules?|directories|files?)\b/i.test(query);
80
+ }
81
+ const featureChecks = {
82
+ shouldTryFastInventoryExplore: shape.shouldTryFastInventoryExplore,
83
+ shouldTryLightMechanismExplore: shape.shouldTryLightMechanismExplore,
84
+ shouldUseCompactExploreBudget: shape.shouldUseCompactExploreBudget,
85
+ shouldBuildApiUsageSurvey: shape.shouldBuildApiUsageSurvey,
86
+ shouldBuildMemberSurvey: shape.shouldBuildMemberSurvey,
87
+ shouldBuildCallerInventory: shape.shouldBuildCallerInventory,
88
+ shouldBuildInheritanceSurvey: shape.shouldBuildInheritanceSurvey,
89
+ shouldBuildKitModuleUsageSurvey: shape.shouldBuildKitModuleUsageSurvey,
90
+ shouldBuildDomainFileSurvey: shape.shouldBuildDomainFileSurvey,
91
+ shouldBuildConfigSection: shape.shouldBuildConfigSection,
92
+ shouldBuildHoverHandlerSurvey: shape.shouldBuildHoverHandlerSurvey,
93
+ shouldPreferMemberUsageInventory: shape.shouldPreferMemberUsageInventory,
94
+ queryAsCrossModuleFlowSurvey: shape.queryAsCrossModuleFlowSurvey,
95
+ queryAsModuleDependencySurvey: shape.queryAsModuleDependencySurvey,
96
+ queryAsModuleExportSurvey: shape.queryAsModuleExportSurvey,
97
+ queryAsReturnValueConsumerSurvey: shape.queryAsReturnValueConsumerSurvey,
98
+ queryAsMechanismSurvey: shape.queryAsMechanismSurvey,
99
+ queryAsDataSourceSurvey: shape.queryAsDataSourceSurvey,
100
+ queryAsDataSourceDistinguishAsk: shape.queryAsDataSourceDistinguishAsk,
101
+ queryAsEventDispatchSurvey: shape.queryAsEventDispatchSurvey,
102
+ queryAsMultiTypeDependencySurvey: shape.queryAsMultiTypeDependencySurvey,
103
+ queryAsDeclarationSiteSurvey: shape.queryAsDeclarationSiteSurvey,
104
+ queryAsConstantUsageSurvey: shape.queryAsConstantUsageSurvey,
105
+ queryAsFieldUsageSurvey: shape.queryAsFieldUsageSurvey,
106
+ queryAsDtsWrapSurvey: shape.queryAsDtsWrapSurvey,
107
+ queryAsTypeLifecycleSurvey: shape.queryAsTypeLifecycleSurvey,
108
+ queryAsContainerCompositionSurvey: shape.queryAsContainerCompositionSurvey,
109
+ queryAsNativeRenderThreadSurvey: shape.queryAsNativeRenderThreadSurvey,
110
+ queryAsNamedControlStateSyncSurvey: shape.queryAsNamedControlStateSyncSurvey,
111
+ queryAsAssignedFlagImpactSurvey: shape.queryAsAssignedFlagImpactSurvey,
112
+ queryAsInterpretationSurvey: shape.queryAsInterpretationSurvey,
113
+ queryAsTestOnlyInterpretation: shape.queryAsTestOnlyInterpretation,
114
+ queryAsLocalSymbolDetail: shape.queryAsLocalSymbolDetail,
115
+ queryHasNamedMemberFocus: shape.queryHasNamedMemberFocus,
116
+ queryAsFocusedUiCluster: shape.queryAsFocusedUiCluster,
117
+ queryAsComponentSurfaceSurvey: shape.queryAsComponentSurfaceSurvey,
118
+ queryAsNamedComponentAction: shape.queryAsNamedComponentAction,
119
+ queryNeedsCoNamedUseBridge: shape.queryNeedsCoNamedUseBridge,
120
+ queryAsInRepoSystemCapabilityHowto: shape.queryAsInRepoSystemCapabilityHowto,
121
+ queryAsCodeChangeOrientation: shape.queryAsCodeChangeOrientation,
122
+ queryLooksLikeLiteralOrCopyHunt: shape.queryLooksLikeLiteralOrCopyHunt,
123
+ };
124
+ function queryPlanFeatures(query) {
125
+ return Object.fromEntries(Object.entries(featureChecks).map(([name, check]) => [name, check(query)]));
126
+ }
127
+ /** Keep this identical to the legacy ALL_CAPS-only compatibility gate. */
128
+ function queryAsPlannedBareSymbolInventory(query) {
129
+ if (process.env.HOMEGRAPH_EXPLORE_SHAPE_ROUTING === '0')
130
+ return false;
131
+ const tokens = String(query || '').split(/[\s,、,]+/).filter(Boolean);
132
+ if (!tokens.length || tokens.length > 6)
133
+ return false;
134
+ if (/如何|怎[么样]|机制|流程|原理|为什么|为何|架构|生命周期|时序|调用链|关系|\b(how|why|flow|mechanism|lifecycle|architecture|sequence|pipeline|between|implement|implementation)\b/i.test(query))
135
+ return false;
136
+ const actions = new Set(['trigger', 'callback', 'handler', 'listener', 'observer', 'dispatch', 'emit',
137
+ 'notify', 'render', 'draw', 'init', 'start', 'stop', 'update', 'refresh', 'subscribe', 'publish',
138
+ 'invoke', 'execute', 'run', 'process', 'handle', 'post', 'send', 'receive', 'load', 'save', 'open', 'close']);
139
+ if (tokens.some((token) => token.replace(/[._]/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2')
140
+ .toLowerCase().split(/\s+/).some((part) => actions.has(part))))
141
+ return false;
142
+ return tokens.every((token) => /^[A-Z][A-Z0-9_]{3,}$/.test(token));
143
+ }
144
+ function localRoute(query, features) {
145
+ if (shape.queryShouldDeferToBuiltinTools(query))
146
+ return 'general';
147
+ if (features.queryAsModuleDependencySurvey)
148
+ return 'modules';
149
+ if (features.queryAsModuleExportSurvey)
150
+ return 'native';
151
+ if (!features.queryAsReturnValueConsumerSurvey) {
152
+ if (features.shouldBuildApiUsageSurvey || queryAsPlannedBareSymbolInventory(query))
153
+ return 'usages';
154
+ if (features.shouldBuildMemberSurvey
155
+ && /哪里(?:用|使用|调用)|哪些.{0,24}(?:用|使用|调用|依赖)|使用位置|引用位置|调用位置|\busages?\b|\bwhere\b.{0,36}\bused\b|\bwhich\b.{0,36}\b(?:files?|functions?|methods?)\b.{0,24}\b(?:use|call|depend)/i.test(query))
156
+ return 'usages';
157
+ }
158
+ if (features.shouldTryFastInventoryExplore)
159
+ return 'inventory';
160
+ if (features.shouldTryLightMechanismExplore)
161
+ return 'mechanism';
162
+ // Compact eligibility also depends on graph hits. Let the legacy executor try it.
163
+ return 'general';
164
+ }
165
+ /** These are textual hints only. Extraction does not certify that an anchor exists. */
166
+ function extractQueryPlanAnchors(query) {
167
+ const explicit = [...query.matchAll(/(?:@[A-Za-z][\w.]*|[A-Za-z_][\w]*(?:(?:\.|::)[A-Za-z_][\w]*)+|\b[A-Za-z][\w.-]*(?:[/\\][A-Za-z][\w.-]*)+|\b[A-Z][A-Z0-9_]{3,}\b|\b[a-z]+[A-Z]\w{2,}\b)/g)]
168
+ .map((match) => match[0]);
169
+ return [...new Set([
170
+ ...explicit,
171
+ ...shape.extractTypeNamesFromQuery(query),
172
+ ...shape.extractLocalDetailAnchors(query),
173
+ ])].filter((value) => value.length <= 256 && query.includes(value)).slice(0, 16);
174
+ }
175
+ /** Preserve explicit user text during provider failure, without translating it. */
176
+ function extractQueryPlanLiteralTexts(query) {
177
+ const values = [...query.matchAll(/"([^"\r\n]{1,256})"|(?<![A-Za-z0-9_])'([^'\r\n]{1,256})'(?![A-Za-z0-9_])|“([^”\r\n]{1,256})”|‘([^’\r\n]{1,256})’|「([^」\r\n]{1,256})」|『([^』\r\n]{1,256})』/g)]
178
+ .map(match => match.slice(1).find(value => value !== undefined)?.trim() ?? '')
179
+ .filter(Boolean);
180
+ return [...new Set(values)].slice(0, 8);
181
+ }
182
+ function buildRuleQueryPlan(query, originalTaskContext) {
183
+ const started = Date.now();
184
+ const taskContext = normalizeQueryPlanTaskContext(originalTaskContext);
185
+ const canonicalQuery = withTaskContext(query, taskContext);
186
+ const features = queryPlanFeatures(canonicalQuery);
187
+ const route = localRoute(canonicalQuery, features);
188
+ const intent = route === 'usages' || route === 'modules' || route === 'native'
189
+ ? route : features.queryAsCrossModuleFlowSurvey ? 'flow' : 'general';
190
+ const anchors = [...new Set([...extractQueryPlanAnchors(query),
191
+ ...extractQueryPlanAnchors(taskContext ?? '')])].slice(0, 16);
192
+ const literalTexts = extractQueryPlanLiteralTexts(canonicalQuery);
193
+ return {
194
+ version: exports.QUERY_PLAN_VERSION,
195
+ originalQuery: query,
196
+ ...(taskContext ? { taskContext } : {}),
197
+ canonicalQuery,
198
+ intent,
199
+ route,
200
+ anchors,
201
+ ...(literalTexts.length ? { literalTexts } : {}),
202
+ searchTerms: shape.extractSearchTerms(canonicalQuery, { stems: false }).slice(0, 24),
203
+ steps: [{ id: 's1', query, intent, anchors: [...anchors],
204
+ ...(literalTexts.length ? { literalTexts: [...literalTexts] } : {}), dependsOn: [] }],
205
+ features,
206
+ source: 'rules',
207
+ confidence: route !== 'general' || anchors.length ? 1 : 0.5,
208
+ telemetry: { durationMs: Date.now() - started },
209
+ };
210
+ }
211
+ /** Eligibility is separate from provider availability, actual requests and plan acceptance. */
212
+ function getModelQueryPlanningDecision(plan) {
213
+ const decision = (eligible, reason) => ({ eligible, reason, ruleRoute: plan.route });
214
+ const defer = shape.queryShouldDeferToBuiltinTools(plan.originalQuery);
215
+ if (defer && defer !== 'file-listing' && defer !== 'concept-or-existence')
216
+ return decision(false, 'builtin_tool');
217
+ // A precise follow-up stays cheap, even under a larger original task.
218
+ const query = plan.originalQuery.trim();
219
+ if (/^[\w@./\\: ,、,-]+$/.test(query) && plan.anchors.length > 0
220
+ && query.split(/[\s,、,]+/).filter(Boolean).every((token) => plan.anchors.includes(token) || /^[A-Za-z_][\w]*(?:[./:][\w.-]+)*$/.test(token))) {
221
+ // Only symbol bags, not ordinary all-English sentences with one Type name.
222
+ const words = query.split(/[\s,、,]+/).filter(Boolean);
223
+ // Hint extraction also returns prose such as "metadata" and "reference".
224
+ // Under task context, only code-shaped tokens (plus an optional declaration
225
+ // kind suffix) qualify as a cheap exact lookup; hints alone certify nothing.
226
+ const scopedExact = words.every((word, i) => /[a-z0-9][A-Z]|[._/:@]|^[A-Z][A-Z0-9_]{3,}$/.test(word)
227
+ || (words.length > 1 && i === words.length - 1 && /^(?:class|struct|interface|enum|function|method)$/.test(word)));
228
+ if (words.length <= 8 && words.every((word) => plan.anchors.includes(word)
229
+ || /[A-Z_./:@]/.test(word)) && (!plan.taskContext || scopedExact))
230
+ return decision(false, 'exact_symbol_or_path');
231
+ }
232
+ // Matching one retrieval shape says nothing about the completeness of a
233
+ // scoped change task. Give explicit llm callers one bounded planning chance.
234
+ if (normalizeQueryPlanTaskContext(plan.taskContext))
235
+ return decision(true, 'task_context_requires_planning');
236
+ // Without task context retain the existing low-cost eligibility behavior.
237
+ const compound = /然后|并且|同时|此外|\bthen\b|\balso\b|\bin addition\b|[;;]/i.test(plan.originalQuery);
238
+ if (!compound && (plan.route !== 'general' || plan.features.queryAsCrossModuleFlowSurvey))
239
+ return decision(false, 'existing_shape_route');
240
+ if (!compound && (plan.features.queryAsLocalSymbolDetail || plan.features.queryHasNamedMemberFocus
241
+ || plan.features.queryAsFocusedUiCluster || plan.features.queryAsNamedComponentAction))
242
+ return decision(false, 'focused_query');
243
+ return decision(true, 'ambiguous_or_compound');
244
+ }
245
+ /** Compatibility boolean for callers that do not need the diagnostic reason. */
246
+ function shouldUseModelQueryPlan(plan) {
247
+ return getModelQueryPlanningDecision(plan).eligible;
248
+ }
249
+ const intentCue = {
250
+ general: '', usages: 'where used usages', modules: 'module dependencies',
251
+ native: 'NAPI exports which APIs', flow: 'call chain', overview: 'project module file overview',
252
+ };
253
+ const relationCue = {
254
+ incoming_references: 'incoming references where used',
255
+ registration_sites: 'registration sites where used',
256
+ outgoing_calls: 'outgoing calls call chain',
257
+ module_imports: 'module imports dependencies',
258
+ module_cycles: 'circular module import cycles',
259
+ };
260
+ /** Relation direction is explicit data, not guessed from a dependency word. */
261
+ function intentForQueryRelation(intent, relation) {
262
+ if (relation === 'incoming_references' || relation === 'registration_sites')
263
+ return 'usages';
264
+ if (relation === 'outgoing_calls')
265
+ return 'flow';
266
+ if (relation === 'module_imports' || relation === 'module_cycles')
267
+ return 'modules';
268
+ return intent;
269
+ }
270
+ /** Add verified/name hints for every intent, including the general retrieval path. */
271
+ function adaptQueryPlanQuery(query, intent, anchors, relation) {
272
+ const cue = relation ? relationCue[relation] : intentCue[intent];
273
+ const tokens = new Set(query.split(/\s+/));
274
+ const extra = [...anchors.filter((anchor) => !tokens.has(anchor)), ...(cue ? [cue] : [])];
275
+ return extra.length ? `${query}\n${extra.join(' ')}` : query;
276
+ }
277
+ function routeForQueryIntent(intent, canonicalQuery, originalQuery = canonicalQuery) {
278
+ if (intent === 'usages' || intent === 'modules' || intent === 'native')
279
+ return intent;
280
+ if (intent === 'overview')
281
+ return queryExplicitlyRequestsProjectMap(originalQuery) ? 'project' : 'general';
282
+ // Never collapse a requested call chain into one unrelated inventory or mechanism.
283
+ if (intent === 'flow')
284
+ return 'general';
285
+ return localRoute(canonicalQuery, queryPlanFeatures(canonicalQuery));
286
+ }
287
+ /** Rebind only exact symbols resolved by the executor, never prose scraped from tool output. */
288
+ function compileQueryPlanStep(plan, step, resolvedAnchors = []) {
289
+ const anchors = [...new Set([...step.anchors, ...resolvedAnchors])]
290
+ .filter((value) => value.length > 0 && value.length <= 256).slice(0, 16);
291
+ const downgradedOverview = step.intent === 'overview' && !queryExplicitlyRequestsProjectMap(plan.originalQuery);
292
+ const relation = step.relation;
293
+ const stepIntent = intentForQueryRelation(downgradedOverview ? 'general' : step.intent, relation);
294
+ const query = downgradedOverview ? plan.originalQuery : step.query;
295
+ const literalTexts = step.literalTexts ?? (plan.steps.length === 1 ? plan.literalTexts : undefined) ?? [];
296
+ const sourceScope = step.sourceScope ?? plan.sourceScope;
297
+ // Scope and negations remain losslessly in originalQuery/taskContext for the
298
+ // executor and cache. Repeating that prose here erases the step's focus.
299
+ // A planner's English explanation is not source text. Only its typed slots
300
+ // become seeds; this prevents a verb such as "locate" matching an SDK method.
301
+ // Legacy/malformed seedless steps retain the USER's query, never planner prose.
302
+ const seeds = [...new Set([...anchors, ...(step.searchTerms ?? []), ...literalTexts])];
303
+ const retrievalQuery = plan.source === 'llm'
304
+ ? seeds.join(' ') || plan.originalQuery : withTaskContext(query, plan.taskContext);
305
+ const canonicalQuery = plan.source === 'rules' && stepIntent === 'general'
306
+ ? retrievalQuery : adaptQueryPlanQuery(retrievalQuery, stepIntent, anchors, relation);
307
+ const searchTerms = plan.source === 'llm' && seeds.length
308
+ ? seeds.slice(0, 24) : [...new Set([...anchors, ...(step.searchTerms ?? []),
309
+ ...shape.extractSearchTerms(retrievalQuery, { stems: false })])].slice(0, 24);
310
+ return {
311
+ ...plan,
312
+ canonicalQuery,
313
+ intent: stepIntent,
314
+ route: routeForQueryIntent(stepIntent, canonicalQuery, plan.originalQuery),
315
+ anchors,
316
+ searchTerms,
317
+ literalTexts,
318
+ relation,
319
+ sourceScope,
320
+ steps: [{ ...step, intent: stepIntent, anchors, literalTexts, sourceScope, dependsOn: [] }],
321
+ features: queryPlanFeatures(canonicalQuery),
322
+ };
323
+ }
324
+ /** Remote planning is lazy, opt-in and has no provider/credential discovery. */
325
+ async function planQuery(query, options) {
326
+ const local = buildRuleQueryPlan(query, options.taskContext);
327
+ local.telemetry.decision = process.env.HOMEGRAPH_QUERY_PLANNER === 'llm'
328
+ ? getModelQueryPlanningDecision(local) : { eligible: false, reason: 'planner_disabled', ruleRoute: local.route };
329
+ if (!local.telemetry.decision.eligible)
330
+ return local;
331
+ const { requestModelQueryPlan } = await Promise.resolve().then(() => __importStar(require('./query-plan-provider')));
332
+ return requestModelQueryPlan(local, options);
333
+ }
334
+ //# sourceMappingURL=query-plan.js.map
@@ -83,7 +83,12 @@ export declare function queryAsOutOfRepoSdkCatalog(query: string): boolean;
83
83
  * *usage* questions stay on explore.
84
84
  * Shape-driven only — no product nouns.
85
85
  */
86
- export type HomeGraphDeferKind = 'file-listing' | 'literal-hunt' | 'concept-or-existence' | 'external-manual' | 'sdk-catalog' | 'greenfield' | 'vcs-history' | 'media-assets';
86
+ export type HomeGraphDeferKind = 'file-listing' | 'literal-hunt' | 'concept-or-existence' | 'external-manual' | 'sdk-catalog' | 'greenfield' | 'vcs-history' | 'media-assets' | 'path-pinned-edit';
87
+ /**
88
+ * Single-file edit with an explicit `path/Foo.ext` (or `Foo.ext`) in the query —
89
+ * Read that file is sufficient; explore adds reasoning tax without locate value.
90
+ */
91
+ export declare function queryAsPathPinnedEdit(query: string): boolean;
87
92
  /**
88
93
  * Agent is about to change an existing codebase (feature / fix / refactor).
89
94
  * Used for explore *routing* (prefer explore / light mechanism), not Skip.
@@ -51,6 +51,7 @@ exports.queryAsCoNamedTypeMethodInteraction = queryAsCoNamedTypeMethodInteractio
51
51
  exports.queryHasNamedMemberFocus = queryHasNamedMemberFocus;
52
52
  exports.queryAsNamedComponentAction = queryAsNamedComponentAction;
53
53
  exports.queryAsOutOfRepoSdkCatalog = queryAsOutOfRepoSdkCatalog;
54
+ exports.queryAsPathPinnedEdit = queryAsPathPinnedEdit;
54
55
  exports.queryAsCodeChangeOrientation = queryAsCodeChangeOrientation;
55
56
  exports.queryAsExternalManualOnly = queryAsExternalManualOnly;
56
57
  exports.queryAsGreenfieldScaffold = queryAsGreenfieldScaffold;
@@ -363,6 +364,34 @@ function queryAsOutOfRepoSdkCatalog(query) {
363
364
  }
364
365
  return false;
365
366
  }
367
+ /**
368
+ * Single-file edit with an explicit `path/Foo.ext` (or `Foo.ext`) in the query —
369
+ * Read that file is sufficient; explore adds reasoning tax without locate value.
370
+ */
371
+ function queryAsPathPinnedEdit(query) {
372
+ if (queryAsMechanismSurvey(query))
373
+ return false;
374
+ if (queryAsCrossModuleFlowSurvey(query))
375
+ return false;
376
+ if (shouldBuildCallerInventory(query))
377
+ return false;
378
+ if (queryNamesMultipleExploreAnchors(query))
379
+ return false;
380
+ const files = extractFileBasenamesFromQuery(query);
381
+ if (files.length !== 1)
382
+ return false;
383
+ const stem = files[0];
384
+ const ext = exports.QUERY_SOURCE_FILE_EXT;
385
+ const hasExplicitFile = new RegExp(`[\\\\/]${stem}\\.(?:${ext})\\b`, 'i').test(query)
386
+ || new RegExp(`\\b${stem}\\.(?:${ext})\\b`, 'i').test(query);
387
+ if (!hasExplicitFile)
388
+ return false;
389
+ if (queryAsInterpretationSurvey(query))
390
+ return false;
391
+ if (queryAsCodeChangeOrientation(query))
392
+ return true;
393
+ return /移除|删除|添加|增加|修改|调整|清理|去掉|refactor|remove|delete|add|modify|update|fix/i.test(query);
394
+ }
366
395
  /**
367
396
  * Agent is about to change an existing codebase (feature / fix / refactor).
368
397
  * Used for explore *routing* (prefer explore / light mechanism), not Skip.
@@ -437,6 +466,9 @@ function queryShouldDeferToBuiltinTools(query) {
437
466
  // Layout chains (`.width('100%')`) can look like member access — still Skip.
438
467
  if (queryLooksLikeLiteralOrCopyHunt(q))
439
468
  return 'literal-hunt';
469
+ // 5b) Path-pinned single-file edits — Read the named file; explore is noise.
470
+ if (queryAsPathPinnedEdit(q))
471
+ return 'path-pinned-edit';
440
472
  // 6) Topic → file list with no Type/file anchor → Glob/Grep.
441
473
  if (!hasType
442
474
  && !hasFile
@@ -466,6 +498,7 @@ function homegraphDeferGuidance(kind, query) {
466
498
  'greenfield': 'Scaffolding an empty project from scratch needs generators/docs, not an existing code graph.',
467
499
  'vcs-history': 'Git/commit/blame/diff history is not in the symbol graph — use git / IDE history.',
468
500
  'media-assets': 'Media/binary asset inventories (.png/.mp4/fonts/…) need Glob, not the symbol graph.',
501
+ 'path-pinned-edit': 'Task already names one source file (`…/Foo.ets`) — **Read that file** and edit. HomeGraph explore on path-pinned edits adds context tax without locate value.',
469
502
  };
470
503
  return [
471
504
  'Skip HomeGraph for this question shape — do **not** retry any `homegraph_*` tool for it.',
@@ -602,6 +635,9 @@ function queryAsksKitInstallDeps(query) {
602
635
  /** Shared-object / binary suffixes — not Type.member (libfoo.so → member "so"). */
603
636
  const FILE_EXT_MEMBER_NOISE = new Set([
604
637
  'so', 'dll', 'dylib', 'a', 'lib', 'exe', 'apk', 'hap', 'bin', 'wasm', 'o', 'obj',
638
+ // Source/config extensions — `Foo.ets` is a file anchor, not Foo.member.
639
+ 'ets', 'ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs', 'json', 'json5', 'yaml', 'yml', 'toml',
640
+ 'hpp', 'h', 'cpp', 'c', 'cmake', 'txt', 'md',
605
641
  ]);
606
642
  function extractMemberAccessFromQuery(query) {
607
643
  const results = [];
@@ -2010,16 +2046,39 @@ function shouldCompactImportListing(siteCount, hasSymbolFilter) {
2010
2046
  }
2011
2047
  /** Single file basename anchor with no flow — render that file only. */
2012
2048
  function shouldLimitToQueryNamedFile(query, hasFlowPath, multiAnchorQuery) {
2013
- if (hasFlowPath || multiAnchorQuery)
2049
+ if (hasFlowPath)
2050
+ return false;
2051
+ const files = extractFileBasenamesFromQuery(query);
2052
+ if (files.length !== 1)
2014
2053
  return false;
2015
- return extractFileBasenamesFromQuery(query).length === 1;
2054
+ if (!multiAnchorQuery)
2055
+ return true;
2056
+ // One explicit `…/Foo.ets` plus only its own stem-as-Type / directory path
2057
+ // scaffolding is still file-scoped — don't expand digests to siblings.
2058
+ const stem = files[0].toLowerCase();
2059
+ const extraTypes = extractTypeNamesFromQuery(query).filter((t) => t.toLowerCase() !== stem);
2060
+ if (extraTypes.length > 0)
2061
+ return false;
2062
+ if (extractMemberAccessFromQuery(query).length > 0)
2063
+ return false;
2064
+ return true;
2016
2065
  }
2017
2066
  /** Multiple named anchors in one query → trace/connect intent, not flat inventory. */
2018
2067
  function queryNamesMultipleExploreAnchors(query) {
2019
- const typeCount = extractTypeNamesFromQuery(query).length;
2068
+ const files = extractFileBasenamesFromQuery(query);
2069
+ const fileStems = new Set(files.map((f) => f.toLowerCase()));
2070
+ // Basename-as-Type is the same anchor as the file — don't double-count.
2071
+ const typeCount = extractTypeNamesFromQuery(query).filter((t) => !fileStems.has(t.toLowerCase())).length;
2020
2072
  const memberCount = extractMemberAccessFromQuery(query).length;
2021
- const fileCount = extractFileBasenamesFromQuery(query).length;
2022
- const pathCount = extractPathSegmentsFromQuery(query).length;
2073
+ const fileCount = files.length;
2074
+ let pathCount = extractPathSegmentsFromQuery(query).length;
2075
+ // Directory prefixes of a named `…/Foo.ext` are scaffolding, not a 2nd anchor.
2076
+ if (fileCount === 1 && pathCount > 0) {
2077
+ const ext = exports.QUERY_SOURCE_FILE_EXT;
2078
+ if (new RegExp(`[\\\\/]${files[0]}\\.(?:${ext})\\b`, 'i').test(query)) {
2079
+ pathCount = 0;
2080
+ }
2081
+ }
2023
2082
  if (typeCount >= 2 || memberCount >= 2)
2024
2083
  return true;
2025
2084
  return typeCount + memberCount + fileCount + pathCount >= 2;
@@ -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
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * Lazy load of the optional `openai` package (Spec 0031).
4
+ *
5
+ * MCP `serve mcp` must start without it. Spec LLM commands require
6
+ * `npm install openai`.
7
+ *
8
+ * @module spec/llm/openai-sdk
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.OPENAI_INSTALL_HINT = void 0;
12
+ exports.loadOpenAI = loadOpenAI;
13
+ exports.tryLoadOpenAI = tryLoadOpenAI;
14
+ exports.OPENAI_INSTALL_HINT = 'The openai package is not installed. Spec LLM calls need it: npm install openai';
15
+ function loadOpenAI() {
16
+ try {
17
+ // Optional dependency: not a static import so `serve mcp` loads without it.
18
+ const mod = require('openai');
19
+ return (mod.default ?? mod);
20
+ }
21
+ catch (err) {
22
+ const code = err.code;
23
+ if (code === 'MODULE_NOT_FOUND') {
24
+ throw new Error(exports.OPENAI_INSTALL_HINT);
25
+ }
26
+ throw err;
27
+ }
28
+ }
29
+ function tryLoadOpenAI() {
30
+ try {
31
+ return loadOpenAI();
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ //# sourceMappingURL=openai-sdk.js.map