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,85 @@
1
+ import type { AgentHost } from '../telemetry/contract.js';
2
+ export { LOCK_STALE_MS, acquireLock, acquireLockIn, releaseLockIn, cacheDir, emptyStats, patchStats, readStats, releaseLock, resolveContextDir, writeJsonAtomic, writeStats, } from '../util/state.js';
3
+ export type { Stats } from '../util/state.js';
4
+ export interface SessionState {
5
+ /** Prompts the prompt hook asked the graph about this session. A count:
6
+ * nothing the person typed is kept (spec section 6). Optional so files
7
+ * written before it still parse. */
8
+ promptAsks?: number;
9
+ /** The repo skills this session used, by name, to when it last went to the workspace as a run (skill-use.ts). */
10
+ skillsUsed?: Record<string, number>;
11
+ graftReads: number;
12
+ sourceReads: number;
13
+ /** Cumulative tokens saved this session via `ask --source` retrieval (est.). */
14
+ savedTokens: number;
15
+ /** Pointers the prompt hook already injected this session (novelty gate:
16
+ * a hit whose pointer was shown once is never re-injected). Optional so
17
+ * session files written before this field still parse. */
18
+ injectedPointers?: string[];
19
+ /** Notes already put in front of the agent this session by the per-prompt
20
+ * hook, by path, so each is shown once (see `notesForPrompt`). */
21
+ injectedNotes?: string[];
22
+ /** `<branch> <function id>` pairs: a teammate's open branch on a function the agent edited, already put in front of it this session. */
23
+ injectedOverlaps?: string[];
24
+ /** Weak-match nudges spent this session, capped so the line stays signal.
25
+ * Optional for the same backwards-compatibility reason as above. */
26
+ nudges?: number;
27
+ /** Turns this session in which the agent used a graft retrieval tool — the
28
+ * denominator for "did it tell the user what that saved". Counted at Stop,
29
+ * and only for turns whose reply we could actually read (see claude/tally.ts). */
30
+ graftTurns?: number;
31
+ /** Of those turns, the ones whose reply carried a "graft saved ~N tokens"
32
+ * tally. `graftTurns - reportedTurns` is silent value: saved, never said. */
33
+ reportedTurns?: number;
34
+ /** Set by the tool-savings hook when the current turn touched graft, cleared
35
+ * at Stop once the turn has been counted. Transient, not a total. */
36
+ turnUsedGraft?: boolean;
37
+ /** `uuid` of the last assistant reply already examined, so a Stop that fires
38
+ * without new prose (or fires twice) can't count one reply as two turns. */
39
+ lastTallyUuid?: string;
40
+ /** Running micro-dollar cost of the input tokens this session has been billed
41
+ * for, and the tokens that bought. Their ratio is the blended price of one
42
+ * input token here — model and cache-hit ratio already folded in — which is
43
+ * what turns `savedTokens` into a dollar figure. Stored as the pair rather
44
+ * than the ratio so the rate re-blends as the session's cache warms rather
45
+ * than freezing at whatever turn one happened to pay. Optional: absent on a
46
+ * host that exposes no transcript, and on turn one of every session. */
47
+ inputCostMicros?: number;
48
+ inputTokensBilled?: number;
49
+ /** `uuid` of the last assistant entry already billed. Each response is
50
+ * billed once, by the Stop read that first sees it (claude/tally.ts); a read
51
+ * that has to start over (no cursor, a lost one, a replaced transcript)
52
+ * bills nothing up to this entry again. */
53
+ lastBillingUuid?: string;
54
+ /** The signs the Stop hook has asked the agent to save a learning about
55
+ * this session (note-signals.ts keys), so each is asked about once and a
56
+ * session at most NOTE_ASKS_PER_SESSION times. */
57
+ noteAsks?: string[];
58
+ /** Set once this session has been rolled up into a `session_summary`
59
+ * telemetry event, so a resumed or long-lived session is counted once.
60
+ * A flag rather than deleting the file: the file still holds
61
+ * `injectedPointers`, which a resumed session needs. */
62
+ summarized?: boolean;
63
+ /** Which host recorded this session, stamped on the first tool use. Lets the
64
+ * `session_summary` be attributed correctly even when Claude Code's idle sweep
65
+ * is what finally flushes a Cursor session. Optional: files written before
66
+ * host-stamping (or an empty session never touched by a tool) fall back to the
67
+ * flushing host. */
68
+ host?: AgentHost;
69
+ }
70
+ /** The per-repo session directory holding one `<id>.json` per agent session. */
71
+ export declare function sessionDir(d: string): string;
72
+ /** Every session id with a file on disk, or `[]` when none exist (never throws).
73
+ * Shared by the telemetry rollup and `graft stats` so they agree on the set. */
74
+ export declare function listSessionIds(d: string): string[];
75
+ export declare function readSession(d: string, id: string): SessionState;
76
+ export declare function writeSession(d: string, id: string, s: SessionState): void;
77
+ /**
78
+ * Take the prompt out of every session file an older version wrote here.
79
+ * Once per repo: the marker skips the read of every file on later session
80
+ * starts. Each file keeps its mtime, since the idle sweep that rolls sessions
81
+ * up into telemetry judges a session closed by it. Best-effort: a file that
82
+ * can't be read or written is tried again next time.
83
+ */
84
+ export declare function dropStoredPrompts(d: string): void;
85
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/claude/state.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACL,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B;;wCAEoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iHAAiH;IACjH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IACxC,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB;;8DAE0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;sEACkE;IAClE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wIAAwI;IACxI,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;wEACoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;sFAEkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;iFAC6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;yEACqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;gFAC4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;4EAMwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;+CAG2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;sDAEkD;IAClD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;4DAGwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;wBAIoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAkBD,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAyC;AAItF;iFACiF;AACjF,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIlD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,CAK/D;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,GAAG,IAAI,CAIzE;AAKD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAmBjD"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Claude Code session state. The shared `graft/.cache/` pieces (the statusline's
3
+ * `Stats` snapshot and the build lock) live in `../util/state.js` so the graph's
4
+ * pre-query auto-refresh can take the same lock; they are re-exported here so
5
+ * every existing import path keeps working.
6
+ */
7
+ import { existsSync, readdirSync, statSync, utimesSync, writeFileSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { cacheDir, readJson, writeJsonAtomic } from '../util/state.js';
10
+ export { LOCK_STALE_MS, acquireLock, acquireLockIn, releaseLockIn, cacheDir, emptyStats, patchStats, readStats, releaseLock, resolveContextDir, writeJsonAtomic, writeStats, } from '../util/state.js';
11
+ function emptySession() {
12
+ return { graftReads: 0, sourceReads: 0, savedTokens: 0, injectedPointers: [], nudges: 0 };
13
+ }
14
+ /** Where versions before 0.23 kept the prompt itself (`lastQuery`, and `perAgentQuery` by agent name). */
15
+ const PROMPT_KEYS = ['lastQuery', 'perAgentQuery'];
16
+ /** `s` without the prompt an older version stored in it. True when there was one. */
17
+ function withoutPrompts(s) {
18
+ let had = false;
19
+ for (const key of PROMPT_KEYS) {
20
+ if (key in s) {
21
+ delete s[key];
22
+ had = true;
23
+ }
24
+ }
25
+ return had;
26
+ }
27
+ /** The per-repo session directory holding one `<id>.json` per agent session. */
28
+ export function sessionDir(d) { return join(cacheDir(d), 'session'); }
29
+ function sessionPath(d, id) { return join(sessionDir(d), `${id}.json`); }
30
+ /** Every session id with a file on disk, or `[]` when none exist (never throws).
31
+ * Shared by the telemetry rollup and `graft stats` so they agree on the set. */
32
+ export function listSessionIds(d) {
33
+ try {
34
+ return readdirSync(sessionDir(d)).filter((f) => f.endsWith('.json')).map((f) => f.slice(0, -'.json'.length));
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ }
40
+ export function readSession(d, id) {
41
+ const s = readJson(sessionPath(d, id));
42
+ if (!s || typeof s !== 'object')
43
+ return emptySession();
44
+ withoutPrompts(s);
45
+ return s;
46
+ }
47
+ export function writeSession(d, id, s) {
48
+ const out = { ...s };
49
+ withoutPrompts(out);
50
+ writeJsonAtomic(sessionPath(d, id), out);
51
+ }
52
+ /** Left in the session dir once every file there is free of prompts. Not `.json`, so never read as a session. */
53
+ const PROMPTS_DROPPED = '.prompts-dropped';
54
+ /**
55
+ * Take the prompt out of every session file an older version wrote here.
56
+ * Once per repo: the marker skips the read of every file on later session
57
+ * starts. Each file keeps its mtime, since the idle sweep that rolls sessions
58
+ * up into telemetry judges a session closed by it. Best-effort: a file that
59
+ * can't be read or written is tried again next time.
60
+ */
61
+ export function dropStoredPrompts(d) {
62
+ const dir = sessionDir(d);
63
+ const marker = join(dir, PROMPTS_DROPPED);
64
+ if (existsSync(marker))
65
+ return;
66
+ let clean = true;
67
+ for (const id of listSessionIds(d)) {
68
+ const path = sessionPath(d, id);
69
+ try {
70
+ const s = readJson(path);
71
+ if (!s || typeof s !== 'object' || !withoutPrompts(s))
72
+ continue;
73
+ const { atime, mtime } = statSync(path);
74
+ writeJsonAtomic(path, s);
75
+ utimesSync(path, atime, mtime);
76
+ }
77
+ catch {
78
+ clean = false;
79
+ }
80
+ }
81
+ if (!clean || !existsSync(dir))
82
+ return;
83
+ try {
84
+ writeFileSync(marker, '');
85
+ }
86
+ catch { /* swept again next time */ }
87
+ }
88
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/claude/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { GraphV1 } from '../graph/types.js';
2
+ import type { Stats } from './state.js';
3
+ export declare function readWiring(projectDir: string): GraphV1 | null;
4
+ export declare function computeStats(w: GraphV1): Pick<Stats, 'nodeCount' | 'edgeCount' | 'languages' | 'totalCount' | 'readyCount'>;
5
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/claude/stats.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAI7D;AAED,wBAAgB,YAAY,CAC1B,CAAC,EAAE,OAAO,GACT,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC,CAWpF"}
@@ -0,0 +1,24 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { resolveContextDir } from '../util/state.js';
4
+ export function readWiring(projectDir) {
5
+ try {
6
+ return JSON.parse(readFileSync(join(resolveContextDir(projectDir), '.graph', 'wiring.json'), 'utf8'));
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ export function computeStats(w) {
13
+ const nodes = w.nodes ?? [];
14
+ const edges = w.edges ?? [];
15
+ const readyCount = nodes.filter((n) => n.summary_state === 'ready').length;
16
+ return {
17
+ nodeCount: w.meta?.nodeCount ?? nodes.length,
18
+ edgeCount: w.meta?.edgeCount ?? edges.length,
19
+ languages: w.meta?.languages ?? [],
20
+ totalCount: nodes.length,
21
+ readyCount,
22
+ };
23
+ }
24
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/claude/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;IACnH,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,CAAU;IAEV,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IAC3E,OAAO;QACL,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC,MAAM;QAC5C,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC,MAAM;QAC5C,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE;QAClC,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,UAAU;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface InitEpilogueOptions {
2
+ /** Whether a graft graph exists on disk (built by this run, or a prior one). */
3
+ graphBuilt: boolean;
4
+ /** Node count from the built graph — only meaningful when `graphBuilt`. */
5
+ nodes?: number;
6
+ /** Edge count from the built graph — only meaningful when `graphBuilt`. */
7
+ edges?: number;
8
+ }
9
+ /** Renders the `graft init` next-steps epilogue (no trailing newline — the
10
+ * caller's `console.error` adds the one trailing newline). */
11
+ export declare function formatInitEpilogue(opts: InitEpilogueOptions): string;
12
+ //# sourceMappingURL=cli-epilogue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-epilogue.d.ts","sourceRoot":"","sources":["../src/cli-epilogue.ts"],"names":[],"mappings":"AA2CA,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;8DAC8D;AAC9D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAyCpE"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * `init`'s closing epilogue: the ASCII wordmark (trail's or graft's, by the name it ran as) + numbered next steps,
3
+ * printed to stderr after the per-file ✓/·/⚠ lines. Extracted out of cli.ts
4
+ * so the exact text — spacing is hand-aligned, not incidental — can be
5
+ * unit-tested without spawning the CLI.
6
+ */
7
+ import { brand, cmd } from "./brand.js";
8
+ // The live node/edge stats go on the wordmark's bottom line of letters (index
9
+ // 4 in both), when a graph exists. graft's stays byte for byte: its output is
10
+ // read by scripts.
11
+ const WORDMARKS = {
12
+ trail: [
13
+ " _ _ _",
14
+ " | |_ _ __ __ _(_) |",
15
+ " | __| '__/ _` | | |",
16
+ " | |_| | | (_| | | |",
17
+ " \\__|_| \\__,_|_|_|",
18
+ ],
19
+ graft: [
20
+ " __ _",
21
+ " __ _ _ __ __ _ / _| |_",
22
+ " / _` | '__/ _` | |_| __|",
23
+ " | (_| | | | (_| | _| |_",
24
+ " \\__, |_| \\__,_|_| \\__|",
25
+ " |___/",
26
+ ],
27
+ };
28
+ const STATS_LINE_INDEX = 4;
29
+ // Nanonets indigo, and a muted grey for the secondary stats suffix — only
30
+ // applied when stderr is a real TTY (tests spawn/call this without one, so
31
+ // existing plain-text assertions keep passing).
32
+ const indigo = (s) => `\x1b[38;2;84;111;255m${s}\x1b[0m`;
33
+ const muted = (s) => `\x1b[38;5;244m${s}\x1b[0m`;
34
+ /** Renders the `graft init` next-steps epilogue (no trailing newline — the
35
+ * caller's `console.error` adds the one trailing newline). */
36
+ export function formatInitEpilogue(opts) {
37
+ const { graphBuilt, nodes, edges } = opts;
38
+ const tty = Boolean(process.stderr.isTTY);
39
+ const wordmark = WORDMARKS[brand()].map((l) => (tty ? indigo(l) : l));
40
+ if (graphBuilt && nodes !== undefined && edges !== undefined) {
41
+ const stats = ` ${nodes.toLocaleString("en-US")} nodes · ${edges.toLocaleString("en-US")} edges`;
42
+ wordmark[STATS_LINE_INDEX] += tty ? muted(stats) : stats;
43
+ }
44
+ const steps = [
45
+ ...(graphBuilt ? [] : [{ label: "build the graph", command: cmd("graft build") }]),
46
+ { label: "restart your agent", command: `a new session picks up ${brand()} automatically` },
47
+ {
48
+ label: "code as usual",
49
+ command: "ask your agent to fix a bug or explain a flow:",
50
+ extra: ["it now answers from the graph"],
51
+ },
52
+ {
53
+ label: "explore by hand",
54
+ command: `${cmd("graft ask")} "where is auth handled?" · ${cmd("graft callers")} <fn> · ${cmd("graft viz")}`,
55
+ },
56
+ ];
57
+ const indent = " ";
58
+ const gap = " ";
59
+ const labelWidth = Math.max(...steps.map((s, i) => `${i + 1}. ${s.label}`.length));
60
+ const columnWidth = indent.length + labelWidth + gap.length;
61
+ const stepLines = [];
62
+ steps.forEach((s, i) => {
63
+ const prefix = `${indent}${i + 1}. ${s.label}`;
64
+ stepLines.push(prefix.padEnd(columnWidth) + s.command);
65
+ for (const extra of s.extra ?? []) {
66
+ stepLines.push(" ".repeat(columnWidth) + extra);
67
+ }
68
+ });
69
+ const closing = `${indent}share it: git add AGENTS.md .trail && git commit; teammates run \`${cmd("graft build")}\` for their own local graph`;
70
+ return [...wordmark, "", ...stepLines, "", closing].join("\n");
71
+ }
72
+ //# sourceMappingURL=cli-epilogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-epilogue.js","sourceRoot":"","sources":["../src/cli-epilogue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /** Locates package.json relative to a module URL (works for both `dist/cli.js`
2
+ * running one level under the published package root, and `src/cli.ts` running
3
+ * one level under the repo root via tsx). */
4
+ export declare function resolvePackageJsonPath(moduleUrl: string): string;
5
+ /**
6
+ * The npm package this code was installed as: `@trailhq/trail-code`, or
7
+ * `@nanonets/graft` (the same code under its old name). Upgrades and update
8
+ * checks go to the package actually installed, not to the name typed.
9
+ */
10
+ export declare function readPackageName(moduleUrl: string): string;
11
+ /** Reads the version of the graft package this module was loaded from. */
12
+ export declare function readCurrentVersion(moduleUrl: string): string;
13
+ /** True when the running module lives under an npx cache dir (e.g.
14
+ * `~/.npm/_npx/<hash>/node_modules/...`) rather than a regular global install.
15
+ *
16
+ * Normalized first: `fileURLToPath` returns the *platform* separator, so on
17
+ * Windows the cache path is `…\_npx\…` and a bare `includes("/_npx/")` is always
18
+ * false — `graft upgrade` would then run `npm install -g` on top of an npx run.
19
+ * Same hardcoded-`/` mistake as #33; `src/util/paths.ts` exists for exactly this. */
20
+ export declare function isRunningViaNpx(moduleUrl: string): boolean;
21
+ export interface NpmViewResult {
22
+ ok: boolean;
23
+ version?: string;
24
+ }
25
+ /** `npm view <pkg> version`, offline-safe: any failure (no npm, no network,
26
+ * timeout) resolves to `{ ok: false }` rather than throwing. */
27
+ export declare function getNpmViewVersion(pkgName?: string, timeoutMs?: number): NpmViewResult;
28
+ /** Pure formatter for `graft version` — no I/O, easy to unit-test. */
29
+ export declare function formatVersionReport(current: string, latest: NpmViewResult): string;
30
+ /** Reads the version actually sitting in the global install, straight from
31
+ * disk — more reliable right after `npm install -g` than re-querying the
32
+ * registry (which just tells you what "latest" is, not what landed locally). */
33
+ export declare function readGlobalInstalledVersion(pkgName?: string): string | null;
34
+ export interface UpgradeResult {
35
+ /** True when `npm install -g` actually ran (false for the npx no-op path). */
36
+ ran: boolean;
37
+ ok: boolean;
38
+ /** Present when ran=true and the install failed. */
39
+ errorMessage?: string;
40
+ oldVersion?: string;
41
+ newVersion?: string;
42
+ /** The `trail` package's version, when `graft upgrade` installed it alongside. */
43
+ trailVersion?: string;
44
+ /** A plain fix for a failure we recognise, shown instead of npm's error block. */
45
+ fix?: string;
46
+ /** npm's own error output, for a failure we don't recognise. */
47
+ npmError?: string;
48
+ }
49
+ /** Pure formatter for a finished upgrade — no I/O, easy to unit-test. */
50
+ export declare function formatUpgradeReport(result: UpgradeResult): string;
51
+ /** What npm's error block names: its code, and the path (and rename dest) it failed on. */
52
+ export interface NpmProblem {
53
+ code: string;
54
+ path?: string;
55
+ dest?: string;
56
+ }
57
+ /** Reads npm's `npm error code …` and `npm error path …` lines (`npm ERR!` before npm 10). */
58
+ export declare function parseNpmError(stderr: string): NpmProblem | null;
59
+ /**
60
+ * Removes what an earlier npm run left behind that makes every later `npm i -g`
61
+ * fail, and says what it removed; null when it's nothing trail should touch.
62
+ *
63
+ * - ENOTEMPTY: npm moves the old package aside to `.<name>-<hash of its path>`
64
+ * before writing the new one. An install stopped midway leaves that folder,
65
+ * and as the name comes from the path, every later install collides with it.
66
+ * - EEXIST: a `trail` or `graft` link in npm's bin folder from another copy of
67
+ * trail (a local build installed from a folder, say), which npm won't replace.
68
+ * Only a link into a trail or graft install, or to nothing, is removed.
69
+ */
70
+ export declare function clearNpmLeftover(problem: NpmProblem | null): string | null;
71
+ /**
72
+ * The fix for a global folder only root can write to (Node from nodejs.org or a
73
+ * system package): an npm prefix in the home folder, set once. Not sudo: a sudo
74
+ * install works once, then every upgrade needs it too.
75
+ */
76
+ export declare function noSudoFix(path: string, pkgs: string[], shell?: string, platform?: string): string;
77
+ /** Runs `npm install -g @nanonets/graft@latest`, clearing npm leftovers that
78
+ * block it (`clearNpmLeftover`) and turning EACCES into the no-sudo fix, then
79
+ * re-reads the freshly installed version. No-ops with guidance when running
80
+ * via npx. */
81
+ export declare function runUpgrade(moduleUrl: string): UpgradeResult;
82
+ //# sourceMappingURL=cli-meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-meta.d.ts","sourceRoot":"","sources":["../src/cli-meta.ts"],"names":[],"mappings":"AAcA;;6CAE6C;AAC7C,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOhE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOzD;AAID,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;;;;;qFAMqF;AACrF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;gEACgE;AAChE,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAiB,EAAE,SAAS,SAAO,GAAG,aAAa,CAc7F;AAED,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAUlF;AAeD;;gFAEgF;AAChF,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,MAAiB,GAAG,MAAM,GAAG,IAAI,CAWpF;AAED,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAcjE;AAED,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAI/D;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAW1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,GAAE,MAAgC,EAAE,QAAQ,GAAE,MAAyB,GAAG,MAAM,CAc5I;AAQD;;;cAGc;AACd,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CA6B3D"}
@@ -0,0 +1,238 @@
1
+ /**
2
+ * `graft version` / `graft --version` / `graft upgrade` support.
3
+ *
4
+ * Split out of cli.ts so the formatting helpers can be unit-tested with
5
+ * injected results instead of hitting the network from tests.
6
+ */
7
+ import { WINHIDE } from "./util/child-process.js";
8
+ import { existsSync, readFileSync, readlinkSync, rmSync } from "node:fs";
9
+ import { execFileSync, spawnSync } from "node:child_process";
10
+ import { basename, dirname, join, resolve } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ import { toPosixPath } from "./util/paths.js";
13
+ import { brand, PACKAGE_FOR } from "./brand.js";
14
+ /** Locates package.json relative to a module URL (works for both `dist/cli.js`
15
+ * running one level under the published package root, and `src/cli.ts` running
16
+ * one level under the repo root via tsx). */
17
+ export function resolvePackageJsonPath(moduleUrl) {
18
+ const moduleDir = dirname(fileURLToPath(moduleUrl));
19
+ const candidates = [resolve(moduleDir, "..", "package.json"), resolve(moduleDir, "package.json")];
20
+ for (const c of candidates) {
21
+ if (existsSync(c))
22
+ return c;
23
+ }
24
+ return candidates[0];
25
+ }
26
+ /**
27
+ * The npm package this code was installed as: `@trailhq/trail-code`, or
28
+ * `@nanonets/graft` (the same code under its old name). Upgrades and update
29
+ * checks go to the package actually installed, not to the name typed.
30
+ */
31
+ export function readPackageName(moduleUrl) {
32
+ try {
33
+ const pkg = JSON.parse(readFileSync(resolvePackageJsonPath(moduleUrl), "utf8"));
34
+ return pkg.name ?? PACKAGE_FOR.graft;
35
+ }
36
+ catch {
37
+ return PACKAGE_FOR.graft;
38
+ }
39
+ }
40
+ const PKG_NAME = readPackageName(import.meta.url);
41
+ /** Reads the version of the graft package this module was loaded from. */
42
+ export function readCurrentVersion(moduleUrl) {
43
+ const raw = readFileSync(resolvePackageJsonPath(moduleUrl), "utf8");
44
+ const pkg = JSON.parse(raw);
45
+ return pkg.version ?? "0.0.0";
46
+ }
47
+ /** True when the running module lives under an npx cache dir (e.g.
48
+ * `~/.npm/_npx/<hash>/node_modules/...`) rather than a regular global install.
49
+ *
50
+ * Normalized first: `fileURLToPath` returns the *platform* separator, so on
51
+ * Windows the cache path is `…\_npx\…` and a bare `includes("/_npx/")` is always
52
+ * false — `graft upgrade` would then run `npm install -g` on top of an npx run.
53
+ * Same hardcoded-`/` mistake as #33; `src/util/paths.ts` exists for exactly this. */
54
+ export function isRunningViaNpx(moduleUrl) {
55
+ return toPosixPath(fileURLToPath(moduleUrl)).includes("/_npx/");
56
+ }
57
+ /** `npm view <pkg> version`, offline-safe: any failure (no npm, no network,
58
+ * timeout) resolves to `{ ok: false }` rather than throwing. */
59
+ export function getNpmViewVersion(pkgName = PKG_NAME, timeoutMs = 2000) {
60
+ try {
61
+ const res = spawnSync("npm", ["view", pkgName, "version"], {
62
+ encoding: "utf8",
63
+ timeout: timeoutMs,
64
+ windowsHide: true,
65
+ });
66
+ if (res.error || res.signal || res.status !== 0)
67
+ return { ok: false };
68
+ const version = res.stdout?.trim();
69
+ if (!version)
70
+ return { ok: false };
71
+ return { ok: true, version };
72
+ }
73
+ catch {
74
+ return { ok: false };
75
+ }
76
+ }
77
+ /** Pure formatter for `graft version` — no I/O, easy to unit-test. */
78
+ export function formatVersionReport(current, latest) {
79
+ const lines = [`${brand()} ${current}`];
80
+ if (!latest.ok || !latest.version) {
81
+ lines.push("latest: unreachable (offline?)");
82
+ }
83
+ else if (latest.version === current) {
84
+ lines.push(`latest on npm: ${current} ✓ up to date`);
85
+ }
86
+ else {
87
+ lines.push(`latest on npm: ${latest.version}, run ${brand()} upgrade`);
88
+ }
89
+ return lines.join("\n");
90
+ }
91
+ /** The global npm node_modules dir (handles Homebrew/Windows/volta layouts). */
92
+ function globalRoot() {
93
+ try {
94
+ const root = execFileSync("npm", ["root", "-g"], { ...WINHIDE, encoding: "utf8",
95
+ stdio: ["ignore", "pipe", "ignore"],
96
+ shell: process.platform === "win32",
97
+ }).trim();
98
+ return root || null;
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ }
104
+ /** Reads the version actually sitting in the global install, straight from
105
+ * disk — more reliable right after `npm install -g` than re-querying the
106
+ * registry (which just tells you what "latest" is, not what landed locally). */
107
+ export function readGlobalInstalledVersion(pkgName = PKG_NAME) {
108
+ const root = globalRoot();
109
+ if (!root)
110
+ return null;
111
+ const pkgJson = join(root, ...pkgName.split("/"), "package.json");
112
+ if (!existsSync(pkgJson))
113
+ return null;
114
+ try {
115
+ const pkg = JSON.parse(readFileSync(pkgJson, "utf8"));
116
+ return pkg.version ?? null;
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ /** Pure formatter for a finished upgrade — no I/O, easy to unit-test. */
123
+ export function formatUpgradeReport(result) {
124
+ if (!result.ran) {
125
+ return (`running via npx: npx already fetches the latest ${brand()} on every run.\n` +
126
+ `For a permanent install: npm install -g ${PKG_NAME}`);
127
+ }
128
+ if (!result.ok) {
129
+ if (result.fix)
130
+ return `✗ ${brand()} wasn't upgraded: ${result.fix}`;
131
+ const failed = `✗ npm install -g ${PKG_NAME}@latest failed${result.errorMessage ? `: ${result.errorMessage}` : ""}`;
132
+ return `${result.npmError?.trim() ? `${result.npmError.trim()}\n` : ""}${failed}`;
133
+ }
134
+ const line = `${brand()} ${result.oldVersion ?? "?"} → ${result.newVersion ?? result.oldVersion ?? "?"}`;
135
+ return result.trailVersion ? `${line}\n✓ trail ${result.trailVersion} installed too: graft keeps working, and trail is its new name` : line;
136
+ }
137
+ /** Reads npm's `npm error code …` and `npm error path …` lines (`npm ERR!` before npm 10). */
138
+ export function parseNpmError(stderr) {
139
+ const field = (name) => stderr.match(new RegExp(`^npm (?:error|ERR!) ${name} (.+)$`, "m"))?.[1].trim();
140
+ const code = field("code");
141
+ return code ? { code, path: field("path"), dest: field("dest") } : null;
142
+ }
143
+ /** A link in npm's bin folder that points into a trail or graft install, or at nothing. */
144
+ function isTrailLink(path) {
145
+ let target;
146
+ try {
147
+ target = resolve(dirname(path), readlinkSync(path));
148
+ }
149
+ catch {
150
+ return false; // not a link: someone else's file
151
+ }
152
+ return !existsSync(target) || /[\\/](@trailhq[\\/]trail-code|@nanonets[\\/]graft)[\\/]|[\\/]dist[\\/]bin[\\/](trail|graft)\.js$/.test(target);
153
+ }
154
+ /**
155
+ * Removes what an earlier npm run left behind that makes every later `npm i -g`
156
+ * fail, and says what it removed; null when it's nothing trail should touch.
157
+ *
158
+ * - ENOTEMPTY: npm moves the old package aside to `.<name>-<hash of its path>`
159
+ * before writing the new one. An install stopped midway leaves that folder,
160
+ * and as the name comes from the path, every later install collides with it.
161
+ * - EEXIST: a `trail` or `graft` link in npm's bin folder from another copy of
162
+ * trail (a local build installed from a folder, say), which npm won't replace.
163
+ * Only a link into a trail or graft install, or to nothing, is removed.
164
+ */
165
+ export function clearNpmLeftover(problem) {
166
+ if (problem?.code === "ENOTEMPTY" && problem.path && problem.dest) {
167
+ if (dirname(problem.dest) !== dirname(problem.path) || !basename(problem.dest).startsWith("."))
168
+ return null;
169
+ rmSync(problem.dest, { recursive: true, force: true });
170
+ return `removed ${problem.dest}, left by an npm install that was stopped midway`;
171
+ }
172
+ if (problem?.code === "EEXIST" && problem.path && isTrailLink(problem.path)) {
173
+ rmSync(problem.path, { force: true });
174
+ return `removed ${problem.path}, a link to another copy of trail`;
175
+ }
176
+ return null;
177
+ }
178
+ /**
179
+ * The fix for a global folder only root can write to (Node from nodejs.org or a
180
+ * system package): an npm prefix in the home folder, set once. Not sudo: a sudo
181
+ * install works once, then every upgrade needs it too.
182
+ */
183
+ export function noSudoFix(path, pkgs, shell = process.env.SHELL ?? "", platform = process.platform) {
184
+ const addToPath = shell.endsWith("fish")
185
+ ? "fish_add_path ~/.npm-global/bin"
186
+ : `echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ${shell.endsWith("zsh") ? "~/.zshrc" : platform === "darwin" ? "~/.bash_profile" : "~/.bashrc"}`;
187
+ return [
188
+ `npm needs sudo to write to ${path}.`,
189
+ " Skip sudo: point npm at a folder in your home, once, and installs never need it again:",
190
+ "",
191
+ " mkdir -p ~/.npm-global",
192
+ " npm config set prefix ~/.npm-global",
193
+ ` ${addToPath}`,
194
+ "",
195
+ ` Then open a new terminal and run: npm i -g ${pkgs.join(" ")}`,
196
+ ].join("\n");
197
+ }
198
+ /** `npm <args>` with npm's stderr kept, to read its error code; stdout still shows. */
199
+ function npmRun(args) {
200
+ const res = spawnSync("npm", args, { stdio: ["inherit", "inherit", "pipe"], encoding: "utf8" });
201
+ return { ok: !res.error && res.status === 0, stderr: res.stderr ?? "", error: res.error?.message };
202
+ }
203
+ /** Runs `npm install -g @nanonets/graft@latest`, clearing npm leftovers that
204
+ * block it (`clearNpmLeftover`) and turning EACCES into the no-sudo fix, then
205
+ * re-reads the freshly installed version. No-ops with guidance when running
206
+ * via npx. */
207
+ export function runUpgrade(moduleUrl) {
208
+ const oldVersion = readCurrentVersion(moduleUrl);
209
+ if (isRunningViaNpx(moduleUrl)) {
210
+ return { ran: false, ok: true, oldVersion };
211
+ }
212
+ // `graft upgrade` is the handover: it also installs the `trail` command, once
213
+ // that package is published. One npm call, so the two land at one version.
214
+ const alongside = PKG_NAME === PACKAGE_FOR.graft && getNpmViewVersion(PACKAGE_FOR.trail).ok ? [PACKAGE_FOR.trail] : [];
215
+ const pkgs = [PKG_NAME, ...alongside];
216
+ const args = ["install", "-g", ...pkgs.map((p) => `${p}@latest`)];
217
+ console.error(`· npm ${args.join(" ")}`);
218
+ let res = npmRun(args);
219
+ // Two leftovers at most (graft upgrade installs two packages), then npm's own error stands.
220
+ for (let retries = 0; !res.ok && retries < 2; retries++) {
221
+ const cleared = clearNpmLeftover(parseNpmError(res.stderr));
222
+ if (!cleared)
223
+ break;
224
+ console.error(`· ${cleared}; trying again`);
225
+ res = npmRun(args);
226
+ }
227
+ if (!res.ok) {
228
+ const problem = parseNpmError(res.stderr);
229
+ if (problem?.code === "EACCES" && process.platform !== "win32") {
230
+ return { ran: true, ok: false, oldVersion, fix: noSudoFix(problem.path ?? "npm's global folder", pkgs) };
231
+ }
232
+ return { ran: true, ok: false, oldVersion, npmError: res.stderr, errorMessage: res.error };
233
+ }
234
+ const newVersion = readGlobalInstalledVersion(PKG_NAME) ?? getNpmViewVersion(PKG_NAME).version ?? oldVersion;
235
+ const trailVersion = alongside.length ? (readGlobalInstalledVersion(PACKAGE_FOR.trail) ?? undefined) : undefined;
236
+ return { ran: true, ok: true, oldVersion, newVersion, trailVersion };
237
+ }
238
+ //# sourceMappingURL=cli-meta.js.map