trail-code 0.0.0-stage → 0.28.0-semantic.3

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 (593) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +567 -2
  3. package/dist/ai/crux.d.ts +88 -0
  4. package/dist/ai/crux.d.ts.map +1 -0
  5. package/dist/ai/crux.js +219 -0
  6. package/dist/ai/crux.js.map +1 -0
  7. package/dist/ai/failure.d.ts +60 -0
  8. package/dist/ai/failure.d.ts.map +1 -0
  9. package/dist/ai/failure.js +86 -0
  10. package/dist/ai/failure.js.map +1 -0
  11. package/dist/ai/llm/anthropic.d.ts +37 -0
  12. package/dist/ai/llm/anthropic.d.ts.map +1 -0
  13. package/dist/ai/llm/anthropic.js +144 -0
  14. package/dist/ai/llm/anthropic.js.map +1 -0
  15. package/dist/ai/llm/factory.d.ts +28 -0
  16. package/dist/ai/llm/factory.d.ts.map +1 -0
  17. package/dist/ai/llm/factory.js +36 -0
  18. package/dist/ai/llm/factory.js.map +1 -0
  19. package/dist/ai/llm/litellm.d.ts +34 -0
  20. package/dist/ai/llm/litellm.d.ts.map +1 -0
  21. package/dist/ai/llm/litellm.js +45 -0
  22. package/dist/ai/llm/litellm.js.map +1 -0
  23. package/dist/ai/llm/openai.d.ts +145 -0
  24. package/dist/ai/llm/openai.d.ts.map +1 -0
  25. package/dist/ai/llm/openai.js +629 -0
  26. package/dist/ai/llm/openai.js.map +1 -0
  27. package/dist/ai/llm/orcarouter.d.ts +34 -0
  28. package/dist/ai/llm/orcarouter.d.ts.map +1 -0
  29. package/dist/ai/llm/orcarouter.js +45 -0
  30. package/dist/ai/llm/orcarouter.js.map +1 -0
  31. package/dist/ai/llm/recover-tool.d.ts +21 -0
  32. package/dist/ai/llm/recover-tool.d.ts.map +1 -0
  33. package/dist/ai/llm/recover-tool.js +109 -0
  34. package/dist/ai/llm/recover-tool.js.map +1 -0
  35. package/dist/ai/llm/types.d.ts +122 -0
  36. package/dist/ai/llm/types.d.ts.map +1 -0
  37. package/dist/ai/llm/types.js +33 -0
  38. package/dist/ai/llm/types.js.map +1 -0
  39. package/dist/ai/providers.d.ts +59 -0
  40. package/dist/ai/providers.d.ts.map +1 -0
  41. package/dist/ai/providers.js +54 -0
  42. package/dist/ai/providers.js.map +1 -0
  43. package/dist/ai/summarize.d.ts +25 -0
  44. package/dist/ai/summarize.d.ts.map +1 -0
  45. package/dist/ai/summarize.js +34 -0
  46. package/dist/ai/summarize.js.map +1 -0
  47. package/dist/ai/synthesize.d.ts +40 -0
  48. package/dist/ai/synthesize.d.ts.map +1 -0
  49. package/dist/ai/synthesize.js +230 -0
  50. package/dist/ai/synthesize.js.map +1 -0
  51. package/dist/ask/ask.d.ts +199 -0
  52. package/dist/ask/ask.d.ts.map +1 -0
  53. package/dist/ask/ask.js +1291 -0
  54. package/dist/ask/ask.js.map +1 -0
  55. package/dist/ask/file-rank.d.ts +72 -0
  56. package/dist/ask/file-rank.d.ts.map +1 -0
  57. package/dist/ask/file-rank.js +160 -0
  58. package/dist/ask/file-rank.js.map +1 -0
  59. package/dist/ask/file-selection.d.ts +22 -0
  60. package/dist/ask/file-selection.d.ts.map +1 -0
  61. package/dist/ask/file-selection.js +66 -0
  62. package/dist/ask/file-selection.js.map +1 -0
  63. package/dist/ask/fuse.d.ts +195 -0
  64. package/dist/ask/fuse.d.ts.map +1 -0
  65. package/dist/ask/fuse.js +344 -0
  66. package/dist/ask/fuse.js.map +1 -0
  67. package/dist/ask/graphrank.d.ts +61 -0
  68. package/dist/ask/graphrank.d.ts.map +1 -0
  69. package/dist/ask/graphrank.js +130 -0
  70. package/dist/ask/graphrank.js.map +1 -0
  71. package/dist/ask/index-file.d.ts +44 -0
  72. package/dist/ask/index-file.d.ts.map +1 -0
  73. package/dist/ask/index-file.js +128 -0
  74. package/dist/ask/index-file.js.map +1 -0
  75. package/dist/ask/semantic.d.ts +42 -0
  76. package/dist/ask/semantic.d.ts.map +1 -0
  77. package/dist/ask/semantic.js +293 -0
  78. package/dist/ask/semantic.js.map +1 -0
  79. package/dist/bin/graft.d.ts +3 -0
  80. package/dist/bin/graft.d.ts.map +1 -0
  81. package/dist/bin/graft.js +14 -0
  82. package/dist/bin/graft.js.map +1 -0
  83. package/dist/bin/trail.d.ts +3 -0
  84. package/dist/bin/trail.d.ts.map +1 -0
  85. package/dist/bin/trail.js +13 -0
  86. package/dist/bin/trail.js.map +1 -0
  87. package/dist/blast/blast-cli.d.ts +35 -0
  88. package/dist/blast/blast-cli.d.ts.map +1 -0
  89. package/dist/blast/blast-cli.js +155 -0
  90. package/dist/blast/blast-cli.js.map +1 -0
  91. package/dist/blast/blast.d.ts +128 -0
  92. package/dist/blast/blast.d.ts.map +1 -0
  93. package/dist/blast/blast.js +383 -0
  94. package/dist/blast/blast.js.map +1 -0
  95. package/dist/blast/diff.d.ts +53 -0
  96. package/dist/blast/diff.d.ts.map +1 -0
  97. package/dist/blast/diff.js +193 -0
  98. package/dist/blast/diff.js.map +1 -0
  99. package/dist/blast/evidence.d.ts +51 -0
  100. package/dist/blast/evidence.d.ts.map +1 -0
  101. package/dist/blast/evidence.js +162 -0
  102. package/dist/blast/evidence.js.map +1 -0
  103. package/dist/blast/modules.d.ts +33 -0
  104. package/dist/blast/modules.d.ts.map +1 -0
  105. package/dist/blast/modules.js +83 -0
  106. package/dist/blast/modules.js.map +1 -0
  107. package/dist/blast/name.d.ts +74 -0
  108. package/dist/blast/name.d.ts.map +1 -0
  109. package/dist/blast/name.js +269 -0
  110. package/dist/blast/name.js.map +1 -0
  111. package/dist/blast/owners.d.ts +85 -0
  112. package/dist/blast/owners.d.ts.map +1 -0
  113. package/dist/blast/owners.js +272 -0
  114. package/dist/blast/owners.js.map +1 -0
  115. package/dist/blast/render.d.ts +46 -0
  116. package/dist/blast/render.d.ts.map +1 -0
  117. package/dist/blast/render.js +422 -0
  118. package/dist/blast/render.js.map +1 -0
  119. package/dist/blast/viz.d.ts +37 -0
  120. package/dist/blast/viz.d.ts.map +1 -0
  121. package/dist/blast/viz.js +180 -0
  122. package/dist/blast/viz.js.map +1 -0
  123. package/dist/brand.d.ts +111 -0
  124. package/dist/brand.d.ts.map +1 -0
  125. package/dist/brand.js +282 -0
  126. package/dist/brand.js.map +1 -0
  127. package/dist/claude/build-progress.d.ts +30 -0
  128. package/dist/claude/build-progress.d.ts.map +1 -0
  129. package/dist/claude/build-progress.js +81 -0
  130. package/dist/claude/build-progress.js.map +1 -0
  131. package/dist/claude/hermes-skill-template.d.ts +16 -0
  132. package/dist/claude/hermes-skill-template.d.ts.map +1 -0
  133. package/dist/claude/hermes-skill-template.js +154 -0
  134. package/dist/claude/hermes-skill-template.js.map +1 -0
  135. package/dist/claude/init.d.ts +65 -0
  136. package/dist/claude/init.d.ts.map +1 -0
  137. package/dist/claude/init.js +258 -0
  138. package/dist/claude/init.js.map +1 -0
  139. package/dist/claude/paths.d.ts +9 -0
  140. package/dist/claude/paths.d.ts.map +1 -0
  141. package/dist/claude/paths.js +22 -0
  142. package/dist/claude/paths.js.map +1 -0
  143. package/dist/claude/session-metrics.d.ts +73 -0
  144. package/dist/claude/session-metrics.d.ts.map +1 -0
  145. package/dist/claude/session-metrics.js +209 -0
  146. package/dist/claude/session-metrics.js.map +1 -0
  147. package/dist/claude/settings-merge.d.ts +76 -0
  148. package/dist/claude/settings-merge.d.ts.map +1 -0
  149. package/dist/claude/settings-merge.js +283 -0
  150. package/dist/claude/settings-merge.js.map +1 -0
  151. package/dist/claude/skill-template.d.ts +13 -0
  152. package/dist/claude/skill-template.d.ts.map +1 -0
  153. package/dist/claude/skill-template.js +290 -0
  154. package/dist/claude/skill-template.js.map +1 -0
  155. package/dist/claude/state.d.ts +85 -0
  156. package/dist/claude/state.d.ts.map +1 -0
  157. package/dist/claude/state.js +88 -0
  158. package/dist/claude/state.js.map +1 -0
  159. package/dist/claude/stats.d.ts +5 -0
  160. package/dist/claude/stats.d.ts.map +1 -0
  161. package/dist/claude/stats.js +24 -0
  162. package/dist/claude/stats.js.map +1 -0
  163. package/dist/cli-epilogue.d.ts +12 -0
  164. package/dist/cli-epilogue.d.ts.map +1 -0
  165. package/dist/cli-epilogue.js +72 -0
  166. package/dist/cli-epilogue.js.map +1 -0
  167. package/dist/cli-meta.d.ts +82 -0
  168. package/dist/cli-meta.d.ts.map +1 -0
  169. package/dist/cli-meta.js +238 -0
  170. package/dist/cli-meta.js.map +1 -0
  171. package/dist/cli-picker.d.ts +139 -0
  172. package/dist/cli-picker.d.ts.map +1 -0
  173. package/dist/cli-picker.js +439 -0
  174. package/dist/cli-picker.js.map +1 -0
  175. package/dist/cli.d.ts +3 -0
  176. package/dist/cli.d.ts.map +1 -0
  177. package/dist/cli.js +1638 -0
  178. package/dist/cli.js.map +1 -0
  179. package/dist/context/batches.d.ts +29 -0
  180. package/dist/context/batches.d.ts.map +1 -0
  181. package/dist/context/batches.js +130 -0
  182. package/dist/context/batches.js.map +1 -0
  183. package/dist/context/build.d.ts +57 -0
  184. package/dist/context/build.d.ts.map +1 -0
  185. package/dist/context/build.js +396 -0
  186. package/dist/context/build.js.map +1 -0
  187. package/dist/context/check.d.ts +42 -0
  188. package/dist/context/check.d.ts.map +1 -0
  189. package/dist/context/check.js +162 -0
  190. package/dist/context/check.js.map +1 -0
  191. package/dist/context/map-dir.d.ts +13 -0
  192. package/dist/context/map-dir.d.ts.map +1 -0
  193. package/dist/context/map-dir.js +81 -0
  194. package/dist/context/map-dir.js.map +1 -0
  195. package/dist/context/node-file.d.ts +109 -0
  196. package/dist/context/node-file.d.ts.map +1 -0
  197. package/dist/context/node-file.js +390 -0
  198. package/dist/context/node-file.js.map +1 -0
  199. package/dist/context/price.d.ts +49 -0
  200. package/dist/context/price.d.ts.map +1 -0
  201. package/dist/context/price.js +83 -0
  202. package/dist/context/price.js.map +1 -0
  203. package/dist/context/savings.d.ts +67 -0
  204. package/dist/context/savings.d.ts.map +1 -0
  205. package/dist/context/savings.js +125 -0
  206. package/dist/context/savings.js.map +1 -0
  207. package/dist/engine.d.ts +85 -0
  208. package/dist/engine.d.ts.map +1 -0
  209. package/dist/engine.js +122 -0
  210. package/dist/engine.js.map +1 -0
  211. package/dist/graph/bindings.d.ts +64 -0
  212. package/dist/graph/bindings.d.ts.map +1 -0
  213. package/dist/graph/bindings.js +713 -0
  214. package/dist/graph/bindings.js.map +1 -0
  215. package/dist/graph/build-run.d.ts +25 -0
  216. package/dist/graph/build-run.d.ts.map +1 -0
  217. package/dist/graph/build-run.js +121 -0
  218. package/dist/graph/build-run.js.map +1 -0
  219. package/dist/graph/build.d.ts +88 -0
  220. package/dist/graph/build.d.ts.map +1 -0
  221. package/dist/graph/build.js +386 -0
  222. package/dist/graph/build.js.map +1 -0
  223. package/dist/graph/cards.d.ts +46 -0
  224. package/dist/graph/cards.d.ts.map +1 -0
  225. package/dist/graph/cards.js +280 -0
  226. package/dist/graph/cards.js.map +1 -0
  227. package/dist/graph/check.d.ts +25 -0
  228. package/dist/graph/check.d.ts.map +1 -0
  229. package/dist/graph/check.js +192 -0
  230. package/dist/graph/check.js.map +1 -0
  231. package/dist/graph/container.d.ts +63 -0
  232. package/dist/graph/container.d.ts.map +1 -0
  233. package/dist/graph/container.js +191 -0
  234. package/dist/graph/container.js.map +1 -0
  235. package/dist/graph/depth-parser.d.ts +61 -0
  236. package/dist/graph/depth-parser.d.ts.map +1 -0
  237. package/dist/graph/depth-parser.js +153 -0
  238. package/dist/graph/depth-parser.js.map +1 -0
  239. package/dist/graph/enrich.d.ts +62 -0
  240. package/dist/graph/enrich.d.ts.map +1 -0
  241. package/dist/graph/enrich.js +258 -0
  242. package/dist/graph/enrich.js.map +1 -0
  243. package/dist/graph/extract-cache.d.ts +101 -0
  244. package/dist/graph/extract-cache.d.ts.map +1 -0
  245. package/dist/graph/extract-cache.js +199 -0
  246. package/dist/graph/extract-cache.js.map +1 -0
  247. package/dist/graph/extract.d.ts +85 -0
  248. package/dist/graph/extract.d.ts.map +1 -0
  249. package/dist/graph/extract.js +2377 -0
  250. package/dist/graph/extract.js.map +1 -0
  251. package/dist/graph/fingerprint.d.ts +76 -0
  252. package/dist/graph/fingerprint.d.ts.map +1 -0
  253. package/dist/graph/fingerprint.js +160 -0
  254. package/dist/graph/fingerprint.js.map +1 -0
  255. package/dist/graph/generic.d.ts +74 -0
  256. package/dist/graph/generic.d.ts.map +1 -0
  257. package/dist/graph/generic.js +773 -0
  258. package/dist/graph/generic.js.map +1 -0
  259. package/dist/graph/invariants.d.ts +33 -0
  260. package/dist/graph/invariants.d.ts.map +1 -0
  261. package/dist/graph/invariants.js +52 -0
  262. package/dist/graph/invariants.js.map +1 -0
  263. package/dist/graph/load.d.ts +29 -0
  264. package/dist/graph/load.d.ts.map +1 -0
  265. package/dist/graph/load.js +97 -0
  266. package/dist/graph/load.js.map +1 -0
  267. package/dist/graph/lsp/client.d.ts +61 -0
  268. package/dist/graph/lsp/client.d.ts.map +1 -0
  269. package/dist/graph/lsp/client.js +217 -0
  270. package/dist/graph/lsp/client.js.map +1 -0
  271. package/dist/graph/lsp/enrich.d.ts +11 -0
  272. package/dist/graph/lsp/enrich.d.ts.map +1 -0
  273. package/dist/graph/lsp/enrich.js +163 -0
  274. package/dist/graph/lsp/enrich.js.map +1 -0
  275. package/dist/graph/lsp/registry.d.ts +22 -0
  276. package/dist/graph/lsp/registry.d.ts.map +1 -0
  277. package/dist/graph/lsp/registry.js +71 -0
  278. package/dist/graph/lsp/registry.js.map +1 -0
  279. package/dist/graph/map.d.ts +107 -0
  280. package/dist/graph/map.d.ts.map +1 -0
  281. package/dist/graph/map.js +239 -0
  282. package/dist/graph/map.js.map +1 -0
  283. package/dist/graph/markdown.d.ts +22 -0
  284. package/dist/graph/markdown.d.ts.map +1 -0
  285. package/dist/graph/markdown.js +143 -0
  286. package/dist/graph/markdown.js.map +1 -0
  287. package/dist/graph/native.d.ts +46 -0
  288. package/dist/graph/native.d.ts.map +1 -0
  289. package/dist/graph/native.js +169 -0
  290. package/dist/graph/native.js.map +1 -0
  291. package/dist/graph/queries/c.scm +13 -0
  292. package/dist/graph/queries/c_sharp.scm +19 -0
  293. package/dist/graph/queries/clojure.scm +58 -0
  294. package/dist/graph/queries/cpp.scm +23 -0
  295. package/dist/graph/queries/dart.scm +42 -0
  296. package/dist/graph/queries/elixir.scm +54 -0
  297. package/dist/graph/queries/gleam.scm +51 -0
  298. package/dist/graph/queries/java.scm +20 -0
  299. package/dist/graph/queries/kotlin.scm +43 -0
  300. package/dist/graph/queries/lua.scm +36 -0
  301. package/dist/graph/queries/nix.scm +32 -0
  302. package/dist/graph/queries/php.scm +40 -0
  303. package/dist/graph/queries/ruby.scm +65 -0
  304. package/dist/graph/queries/rust.scm +41 -0
  305. package/dist/graph/queries/scala.scm +66 -0
  306. package/dist/graph/queries/solidity.scm +43 -0
  307. package/dist/graph/queries/swift.scm +51 -0
  308. package/dist/graph/refresh.d.ts +106 -0
  309. package/dist/graph/refresh.d.ts.map +1 -0
  310. package/dist/graph/refresh.js +430 -0
  311. package/dist/graph/refresh.js.map +1 -0
  312. package/dist/graph/relations.d.ts +14 -0
  313. package/dist/graph/relations.d.ts.map +1 -0
  314. package/dist/graph/relations.js +8 -0
  315. package/dist/graph/relations.js.map +1 -0
  316. package/dist/graph/resolve.d.ts +17 -0
  317. package/dist/graph/resolve.d.ts.map +1 -0
  318. package/dist/graph/resolve.js +716 -0
  319. package/dist/graph/resolve.js.map +1 -0
  320. package/dist/graph/root.d.ts +11 -0
  321. package/dist/graph/root.d.ts.map +1 -0
  322. package/dist/graph/root.js +40 -0
  323. package/dist/graph/root.js.map +1 -0
  324. package/dist/graph/scopes.d.ts +40 -0
  325. package/dist/graph/scopes.d.ts.map +1 -0
  326. package/dist/graph/scopes.js +383 -0
  327. package/dist/graph/scopes.js.map +1 -0
  328. package/dist/graph/seed.d.ts +38 -0
  329. package/dist/graph/seed.d.ts.map +1 -0
  330. package/dist/graph/seed.js +229 -0
  331. package/dist/graph/seed.js.map +1 -0
  332. package/dist/graph/source-files.d.ts +46 -0
  333. package/dist/graph/source-files.d.ts.map +1 -0
  334. package/dist/graph/source-files.js +118 -0
  335. package/dist/graph/source-files.js.map +1 -0
  336. package/dist/graph/traverse-cli.d.ts +55 -0
  337. package/dist/graph/traverse-cli.d.ts.map +1 -0
  338. package/dist/graph/traverse-cli.js +189 -0
  339. package/dist/graph/traverse-cli.js.map +1 -0
  340. package/dist/graph/traverse.d.ts +112 -0
  341. package/dist/graph/traverse.d.ts.map +1 -0
  342. package/dist/graph/traverse.js +192 -0
  343. package/dist/graph/traverse.js.map +1 -0
  344. package/dist/graph/types.d.ts +78 -0
  345. package/dist/graph/types.d.ts.map +1 -0
  346. package/dist/graph/types.js +14 -0
  347. package/dist/graph/types.js.map +1 -0
  348. package/dist/graph/wasm-runtime.d.ts +19 -0
  349. package/dist/graph/wasm-runtime.d.ts.map +1 -0
  350. package/dist/graph/wasm-runtime.js +38 -0
  351. package/dist/graph/wasm-runtime.js.map +1 -0
  352. package/dist/graph/workspace-cli.d.ts +56 -0
  353. package/dist/graph/workspace-cli.d.ts.map +1 -0
  354. package/dist/graph/workspace-cli.js +111 -0
  355. package/dist/graph/workspace-cli.js.map +1 -0
  356. package/dist/graph/workspace.d.ts +172 -0
  357. package/dist/graph/workspace.d.ts.map +1 -0
  358. package/dist/graph/workspace.js +714 -0
  359. package/dist/graph/workspace.js.map +1 -0
  360. package/dist/graph/write.d.ts +13 -0
  361. package/dist/graph/write.d.ts.map +1 -0
  362. package/dist/graph/write.js +86 -0
  363. package/dist/graph/write.js.map +1 -0
  364. package/dist/hosts/antigravity.d.ts +14 -0
  365. package/dist/hosts/antigravity.d.ts.map +1 -0
  366. package/dist/hosts/antigravity.js +59 -0
  367. package/dist/hosts/antigravity.js.map +1 -0
  368. package/dist/hosts/auto.d.ts +37 -0
  369. package/dist/hosts/auto.d.ts.map +1 -0
  370. package/dist/hosts/auto.js +141 -0
  371. package/dist/hosts/auto.js.map +1 -0
  372. package/dist/hosts/claude-global.d.ts +72 -0
  373. package/dist/hosts/claude-global.d.ts.map +1 -0
  374. package/dist/hosts/claude-global.js +230 -0
  375. package/dist/hosts/claude-global.js.map +1 -0
  376. package/dist/hosts/config-write.d.ts +36 -0
  377. package/dist/hosts/config-write.d.ts.map +1 -0
  378. package/dist/hosts/config-write.js +64 -0
  379. package/dist/hosts/config-write.js.map +1 -0
  380. package/dist/hosts/init.d.ts +28 -0
  381. package/dist/hosts/init.d.ts.map +1 -0
  382. package/dist/hosts/init.js +89 -0
  383. package/dist/hosts/init.js.map +1 -0
  384. package/dist/hosts/instructions.d.ts +14 -0
  385. package/dist/hosts/instructions.d.ts.map +1 -0
  386. package/dist/hosts/instructions.js +95 -0
  387. package/dist/hosts/instructions.js.map +1 -0
  388. package/dist/hosts/mcp-config.d.ts +78 -0
  389. package/dist/hosts/mcp-config.d.ts.map +1 -0
  390. package/dist/hosts/mcp-config.js +251 -0
  391. package/dist/hosts/mcp-config.js.map +1 -0
  392. package/dist/hosts/plan.d.ts +32 -0
  393. package/dist/hosts/plan.d.ts.map +1 -0
  394. package/dist/hosts/plan.js +73 -0
  395. package/dist/hosts/plan.js.map +1 -0
  396. package/dist/hosts/registry.d.ts +41 -0
  397. package/dist/hosts/registry.d.ts.map +1 -0
  398. package/dist/hosts/registry.js +164 -0
  399. package/dist/hosts/registry.js.map +1 -0
  400. package/dist/hosts/retract.d.ts +47 -0
  401. package/dist/hosts/retract.d.ts.map +1 -0
  402. package/dist/hosts/retract.js +520 -0
  403. package/dist/hosts/retract.js.map +1 -0
  404. package/dist/hosts/sections.d.ts +47 -0
  405. package/dist/hosts/sections.d.ts.map +1 -0
  406. package/dist/hosts/sections.js +127 -0
  407. package/dist/hosts/sections.js.map +1 -0
  408. package/dist/index.d.ts +41 -0
  409. package/dist/index.d.ts.map +1 -0
  410. package/dist/index.js +32 -0
  411. package/dist/index.js.map +1 -0
  412. package/dist/ingest/fs.d.ts +79 -0
  413. package/dist/ingest/fs.d.ts.map +1 -0
  414. package/dist/ingest/fs.js +306 -0
  415. package/dist/ingest/fs.js.map +1 -0
  416. package/dist/init-guard.d.ts +16 -0
  417. package/dist/init-guard.d.ts.map +1 -0
  418. package/dist/init-guard.js +27 -0
  419. package/dist/init-guard.js.map +1 -0
  420. package/dist/mcp/instructions.d.ts +5 -0
  421. package/dist/mcp/instructions.d.ts.map +1 -0
  422. package/dist/mcp/instructions.js +64 -0
  423. package/dist/mcp/instructions.js.map +1 -0
  424. package/dist/mcp/kept-listing.d.ts +27 -0
  425. package/dist/mcp/kept-listing.d.ts.map +1 -0
  426. package/dist/mcp/kept-listing.js +63 -0
  427. package/dist/mcp/kept-listing.js.map +1 -0
  428. package/dist/mcp/server.d.ts +4 -0
  429. package/dist/mcp/server.d.ts.map +1 -0
  430. package/dist/mcp/server.js +147 -0
  431. package/dist/mcp/server.js.map +1 -0
  432. package/dist/mcp/tool-names.d.ts +27 -0
  433. package/dist/mcp/tool-names.d.ts.map +1 -0
  434. package/dist/mcp/tool-names.js +47 -0
  435. package/dist/mcp/tool-names.js.map +1 -0
  436. package/dist/mcp/tools.d.ts +22 -0
  437. package/dist/mcp/tools.d.ts.map +1 -0
  438. package/dist/mcp/tools.js +440 -0
  439. package/dist/mcp/tools.js.map +1 -0
  440. package/dist/node-version.d.ts +15 -0
  441. package/dist/node-version.d.ts.map +1 -0
  442. package/dist/node-version.js +23 -0
  443. package/dist/node-version.js.map +1 -0
  444. package/dist/search/grep-cli.d.ts +35 -0
  445. package/dist/search/grep-cli.d.ts.map +1 -0
  446. package/dist/search/grep-cli.js +115 -0
  447. package/dist/search/grep-cli.js.map +1 -0
  448. package/dist/search/grep.d.ts +60 -0
  449. package/dist/search/grep.d.ts.map +1 -0
  450. package/dist/search/grep.js +143 -0
  451. package/dist/search/grep.js.map +1 -0
  452. package/dist/search/ignored-code.d.ts +9 -0
  453. package/dist/search/ignored-code.d.ts.map +1 -0
  454. package/dist/search/ignored-code.js +73 -0
  455. package/dist/search/ignored-code.js.map +1 -0
  456. package/dist/search/user-regexp.d.ts +26 -0
  457. package/dist/search/user-regexp.d.ts.map +1 -0
  458. package/dist/search/user-regexp.js +150 -0
  459. package/dist/search/user-regexp.js.map +1 -0
  460. package/dist/telemetry/contract.d.ts +117 -0
  461. package/dist/telemetry/contract.d.ts.map +1 -0
  462. package/dist/telemetry/contract.js +341 -0
  463. package/dist/telemetry/contract.js.map +1 -0
  464. package/dist/telemetry/flush.d.ts +21 -0
  465. package/dist/telemetry/flush.d.ts.map +1 -0
  466. package/dist/telemetry/flush.js +85 -0
  467. package/dist/telemetry/flush.js.map +1 -0
  468. package/dist/telemetry/gate.d.ts +30 -0
  469. package/dist/telemetry/gate.d.ts.map +1 -0
  470. package/dist/telemetry/gate.js +81 -0
  471. package/dist/telemetry/gate.js.map +1 -0
  472. package/dist/telemetry/identity.d.ts +40 -0
  473. package/dist/telemetry/identity.d.ts.map +1 -0
  474. package/dist/telemetry/identity.js +80 -0
  475. package/dist/telemetry/identity.js.map +1 -0
  476. package/dist/telemetry/index.d.ts +18 -0
  477. package/dist/telemetry/index.d.ts.map +1 -0
  478. package/dist/telemetry/index.js +16 -0
  479. package/dist/telemetry/index.js.map +1 -0
  480. package/dist/telemetry/key.d.ts +21 -0
  481. package/dist/telemetry/key.d.ts.map +1 -0
  482. package/dist/telemetry/key.js +49 -0
  483. package/dist/telemetry/key.js.map +1 -0
  484. package/dist/telemetry/notice.d.ts +19 -0
  485. package/dist/telemetry/notice.d.ts.map +1 -0
  486. package/dist/telemetry/notice.js +93 -0
  487. package/dist/telemetry/notice.js.map +1 -0
  488. package/dist/telemetry/queue.d.ts +35 -0
  489. package/dist/telemetry/queue.d.ts.map +1 -0
  490. package/dist/telemetry/queue.js +162 -0
  491. package/dist/telemetry/queue.js.map +1 -0
  492. package/dist/telemetry/send.d.ts +19 -0
  493. package/dist/telemetry/send.d.ts.map +1 -0
  494. package/dist/telemetry/send.js +84 -0
  495. package/dist/telemetry/send.js.map +1 -0
  496. package/dist/telemetry/sessions.d.ts +25 -0
  497. package/dist/telemetry/sessions.d.ts.map +1 -0
  498. package/dist/telemetry/sessions.js +104 -0
  499. package/dist/telemetry/sessions.js.map +1 -0
  500. package/dist/telemetry/track.d.ts +62 -0
  501. package/dist/telemetry/track.d.ts.map +1 -0
  502. package/dist/telemetry/track.js +143 -0
  503. package/dist/telemetry/track.js.map +1 -0
  504. package/dist/upkeep-run.d.ts +22 -0
  505. package/dist/upkeep-run.d.ts.map +1 -0
  506. package/dist/upkeep-run.js +85 -0
  507. package/dist/upkeep-run.js.map +1 -0
  508. package/dist/upkeep.d.ts +127 -0
  509. package/dist/upkeep.d.ts.map +1 -0
  510. package/dist/upkeep.js +252 -0
  511. package/dist/upkeep.js.map +1 -0
  512. package/dist/util/actions-folder.d.ts +2 -0
  513. package/dist/util/actions-folder.d.ts.map +1 -0
  514. package/dist/util/actions-folder.js +9 -0
  515. package/dist/util/actions-folder.js.map +1 -0
  516. package/dist/util/browser.d.ts +3 -0
  517. package/dist/util/browser.d.ts.map +1 -0
  518. package/dist/util/browser.js +14 -0
  519. package/dist/util/browser.js.map +1 -0
  520. package/dist/util/child-process.d.ts +15 -0
  521. package/dist/util/child-process.d.ts.map +1 -0
  522. package/dist/util/child-process.js +15 -0
  523. package/dist/util/child-process.js.map +1 -0
  524. package/dist/util/front-matter.d.ts +46 -0
  525. package/dist/util/front-matter.d.ts.map +1 -0
  526. package/dist/util/front-matter.js +113 -0
  527. package/dist/util/front-matter.js.map +1 -0
  528. package/dist/util/id.d.ts +7 -0
  529. package/dist/util/id.d.ts.map +1 -0
  530. package/dist/util/id.js +14 -0
  531. package/dist/util/id.js.map +1 -0
  532. package/dist/util/paths.d.ts +29 -0
  533. package/dist/util/paths.d.ts.map +1 -0
  534. package/dist/util/paths.js +71 -0
  535. package/dist/util/paths.js.map +1 -0
  536. package/dist/util/private-file.d.ts +14 -0
  537. package/dist/util/private-file.d.ts.map +1 -0
  538. package/dist/util/private-file.js +82 -0
  539. package/dist/util/private-file.js.map +1 -0
  540. package/dist/util/source.d.ts +4 -0
  541. package/dist/util/source.d.ts.map +1 -0
  542. package/dist/util/source.js +12 -0
  543. package/dist/util/source.js.map +1 -0
  544. package/dist/util/spinner.d.ts +15 -0
  545. package/dist/util/spinner.d.ts.map +1 -0
  546. package/dist/util/spinner.js +52 -0
  547. package/dist/util/spinner.js.map +1 -0
  548. package/dist/util/state.d.ts +120 -0
  549. package/dist/util/state.d.ts.map +1 -0
  550. package/dist/util/state.js +264 -0
  551. package/dist/util/state.js.map +1 -0
  552. package/dist/vendor/grammars/tree-sitter-go.LICENSE +21 -0
  553. package/dist/vendor/grammars/tree-sitter-go.wasm +0 -0
  554. package/dist/vendor/grammars/tree-sitter-java.LICENSE +21 -0
  555. package/dist/vendor/grammars/tree-sitter-java.wasm +0 -0
  556. package/dist/vendor/grammars/tree-sitter-kotlin.LICENSE +9 -0
  557. package/dist/vendor/grammars/tree-sitter-kotlin.wasm +0 -0
  558. package/dist/vendor/grammars/tree-sitter-php.LICENSE +22 -0
  559. package/dist/vendor/grammars/tree-sitter-php.wasm +0 -0
  560. package/dist/vendor/grammars/tree-sitter-python.LICENSE +21 -0
  561. package/dist/vendor/grammars/tree-sitter-python.wasm +0 -0
  562. package/dist/vendor/grammars/tree-sitter-r.LICENSE +9 -0
  563. package/dist/vendor/grammars/tree-sitter-r.wasm +0 -0
  564. package/dist/vendor/grammars/tree-sitter-swift.LICENSE +21 -0
  565. package/dist/vendor/grammars/tree-sitter-swift.wasm +0 -0
  566. package/dist/vendor/grammars/tree-sitter-tsx.wasm +0 -0
  567. package/dist/vendor/grammars/tree-sitter-typescript.LICENSE +21 -0
  568. package/dist/vendor/grammars/tree-sitter-typescript.wasm +0 -0
  569. package/dist/viewer/app.js +2 -0
  570. package/dist/viewer/index.html +49 -0
  571. package/dist/viewer/style.css +154 -0
  572. package/dist/viz/assemble.d.ts +83 -0
  573. package/dist/viz/assemble.d.ts.map +1 -0
  574. package/dist/viz/assemble.js +101 -0
  575. package/dist/viz/assemble.js.map +1 -0
  576. package/dist/viz/export.d.ts +39 -0
  577. package/dist/viz/export.d.ts.map +1 -0
  578. package/dist/viz/export.js +98 -0
  579. package/dist/viz/export.js.map +1 -0
  580. package/dist/viz/serve.d.ts +13 -0
  581. package/dist/viz/serve.d.ts.map +1 -0
  582. package/dist/viz/serve.js +130 -0
  583. package/dist/viz/serve.js.map +1 -0
  584. package/package.json +115 -4
  585. package/scripts/build-grammar-wasm.mjs +112 -0
  586. package/scripts/build-viewer.mjs +44 -0
  587. package/scripts/graph-quality.mjs +117 -0
  588. package/scripts/pack-trail.mjs +53 -0
  589. package/scripts/postinstall.mjs +65 -0
  590. package/scripts/run-tests.mjs +72 -0
  591. package/scripts/stamp-telemetry-key.mjs +56 -0
  592. package/scripts/tally-audit.mjs +140 -0
  593. package/scripts/vendor-grammars.mjs +53 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Tier-2 "meaning" call for the code graph — batched one request per file.
3
+ *
4
+ * Given a source file (with 1-based line numbers) and the list of definitions in
5
+ * it, one call returns, for each definition:
6
+ * 1. `summary` — one plain-English sentence: what the symbol is *for*, at the
7
+ * business-logic level, not a restatement of its signature.
8
+ * 2. `crux_start`/`crux_end` — the smallest contiguous range of FILE line
9
+ * numbers (inside that symbol's own span) that a reviewer must read to see
10
+ * the decision or rule the code encodes. `0/0` means there is no single
11
+ * crux (a trivial getter, a plain data holder).
12
+ *
13
+ * Batching per file means N definitions cost one request, not N — and the model
14
+ * sees each symbol's neighbours, which sharpens the summaries. Line numbers are
15
+ * consumed once, at write time, to slice the crux text verbatim from source.
16
+ */
17
+ import type { ChatModel, ChatResponse } from "./llm/types.js";
18
+ import type { Kind } from "../graph/types.js";
19
+ /** One definition we want described, located by its line span within the file. */
20
+ export interface NodeRef {
21
+ id: string;
22
+ kind: Kind;
23
+ signature: string | null;
24
+ startLine: number;
25
+ endLine: number;
26
+ }
27
+ export interface FileCruxInput {
28
+ path: string;
29
+ source: string;
30
+ nodes: NodeRef[];
31
+ }
32
+ export interface NodeCrux {
33
+ id: string;
34
+ summary: string;
35
+ crux_start: number;
36
+ crux_end: number;
37
+ }
38
+ export interface CruxSummarizer {
39
+ describeFile(input: FileCruxInput): Promise<NodeCrux[]>;
40
+ /** Set by {@link ChatCruxSummarizer} after each call; optional on fakes. */
41
+ lastMiss?: CruxMiss | null;
42
+ }
43
+ /** Why a crux call produced no usable summaries (#235). */
44
+ export type CruxMissKind = "empty-toolCalls" | "unparseable" | "truncated" | "empty-parsed" | "id-mismatch";
45
+ export interface CruxMiss {
46
+ kind: CruxMissKind;
47
+ finishReason: string | null;
48
+ /** `id-mismatch` only: how many entries came back, and the first one's raw id. */
49
+ returned?: number;
50
+ firstId?: string;
51
+ }
52
+ /**
53
+ * Classify an empty/unusable crux reply. `null` means at least one usable summary.
54
+ * With `requested`, a summary only counts when its id is one we asked for: enrich
55
+ * looks results up by node id, so a summary under any other id is never applied.
56
+ */
57
+ export declare function classifyCruxMiss(res: ChatResponse, parsed: NodeCrux[], requested?: readonly string[]): CruxMiss | null;
58
+ /** Per-file error text: miss class + the provider's finish_reason (#235). */
59
+ export declare function formatCruxMiss(kind: CruxMissKind, finishReason: string | null): string;
60
+ /**
61
+ * The model's text for an `id-mismatch`, kept apart from {@link formatCruxMiss}:
62
+ * the failure gate matches words like "quota" in the error message, and a
63
+ * returned id can carry any source text, so it must never reach the gate.
64
+ */
65
+ export declare function formatCruxMissDetail(miss: CruxMiss | null | undefined): string;
66
+ /**
67
+ * Map an id the model returned onto one of the ids we asked for, or null.
68
+ *
69
+ * Models echo decorated target rows instead of the bare id (#259, #298, #486).
70
+ * Rather than cut the string at a guessed delimiter, every rule compares against
71
+ * the requested ids, so the result is always an id we asked for — never a
72
+ * fragment of a hallucinated one — and no rule assumes which characters an id
73
+ * may contain. In order:
74
+ * 1. exact match;
75
+ * 2. a requested id followed by ` | ` (the row echoed from the id onwards);
76
+ * 3. the same two with a leading `id=` removed;
77
+ * 4. a row ending in ` | id=<requested id>` (the current layout echoed whole).
78
+ * When several requested ids qualify, the longest wins.
79
+ */
80
+ export declare function resolveTargetId(raw: string, requested: readonly string[]): string | null;
81
+ /** Crux summarizer backed by any {@link ChatModel} via forced tool calling. */
82
+ export declare class ChatCruxSummarizer implements CruxSummarizer {
83
+ private model;
84
+ lastMiss: CruxMiss | null;
85
+ constructor(model: ChatModel);
86
+ describeFile(input: FileCruxInput): Promise<NodeCrux[]>;
87
+ }
88
+ //# sourceMappingURL=crux.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crux.d.ts","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxD,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC5B;AAED,2DAA2D;AAC3D,MAAM,MAAM,YAAY,GACpB,iBAAiB,GACjB,aAAa,GACb,WAAW,GACX,cAAc,GACd,aAAa,CAAC;AAElB,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,QAAQ,EAAE,EAClB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAC5B,QAAQ,GAAG,IAAI,CAcjB;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAMtF;AAKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAO9E;AAwED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAYxF;AA2CD,+EAA+E;AAC/E,qBAAa,kBAAmB,YAAW,cAAc;IAG3C,OAAO,CAAC,KAAK;IAFzB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;gBAEb,KAAK,EAAE,SAAS;IAE9B,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAwB9D"}
@@ -0,0 +1,219 @@
1
+ import { recoverToolArgsFromContent, warnToolChoiceIgnored } from "./llm/recover-tool.js";
2
+ function isTruncatedStop(reason) {
3
+ if (!reason)
4
+ return false;
5
+ const r = reason.toLowerCase();
6
+ return r === "length" || r === "max_tokens";
7
+ }
8
+ /**
9
+ * Classify an empty/unusable crux reply. `null` means at least one usable summary.
10
+ * With `requested`, a summary only counts when its id is one we asked for: enrich
11
+ * looks results up by node id, so a summary under any other id is never applied.
12
+ */
13
+ export function classifyCruxMiss(res, parsed, requested) {
14
+ const finishReason = res.stopReason;
15
+ const wanted = requested ? new Set(requested) : undefined;
16
+ const matched = wanted ? parsed.filter((p) => wanted.has(p.id)) : parsed;
17
+ if (matched.some((p) => p.summary.trim()))
18
+ return null;
19
+ if (isTruncatedStop(finishReason))
20
+ return { kind: "truncated", finishReason };
21
+ if (parsed.length > 0 && matched.length === 0) {
22
+ return { kind: "id-mismatch", finishReason, returned: parsed.length, firstId: parsed[0].id };
23
+ }
24
+ if (parsed.length > 0)
25
+ return { kind: "empty-parsed", finishReason };
26
+ const emptyTools = res.toolCalls.length === 0;
27
+ const emptyText = !res.text?.trim();
28
+ if (emptyTools && emptyText)
29
+ return { kind: "empty-toolCalls", finishReason };
30
+ return { kind: "unparseable", finishReason };
31
+ }
32
+ /** Per-file error text: miss class + the provider's finish_reason (#235). */
33
+ export function formatCruxMiss(kind, finishReason) {
34
+ const fr = finishReason == null || finishReason === "" ? "null" : finishReason;
35
+ if (kind === "id-mismatch") {
36
+ return `model returned summaries but no id matched a requested target [${kind}, finish_reason=${fr}]`;
37
+ }
38
+ return `model returned no usable symbol summaries [${kind}, finish_reason=${fr}]`;
39
+ }
40
+ /** Longest echoed id shown in an error; a whole echoed row can carry a long signature. */
41
+ const MAX_SHOWN_ID_CHARS = 200;
42
+ /**
43
+ * The model's text for an `id-mismatch`, kept apart from {@link formatCruxMiss}:
44
+ * the failure gate matches words like "quota" in the error message, and a
45
+ * returned id can carry any source text, so it must never reach the gate.
46
+ */
47
+ export function formatCruxMissDetail(miss) {
48
+ if (miss?.kind !== "id-mismatch" || miss.firstId === undefined)
49
+ return "";
50
+ const id = miss.firstId.length > MAX_SHOWN_ID_CHARS
51
+ ? `${miss.firstId.slice(0, MAX_SHOWN_ID_CHARS)}…`
52
+ : miss.firstId;
53
+ return `first of ${miss.returned ?? 1} returned id(s): ${JSON.stringify(id)}`;
54
+ }
55
+ const SYSTEM_PROMPT = `You explain code definitions for a code graph that helps engineers navigate a codebase.
56
+
57
+ You are given ONE source file with 1-based line numbers, and a list of TARGET definitions in it. Describe EVERY target via the record_symbols tool.
58
+
59
+ Rules:
60
+ - Return EXACTLY ONE entry for EVERY target id, using that id verbatim. The number of entries you return MUST equal the number of targets. Never omit a target: a reply missing any id is invalid and will be re-requested.
61
+ - A trivial symbol is NOT an exception. You still return it — with a one-sentence summary and crux 0/0 (see below). "Skip" means "give it no crux span", NEVER "leave it out".
62
+ - summary: ONE sentence — what the symbol is FOR at the business-logic level (the problem it solves or the rule it enforces), not a restatement of its signature.
63
+ - crux_start / crux_end: FILE line numbers (as shown), inside that symbol's own line range. Pick the SINGLE most important contiguous span — the core branch, formula, guard, or state change — at most ~8 lines, and NEVER the whole function. When there is no single focal span (a trivial getter, a plain data holder, a one-line delegation, or logic spread evenly), use crux_start: 0 and crux_end: 0. That 0/0 IS the answer — do not drop the entry.`;
64
+ const RECORD_TOOL = "record_symbols";
65
+ const SYMBOLS_SCHEMA = {
66
+ type: "object",
67
+ properties: {
68
+ symbols: {
69
+ type: "array",
70
+ items: {
71
+ type: "object",
72
+ properties: {
73
+ id: { type: "string" },
74
+ summary: { type: "string" },
75
+ crux_start: { type: "number" },
76
+ crux_end: { type: "number" },
77
+ },
78
+ required: ["id", "summary", "crux_start", "crux_end"],
79
+ },
80
+ },
81
+ },
82
+ required: ["symbols"],
83
+ };
84
+ /** Cap the file text sent per request so one huge file can't blow the context. */
85
+ const MAX_CODE_CHARS = 18_000;
86
+ function numberLines(source) {
87
+ const clipped = source.length > MAX_CODE_CHARS ? `${source.slice(0, MAX_CODE_CHARS)}\n… (truncated)` : source;
88
+ return clipped
89
+ .split("\n")
90
+ .map((line, i) => `${i + 1}\t${line}`)
91
+ .join("\n");
92
+ }
93
+ /**
94
+ * `id=` is the LAST field of a target line, so the id ends where the line does.
95
+ * With the id first nothing terminated it, and models asked for the id
96
+ * "verbatim" copied the whole row — `a.cs#Level | variable | lines L58-L58 | sig`
97
+ * — into `id` (#259). {@link resolveTargetId} still repairs echoes of either layout.
98
+ */
99
+ function userContent(input) {
100
+ const targets = input.nodes
101
+ .map((n) => `- ${n.kind} | lines L${n.startLine}-L${n.endLine}` +
102
+ (n.signature ? ` | ${n.signature}` : "") +
103
+ ` | id=${n.id}`)
104
+ .join("\n");
105
+ const n = input.nodes.length;
106
+ return `FILE: ${input.path}\n\n${numberLines(input.source)}\n\nTARGETS (${n} — return all ${n}, one entry per id):\n${targets}`;
107
+ }
108
+ /** The longest requested id `test` accepts, or null. */
109
+ function longestMatch(requested, test) {
110
+ let best = null;
111
+ for (const id of requested)
112
+ if (test(id) && (best === null || id.length > best.length))
113
+ best = id;
114
+ return best;
115
+ }
116
+ /**
117
+ * Map an id the model returned onto one of the ids we asked for, or null.
118
+ *
119
+ * Models echo decorated target rows instead of the bare id (#259, #298, #486).
120
+ * Rather than cut the string at a guessed delimiter, every rule compares against
121
+ * the requested ids, so the result is always an id we asked for — never a
122
+ * fragment of a hallucinated one — and no rule assumes which characters an id
123
+ * may contain. In order:
124
+ * 1. exact match;
125
+ * 2. a requested id followed by ` | ` (the row echoed from the id onwards);
126
+ * 3. the same two with a leading `id=` removed;
127
+ * 4. a row ending in ` | id=<requested id>` (the current layout echoed whole).
128
+ * When several requested ids qualify, the longest wins.
129
+ */
130
+ export function resolveTargetId(raw, requested) {
131
+ const id = raw.trim();
132
+ if (requested.includes(id))
133
+ return id;
134
+ const echoed = longestMatch(requested, (r) => id.startsWith(`${r} | `));
135
+ if (echoed)
136
+ return echoed;
137
+ if (id.startsWith("id=")) {
138
+ const bare = id.slice(3).trim();
139
+ if (requested.includes(bare))
140
+ return bare;
141
+ const bareEchoed = longestMatch(requested, (r) => bare.startsWith(`${r} | `));
142
+ if (bareEchoed)
143
+ return bareEchoed;
144
+ }
145
+ return longestMatch(requested, (r) => id.endsWith(` | id=${r}`));
146
+ }
147
+ /**
148
+ * Normalize the tool's parsed argument object into a {@link NodeCrux} list. Ids
149
+ * are resolved against `requested`; one that matches nothing keeps its raw text
150
+ * so {@link classifyCruxMiss} can report what the model actually sent.
151
+ */
152
+ function parseResults(obj, requested) {
153
+ if (!obj || !Array.isArray(obj.symbols))
154
+ return [];
155
+ const num = (v) => (typeof v === "number" && Number.isFinite(v) ? Math.trunc(v) : 0);
156
+ return obj.symbols
157
+ .map((s) => s)
158
+ .filter((s) => typeof s.id === "string")
159
+ .map((s) => ({
160
+ id: resolveTargetId(s.id, requested) ?? s.id,
161
+ summary: typeof s.summary === "string" ? s.summary.trim() : "",
162
+ crux_start: num(s.crux_start),
163
+ crux_end: num(s.crux_end),
164
+ }));
165
+ }
166
+ /**
167
+ * Some OpenAI-compatible gateways ignore forced `tool_choice` and put the tool
168
+ * payload in `content` instead (plain `{symbols:…}`, fenced JSON, or an emulated
169
+ * `[{name, parameters}]` array). Without this recovery the meaning pass sees an
170
+ * empty `toolCalls` list, leaves every node `pending`, and `graft check` loops
171
+ * on "run --deep" forever (#172; same trigger as #129 for the crux path).
172
+ */
173
+ function argsFromResponse(res) {
174
+ const call = res.toolCalls.find((c) => c.name === RECORD_TOOL) ?? res.toolCalls[0];
175
+ if (call?.args && typeof call.args === "object" && !Array.isArray(call.args)) {
176
+ return call.args;
177
+ }
178
+ const recovered = recoverToolArgsFromContent(res.text, {
179
+ toolNames: [RECORD_TOOL, "emit_json"],
180
+ payloadKey: "symbols",
181
+ });
182
+ if (!recovered)
183
+ warnToolChoiceIgnored("crux", res.text?.trim() ? "unparsed" : "empty");
184
+ return recovered;
185
+ }
186
+ /** Crux summarizer backed by any {@link ChatModel} via forced tool calling. */
187
+ export class ChatCruxSummarizer {
188
+ model;
189
+ lastMiss = null;
190
+ constructor(model) {
191
+ this.model = model;
192
+ }
193
+ async describeFile(input) {
194
+ this.lastMiss = null;
195
+ if (input.nodes.length === 0)
196
+ return [];
197
+ const res = await this.model.create({
198
+ temperature: 0,
199
+ maxTokens: 8192,
200
+ tools: [
201
+ {
202
+ name: RECORD_TOOL,
203
+ description: "Record each target definition's purpose and crux line range.",
204
+ parameters: SYMBOLS_SCHEMA,
205
+ },
206
+ ],
207
+ responseFormat: { kind: "tool", name: RECORD_TOOL },
208
+ messages: [
209
+ { role: "system", content: SYSTEM_PROMPT },
210
+ { role: "user", content: userContent(input) },
211
+ ],
212
+ });
213
+ const requested = input.nodes.map((n) => n.id);
214
+ const parsed = parseResults(argsFromResponse(res), requested);
215
+ this.lastMiss = classifyCruxMiss(res, parsed, requested);
216
+ return parsed;
217
+ }
218
+ }
219
+ //# sourceMappingURL=crux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crux.js","sourceRoot":"","sources":["../../src/ai/crux.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * When to stop calling a provider that is failing (#127).
3
+ *
4
+ * Both LLM passes of `build --deep` — the per-file concept summaries
5
+ * (`context/build.ts`) and the per-file crux pass (`graph/enrich.ts`) — used to
6
+ * catch every error per file, keep going, and finish with a clean exit. On an
7
+ * 884-file repo behind a gateway whose token quota was spent that produced 1,617
8
+ * failed calls, a normal success footer, and a graph whose meaning tier was
9
+ * missing; the degradation surfaced days later as bad `ask` results.
10
+ *
11
+ * One gate, shared by both passes, so they agree on what "the provider stopped
12
+ * working" means and a caller can report it once.
13
+ *
14
+ * Content-quality misses (empty/unusable crux, #235) still count as failed files
15
+ * so they are not cached as success (#177), but they do not increment the
16
+ * consecutive-failure cutoff — the provider is answering, just not usefully for
17
+ * those files. Quota/auth stay immediately terminal (#127).
18
+ */
19
+ /** Consecutive failures that end a pass. One flaky file is normal; five in a row is
20
+ * a provider that is not going to start working, and each further call is spend
21
+ * with no chance of a result. */
22
+ export declare const MAX_CONSECUTIVE_FAILURES = 5;
23
+ /**
24
+ * Errors no amount of retrying fixes: the key is wrong, or the account/quota is
25
+ * spent. Matched on the message because that is all a provider-neutral transport
26
+ * carries — over-matching costs a build that was going to fail anyway, while
27
+ * under-matching just falls back to the consecutive-failure cutoff.
28
+ */
29
+ export declare function terminalReason(message: string): string | null;
30
+ /**
31
+ * Failure bookkeeping for one LLM pass: how many units failed, how many were
32
+ * skipped once it gave up, and the human-readable reason it did.
33
+ *
34
+ * Single-threaded by construction — every mutation happens between awaits in the
35
+ * pass's own worker — so no locking is needed despite the concurrency above it.
36
+ */
37
+ export declare class LlmFailureGate {
38
+ /** Units (files) whose call failed. */
39
+ failed: number;
40
+ /** Units never attempted because the pass had already given up. */
41
+ skipped: number;
42
+ /** Why the pass stopped, when it did. */
43
+ fatal?: string;
44
+ private consecutive;
45
+ /** True once the pass should stop issuing calls. */
46
+ get stopped(): boolean;
47
+ /**
48
+ * Record a failed unit; sets {@link fatal} when this failure is the last straw.
49
+ * Pass `{ quality: true }` for a content-quality miss (#235): counted, not fatal,
50
+ * unless the message is quota/auth (those still stop immediately).
51
+ */
52
+ record(message: string, opts?: {
53
+ quality?: boolean;
54
+ }): void;
55
+ /** Record a success — a failure run only counts while it is unbroken. */
56
+ succeeded(): void;
57
+ /** Record a unit that was not attempted because the pass had stopped. */
58
+ skip(): void;
59
+ }
60
+ //# sourceMappingURL=failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../../src/ai/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;iCAEiC;AACjC,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7D;AAED;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,uCAAuC;IACvC,MAAM,SAAK;IACX,mEAAmE;IACnE,OAAO,SAAK;IACZ,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,WAAW,CAAK;IAExB,oDAAoD;IACpD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAc3D,yEAAyE;IACzE,SAAS,IAAI,IAAI;IAIjB,yEAAyE;IACzE,IAAI,IAAI,IAAI;CAGb"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * When to stop calling a provider that is failing (#127).
3
+ *
4
+ * Both LLM passes of `build --deep` — the per-file concept summaries
5
+ * (`context/build.ts`) and the per-file crux pass (`graph/enrich.ts`) — used to
6
+ * catch every error per file, keep going, and finish with a clean exit. On an
7
+ * 884-file repo behind a gateway whose token quota was spent that produced 1,617
8
+ * failed calls, a normal success footer, and a graph whose meaning tier was
9
+ * missing; the degradation surfaced days later as bad `ask` results.
10
+ *
11
+ * One gate, shared by both passes, so they agree on what "the provider stopped
12
+ * working" means and a caller can report it once.
13
+ *
14
+ * Content-quality misses (empty/unusable crux, #235) still count as failed files
15
+ * so they are not cached as success (#177), but they do not increment the
16
+ * consecutive-failure cutoff — the provider is answering, just not usefully for
17
+ * those files. Quota/auth stay immediately terminal (#127).
18
+ */
19
+ /** Consecutive failures that end a pass. One flaky file is normal; five in a row is
20
+ * a provider that is not going to start working, and each further call is spend
21
+ * with no chance of a result. */
22
+ export const MAX_CONSECUTIVE_FAILURES = 5;
23
+ /**
24
+ * Errors no amount of retrying fixes: the key is wrong, or the account/quota is
25
+ * spent. Matched on the message because that is all a provider-neutral transport
26
+ * carries — over-matching costs a build that was going to fail anyway, while
27
+ * under-matching just falls back to the consecutive-failure cutoff.
28
+ */
29
+ export function terminalReason(message) {
30
+ const m = message.toLowerCase();
31
+ if (/quota|insufficient[_ ]funds|insufficient[_ ]quota|billing|payment required|402/.test(m)) {
32
+ return "the provider reports the quota/credit for this key is exhausted";
33
+ }
34
+ if (/\b401\b|\b403\b|unauthorized|invalid api key|invalid_api_key|authentication/.test(m)) {
35
+ return "the provider rejected the API key";
36
+ }
37
+ return null;
38
+ }
39
+ /**
40
+ * Failure bookkeeping for one LLM pass: how many units failed, how many were
41
+ * skipped once it gave up, and the human-readable reason it did.
42
+ *
43
+ * Single-threaded by construction — every mutation happens between awaits in the
44
+ * pass's own worker — so no locking is needed despite the concurrency above it.
45
+ */
46
+ export class LlmFailureGate {
47
+ /** Units (files) whose call failed. */
48
+ failed = 0;
49
+ /** Units never attempted because the pass had already given up. */
50
+ skipped = 0;
51
+ /** Why the pass stopped, when it did. */
52
+ fatal;
53
+ consecutive = 0;
54
+ /** True once the pass should stop issuing calls. */
55
+ get stopped() {
56
+ return this.fatal !== undefined;
57
+ }
58
+ /**
59
+ * Record a failed unit; sets {@link fatal} when this failure is the last straw.
60
+ * Pass `{ quality: true }` for a content-quality miss (#235): counted, not fatal,
61
+ * unless the message is quota/auth (those still stop immediately).
62
+ */
63
+ record(message, opts) {
64
+ this.failed++;
65
+ const terminal = terminalReason(message);
66
+ if (terminal) {
67
+ this.fatal = `${terminal} — stopped after ${this.failed} failed file(s). First error: ${message}`;
68
+ return;
69
+ }
70
+ if (opts?.quality)
71
+ return;
72
+ this.consecutive++;
73
+ if (this.consecutive >= MAX_CONSECUTIVE_FAILURES) {
74
+ this.fatal = `${this.consecutive} files in a row failed, so the pass stopped rather than keep calling. Last error: ${message}`;
75
+ }
76
+ }
77
+ /** Record a success — a failure run only counts while it is unbroken. */
78
+ succeeded() {
79
+ this.consecutive = 0;
80
+ }
81
+ /** Record a unit that was not attempted because the pass had stopped. */
82
+ skip() {
83
+ this.skipped++;
84
+ }
85
+ }
86
+ //# sourceMappingURL=failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.js","sourceRoot":"","sources":["../../src/ai/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;iCAEiC;AACjC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,gFAAgF,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,iEAAiE,CAAC;IAC3E,CAAC;IACD,IAAI,6EAA6E,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1F,OAAO,mCAAmC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IACzB,uCAAuC;IACvC,MAAM,GAAG,CAAC,CAAC;IACX,mEAAmE;IACnE,OAAO,GAAG,CAAC,CAAC;IACZ,yCAAyC;IACzC,KAAK,CAAU;IACP,WAAW,GAAG,CAAC,CAAC;IAExB,oDAAoD;IACpD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAe,EAAE,IAA4B;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,GAAG,GAAG,QAAQ,oBAAoB,IAAI,CAAC,MAAM,iCAAiC,OAAO,EAAE,CAAC;YAClG,OAAO;QACT,CAAC;QACD,IAAI,IAAI,EAAE,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,WAAW,IAAI,wBAAwB,EAAE,CAAC;YACjD,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,WAAW,qFAAqF,OAAO,EAAE,CAAC;QACjI,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,SAAS;QACP,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,yEAAyE;IACzE,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Native Anthropic transport. Wraps `@anthropic-ai/sdk` (the Messages API), so
3
+ * Claude is a first-class provider rather than something tunneled through an
4
+ * OpenAI-compatible endpoint.
5
+ *
6
+ * The Messages API differs from Chat Completions in ways this adapter absorbs so
7
+ * the rest of graft never sees them:
8
+ * - `system` is a top-level parameter, not a message.
9
+ * - tool results ride inside a USER turn, and all results answering one
10
+ * assistant turn must be coalesced into a single user message.
11
+ * - `max_tokens` is required (callers get a default).
12
+ * - `temperature` is rejected by current models, so it is never forwarded.
13
+ * - structured output is a forced tool (there is no `response_format`).
14
+ * - assistant turns are replayed verbatim (via `providerRaw`) so thinking-block
15
+ * signatures survive a multi-turn loop.
16
+ */
17
+ import Anthropic from "@anthropic-ai/sdk";
18
+ import type { ChatModel, ChatRequest, ChatResponse } from "./types.js";
19
+ export interface AnthropicChatModelOptions {
20
+ apiKey: string;
21
+ model: string;
22
+ baseUrl?: string;
23
+ label?: string;
24
+ /** Inject a pre-built client (tests pass a stub; production omits it). */
25
+ client?: Anthropic;
26
+ }
27
+ export declare class AnthropicChatModel implements ChatModel {
28
+ readonly label: string;
29
+ private client;
30
+ private model;
31
+ constructor(opts: AnthropicChatModelOptions);
32
+ create(req: ChatRequest): Promise<ChatResponse>;
33
+ /** Reconstruct an assistant turn, replaying the original blocks when we made them. */
34
+ private assistantParam;
35
+ private fromResponse;
36
+ }
37
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAsC,MAAM,YAAY,CAAC;AAM3G,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAKD,qBAAa,kBAAmB,YAAW,SAAS;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,IAAI,EAAE,yBAAyB;IAQrC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuDrD,sFAAsF;IACtF,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,YAAY;CA4BrB"}