@nanonets/graft 0.24.1 → 0.25.0

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 (480) hide show
  1. package/README.md +26 -21
  2. package/dist/blast/render.js +1 -1
  3. package/dist/blast/render.js.map +1 -1
  4. package/dist/brand.js +1 -1
  5. package/dist/brand.js.map +1 -1
  6. package/dist/check/learning-edits.d.ts +18 -3
  7. package/dist/check/learning-edits.d.ts.map +1 -1
  8. package/dist/check/learning-edits.js +54 -10
  9. package/dist/check/learning-edits.js.map +1 -1
  10. package/dist/check/local-check.d.ts +7 -3
  11. package/dist/check/local-check.d.ts.map +1 -1
  12. package/dist/check/local-check.js +55 -11
  13. package/dist/check/local-check.js.map +1 -1
  14. package/dist/check/types.d.ts +11 -2
  15. package/dist/check/types.d.ts.map +1 -1
  16. package/dist/claude/format.d.ts +11 -7
  17. package/dist/claude/format.d.ts.map +1 -1
  18. package/dist/claude/format.js +50 -28
  19. package/dist/claude/format.js.map +1 -1
  20. package/dist/claude/hook-io.js +1 -1
  21. package/dist/claude/hook-io.js.map +1 -1
  22. package/dist/claude/hook-layers.d.ts +4 -2
  23. package/dist/claude/hook-layers.d.ts.map +1 -1
  24. package/dist/claude/hook-layers.js +21 -4
  25. package/dist/claude/hook-layers.js.map +1 -1
  26. package/dist/claude/hooks.d.ts +9 -32
  27. package/dist/claude/hooks.d.ts.map +1 -1
  28. package/dist/claude/hooks.js +154 -350
  29. package/dist/claude/hooks.js.map +1 -1
  30. package/dist/claude/init.d.ts.map +1 -1
  31. package/dist/claude/init.js +56 -18
  32. package/dist/claude/init.js.map +1 -1
  33. package/dist/claude/note-signals.d.ts +6 -0
  34. package/dist/claude/note-signals.d.ts.map +1 -1
  35. package/dist/claude/note-signals.js +14 -3
  36. package/dist/claude/note-signals.js.map +1 -1
  37. package/dist/claude/post-bash.d.ts +26 -0
  38. package/dist/claude/post-bash.d.ts.map +1 -0
  39. package/dist/claude/post-bash.js +191 -0
  40. package/dist/claude/post-bash.js.map +1 -0
  41. package/dist/claude/pre-bash-skills.d.ts +21 -0
  42. package/dist/claude/pre-bash-skills.d.ts.map +1 -0
  43. package/dist/claude/pre-bash-skills.js +253 -0
  44. package/dist/claude/pre-bash-skills.js.map +1 -0
  45. package/dist/claude/pre-bash.d.ts +50 -0
  46. package/dist/claude/pre-bash.d.ts.map +1 -0
  47. package/dist/claude/pre-bash.js +245 -0
  48. package/dist/claude/pre-bash.js.map +1 -0
  49. package/dist/claude/prompt-consent.d.ts +19 -0
  50. package/dist/claude/prompt-consent.d.ts.map +1 -0
  51. package/dist/claude/prompt-consent.js +14 -0
  52. package/dist/claude/prompt-consent.js.map +1 -0
  53. package/dist/claude/prompt-hook.d.ts +76 -0
  54. package/dist/claude/prompt-hook.d.ts.map +1 -0
  55. package/dist/claude/prompt-hook.js +303 -0
  56. package/dist/claude/prompt-hook.js.map +1 -0
  57. package/dist/claude/prompt-skills.d.ts +19 -0
  58. package/dist/claude/prompt-skills.d.ts.map +1 -0
  59. package/dist/claude/prompt-skills.js +305 -0
  60. package/dist/claude/prompt-skills.js.map +1 -0
  61. package/dist/claude/session-metrics.js +4 -4
  62. package/dist/claude/session-metrics.js.map +1 -1
  63. package/dist/claude/settings-merge.d.ts +10 -0
  64. package/dist/claude/settings-merge.d.ts.map +1 -1
  65. package/dist/claude/settings-merge.js +46 -17
  66. package/dist/claude/settings-merge.js.map +1 -1
  67. package/dist/claude/shim-template.d.ts.map +1 -1
  68. package/dist/claude/shim-template.js +86 -28
  69. package/dist/claude/shim-template.js.map +1 -1
  70. package/dist/claude/skill-template.d.ts +2 -0
  71. package/dist/claude/skill-template.d.ts.map +1 -1
  72. package/dist/claude/skill-template.js +53 -34
  73. package/dist/claude/skill-template.js.map +1 -1
  74. package/dist/claude/skill-use.d.ts +16 -0
  75. package/dist/claude/skill-use.d.ts.map +1 -0
  76. package/dist/claude/skill-use.js +78 -0
  77. package/dist/claude/skill-use.js.map +1 -0
  78. package/dist/claude/skills-wiring.d.ts +26 -0
  79. package/dist/claude/skills-wiring.d.ts.map +1 -0
  80. package/dist/claude/skills-wiring.js +110 -0
  81. package/dist/claude/skills-wiring.js.map +1 -0
  82. package/dist/claude/start-init.d.ts +13 -0
  83. package/dist/claude/start-init.d.ts.map +1 -0
  84. package/dist/claude/start-init.js +75 -0
  85. package/dist/claude/start-init.js.map +1 -0
  86. package/dist/claude/start-skills.d.ts +31 -0
  87. package/dist/claude/start-skills.d.ts.map +1 -0
  88. package/dist/claude/start-skills.js +274 -0
  89. package/dist/claude/start-skills.js.map +1 -0
  90. package/dist/claude/state.d.ts +19 -7
  91. package/dist/claude/state.d.ts.map +1 -1
  92. package/dist/claude/state.js +59 -4
  93. package/dist/claude/state.js.map +1 -1
  94. package/dist/claude/stop-skills.d.ts +23 -0
  95. package/dist/claude/stop-skills.d.ts.map +1 -0
  96. package/dist/claude/stop-skills.js +233 -0
  97. package/dist/claude/stop-skills.js.map +1 -0
  98. package/dist/claude/stop.d.ts +23 -0
  99. package/dist/claude/stop.d.ts.map +1 -0
  100. package/dist/claude/stop.js +219 -0
  101. package/dist/claude/stop.js.map +1 -0
  102. package/dist/claude/tally.d.ts +29 -41
  103. package/dist/claude/tally.d.ts.map +1 -1
  104. package/dist/claude/tally.js +111 -165
  105. package/dist/claude/tally.js.map +1 -1
  106. package/dist/claude/walls-hook.d.ts +52 -0
  107. package/dist/claude/walls-hook.d.ts.map +1 -0
  108. package/dist/claude/walls-hook.js +279 -0
  109. package/dist/claude/walls-hook.js.map +1 -0
  110. package/dist/cli-epilogue.d.ts.map +1 -1
  111. package/dist/cli-epilogue.js +24 -14
  112. package/dist/cli-epilogue.js.map +1 -1
  113. package/dist/cli-meta.js +3 -3
  114. package/dist/cli-meta.js.map +1 -1
  115. package/dist/cli-picker.d.ts.map +1 -1
  116. package/dist/cli-picker.js +8 -6
  117. package/dist/cli-picker.js.map +1 -1
  118. package/dist/cli.d.ts.map +1 -1
  119. package/dist/cli.js +238 -402
  120. package/dist/cli.js.map +1 -1
  121. package/dist/cloud/head-learnings.d.ts +13 -0
  122. package/dist/cloud/head-learnings.d.ts.map +1 -0
  123. package/dist/cloud/head-learnings.js +84 -0
  124. package/dist/cloud/head-learnings.js.map +1 -0
  125. package/dist/cloud/lookup-activity.d.ts +5 -3
  126. package/dist/cloud/lookup-activity.d.ts.map +1 -1
  127. package/dist/cloud/lookup-activity.js +8 -8
  128. package/dist/cloud/lookup-activity.js.map +1 -1
  129. package/dist/cloud/nudge.d.ts +15 -7
  130. package/dist/cloud/nudge.d.ts.map +1 -1
  131. package/dist/cloud/nudge.js +42 -33
  132. package/dist/cloud/nudge.js.map +1 -1
  133. package/dist/cloud/onboarding.d.ts +37 -1
  134. package/dist/cloud/onboarding.d.ts.map +1 -1
  135. package/dist/cloud/onboarding.js +77 -1
  136. package/dist/cloud/onboarding.js.map +1 -1
  137. package/dist/cloud/other-repos.d.ts +39 -0
  138. package/dist/cloud/other-repos.d.ts.map +1 -0
  139. package/dist/cloud/other-repos.js +137 -0
  140. package/dist/cloud/other-repos.js.map +1 -0
  141. package/dist/cloud/pair.d.ts +17 -7
  142. package/dist/cloud/pair.d.ts.map +1 -1
  143. package/dist/cloud/pair.js +81 -60
  144. package/dist/cloud/pair.js.map +1 -1
  145. package/dist/cloud/workspace-sync.d.ts +67 -11
  146. package/dist/cloud/workspace-sync.d.ts.map +1 -1
  147. package/dist/cloud/workspace-sync.js +299 -55
  148. package/dist/cloud/workspace-sync.js.map +1 -1
  149. package/dist/cloud/workspace.d.ts +74 -10
  150. package/dist/cloud/workspace.d.ts.map +1 -1
  151. package/dist/cloud/workspace.js +96 -8
  152. package/dist/cloud/workspace.js.map +1 -1
  153. package/dist/hosts/claude-global.js +1 -1
  154. package/dist/hosts/claude-global.js.map +1 -1
  155. package/dist/hosts/codex-hooks.d.ts +6 -0
  156. package/dist/hosts/codex-hooks.d.ts.map +1 -1
  157. package/dist/hosts/codex-hooks.js +89 -16
  158. package/dist/hosts/codex-hooks.js.map +1 -1
  159. package/dist/hosts/codex-trust.d.ts +28 -0
  160. package/dist/hosts/codex-trust.d.ts.map +1 -0
  161. package/dist/hosts/codex-trust.js +280 -0
  162. package/dist/hosts/codex-trust.js.map +1 -0
  163. package/dist/hosts/cursor-hooks.d.ts.map +1 -1
  164. package/dist/hosts/cursor-hooks.js +3 -1
  165. package/dist/hosts/cursor-hooks.js.map +1 -1
  166. package/dist/init/candidates.d.ts +60 -0
  167. package/dist/init/candidates.d.ts.map +1 -0
  168. package/dist/init/candidates.js +202 -0
  169. package/dist/init/candidates.js.map +1 -0
  170. package/dist/init/claude-call.d.ts +51 -0
  171. package/dist/init/claude-call.d.ts.map +1 -0
  172. package/dist/init/claude-call.js +199 -0
  173. package/dist/init/claude-call.js.map +1 -0
  174. package/dist/init/discover-worker.d.ts +18 -0
  175. package/dist/init/discover-worker.d.ts.map +1 -0
  176. package/dist/init/discover-worker.js +111 -0
  177. package/dist/init/discover-worker.js.map +1 -0
  178. package/dist/init/handover.d.ts +16 -0
  179. package/dist/init/handover.d.ts.map +1 -0
  180. package/dist/init/handover.js +92 -0
  181. package/dist/init/handover.js.map +1 -0
  182. package/dist/init/howtos.d.ts +20 -0
  183. package/dist/init/howtos.d.ts.map +1 -0
  184. package/dist/init/howtos.js +90 -0
  185. package/dist/init/howtos.js.map +1 -0
  186. package/dist/init/init-record.d.ts +134 -0
  187. package/dist/init/init-record.d.ts.map +1 -0
  188. package/dist/init/init-record.js +339 -0
  189. package/dist/init/init-record.js.map +1 -0
  190. package/dist/init/install-paths.d.ts +6 -0
  191. package/dist/init/install-paths.d.ts.map +1 -0
  192. package/dist/init/install-paths.js +87 -0
  193. package/dist/init/install-paths.js.map +1 -0
  194. package/dist/init/keep-answer.d.ts +43 -0
  195. package/dist/init/keep-answer.d.ts.map +1 -0
  196. package/dist/init/keep-answer.js +118 -0
  197. package/dist/init/keep-answer.js.map +1 -0
  198. package/dist/init/keep-gate.d.ts +30 -0
  199. package/dist/init/keep-gate.d.ts.map +1 -0
  200. package/dist/init/keep-gate.js +178 -0
  201. package/dist/init/keep-gate.js.map +1 -0
  202. package/dist/init/keep-list.d.ts +67 -0
  203. package/dist/init/keep-list.d.ts.map +1 -0
  204. package/dist/init/keep-list.js +232 -0
  205. package/dist/init/keep-list.js.map +1 -0
  206. package/dist/init/keep.d.ts +52 -0
  207. package/dist/init/keep.d.ts.map +1 -0
  208. package/dist/init/keep.js +393 -0
  209. package/dist/init/keep.js.map +1 -0
  210. package/dist/init/look-back-mine.d.ts +37 -0
  211. package/dist/init/look-back-mine.d.ts.map +1 -0
  212. package/dist/init/look-back-mine.js +215 -0
  213. package/dist/init/look-back-mine.js.map +1 -0
  214. package/dist/init/look-back.d.ts +81 -0
  215. package/dist/init/look-back.d.ts.map +1 -0
  216. package/dist/init/look-back.js +170 -0
  217. package/dist/init/look-back.js.map +1 -0
  218. package/dist/init/miners.d.ts +46 -0
  219. package/dist/init/miners.d.ts.map +1 -0
  220. package/dist/init/miners.js +141 -0
  221. package/dist/init/miners.js.map +1 -0
  222. package/dist/init/name-call.d.ts +37 -0
  223. package/dist/init/name-call.d.ts.map +1 -0
  224. package/dist/init/name-call.js +151 -0
  225. package/dist/init/name-call.js.map +1 -0
  226. package/dist/init/plain-file.d.ts.map +1 -1
  227. package/dist/init/plain-file.js +3 -0
  228. package/dist/init/plain-file.js.map +1 -1
  229. package/dist/init/prefs.d.ts +70 -0
  230. package/dist/init/prefs.d.ts.map +1 -0
  231. package/dist/init/prefs.js +282 -0
  232. package/dist/init/prefs.js.map +1 -0
  233. package/dist/init/relay.d.ts +15 -0
  234. package/dist/init/relay.d.ts.map +1 -0
  235. package/dist/init/relay.js +15 -0
  236. package/dist/init/relay.js.map +1 -0
  237. package/dist/init/replay-runs.d.ts +121 -0
  238. package/dist/init/replay-runs.d.ts.map +1 -0
  239. package/dist/init/replay-runs.js +457 -0
  240. package/dist/init/replay-runs.js.map +1 -0
  241. package/dist/init/replay-tamper.d.ts +18 -0
  242. package/dist/init/replay-tamper.d.ts.map +1 -0
  243. package/dist/init/replay-tamper.js +87 -0
  244. package/dist/init/replay-tamper.js.map +1 -0
  245. package/dist/init/review-screen.d.ts +74 -0
  246. package/dist/init/review-screen.d.ts.map +1 -0
  247. package/dist/init/review-screen.js +258 -0
  248. package/dist/init/review-screen.js.map +1 -0
  249. package/dist/init/review-tty.d.ts +29 -0
  250. package/dist/init/review-tty.d.ts.map +1 -0
  251. package/dist/init/review-tty.js +218 -0
  252. package/dist/init/review-tty.js.map +1 -0
  253. package/dist/init/review.d.ts +12 -0
  254. package/dist/init/review.d.ts.map +1 -0
  255. package/dist/init/review.js +12 -0
  256. package/dist/init/review.js.map +1 -0
  257. package/dist/init/run.d.ts +87 -0
  258. package/dist/init/run.d.ts.map +1 -0
  259. package/dist/init/run.js +347 -0
  260. package/dist/init/run.js.map +1 -0
  261. package/dist/init/sessions.d.ts +63 -0
  262. package/dist/init/sessions.d.ts.map +1 -0
  263. package/dist/init/sessions.js +377 -0
  264. package/dist/init/sessions.js.map +1 -0
  265. package/dist/init/transcript.d.ts +81 -0
  266. package/dist/init/transcript.d.ts.map +1 -0
  267. package/dist/init/transcript.js +216 -0
  268. package/dist/init/transcript.js.map +1 -0
  269. package/dist/init/types.d.ts +139 -0
  270. package/dist/init/types.d.ts.map +1 -0
  271. package/dist/init/types.js +2 -0
  272. package/dist/init/types.js.map +1 -0
  273. package/dist/notes/cold-start.d.ts +5 -213
  274. package/dist/notes/cold-start.d.ts.map +1 -1
  275. package/dist/notes/cold-start.js +5 -654
  276. package/dist/notes/cold-start.js.map +1 -1
  277. package/dist/notes/edit-overlap.d.ts.map +1 -1
  278. package/dist/notes/edit-overlap.js +4 -1
  279. package/dist/notes/edit-overlap.js.map +1 -1
  280. package/dist/notes/notes.d.ts +8 -4
  281. package/dist/notes/notes.d.ts.map +1 -1
  282. package/dist/notes/notes.js +9 -7
  283. package/dist/notes/notes.js.map +1 -1
  284. package/dist/notes/pr-reviews.d.ts +4 -0
  285. package/dist/notes/pr-reviews.d.ts.map +1 -1
  286. package/dist/notes/pr-reviews.js +6 -5
  287. package/dist/notes/pr-reviews.js.map +1 -1
  288. package/dist/notes/repo-trail.d.ts +1 -1
  289. package/dist/notes/repo-trail.d.ts.map +1 -1
  290. package/dist/notes/repo-trail.js +24 -4
  291. package/dist/notes/repo-trail.js.map +1 -1
  292. package/dist/search/grep.d.ts.map +1 -1
  293. package/dist/search/grep.js +4 -2
  294. package/dist/search/grep.js.map +1 -1
  295. package/dist/search/user-regexp.d.ts +26 -0
  296. package/dist/search/user-regexp.d.ts.map +1 -0
  297. package/dist/search/user-regexp.js +150 -0
  298. package/dist/search/user-regexp.js.map +1 -0
  299. package/dist/skills/anchors-cli.d.ts +5 -0
  300. package/dist/skills/anchors-cli.d.ts.map +1 -1
  301. package/dist/skills/anchors-cli.js +7 -2
  302. package/dist/skills/anchors-cli.js.map +1 -1
  303. package/dist/skills/anchors-wide.js +2 -2
  304. package/dist/skills/anchors-wide.js.map +1 -1
  305. package/dist/skills/cli-skills-1b.d.ts +17 -0
  306. package/dist/skills/cli-skills-1b.d.ts.map +1 -0
  307. package/dist/skills/cli-skills-1b.js +166 -0
  308. package/dist/skills/cli-skills-1b.js.map +1 -0
  309. package/dist/skills/cli-skills-2.d.ts +35 -0
  310. package/dist/skills/cli-skills-2.d.ts.map +1 -0
  311. package/dist/skills/cli-skills-2.js +129 -0
  312. package/dist/skills/cli-skills-2.js.map +1 -0
  313. package/dist/skills/cli-skills-report-1b.d.ts +49 -0
  314. package/dist/skills/cli-skills-report-1b.d.ts.map +1 -0
  315. package/dist/skills/cli-skills-report-1b.js +191 -0
  316. package/dist/skills/cli-skills-report-1b.js.map +1 -0
  317. package/dist/skills/cli-skills-report.d.ts +86 -0
  318. package/dist/skills/cli-skills-report.d.ts.map +1 -0
  319. package/dist/skills/cli-skills-report.js +121 -0
  320. package/dist/skills/cli-skills-report.js.map +1 -0
  321. package/dist/skills/cli-skills.d.ts +30 -0
  322. package/dist/skills/cli-skills.d.ts.map +1 -0
  323. package/dist/skills/cli-skills.js +379 -0
  324. package/dist/skills/cli-skills.js.map +1 -0
  325. package/dist/skills/compile-split.d.ts.map +1 -1
  326. package/dist/skills/compile-split.js +18 -0
  327. package/dist/skills/compile-split.js.map +1 -1
  328. package/dist/skills/compile-words.d.ts +4 -1
  329. package/dist/skills/compile-words.d.ts.map +1 -1
  330. package/dist/skills/compile-words.js +68 -8
  331. package/dist/skills/compile-words.js.map +1 -1
  332. package/dist/skills/compile.d.ts +7 -0
  333. package/dist/skills/compile.d.ts.map +1 -1
  334. package/dist/skills/compile.js +17 -0
  335. package/dist/skills/compile.js.map +1 -1
  336. package/dist/skills/credit.d.ts +86 -0
  337. package/dist/skills/credit.d.ts.map +1 -0
  338. package/dist/skills/credit.js +259 -0
  339. package/dist/skills/credit.js.map +1 -0
  340. package/dist/skills/fold-gated.d.ts +3 -0
  341. package/dist/skills/fold-gated.d.ts.map +1 -0
  342. package/dist/skills/fold-gated.js +78 -0
  343. package/dist/skills/fold-gated.js.map +1 -0
  344. package/dist/skills/fold.d.ts +87 -0
  345. package/dist/skills/fold.d.ts.map +1 -0
  346. package/dist/skills/fold.js +348 -0
  347. package/dist/skills/fold.js.map +1 -0
  348. package/dist/skills/follow-learnings.d.ts +128 -0
  349. package/dist/skills/follow-learnings.d.ts.map +1 -0
  350. package/dist/skills/follow-learnings.js +278 -0
  351. package/dist/skills/follow-learnings.js.map +1 -0
  352. package/dist/skills/learning-steps.d.ts +43 -0
  353. package/dist/skills/learning-steps.d.ts.map +1 -0
  354. package/dist/skills/learning-steps.js +294 -0
  355. package/dist/skills/learning-steps.js.map +1 -0
  356. package/dist/skills/lesson-gate.d.ts +25 -0
  357. package/dist/skills/lesson-gate.d.ts.map +1 -0
  358. package/dist/skills/lesson-gate.js +316 -0
  359. package/dist/skills/lesson-gate.js.map +1 -0
  360. package/dist/skills/offer-drift.d.ts +35 -0
  361. package/dist/skills/offer-drift.d.ts.map +1 -0
  362. package/dist/skills/offer-drift.js +98 -0
  363. package/dist/skills/offer-drift.js.map +1 -0
  364. package/dist/skills/offer-lesson.d.ts +31 -0
  365. package/dist/skills/offer-lesson.d.ts.map +1 -0
  366. package/dist/skills/offer-lesson.js +123 -0
  367. package/dist/skills/offer-lesson.js.map +1 -0
  368. package/dist/skills/offer-lines.d.ts +40 -0
  369. package/dist/skills/offer-lines.d.ts.map +1 -0
  370. package/dist/skills/offer-lines.js +80 -0
  371. package/dist/skills/offer-lines.js.map +1 -0
  372. package/dist/skills/offer-moment.d.ts +102 -0
  373. package/dist/skills/offer-moment.d.ts.map +1 -0
  374. package/dist/skills/offer-moment.js +260 -0
  375. package/dist/skills/offer-moment.js.map +1 -0
  376. package/dist/skills/offer-repair.d.ts +36 -0
  377. package/dist/skills/offer-repair.d.ts.map +1 -0
  378. package/dist/skills/offer-repair.js +212 -0
  379. package/dist/skills/offer-repair.js.map +1 -0
  380. package/dist/skills/offer-retire.d.ts +53 -0
  381. package/dist/skills/offer-retire.d.ts.map +1 -0
  382. package/dist/skills/offer-retire.js +149 -0
  383. package/dist/skills/offer-retire.js.map +1 -0
  384. package/dist/skills/offer-update.d.ts +54 -0
  385. package/dist/skills/offer-update.d.ts.map +1 -0
  386. package/dist/skills/offer-update.js +115 -0
  387. package/dist/skills/offer-update.js.map +1 -0
  388. package/dist/skills/offer-words-1b.d.ts +32 -0
  389. package/dist/skills/offer-words-1b.d.ts.map +1 -0
  390. package/dist/skills/offer-words-1b.js +80 -0
  391. package/dist/skills/offer-words-1b.js.map +1 -0
  392. package/dist/skills/offer-words-2.d.ts +123 -0
  393. package/dist/skills/offer-words-2.d.ts.map +1 -0
  394. package/dist/skills/offer-words-2.js +194 -0
  395. package/dist/skills/offer-words-2.js.map +1 -0
  396. package/dist/skills/offer-words.d.ts +65 -0
  397. package/dist/skills/offer-words.d.ts.map +1 -0
  398. package/dist/skills/offer-words.js +205 -0
  399. package/dist/skills/offer-words.js.map +1 -0
  400. package/dist/skills/offers.d.ts +66 -0
  401. package/dist/skills/offers.d.ts.map +1 -0
  402. package/dist/skills/offers.js +284 -0
  403. package/dist/skills/offers.js.map +1 -0
  404. package/dist/skills/runblock.d.ts +2 -0
  405. package/dist/skills/runblock.d.ts.map +1 -1
  406. package/dist/skills/runblock.js +11 -6
  407. package/dist/skills/runblock.js.map +1 -1
  408. package/dist/skills/save-gate.d.ts +64 -0
  409. package/dist/skills/save-gate.d.ts.map +1 -0
  410. package/dist/skills/save-gate.js +354 -0
  411. package/dist/skills/save-gate.js.map +1 -0
  412. package/dist/skills/save-verify.d.ts +59 -0
  413. package/dist/skills/save-verify.d.ts.map +1 -0
  414. package/dist/skills/save-verify.js +390 -0
  415. package/dist/skills/save-verify.js.map +1 -0
  416. package/dist/skills/settings.d.ts +12 -2
  417. package/dist/skills/settings.d.ts.map +1 -1
  418. package/dist/skills/settings.js +24 -2
  419. package/dist/skills/settings.js.map +1 -1
  420. package/dist/skills/skills.d.ts +26 -8
  421. package/dist/skills/skills.d.ts.map +1 -1
  422. package/dist/skills/skills.js +105 -52
  423. package/dist/skills/skills.js.map +1 -1
  424. package/dist/skills/types.d.ts +8 -0
  425. package/dist/skills/types.d.ts.map +1 -1
  426. package/dist/skills/update-gate.d.ts +36 -0
  427. package/dist/skills/update-gate.d.ts.map +1 -0
  428. package/dist/skills/update-gate.js +357 -0
  429. package/dist/skills/update-gate.js.map +1 -0
  430. package/dist/skills/update-plan.d.ts +40 -0
  431. package/dist/skills/update-plan.d.ts.map +1 -0
  432. package/dist/skills/update-plan.js +196 -0
  433. package/dist/skills/update-plan.js.map +1 -0
  434. package/dist/skills/value-line.d.ts +94 -0
  435. package/dist/skills/value-line.d.ts.map +1 -0
  436. package/dist/skills/value-line.js +355 -0
  437. package/dist/skills/value-line.js.map +1 -0
  438. package/dist/telemetry/contract.d.ts +15 -1
  439. package/dist/telemetry/contract.d.ts.map +1 -1
  440. package/dist/telemetry/contract.js +80 -11
  441. package/dist/telemetry/contract.js.map +1 -1
  442. package/dist/telemetry/gate.js +4 -4
  443. package/dist/telemetry/gate.js.map +1 -1
  444. package/dist/telemetry/index.d.ts +1 -1
  445. package/dist/telemetry/index.d.ts.map +1 -1
  446. package/dist/telemetry/index.js +1 -1
  447. package/dist/telemetry/index.js.map +1 -1
  448. package/dist/telemetry/notice.js +5 -5
  449. package/dist/telemetry/notice.js.map +1 -1
  450. package/dist/telemetry/queue.d.ts.map +1 -1
  451. package/dist/telemetry/queue.js +7 -7
  452. package/dist/telemetry/queue.js.map +1 -1
  453. package/dist/telemetry/track.d.ts.map +1 -1
  454. package/dist/telemetry/track.js +4 -3
  455. package/dist/telemetry/track.js.map +1 -1
  456. package/dist/trace/checks.d.ts.map +1 -1
  457. package/dist/trace/checks.js +10 -2
  458. package/dist/trace/checks.js.map +1 -1
  459. package/dist/trace/gate-file.d.ts +1 -1
  460. package/dist/trace/gate-file.d.ts.map +1 -1
  461. package/dist/trace/gate-file.js +3 -3
  462. package/dist/trace/gate-file.js.map +1 -1
  463. package/dist/upkeep-run.d.ts.map +1 -1
  464. package/dist/upkeep-run.js +2 -23
  465. package/dist/upkeep-run.js.map +1 -1
  466. package/dist/upkeep.d.ts.map +1 -1
  467. package/dist/upkeep.js +2 -3
  468. package/dist/upkeep.js.map +1 -1
  469. package/dist/util/private-fs.d.ts +6 -0
  470. package/dist/util/private-fs.d.ts.map +1 -1
  471. package/dist/util/private-fs.js +9 -1
  472. package/dist/util/private-fs.js.map +1 -1
  473. package/dist/util/state.d.ts.map +1 -1
  474. package/dist/util/state.js +17 -3
  475. package/dist/util/state.js.map +1 -1
  476. package/package.json +1 -1
  477. package/dist/skills/found-skill.d.ts +0 -35
  478. package/dist/skills/found-skill.d.ts.map +0 -1
  479. package/dist/skills/found-skill.js +0 -66
  480. package/dist/skills/found-skill.js.map +0 -1
@@ -0,0 +1,87 @@
1
+ /**
2
+ * D120 (2): the repo paths a `trail init` run may write in each checkout (every
3
+ * host's repo files, so a retracted one counts too, `.trail/README.md`, the
4
+ * `.gitignore` and `.ignore` lines the graph build adds and `.trail/.gitignore`,
5
+ * and what it removes: the graft-named copies in a repo moving from graft, and
6
+ * the layout before 0.23, the shims under `.claude/helpers/` and the skill in
7
+ * `.claude/skills/`, which claude/init.ts clears away), looked at before it
8
+ * writes and recorded after (install-record.ts). Kept out of the hook's import
9
+ * closure.
10
+ */
11
+ import { lstatSync, readdirSync } from 'node:fs';
12
+ import { join, relative, sep } from 'node:path';
13
+ import { claudeTargetsFor, legacyClaudeTargets } from '../claude/init.js';
14
+ import { planInit } from '../hosts/plan.js';
15
+ import { cursorHookShimRelPath, HOSTS } from '../hosts/registry.js';
16
+ import { repoPlace } from '../notes/home.js';
17
+ import { recordInstall, snapInstall } from './install-record.js';
18
+ const SHIMS = ['graft', 'trail'].flatMap((b) => ['hooks', 'statusline'].map((k) => `.claude/helpers/${b}-${k}.cjs`));
19
+ /** The graph build's ignore lines under graft, and under trail the one file that keeps `.trail/cache/` and the status line out of git (#619). */
20
+ const IGNORES = ['.gitignore', '.ignore', '.trail/.gitignore'];
21
+ /** The plain files under a folder init removes whole (graft's old Claude Code skill folder), at most 50, no links followed. */
22
+ function filesUnder(dir, depth = 0, out = []) {
23
+ if (depth > 3 || out.length >= 50)
24
+ return out;
25
+ let names;
26
+ try {
27
+ names = readdirSync(dir);
28
+ }
29
+ catch {
30
+ return out;
31
+ }
32
+ for (const n of names.slice(0, 50)) {
33
+ const p = join(dir, n);
34
+ try {
35
+ const st = lstatSync(p);
36
+ if (st.isFile())
37
+ out.push(p);
38
+ else if (st.isDirectory())
39
+ filesUnder(p, depth + 1, out);
40
+ }
41
+ catch { /* gone */ }
42
+ if (out.length >= 50)
43
+ break;
44
+ }
45
+ return out;
46
+ }
47
+ /**
48
+ * fix-lab5: what a `trail init` removes in a repo moving from graft's names: graft's Claude Code shims and its whole
49
+ * `.claude/skills/graft/` folder (claude/init.ts), each owned host's graft-named copy (hosts/init.ts), and Cursor's
50
+ * graft shim. Looked at before init runs, so a deletion is recorded like a write.
51
+ */
52
+ function graftCopies(target) {
53
+ const claude = claudeTargetsFor(target, 'graft').map((w) => w.path);
54
+ const skillDir = join(target, '.claude', 'skills', 'graft');
55
+ return [...claude, ...filesUnder(skillDir), ...HOSTS.filter((h) => h.kind === 'owned').map((h) => join(target, h.relPath)),
56
+ join(target, cursorHookShimRelPath('graft'))];
57
+ }
58
+ /** #619: trail's layout before 0.23, which init clears away in a repo it set up then: its repo skill folder and `.mcp.json` server. */
59
+ function oldTrailLayout(target) {
60
+ return [...legacyClaudeTargets(target, 'trail').map((w) => w.path), ...filesUnder(join(target, '.claude', 'skills', 'trail'))];
61
+ }
62
+ function pathsFor(target, checkout, home) {
63
+ const writes = planInit(target, { home }).flatMap((p) => p.writes).filter((w) => w.scope === 'repo').map((w) => w.path);
64
+ return [...writes, ...graftCopies(target), ...oldTrailLayout(target), ...[...SHIMS, ...IGNORES].map((s) => join(target, s)), join(checkout, '.trail', 'README.md')]
65
+ .map((p) => relative(checkout, p).split(sep).join('/'))
66
+ .filter((r) => r && !r.startsWith('..'));
67
+ }
68
+ /** One look per checkout, before init writes anything. */
69
+ export function snapInit(targets, home, env = process.env) {
70
+ const rels = new Map();
71
+ for (const target of targets) {
72
+ const place = repoPlace(target, env);
73
+ if (place.git)
74
+ rels.set(place.checkout, [...(rels.get(place.checkout) ?? []), ...pathsFor(target, place.checkout, home)]);
75
+ }
76
+ return [...rels].map(([checkout, list]) => snapInstall(checkout, list, env));
77
+ }
78
+ /** After the writes. A record that can't be written only means the probe blocks on init's files, as before. */
79
+ export function recordInit(snaps, env = process.env) {
80
+ for (const s of snaps) {
81
+ try {
82
+ recordInstall(s, env);
83
+ }
84
+ catch { /* the probe reads no record */ }
85
+ }
86
+ }
87
+ //# sourceMappingURL=install-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-paths.js","sourceRoot":"","sources":["../../src/init/install-paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The person's answer to init's list, and whether the agent showed that
3
+ * list (design 4.9 steps 3 and 4). Shared by the PreToolUse keep gate and
4
+ * `trail keep`'s CLI half, so both decide the same way. No imports beyond
5
+ * node: the gate loads this on the hook's path.
6
+ *
7
+ * - `parseKeepAnswer`: whole-message forms only. Numbers joined by spaces,
8
+ * commas, `and` or `&`, with `keep`, `just`, `only` or `please` around
9
+ * them; `all`; `none`. Anything else ("sure do whats recommended here",
10
+ * "the release one") is no answer: Trail needs the numbers the person typed.
11
+ * - `replyNamesList`: every item is named as `{n}.` followed by its name
12
+ * words, in any wording around them, so a list of the agent's own whose
13
+ * numbers point at other items is not the list (R22).
14
+ */
15
+ import type { KeepAnswer } from './types.js';
16
+ /** The answer a typed message gives, or null when it isn't one of the whole-message forms. */
17
+ export declare function parseKeepAnswer(typed: string): KeepAnswer | null;
18
+ /**
19
+ * Every item of the list is named in `reply` as `{n}.` followed by its name words (4.9 step 3, R22), and no number
20
+ * of the list is followed by another item's name words without its own (b6 review): "I'd pick 1. no-timeout" after
21
+ * the real list would point the person's "1" at item 2.
22
+ */
23
+ export declare function replyNamesList(reply: string, items: Array<{
24
+ n: number;
25
+ nameWords: string[];
26
+ }>): boolean;
27
+ export declare function leadWords(line: string): string[];
28
+ /** The command's numbers are within what the person typed (4.9 step 5). */
29
+ export declare function withinAnswer(asked: KeepAnswer, typed: KeepAnswer, listed: number[]): boolean;
30
+ /**
31
+ * The words `trail keep` gets from the text after it, the way the shell hands them over: redirections dropped, and
32
+ * everything from the first `;`, `&`, `|`, `)`, quote, backtick or newline on is another command (`| cat`,
33
+ * `; echo done`, `&& echo ok`), returned as `more`. Shared by the PreToolUse gate and the CLI half (fix-lab5).
34
+ */
35
+ export declare function keepWords(text: string): {
36
+ words: string[];
37
+ more: string;
38
+ };
39
+ /** `trail keep`'s own arguments as an answer: numbers, `all` or `none`; null for anything else. Shell noise in them is read past (keepWords). */
40
+ export declare function keepArgs(args: string[]): KeepAnswer | null;
41
+ /** "1 and 3", "all", "none": the typed answer in words for a deny reason. */
42
+ export declare function answerWords(a: KeepAnswer): string;
43
+ //# sourceMappingURL=keep-answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-answer.d.ts","sourceRoot":"","sources":["../../src/init/keep-answer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAUhE;AAgCD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAAG,OAAO,CAMvG;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAO5F;AAQD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAKzE;AAED,iJAAiJ;AACjJ,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAO1D;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAKjD"}
@@ -0,0 +1,118 @@
1
+ const NUMS = /^(?:(?:please|keep|just|only)\s+)*(\d{1,2}(?:\s*(?:,|&|\band\b|\s)\s*\d{1,2})*)(?:\s+please)?$/;
2
+ const ALL = /^(?:please\s+)?(?:keep\s+)?all(?:\s+of\s+them)?(?:\s+please)?$/;
3
+ const NONE = /^(?:(?:keep\s+)?(?:none|nothing)|no)$/;
4
+ /** The answer a typed message gives, or null when it isn't one of the whole-message forms. */
5
+ export function parseKeepAnswer(typed) {
6
+ if (typeof typed !== 'string' || typed.length > 200)
7
+ return null;
8
+ const t = typed.toLowerCase().replace(/[‘’]/g, "'").replace(/\s+/g, ' ').trim().replace(/[.!]+$/, '').trim();
9
+ if (!t)
10
+ return null;
11
+ if (NONE.test(t))
12
+ return { none: true };
13
+ if (ALL.test(t))
14
+ return { all: true };
15
+ const m = NUMS.exec(t);
16
+ if (!m)
17
+ return null;
18
+ const numbers = [...new Set((m[1].match(/\d{1,2}/g) ?? []).map(Number))].filter((n) => n >= 1).sort((a, b) => a - b);
19
+ return numbers.length ? { numbers } : null;
20
+ }
21
+ /** Words as the list check compares them: lowercase, curly quotes straightened, split like the candidates' lead words. */
22
+ function tokens(text) {
23
+ return text.toLowerCase().replace(/[‘’]/g, "'").split(/[^a-z0-9'+-]+/).map((w) => w.replace(/^'+|'+$/g, '')).filter(Boolean);
24
+ }
25
+ /** Whether `want` appears in `have` in order (other words may sit between). */
26
+ function inOrder(have, want) {
27
+ let k = 0;
28
+ for (const w of have)
29
+ if (k < want.length && w === want[k].toLowerCase().replace(/^'+|'+$/g, ''))
30
+ k++;
31
+ return k === want.length;
32
+ }
33
+ /**
34
+ * The text after each `{n}.` marker up to the next marker or line end. A marker is a number of one or two digits
35
+ * and a dot that is not part of a longer number (`1.` yes, `1.2` and `21.` for 1 no).
36
+ */
37
+ function segments(text) {
38
+ const out = new Map();
39
+ for (const line of text.split('\n')) {
40
+ const marks = [...line.matchAll(/(?:^|[^\w.])(\d{1,2})\.(?!\d)/g)];
41
+ marks.forEach((m, k) => {
42
+ const start = m.index + m[0].length;
43
+ const end = k + 1 < marks.length ? marks[k + 1].index : line.length;
44
+ const n = Number(m[1]);
45
+ out.set(n, [...(out.get(n) ?? []), tokens(line.slice(start, end))]);
46
+ });
47
+ }
48
+ return out;
49
+ }
50
+ /**
51
+ * Every item of the list is named in `reply` as `{n}.` followed by its name words (4.9 step 3, R22), and no number
52
+ * of the list is followed by another item's name words without its own (b6 review): "I'd pick 1. no-timeout" after
53
+ * the real list would point the person's "1" at item 2.
54
+ */
55
+ export function replyNamesList(reply, items) {
56
+ if (typeof reply !== 'string' || !items.length)
57
+ return false;
58
+ const segs = segments(reply);
59
+ if (!items.every((it) => it.nameWords.length > 0 && (segs.get(it.n) ?? []).some((s) => inOrder(s, it.nameWords))))
60
+ return false;
61
+ return items.every((it) => (segs.get(it.n) ?? []).every((s) => inOrder(s, it.nameWords)
62
+ || !items.some((o) => o.n !== it.n && o.nameWords.length > 0 && inOrder(s, o.nameWords))));
63
+ }
64
+ /** Lead words of a preference's line, as the candidates make them (candidates.ts): the first 4 that aren't stop words. */
65
+ const STOP = new Set(['a', 'an', 'the', 'to', 'of', 'in', 'on', 'for', 'and', 'or', 'it', 'this', 'that', 'is', 'be', 'with', 'please', 'here', 'i', 'you', 'we']);
66
+ export function leadWords(line) {
67
+ return line.toLowerCase().split(/[^a-z0-9'+-]+/).filter((w) => w && !STOP.has(w)).slice(0, 4);
68
+ }
69
+ /** The command's numbers are within what the person typed (4.9 step 5). */
70
+ export function withinAnswer(asked, typed, listed) {
71
+ if ('none' in asked)
72
+ return 'none' in typed;
73
+ if ('none' in typed)
74
+ return false;
75
+ if ('all' in typed)
76
+ return true;
77
+ const ok = new Set(typed.numbers);
78
+ const want = 'all' in asked ? listed : asked.numbers;
79
+ return want.length > 0 && want.every((n) => ok.has(n));
80
+ }
81
+ /**
82
+ * A redirection (`2>&1`, `>/dev/null`, `> out.txt`, `&>/dev/null`, `2>>log`, `< /dev/null`): it changes where the
83
+ * output goes, never what `trail keep` is asked. Linear: one pass, no nested repeats.
84
+ */
85
+ const REDIRECT = /(^|\s)(?:\d+|&)?(?:>>?|<)(?:&(?:\d+|-)|\s*[^\s;&|<>()`'"]+)?(?=\s|$|[;&|)])/g;
86
+ /**
87
+ * The words `trail keep` gets from the text after it, the way the shell hands them over: redirections dropped, and
88
+ * everything from the first `;`, `&`, `|`, `)`, quote, backtick or newline on is another command (`| cat`,
89
+ * `; echo done`, `&& echo ok`), returned as `more`. Shared by the PreToolUse gate and the CLI half (fix-lab5).
90
+ */
91
+ export function keepWords(text) {
92
+ const s = String(text ?? '').slice(0, 4096).replace(REDIRECT, '$1 ');
93
+ const cut = s.search(/[;&|)`'"\n]/);
94
+ const head = cut < 0 ? s : s.slice(0, cut);
95
+ return { words: head.split(/[\s,]+/).filter(Boolean), more: cut < 0 ? '' : s.slice(cut) };
96
+ }
97
+ /** `trail keep`'s own arguments as an answer: numbers, `all` or `none`; null for anything else. Shell noise in them is read past (keepWords). */
98
+ export function keepArgs(args) {
99
+ const words = keepWords(args.map(String).join(' ')).words.map((w) => w.toLowerCase());
100
+ if (words.length === 1 && words[0] === 'none')
101
+ return { none: true };
102
+ if (words.length === 1 && words[0] === 'all')
103
+ return { all: true };
104
+ if (!words.length || !words.every((w) => /^\d{1,2}$/.test(w)))
105
+ return null;
106
+ const numbers = [...new Set(words.map(Number))].filter((n) => n >= 1).sort((a, b) => a - b);
107
+ return numbers.length === words.length ? { numbers } : null;
108
+ }
109
+ /** "1 and 3", "all", "none": the typed answer in words for a deny reason. */
110
+ export function answerWords(a) {
111
+ if ('none' in a)
112
+ return 'none';
113
+ if ('all' in a)
114
+ return 'all';
115
+ const n = a.numbers.map(String);
116
+ return n.length < 2 ? n.join('') : `${n.slice(0, -1).join(', ')} and ${n[n.length - 1]}`;
117
+ }
118
+ //# sourceMappingURL=keep-answer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-answer.js","sourceRoot":"","sources":["../../src/init/keep-answer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { PreBashDecision } from '../claude/pre-bash.js';
2
+ import { type InitRecord } from './init-record.js';
3
+ import type { KeepAnswer } from './types.js';
4
+ export { TAIL_BYTES } from './keep-list.js';
5
+ export declare function isKeepCommand(command: string): boolean;
6
+ /** Whether a shell command runs `trail init`. */
7
+ export declare function isInitCommand(command: string): boolean;
8
+ export declare const WAIT = "Wait for the person's answer before running trail keep: show them the list trail init printed, as written, and run trail keep only with the numbers they choose. Don't choose for them.";
9
+ export declare const CUT = "Show the person the list trail init printed: run trail init again without a pipe or redirect, then ask them.";
10
+ export declare const SHOW_LIST = "Show the person the whole list as trail init printed it, numbers and names, then ask which to keep.";
11
+ export declare const NEED_NUMBERS = "Trail needs the numbers the person typed. Ask them which numbers to keep, or none.";
12
+ export declare const NOT_THIS_LIST = "That list isn't the one waiting in this repo: run trail init again, show the person its list as written, then ask them.";
13
+ export declare const CHANGED = "This session changed Trail's own files after the list, so Trail won't keep anything from it. Run trail init again and show the person its list.";
14
+ /**
15
+ * What `trail keep` asks for in this command, or null when its words aren't numbers, all or none. `trail keep 1 2>&1`
16
+ * and `trail keep 1 | cat` ask for 1 (fix-lab5); a second `trail keep` asking for something else is no answer.
17
+ */
18
+ export declare function keepCommandAnswer(command: string): KeepAnswer | null;
19
+ /** `trail keep --help` or `-h`, with or without a redirect or a reader after it: usage only, never denied (B4, P36). Not when another `trail keep` is chained on. */
20
+ export declare function keepHelp(command: string): boolean;
21
+ /** The pending items with their name words; a preference's rebuilt from the person's line, read again by its pointer. */
22
+ export declare function pendingNames(r: InitRecord, env: NodeJS.ProcessEnv): Array<{
23
+ n: number;
24
+ nameWords: string[];
25
+ }>;
26
+ /** receipts/<session-id>.keep.json */
27
+ export declare function keepReceiptPath(sessionId: string, env?: NodeJS.ProcessEnv): string;
28
+ /** The decision for a Bash call: deny a `trail keep` the person hasn't answered for, null (and a receipt) to let it run. Never throws. */
29
+ export declare function keepDecision(input: unknown, _dir: string, env?: NodeJS.ProcessEnv, now?: Date): PreBashDecision | null;
30
+ //# sourceMappingURL=keep-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-gate.d.ts","sourceRoot":"","sources":["../../src/init/keep-gate.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAIpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQ5C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,eAAO,MAAM,IAAI,4LAC0K,CAAC;AAC5L,eAAO,MAAM,GAAG,iHAAiH,CAAC;AAClI,eAAO,MAAM,SAAS,wGAAwG,CAAC;AAC/H,eAAO,MAAM,YAAY,uFAAuF,CAAC;AACjH,eAAO,MAAM,aAAa,4HAA4H,CAAC;AACvJ,eAAO,MAAM,OAAO,oJAAoJ,CAAC;AAUzK;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAMpE;AAED,qKAAqK;AACrK,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAO7G;AAKD,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAElF;AAgBD,0IAA0I;AAC1I,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,GAAG,GAAE,IAAiB,GAAG,eAAe,GAAG,IAAI,CA2D/I"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * The PreToolUse check for `trail keep` (design 4.9, PreToolUse half): an
3
+ * agent may keep init's items only with the numbers the person typed after
4
+ * seeing the list.
5
+ *
6
+ * 1. `trail keep --help` / `-h` pass, nothing else checked (B4, P36).
7
+ * 2. The list (keep-list.ts, R22): the newest clean `trail init` call's own
8
+ * result, or this session's handover offset from the init record. A
9
+ * `trail init | tail` (or a redirect) is denied with words that say to run
10
+ * it plainly. No list: phase 0's wait reason.
11
+ * 3. The agent's text between the list and the person's next typed line
12
+ * names every pending item as `{n}.` and its name words.
13
+ * 4. That typed line is a whole-message answer (numbers, all, none).
14
+ * 5. The command's numbers are within it.
15
+ * 6. On allow it writes the KeepReceipt `trail keep`'s CLI half needs (R23)
16
+ * and returns null. The write is idempotent: both registered copies of the
17
+ * hook may run it, and the second finds the same receipt there.
18
+ *
19
+ * Loaded lazily by `pre-bash.ts` `keepReply`, only for a command that says
20
+ * `keep`. Fails open (null) on a payload that isn't Claude Code's or a
21
+ * transcript it can't read; then no receipt is written and the CLI holds.
22
+ */
23
+ import { createHash } from 'node:crypto';
24
+ import { detectHost } from '../trace/host.js';
25
+ import { readJsonSafe, trailPath, writePrivate } from '../util/private-fs.js';
26
+ import { listInitRecords } from './init-record.js';
27
+ import { answerWords, keepArgs, keepWords, leadWords, parseKeepAnswer, replyNamesList, withinAnswer } from './keep-answer.js';
28
+ import { afterList, findList, typedLine } from './keep-list.js';
29
+ import { prefText } from './prefs.js';
30
+ export { TAIL_BYTES } from './keep-list.js';
31
+ /** `trail <sub> …` however it's spelled: through a path, npx, node on the built file, inside `bash -c "…"`, after env assignments or `cd … &&`, with global options before the subcommand. */
32
+ const run = (sub) => new RegExp(`(?:^|[\\s;&|(\`'"/=])(?:trail|graft|trail-code)(?:\\.[cm]?[jt]s)?['"]?\\s+(?:--?[\\w-]+(?:=\\S+|\\s+(?!${sub}\\b)[^\\s-]\\S*)?\\s+)*${sub}(?=$|[\\s;&|)'"\`])`);
33
+ const KEEP = run('keep');
34
+ const INIT = run('init');
35
+ export function isKeepCommand(command) {
36
+ return KEEP.test(command);
37
+ }
38
+ /** Whether a shell command runs `trail init`. */
39
+ export function isInitCommand(command) {
40
+ return INIT.test(command);
41
+ }
42
+ export const WAIT = "Wait for the person's answer before running trail keep: show them the list trail init printed, as written, and run trail keep only with the numbers they choose. Don't choose for them.";
43
+ export const CUT = 'Show the person the list trail init printed: run trail init again without a pipe or redirect, then ask them.';
44
+ export const SHOW_LIST = 'Show the person the whole list as trail init printed it, numbers and names, then ask which to keep.';
45
+ export const NEED_NUMBERS = 'Trail needs the numbers the person typed. Ask them which numbers to keep, or none.';
46
+ export const NOT_THIS_LIST = "That list isn't the one waiting in this repo: run trail init again, show the person its list as written, then ask them.";
47
+ export const CHANGED = "This session changed Trail's own files after the list, so Trail won't keep anything from it. Run trail init again and show the person its list.";
48
+ const typedOnly = (a) => `The person typed ${answerWords(a)}; keep only those.`;
49
+ /** What `trail keep` asks for in this command, or null when its words aren't numbers, all or none. */
50
+ /** Every `trail keep` in the command, as the words each one gets (keepWords: redirections and trailing commands read past). */
51
+ function keepCalls(command) {
52
+ const all = new RegExp(KEEP.source, 'g');
53
+ return [...String(command).slice(0, 64 * 1024).matchAll(all)].slice(0, 8).map((m) => keepWords(command.slice(m.index + m[0].length)).words);
54
+ }
55
+ /**
56
+ * What `trail keep` asks for in this command, or null when its words aren't numbers, all or none. `trail keep 1 2>&1`
57
+ * and `trail keep 1 | cat` ask for 1 (fix-lab5); a second `trail keep` asking for something else is no answer.
58
+ */
59
+ export function keepCommandAnswer(command) {
60
+ const calls = keepCalls(command);
61
+ if (!calls.length)
62
+ return null;
63
+ const answers = calls.map((w) => keepArgs(w));
64
+ const first = answers[0];
65
+ return first && answers.every((a) => JSON.stringify(a) === JSON.stringify(first)) ? first : null;
66
+ }
67
+ /** `trail keep --help` or `-h`, with or without a redirect or a reader after it: usage only, never denied (B4, P36). Not when another `trail keep` is chained on. */
68
+ export function keepHelp(command) {
69
+ const calls = keepCalls(command);
70
+ return calls.length === 1 && calls[0].length === 1 && /^(?:--help|-h)$/.test(calls[0][0]);
71
+ }
72
+ /** The pending items with their name words; a preference's rebuilt from the person's line, read again by its pointer. */
73
+ export function pendingNames(r, env) {
74
+ return r.pending.map((p) => {
75
+ if (p.kind !== 'preference')
76
+ return { n: p.n, nameWords: p.nameWords };
77
+ const ref = p.pref?.refs[0];
78
+ const text = ref ? typedLine(ref, env) : null;
79
+ return { n: p.n, nameWords: text ? leadWords(prefText(text).slice(0, 120)) : [] };
80
+ });
81
+ }
82
+ const fileId = (sessionId) => /^[A-Za-z0-9_-][A-Za-z0-9._-]{0,127}$/.test(sessionId) ? sessionId : `h-${createHash('sha256').update(sessionId).digest('hex').slice(0, 16)}`;
83
+ /** receipts/<session-id>.keep.json */
84
+ export function keepReceiptPath(sessionId, env) {
85
+ return trailPath(env, 'receipts', `${fileId(sessionId)}.keep.json`);
86
+ }
87
+ const sameAnswer = (a, b) => a.session === b.session && a.toolUseId === b.toolUseId && a.list.offset === b.list.offset && a.list.initRunId === b.list.initRunId
88
+ && a.typed.offset === b.typed.offset && a.typed.lineSha === b.typed.lineSha && a.replySha === b.replySha && JSON.stringify(a.numbers) === JSON.stringify(b.numbers);
89
+ /** Writes the receipt unless the same one, unused, is already there (the other hook copy wrote it). */
90
+ function writeKeepReceipt(r, env) {
91
+ const path = keepReceiptPath(r.session, env);
92
+ const cur = readJsonSafe(path);
93
+ if (cur && cur.usedAt === null && sameAnswer(cur, r))
94
+ return;
95
+ writePrivate(path, `${JSON.stringify(r, null, 2)}\n`);
96
+ }
97
+ const deny = (reason) => ({ permissionDecision: 'deny', reason });
98
+ /** The decision for a Bash call: deny a `trail keep` the person hasn't answered for, null (and a receipt) to let it run. Never throws. */
99
+ export function keepDecision(input, _dir, env = process.env, now = new Date()) {
100
+ try {
101
+ if (!input || typeof input !== 'object' || Array.isArray(input))
102
+ return null;
103
+ const payload = input;
104
+ const command = payload.tool_input?.command;
105
+ if (typeof command !== 'string' || !isKeepCommand(command))
106
+ return null;
107
+ // Another host's transcript isn't Claude Code's to read.
108
+ if (detectHost(payload).host !== 'claude')
109
+ return null;
110
+ if (keepHelp(command) && !isInitCommand(command))
111
+ return null;
112
+ if (isInitCommand(command))
113
+ return deny(WAIT);
114
+ const path = payload.transcript_path;
115
+ const session = typeof payload.session_id === 'string' ? payload.session_id : '';
116
+ if (typeof path !== 'string' || !path || !session)
117
+ return null;
118
+ // Every record on this machine, not the cwd's repo: resolving the repo would load the notes layer on the hook's path.
119
+ const records = listInitRecords(env);
120
+ const handed = records.filter((x) => x.record.handover?.session === session && x.record.pending.length && x.record.pendingFrom)
121
+ .sort((a, b) => b.record.handover.offset - a.record.handover.offset)[0];
122
+ const found = findList(path, isInitCommand, handed ? { offset: handed.record.handover.offset } : null);
123
+ if (!found)
124
+ return null;
125
+ if (found.cut !== null)
126
+ return deny(CUT);
127
+ const list = found.list;
128
+ if (!list)
129
+ return deny(WAIT);
130
+ let record = null;
131
+ let items = [];
132
+ if (list.via === 'handover') {
133
+ record = handed.record;
134
+ items = pendingNames(record, env);
135
+ }
136
+ else {
137
+ // The record whose waiting list is the one this call printed, newest first.
138
+ for (const x of records.filter((r) => r.record.pending.length && r.record.pendingFrom).sort((a, b) => String(b.record.shownAt).localeCompare(String(a.record.shownAt)))) {
139
+ const names = pendingNames(x.record, env);
140
+ if (replyNamesList(list.text, names)) {
141
+ record = x.record;
142
+ items = names;
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ if (!record || !record.pendingFrom)
148
+ return deny(NOT_THIS_LIST);
149
+ const after = afterList(path, list, env);
150
+ if (!after)
151
+ return null;
152
+ if (after.tampered)
153
+ return deny(CHANGED);
154
+ if (!after.typed)
155
+ return deny(WAIT);
156
+ if (!replyNamesList(after.reply, items))
157
+ return deny(SHOW_LIST);
158
+ const typed = parseKeepAnswer(after.typed.text);
159
+ if (!typed)
160
+ return deny(NEED_NUMBERS);
161
+ const asked = keepCommandAnswer(command);
162
+ if (!asked)
163
+ return deny(NEED_NUMBERS);
164
+ if (!withinAnswer(asked, typed, record.pending.map((p) => p.n)))
165
+ return deny(typedOnly(typed));
166
+ writeKeepReceipt({
167
+ v: 1, kind: 'keep', session, transcriptPath: path, toolUseId: typeof payload.tool_use_id === 'string' ? payload.tool_use_id : '',
168
+ list: { offset: list.offset, initRunId: record.pendingFrom, via: list.via },
169
+ typed: { offset: after.typed.offset, lineSha: after.typed.lineSha }, replySha: after.replySha,
170
+ numbers: 'none' in asked ? 'none' : 'all' in asked ? 'all' : asked.numbers, at: now.toISOString(), verdict: 'live', usedAt: null,
171
+ }, env);
172
+ return null;
173
+ }
174
+ catch {
175
+ return null;
176
+ }
177
+ }
178
+ //# sourceMappingURL=keep-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-gate.js","sourceRoot":"","sources":["../../src/init/keep-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /** How much of the transcript is read: the list is printed moments before the answer. */
2
+ export declare const TAIL_BYTES: number;
3
+ /** Whole lines with their byte offsets, from `from` (a line start) or the last `bytes` of the file; null when unreadable. */
4
+ export declare function linesFrom(path: string, opts: {
5
+ from?: number;
6
+ bytes?: number;
7
+ }): Array<{
8
+ line: string;
9
+ offset: number;
10
+ }> | null;
11
+ /**
12
+ * A Bash command that only runs `trail init`: Trail's own (1a's `onlyTrail`), with no pipe that could cut its list,
13
+ * and nothing else beside it but leading `cd`s (b6 review): `trail init; echo …`, `echo …; trail init --help` or
14
+ * `trail init && cat saved.txt` would put text of the agent's own in the same result as the list.
15
+ */
16
+ export declare function initOnly(command: string): boolean;
17
+ export interface ListAt {
18
+ via: 'init-call' | 'handover';
19
+ /** The tool_result line's offset (init call), or the handover's recorded offset. */
20
+ offset: number;
21
+ /** The tool result's text (init call); '' for a handover. */
22
+ text: string;
23
+ }
24
+ /**
25
+ * The newest list in the transcript's tail: a clean `trail init` call's result, or this session's handover offset.
26
+ * `cut` when the newest `trail init` call is newer than any list and its output is not a list (a pipe, a redirect,
27
+ * another command with it). Null when there is none, or the transcript can't be read.
28
+ */
29
+ export declare function findList(path: string, isInit: (command: string) => boolean, handover: {
30
+ offset: number;
31
+ } | null): {
32
+ list: ListAt | null;
33
+ cut: number | null;
34
+ } | null;
35
+ export interface AfterList {
36
+ /** The agent's text between the list and the person's newest typed line, joined by newlines. */
37
+ reply: string;
38
+ replySha: string;
39
+ typed: {
40
+ offset: number;
41
+ lineSha: string;
42
+ text: string;
43
+ } | null;
44
+ /** A call after the list wrote Trail's or the host's files. */
45
+ tampered: boolean;
46
+ }
47
+ /**
48
+ * What follows the list: read from its offset (an init call's result line is skipped). The answer is the person's
49
+ * newest typed line after the list (b6 review): the relay itself invites "Show one in full", so a first line that asks
50
+ * to see an item must not lock the list; a later change of mind ("actually none") wins over earlier numbers. The
51
+ * reply is the agent's text from the list up to that line.
52
+ */
53
+ export declare function afterList(path: string, list: {
54
+ offset: number;
55
+ via: 'init-call' | 'handover';
56
+ }, env?: NodeJS.ProcessEnv): AfterList | null;
57
+ /**
58
+ * The person's line a pointer names, read again: replay-runs' `typedAt` rules (a transcript in Claude Code's projects
59
+ * folder reached with no link, the line at the offset with the same sha, a line the person typed), in this light
60
+ * file so the hook's keep check never loads the replay and compile (R11). Null otherwise.
61
+ */
62
+ export declare function typedLine(ref: {
63
+ t: string;
64
+ o: number;
65
+ s: string;
66
+ }, env?: NodeJS.ProcessEnv): string | null;
67
+ //# sourceMappingURL=keep-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-list.d.ts","sourceRoot":"","sources":["../../src/init/keep-list.ts"],"names":[],"mappings":"AA4BA,yFAAyF;AACzF,eAAO,MAAM,UAAU,QAAkB,CAAC;AAI1C,6HAA6H;AAC7H,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAmC/H;AAcD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,WAAW,GAAG,UAAU,CAAC;IAC9B,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,EAAE,QAAQ,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC9G;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAmCnD;AAED,MAAM,WAAW,SAAS;IACxB,gGAAgG;IAChG,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChE,+DAA+D;IAC/D,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,WAAW,GAAG,UAAU,CAAA;CAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,GAAG,IAAI,CA0CvJ;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,IAAI,CAcvH"}