@nanonets/graft 0.24.0 → 0.24.1

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 (396) hide show
  1. package/dist/ask/ask.d.ts +8 -0
  2. package/dist/ask/ask.d.ts.map +1 -1
  3. package/dist/ask/ask.js +33 -12
  4. package/dist/ask/ask.js.map +1 -1
  5. package/dist/claude/hook-io.d.ts +44 -0
  6. package/dist/claude/hook-io.d.ts.map +1 -0
  7. package/dist/claude/hook-io.js +144 -0
  8. package/dist/claude/hook-io.js.map +1 -0
  9. package/dist/claude/skills-hook-util.d.ts +25 -0
  10. package/dist/claude/skills-hook-util.d.ts.map +1 -0
  11. package/dist/claude/skills-hook-util.js +71 -0
  12. package/dist/claude/skills-hook-util.js.map +1 -0
  13. package/dist/cli-picker.d.ts +24 -0
  14. package/dist/cli-picker.d.ts.map +1 -1
  15. package/dist/cli-picker.js +36 -5
  16. package/dist/cli-picker.js.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +278 -29
  19. package/dist/cli.js.map +1 -1
  20. package/dist/cloud/lookup-activity.d.ts +16 -0
  21. package/dist/cloud/lookup-activity.d.ts.map +1 -0
  22. package/dist/cloud/lookup-activity.js +56 -0
  23. package/dist/cloud/lookup-activity.js.map +1 -0
  24. package/dist/cloud/nudge.d.ts.map +1 -1
  25. package/dist/cloud/nudge.js +3 -0
  26. package/dist/cloud/nudge.js.map +1 -1
  27. package/dist/cloud/onboarding.d.ts +237 -0
  28. package/dist/cloud/onboarding.d.ts.map +1 -0
  29. package/dist/cloud/onboarding.js +536 -0
  30. package/dist/cloud/onboarding.js.map +1 -0
  31. package/dist/cloud/pair.d.ts +76 -0
  32. package/dist/cloud/pair.d.ts.map +1 -0
  33. package/dist/cloud/pair.js +249 -0
  34. package/dist/cloud/pair.js.map +1 -0
  35. package/dist/cloud/workspace-sync.d.ts +10 -2
  36. package/dist/cloud/workspace-sync.d.ts.map +1 -1
  37. package/dist/cloud/workspace-sync.js +119 -7
  38. package/dist/cloud/workspace-sync.js.map +1 -1
  39. package/dist/cloud/workspace.d.ts +22 -1
  40. package/dist/cloud/workspace.d.ts.map +1 -1
  41. package/dist/cloud/workspace.js +16 -1
  42. package/dist/cloud/workspace.js.map +1 -1
  43. package/dist/graph/native.d.ts +2 -0
  44. package/dist/graph/native.d.ts.map +1 -1
  45. package/dist/graph/native.js +29 -4
  46. package/dist/graph/native.js.map +1 -1
  47. package/dist/hosts/claude-global.d.ts +14 -0
  48. package/dist/hosts/claude-global.d.ts.map +1 -1
  49. package/dist/hosts/claude-global.js +38 -3
  50. package/dist/hosts/claude-global.js.map +1 -1
  51. package/dist/init/install-record.d.ts +21 -0
  52. package/dist/init/install-record.d.ts.map +1 -0
  53. package/dist/init/install-record.js +144 -0
  54. package/dist/init/install-record.js.map +1 -0
  55. package/dist/init/plain-file.d.ts +11 -0
  56. package/dist/init/plain-file.d.ts.map +1 -0
  57. package/dist/init/plain-file.js +80 -0
  58. package/dist/init/plain-file.js.map +1 -0
  59. package/dist/mcp/brains.d.ts +72 -0
  60. package/dist/mcp/brains.d.ts.map +1 -0
  61. package/dist/mcp/brains.js +220 -0
  62. package/dist/mcp/brains.js.map +1 -0
  63. package/dist/mcp/server.d.ts +3 -1
  64. package/dist/mcp/server.d.ts.map +1 -1
  65. package/dist/mcp/server.js +40 -5
  66. package/dist/mcp/server.js.map +1 -1
  67. package/dist/mcp/tools.d.ts.map +1 -1
  68. package/dist/mcp/tools.js +7 -2
  69. package/dist/mcp/tools.js.map +1 -1
  70. package/dist/notes/cold-start.d.ts +30 -1
  71. package/dist/notes/cold-start.d.ts.map +1 -1
  72. package/dist/notes/cold-start.js +98 -19
  73. package/dist/notes/cold-start.js.map +1 -1
  74. package/dist/notes/every-repo.d.ts +18 -0
  75. package/dist/notes/every-repo.d.ts.map +1 -0
  76. package/dist/notes/every-repo.js +86 -0
  77. package/dist/notes/every-repo.js.map +1 -0
  78. package/dist/notes/guardrails.d.ts +8 -0
  79. package/dist/notes/guardrails.d.ts.map +1 -0
  80. package/dist/notes/guardrails.js +38 -0
  81. package/dist/notes/guardrails.js.map +1 -0
  82. package/dist/notes/lesson-index.d.ts +13 -0
  83. package/dist/notes/lesson-index.d.ts.map +1 -0
  84. package/dist/notes/lesson-index.js +135 -0
  85. package/dist/notes/lesson-index.js.map +1 -0
  86. package/dist/notes/linked-learnings.d.ts +8 -0
  87. package/dist/notes/linked-learnings.d.ts.map +1 -0
  88. package/dist/notes/linked-learnings.js +113 -0
  89. package/dist/notes/linked-learnings.js.map +1 -0
  90. package/dist/notes/replace.d.ts +14 -0
  91. package/dist/notes/replace.d.ts.map +1 -0
  92. package/dist/notes/replace.js +38 -0
  93. package/dist/notes/replace.js.map +1 -0
  94. package/dist/notes/repo-notes-dir.d.ts +2 -0
  95. package/dist/notes/repo-notes-dir.d.ts.map +1 -0
  96. package/dist/notes/repo-notes-dir.js +16 -0
  97. package/dist/notes/repo-notes-dir.js.map +1 -0
  98. package/dist/skills/anchors-cli.d.ts +33 -0
  99. package/dist/skills/anchors-cli.d.ts.map +1 -0
  100. package/dist/skills/anchors-cli.js +274 -0
  101. package/dist/skills/anchors-cli.js.map +1 -0
  102. package/dist/skills/anchors-git.d.ts +29 -0
  103. package/dist/skills/anchors-git.d.ts.map +1 -0
  104. package/dist/skills/anchors-git.js +241 -0
  105. package/dist/skills/anchors-git.js.map +1 -0
  106. package/dist/skills/anchors-wide.d.ts +25 -0
  107. package/dist/skills/anchors-wide.d.ts.map +1 -0
  108. package/dist/skills/anchors-wide.js +481 -0
  109. package/dist/skills/anchors-wide.js.map +1 -0
  110. package/dist/skills/anchors.d.ts +32 -0
  111. package/dist/skills/anchors.d.ts.map +1 -0
  112. package/dist/skills/anchors.js +485 -0
  113. package/dist/skills/anchors.js.map +1 -0
  114. package/dist/skills/check-result.d.ts +26 -0
  115. package/dist/skills/check-result.d.ts.map +1 -0
  116. package/dist/skills/check-result.js +46 -0
  117. package/dist/skills/check-result.js.map +1 -0
  118. package/dist/skills/codex-sandbox.d.ts +6 -0
  119. package/dist/skills/codex-sandbox.d.ts.map +1 -0
  120. package/dist/skills/codex-sandbox.js +55 -0
  121. package/dist/skills/codex-sandbox.js.map +1 -0
  122. package/dist/skills/compile-split.d.ts +57 -0
  123. package/dist/skills/compile-split.d.ts.map +1 -0
  124. package/dist/skills/compile-split.js +532 -0
  125. package/dist/skills/compile-split.js.map +1 -0
  126. package/dist/skills/compile-version.d.ts +37 -0
  127. package/dist/skills/compile-version.d.ts.map +1 -0
  128. package/dist/skills/compile-version.js +56 -0
  129. package/dist/skills/compile-version.js.map +1 -0
  130. package/dist/skills/compile-waits.d.ts +12 -0
  131. package/dist/skills/compile-waits.d.ts.map +1 -0
  132. package/dist/skills/compile-waits.js +52 -0
  133. package/dist/skills/compile-waits.js.map +1 -0
  134. package/dist/skills/compile-words.d.ts +82 -0
  135. package/dist/skills/compile-words.d.ts.map +1 -0
  136. package/dist/skills/compile-words.js +385 -0
  137. package/dist/skills/compile-words.js.map +1 -0
  138. package/dist/skills/compile.d.ts +35 -0
  139. package/dist/skills/compile.d.ts.map +1 -0
  140. package/dist/skills/compile.js +488 -0
  141. package/dist/skills/compile.js.map +1 -0
  142. package/dist/skills/credit-facts.d.ts +8 -0
  143. package/dist/skills/credit-facts.d.ts.map +1 -0
  144. package/dist/skills/credit-facts.js +32 -0
  145. package/dist/skills/credit-facts.js.map +1 -0
  146. package/dist/skills/directive-words.d.ts +11 -0
  147. package/dist/skills/directive-words.d.ts.map +1 -0
  148. package/dist/skills/directive-words.js +33 -0
  149. package/dist/skills/directive-words.js.map +1 -0
  150. package/dist/skills/fidelity.d.ts +42 -0
  151. package/dist/skills/fidelity.d.ts.map +1 -0
  152. package/dist/skills/fidelity.js +138 -0
  153. package/dist/skills/fidelity.js.map +1 -0
  154. package/dist/skills/forget-notice.d.ts +44 -0
  155. package/dist/skills/forget-notice.d.ts.map +1 -0
  156. package/dist/skills/forget-notice.js +131 -0
  157. package/dist/skills/forget-notice.js.map +1 -0
  158. package/dist/skills/found-skill.d.ts +35 -0
  159. package/dist/skills/found-skill.d.ts.map +1 -0
  160. package/dist/skills/found-skill.js +66 -0
  161. package/dist/skills/found-skill.js.map +1 -0
  162. package/dist/skills/front-version.d.ts +12 -0
  163. package/dist/skills/front-version.d.ts.map +1 -0
  164. package/dist/skills/front-version.js +87 -0
  165. package/dist/skills/front-version.js.map +1 -0
  166. package/dist/skills/host-facts.d.ts +51 -0
  167. package/dist/skills/host-facts.d.ts.map +1 -0
  168. package/dist/skills/host-facts.js +134 -0
  169. package/dist/skills/host-facts.js.map +1 -0
  170. package/dist/skills/ledger.d.ts +43 -0
  171. package/dist/skills/ledger.d.ts.map +1 -0
  172. package/dist/skills/ledger.js +336 -0
  173. package/dist/skills/ledger.js.map +1 -0
  174. package/dist/skills/lessons.d.ts +60 -0
  175. package/dist/skills/lessons.d.ts.map +1 -0
  176. package/dist/skills/lessons.js +396 -0
  177. package/dist/skills/lessons.js.map +1 -0
  178. package/dist/skills/offer-answers.d.ts +20 -0
  179. package/dist/skills/offer-answers.d.ts.map +1 -0
  180. package/dist/skills/offer-answers.js +51 -0
  181. package/dist/skills/offer-answers.js.map +1 -0
  182. package/dist/skills/own-folder.d.ts +9 -0
  183. package/dist/skills/own-folder.d.ts.map +1 -0
  184. package/dist/skills/own-folder.js +36 -0
  185. package/dist/skills/own-folder.js.map +1 -0
  186. package/dist/skills/person.d.ts +34 -0
  187. package/dist/skills/person.d.ts.map +1 -0
  188. package/dist/skills/person.js +102 -0
  189. package/dist/skills/person.js.map +1 -0
  190. package/dist/skills/probe-clean.d.ts +9 -0
  191. package/dist/skills/probe-clean.d.ts.map +1 -0
  192. package/dist/skills/probe-clean.js +48 -0
  193. package/dist/skills/probe-clean.js.map +1 -0
  194. package/dist/skills/probes.d.ts +26 -0
  195. package/dist/skills/probes.d.ts.map +1 -0
  196. package/dist/skills/probes.js +225 -0
  197. package/dist/skills/probes.js.map +1 -0
  198. package/dist/skills/recall.d.ts +119 -0
  199. package/dist/skills/recall.d.ts.map +1 -0
  200. package/dist/skills/recall.js +370 -0
  201. package/dist/skills/recall.js.map +1 -0
  202. package/dist/skills/receipts.d.ts +44 -0
  203. package/dist/skills/receipts.d.ts.map +1 -0
  204. package/dist/skills/receipts.js +223 -0
  205. package/dist/skills/receipts.js.map +1 -0
  206. package/dist/skills/run-checkout.d.ts +4 -0
  207. package/dist/skills/run-checkout.d.ts.map +1 -0
  208. package/dist/skills/run-checkout.js +37 -0
  209. package/dist/skills/run-checkout.js.map +1 -0
  210. package/dist/skills/runblock.d.ts +45 -0
  211. package/dist/skills/runblock.d.ts.map +1 -0
  212. package/dist/skills/runblock.js +222 -0
  213. package/dist/skills/runblock.js.map +1 -0
  214. package/dist/skills/save-parse.d.ts +42 -0
  215. package/dist/skills/save-parse.d.ts.map +1 -0
  216. package/dist/skills/save-parse.js +172 -0
  217. package/dist/skills/save-parse.js.map +1 -0
  218. package/dist/skills/save-store.d.ts +12 -0
  219. package/dist/skills/save-store.d.ts.map +1 -0
  220. package/dist/skills/save-store.js +22 -0
  221. package/dist/skills/save-store.js.map +1 -0
  222. package/dist/skills/settings.d.ts +38 -0
  223. package/dist/skills/settings.d.ts.map +1 -0
  224. package/dist/skills/settings.js +133 -0
  225. package/dist/skills/settings.js.map +1 -0
  226. package/dist/skills/skill-diff.d.ts +40 -0
  227. package/dist/skills/skill-diff.d.ts.map +1 -0
  228. package/dist/skills/skill-diff.js +191 -0
  229. package/dist/skills/skill-diff.js.map +1 -0
  230. package/dist/skills/skill-file.d.ts +24 -0
  231. package/dist/skills/skill-file.d.ts.map +1 -0
  232. package/dist/skills/skill-file.js +97 -0
  233. package/dist/skills/skill-file.js.map +1 -0
  234. package/dist/skills/skill-rebuild.d.ts +27 -0
  235. package/dist/skills/skill-rebuild.d.ts.map +1 -0
  236. package/dist/skills/skill-rebuild.js +85 -0
  237. package/dist/skills/skill-rebuild.js.map +1 -0
  238. package/dist/skills/skillmd.d.ts +17 -0
  239. package/dist/skills/skillmd.d.ts.map +1 -0
  240. package/dist/skills/skillmd.js +219 -0
  241. package/dist/skills/skillmd.js.map +1 -0
  242. package/dist/skills/skills.d.ts +2 -0
  243. package/dist/skills/skills.d.ts.map +1 -1
  244. package/dist/skills/skills.js +1 -1
  245. package/dist/skills/skills.js.map +1 -1
  246. package/dist/skills/staleness.d.ts +27 -0
  247. package/dist/skills/staleness.d.ts.map +1 -0
  248. package/dist/skills/staleness.js +178 -0
  249. package/dist/skills/staleness.js.map +1 -0
  250. package/dist/skills/state.d.ts +36 -0
  251. package/dist/skills/state.d.ts.map +1 -0
  252. package/dist/skills/state.js +259 -0
  253. package/dist/skills/state.js.map +1 -0
  254. package/dist/skills/store-fs.d.ts +77 -0
  255. package/dist/skills/store-fs.d.ts.map +1 -0
  256. package/dist/skills/store-fs.js +194 -0
  257. package/dist/skills/store-fs.js.map +1 -0
  258. package/dist/skills/store-held.d.ts +44 -0
  259. package/dist/skills/store-held.d.ts.map +1 -0
  260. package/dist/skills/store-held.js +147 -0
  261. package/dist/skills/store-held.js.map +1 -0
  262. package/dist/skills/store.d.ts +73 -0
  263. package/dist/skills/store.d.ts.map +1 -0
  264. package/dist/skills/store.js +279 -0
  265. package/dist/skills/store.js.map +1 -0
  266. package/dist/skills/validate.d.ts +11 -0
  267. package/dist/skills/validate.d.ts.map +1 -0
  268. package/dist/skills/validate.js +112 -0
  269. package/dist/skills/validate.js.map +1 -0
  270. package/dist/skills/versions-fs.d.ts +45 -0
  271. package/dist/skills/versions-fs.d.ts.map +1 -0
  272. package/dist/skills/versions-fs.js +234 -0
  273. package/dist/skills/versions-fs.js.map +1 -0
  274. package/dist/skills/versions.d.ts +56 -0
  275. package/dist/skills/versions.d.ts.map +1 -0
  276. package/dist/skills/versions.js +351 -0
  277. package/dist/skills/versions.js.map +1 -0
  278. package/dist/trace/checks.d.ts +63 -0
  279. package/dist/trace/checks.d.ts.map +1 -0
  280. package/dist/trace/checks.js +487 -0
  281. package/dist/trace/checks.js.map +1 -0
  282. package/dist/trace/claude.d.ts +124 -0
  283. package/dist/trace/claude.d.ts.map +1 -0
  284. package/dist/trace/claude.js +303 -0
  285. package/dist/trace/claude.js.map +1 -0
  286. package/dist/trace/codex-exec.d.ts +22 -0
  287. package/dist/trace/codex-exec.d.ts.map +1 -0
  288. package/dist/trace/codex-exec.js +129 -0
  289. package/dist/trace/codex-exec.js.map +1 -0
  290. package/dist/trace/codex-meta.d.ts +23 -0
  291. package/dist/trace/codex-meta.d.ts.map +1 -0
  292. package/dist/trace/codex-meta.js +112 -0
  293. package/dist/trace/codex-meta.js.map +1 -0
  294. package/dist/trace/codex.d.ts +33 -0
  295. package/dist/trace/codex.d.ts.map +1 -0
  296. package/dist/trace/codex.js +485 -0
  297. package/dist/trace/codex.js.map +1 -0
  298. package/dist/trace/cursor.d.ts +16 -0
  299. package/dist/trace/cursor.d.ts.map +1 -0
  300. package/dist/trace/cursor.js +133 -0
  301. package/dist/trace/cursor.js.map +1 -0
  302. package/dist/trace/dialect.d.ts +43 -0
  303. package/dist/trace/dialect.d.ts.map +1 -0
  304. package/dist/trace/dialect.js +95 -0
  305. package/dist/trace/dialect.js.map +1 -0
  306. package/dist/trace/epochs.d.ts +10 -0
  307. package/dist/trace/epochs.d.ts.map +1 -0
  308. package/dist/trace/epochs.js +16 -0
  309. package/dist/trace/epochs.js.map +1 -0
  310. package/dist/trace/failure.d.ts +15 -0
  311. package/dist/trace/failure.d.ts.map +1 -0
  312. package/dist/trace/failure.js +69 -0
  313. package/dist/trace/failure.js.map +1 -0
  314. package/dist/trace/gate-file.d.ts +71 -0
  315. package/dist/trace/gate-file.d.ts.map +1 -0
  316. package/dist/trace/gate-file.js +329 -0
  317. package/dist/trace/gate-file.js.map +1 -0
  318. package/dist/trace/guard-fast.d.ts +22 -0
  319. package/dist/trace/guard-fast.d.ts.map +1 -0
  320. package/dist/trace/guard-fast.js +213 -0
  321. package/dist/trace/guard-fast.js.map +1 -0
  322. package/dist/trace/housekeeping.d.ts +5 -0
  323. package/dist/trace/housekeeping.d.ts.map +1 -0
  324. package/dist/trace/housekeeping.js +93 -0
  325. package/dist/trace/housekeeping.js.map +1 -0
  326. package/dist/trace/jobs.d.ts +52 -0
  327. package/dist/trace/jobs.d.ts.map +1 -0
  328. package/dist/trace/jobs.js +182 -0
  329. package/dist/trace/jobs.js.map +1 -0
  330. package/dist/trace/known-repo.d.ts +3 -0
  331. package/dist/trace/known-repo.d.ts.map +1 -0
  332. package/dist/trace/known-repo.js +55 -0
  333. package/dist/trace/known-repo.js.map +1 -0
  334. package/dist/trace/pool.d.ts +40 -0
  335. package/dist/trace/pool.d.ts.map +1 -0
  336. package/dist/trace/pool.js +154 -0
  337. package/dist/trace/pool.js.map +1 -0
  338. package/dist/trace/repairs.d.ts +27 -0
  339. package/dist/trace/repairs.d.ts.map +1 -0
  340. package/dist/trace/repairs.js +303 -0
  341. package/dist/trace/repairs.js.map +1 -0
  342. package/dist/trace/run-calls.d.ts +82 -0
  343. package/dist/trace/run-calls.d.ts.map +1 -0
  344. package/dist/trace/run-calls.js +331 -0
  345. package/dist/trace/run-calls.js.map +1 -0
  346. package/dist/trace/run-join.d.ts +20 -0
  347. package/dist/trace/run-join.d.ts.map +1 -0
  348. package/dist/trace/run-join.js +99 -0
  349. package/dist/trace/run-join.js.map +1 -0
  350. package/dist/trace/run-sheets.d.ts +26 -0
  351. package/dist/trace/run-sheets.d.ts.map +1 -0
  352. package/dist/trace/run-sheets.js +145 -0
  353. package/dist/trace/run-sheets.js.map +1 -0
  354. package/dist/trace/run-turns.d.ts +24 -0
  355. package/dist/trace/run-turns.d.ts.map +1 -0
  356. package/dist/trace/run-turns.js +67 -0
  357. package/dist/trace/run-turns.js.map +1 -0
  358. package/dist/trace/run-verdict.d.ts +24 -0
  359. package/dist/trace/run-verdict.d.ts.map +1 -0
  360. package/dist/trace/run-verdict.js +176 -0
  361. package/dist/trace/run-verdict.js.map +1 -0
  362. package/dist/trace/runs.d.ts +54 -0
  363. package/dist/trace/runs.d.ts.map +1 -0
  364. package/dist/trace/runs.js +501 -0
  365. package/dist/trace/runs.js.map +1 -0
  366. package/dist/trace/skill-session.d.ts +64 -0
  367. package/dist/trace/skill-session.d.ts.map +1 -0
  368. package/dist/trace/skill-session.js +232 -0
  369. package/dist/trace/skill-session.js.map +1 -0
  370. package/dist/trace/tamper.d.ts +12 -0
  371. package/dist/trace/tamper.d.ts.map +1 -0
  372. package/dist/trace/tamper.js +405 -0
  373. package/dist/trace/tamper.js.map +1 -0
  374. package/dist/trace/typed.d.ts +30 -0
  375. package/dist/trace/typed.d.ts.map +1 -0
  376. package/dist/trace/typed.js +132 -0
  377. package/dist/trace/typed.js.map +1 -0
  378. package/dist/trace/wall-state.d.ts +86 -0
  379. package/dist/trace/wall-state.d.ts.map +1 -0
  380. package/dist/trace/wall-state.js +279 -0
  381. package/dist/trace/wall-state.js.map +1 -0
  382. package/dist/trace/walls.d.ts +40 -0
  383. package/dist/trace/walls.d.ts.map +1 -0
  384. package/dist/trace/walls.js +318 -0
  385. package/dist/trace/walls.js.map +1 -0
  386. package/dist/vendor/tree-sitter-swift/LICENSE +21 -0
  387. package/dist/vendor/tree-sitter-swift/node-types.json +30694 -0
  388. package/dist/vendor/tree-sitter-swift/prebuilds/darwin-arm64/tree-sitter-swift.node +0 -0
  389. package/dist/vendor/tree-sitter-swift/prebuilds/darwin-x64/tree-sitter-swift.node +0 -0
  390. package/dist/vendor/tree-sitter-swift/prebuilds/linux-arm64/tree-sitter-swift.node +0 -0
  391. package/dist/vendor/tree-sitter-swift/prebuilds/linux-x64/tree-sitter-swift.node +0 -0
  392. package/dist/vendor/tree-sitter-swift/prebuilds/win32-arm64/tree-sitter-swift.node +0 -0
  393. package/dist/vendor/tree-sitter-swift/prebuilds/win32-x64/tree-sitter-swift.node +0 -0
  394. package/package.json +6 -3
  395. package/scripts/stamp-telemetry-key.mjs +8 -5
  396. package/scripts/vendor-grammars.mjs +35 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * `~/.trail/state/skills.json` (design 2.2, spec 6): what changes often
3
+ * about each skill, per person, keyed by the skill id, for every scope:
4
+ * status, where it came from, uses and checked uses, when it last worked,
5
+ * the hash of the file as Trail last wrote it, and the failed step of the
6
+ * last two uses. The SKILL.md holds only what describes the skill.
7
+ *
8
+ * Status moves (4.8, spec 13): a candidate becomes active on its first use
9
+ * whose check passed; two uses in a row that failed at the same step, or
10
+ * that the person corrected, make it needs-fix (never injected; the index
11
+ * says why), and it goes back to what it was when its SKILL.md is changed by
12
+ * hand. A failed ready probe never counts against it. Every move is a ledger
13
+ * `status` line, written after the state file.
14
+ *
15
+ * Every write is a locked read-modify-write; a lock that can't be had in
16
+ * time changes nothing. Keys a later version adds are kept.
17
+ */
18
+ import { readFileSync, statSync } from 'node:fs';
19
+ import { readJsonSafe, trailPath, withLock, writePrivate } from '../util/private-fs.js';
20
+ import { appendLedger, readLedger } from './ledger.js';
21
+ import { localDate } from './settings.js';
22
+ import { parseSkillMd, skillHash } from './skillmd.js';
23
+ import { isLinked } from './own-folder.js';
24
+ import { dirname } from 'node:path';
25
+ const STATUSES = new Set(['candidate', 'active', 'needs-fix', 'retired']);
26
+ const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
27
+ /** 'Nov 2', in local time. */
28
+ const monthDay = (iso) => {
29
+ const d = new Date(iso);
30
+ return Number.isNaN(d.getTime()) ? 'an earlier day' : `${MONTHS[d.getMonth()]} ${d.getDate()}`;
31
+ };
32
+ export function skillsStatePath(env) {
33
+ return trailPath(env, 'state', 'skills.json');
34
+ }
35
+ const isMap = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
36
+ const strOr = (v, d) => (typeof v === 'string' ? v : d);
37
+ const num = (v) => (typeof v === 'number' && Number.isFinite(v) && v >= 0 ? Math.floor(v) : 0);
38
+ /** An entry as read: null when it isn't one; missing newer fields get their defaults; unknown keys stay. */
39
+ function entryOf(v) {
40
+ if (!isMap(v) || typeof v.name !== 'string' || !STATUSES.has(v.status))
41
+ return null;
42
+ const src = isMap(v.source) && typeof v.source.at === 'string' ? { commands: num(v.source.commands), failed: num(v.source.failed), at: v.source.at } : null;
43
+ const fails = Array.isArray(v.lastFails)
44
+ ? v.lastFails.filter((f) => isMap(f) && typeof f.step === 'number' && typeof f.at === 'string').slice(-2)
45
+ : [];
46
+ const { fixHash, ...rest } = v;
47
+ return {
48
+ ...rest,
49
+ ...(typeof fixHash === 'string' ? { fixHash } : {}),
50
+ name: v.name,
51
+ scope: v.scope === 'repo' || v.scope === 'team' ? v.scope : 'personal',
52
+ status: v.status,
53
+ from: v.from === 'init' || v.from === 'repeated' || v.from === 'repaired' ? v.from : 'asked',
54
+ runId: strOr(v.runId, null),
55
+ addedAt: strOr(v.addedAt, ''),
56
+ lastWorked: strOr(v.lastWorked, null),
57
+ lastUsedAt: strOr(v.lastUsedAt, null),
58
+ lastUsedRepo: strOr(v.lastUsedRepo, null),
59
+ uses: num(v.uses),
60
+ checkedUses: num(v.checkedUses),
61
+ hash: strOr(v.hash, ''),
62
+ source: src,
63
+ lastFails: fails.map((f) => ({ step: f.step, at: f.at })),
64
+ promoteOffers: isMap(v.promoteOffers) ? v.promoteOffers : {},
65
+ };
66
+ }
67
+ function fileOf(raw) {
68
+ const skills = {};
69
+ if (isMap(raw) && isMap(raw.skills)) {
70
+ for (const [id, v] of Object.entries(raw.skills)) {
71
+ const e = entryOf(v);
72
+ if (e)
73
+ skills[id] = e;
74
+ }
75
+ }
76
+ return { v: 1, skills };
77
+ }
78
+ export function readSkillsState(env) {
79
+ return fileOf(readJsonSafe(skillsStatePath(env)));
80
+ }
81
+ export function getSkillState(id, env) {
82
+ return readSkillsState(env).skills[id] ?? null;
83
+ }
84
+ /**
85
+ * Locked read-modify-write of one entry. Return undefined from fn to delete. undefined also when the lock timed out,
86
+ * or when the state folder is a link (never written through, own-folder.ts): nothing changed either way.
87
+ */
88
+ export function updateSkillState(id, fn, env) {
89
+ const path = skillsStatePath(env);
90
+ if (isLinked(dirname(path)))
91
+ return undefined;
92
+ const done = withLock(path, () => {
93
+ const raw = readJsonSafe(path);
94
+ const keep = isMap(raw) ? raw : {};
95
+ const file = fileOf(raw);
96
+ const had = file.skills[id];
97
+ const next = fn(had === undefined ? undefined : structuredClone(had));
98
+ if (next === undefined) {
99
+ if (had === undefined)
100
+ return undefined;
101
+ delete file.skills[id];
102
+ }
103
+ else
104
+ file.skills[id] = next;
105
+ writePrivate(path, `${JSON.stringify({ ...keep, v: 1, skills: file.skills }, null, 2)}\n`);
106
+ return next;
107
+ });
108
+ return done.ok ? done.value : undefined;
109
+ }
110
+ /** updateSkillState, then the ledger status lines fn collected, only once the state is written. */
111
+ function change(id, env, fn) {
112
+ const moves = [];
113
+ const next = updateSkillState(id, (s) => (s ? fn(s, moves) : undefined), env);
114
+ if (next)
115
+ for (const m of moves) {
116
+ try {
117
+ appendLedger(id, { event: 'status', skill: id, ...m }, env);
118
+ }
119
+ catch { /* the state is the truth; the ledger is its record */ }
120
+ }
121
+ return next;
122
+ }
123
+ /**
124
+ * The hash of the personal skill's SKILL.md as it is now (`skills/<name>/SKILL.md`, a regular file of at most
125
+ * 64 KB that is still this skill's), or undefined. D65: kept when the skill is marked needs-fix, so a hand edit
126
+ * made before the failures is not taken for a fix.
127
+ */
128
+ function fileHashOf(id, name, env) {
129
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name) || name.includes('..'))
130
+ return undefined; // one folder name only
131
+ try {
132
+ const file = trailPath(env, 'skills', name, 'SKILL.md');
133
+ const st = statSync(file);
134
+ if (!st.isFile() || st.size > 64 * 1024)
135
+ return undefined;
136
+ const text = readFileSync(file, 'utf8');
137
+ return parseSkillMd(text, name)?.meta.trail === id ? skillHash(text) : undefined;
138
+ }
139
+ catch {
140
+ return undefined;
141
+ }
142
+ }
143
+ /** To needs-fix from candidate or active, keeping what it was and the file's hash right now. */
144
+ function markNeedsFix(id, s, why, at, moves, env) {
145
+ if (s.status !== 'candidate' && s.status !== 'active')
146
+ return;
147
+ moves.push({ at, from: s.status, to: 'needs-fix', reason: 'failed-twice' });
148
+ s.prevStatus = s.status;
149
+ s.status = 'needs-fix';
150
+ s.statusWhy = why;
151
+ const now = fileHashOf(id, s.name, env);
152
+ if (now)
153
+ s.fixHash = now;
154
+ else
155
+ delete s.fixHash;
156
+ }
157
+ /**
158
+ * 4.8, after the caller wrote the ledger `use` line: uses, lastUsedAt/Repo; a passed check counts as a checked use,
159
+ * sets lastWorked (local date) and makes a candidate active; the failed step joins lastFails (the last two), and two
160
+ * at the same step make it needs-fix; a use with no failed step empties lastFails. Ready probes never count.
161
+ */
162
+ export function recordUse(id, use, env) {
163
+ return change(id, env, (s, moves) => {
164
+ s.uses += 1;
165
+ s.lastUsedAt = use.at;
166
+ s.lastUsedRepo = use.repo;
167
+ if (use.check === 'passed') {
168
+ s.checkedUses += 1;
169
+ s.lastWorked = localDate(use.at);
170
+ if (s.status === 'candidate') {
171
+ moves.push({ at: use.at, from: 'candidate', to: 'active', reason: 'checked-use' });
172
+ s.status = 'active';
173
+ }
174
+ }
175
+ if (use.failedStep === null)
176
+ s.lastFails = [];
177
+ else {
178
+ s.lastFails = [...s.lastFails, { step: use.failedStep, at: use.at }].slice(-2);
179
+ const [a, b] = s.lastFails;
180
+ if (a && b && a.step === b.step)
181
+ markNeedsFix(id, s, `step ${b.step} failed on ${monthDay(a.at)} and ${monthDay(b.at)}`, use.at, moves, env);
182
+ }
183
+ return s;
184
+ });
185
+ }
186
+ /**
187
+ * The person corrected a use within 2 prompts (3.2 step 5): one ledger `corrected` line per use, and when the use
188
+ * right before or after it in the ledger was corrected too, needs-fix (spec 13: two uses in a row corrected).
189
+ * The ledger is read and the line written under the state lock, so two hooks correcting neighbouring uses at once
190
+ * each see the other's line. undefined when the skill has no state or no such use, or the ledger can't be written.
191
+ */
192
+ export function recordCorrected(id, useId, env, now = new Date()) {
193
+ const at = now.toISOString();
194
+ let found = false;
195
+ const next = change(id, env, (s, moves) => {
196
+ const lines = readLedger(id, env);
197
+ const uses = lines.filter((l) => l.event === 'use');
198
+ const i = uses.findIndex((u) => u.useId === useId);
199
+ if (i < 0)
200
+ return s;
201
+ const corrected = new Set(lines.flatMap((l) => (l.event === 'corrected' ? [l.useId] : [])));
202
+ if (!corrected.has(useId)) {
203
+ try {
204
+ appendLedger(id, { at, event: 'corrected', skill: id, useId }, env);
205
+ }
206
+ catch {
207
+ return s;
208
+ }
209
+ corrected.add(useId);
210
+ }
211
+ found = true;
212
+ const pair = [uses[i - 1], uses[i + 1]].find((u) => u && corrected.has(u.useId));
213
+ if (pair) {
214
+ const [a, b] = Date.parse(pair.at) < Date.parse(uses[i].at) ? [pair, uses[i]] : [uses[i], pair];
215
+ markNeedsFix(id, s, `corrected after its use on ${monthDay(a.at)} and ${monthDay(b.at)}`, at, moves, env);
216
+ }
217
+ return s;
218
+ });
219
+ return found ? next : undefined;
220
+ }
221
+ /**
222
+ * A needs-fix skill whose SKILL.md changed by hand after it was marked (its hash is not the one kept at the mark,
223
+ * `fixHash`, D65; the hash Trail wrote when no mark hash was kept) was fixed: it goes back to what it was (4.8;
224
+ * candidate when that is unknown), with its failures forgotten. An edit made before the failures is not a fix, so
225
+ * it can't bring the skill back read after read. `hash` stays the one Trail wrote (spec 6: hand edits are phase 2's
226
+ * to propose a diff for). Any other status is left alone.
227
+ */
228
+ export function handEdited(id, fileHash, env, now = new Date()) {
229
+ // Checked before the lock (most reads change nothing) and again under it.
230
+ const edited = (e) => e.status === 'needs-fix' && fileHash !== (e.fixHash ?? e.hash);
231
+ const s = getSkillState(id, env);
232
+ if (!s || !edited(s))
233
+ return s ?? undefined;
234
+ return change(id, env, (e, moves) => {
235
+ if (!edited(e))
236
+ return e;
237
+ const back = e.prevStatus && e.prevStatus !== 'needs-fix' && e.prevStatus !== 'retired' ? e.prevStatus : 'candidate';
238
+ moves.push({ at: now.toISOString(), from: 'needs-fix', to: back, reason: 'restore' });
239
+ e.status = back;
240
+ e.lastFails = [];
241
+ delete e.statusWhy;
242
+ delete e.prevStatus;
243
+ delete e.fixHash;
244
+ return e;
245
+ });
246
+ }
247
+ /** The skill used most recently in any of repoKeys, with when (for the check cue). A retired skill never answers. */
248
+ export function lastUsedIn(repoKeys, env) {
249
+ const keys = new Set(repoKeys.map((k) => k.toLowerCase()));
250
+ let best = null;
251
+ for (const [id, s] of Object.entries(readSkillsState(env).skills)) {
252
+ if (s.status === 'retired' || !s.lastUsedAt || !s.lastUsedRepo || !keys.has(s.lastUsedRepo.toLowerCase()))
253
+ continue;
254
+ if (!best || Date.parse(s.lastUsedAt) > Date.parse(best.at))
255
+ best = { id, at: s.lastUsedAt };
256
+ }
257
+ return best;
258
+ }
259
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/skills/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The file side of the skill store (store.ts, store-held.ts): private
3
+ * folders that never chmod or write through a link, capped reads, the one
4
+ * store lock, a skill folder written whole, and the state entry and ledger
5
+ * line a new personal skill starts with.
6
+ *
7
+ * A name reaches here from an agent's command line or a person's, so every
8
+ * name is checked to be one folder name before it is joined to a path.
9
+ */
10
+ import { type Stats } from 'node:fs';
11
+ import type { CompiledSkill, SkillFrom, SkillRef, SkillState } from './types.js';
12
+ import { type Locked } from '../util/private-fs.js';
13
+ /** SKILL.md is at most 60 lines; anything this big is not one. */
14
+ export declare const MAX_SKILL_BYTES: number;
15
+ /** How long a person's command waits for the store; a hook's bookkeeping waits less. */
16
+ export declare const PERSON_WAIT_MS = 1000;
17
+ export declare const HOOK_WAIT_MS = 200;
18
+ /** One folder name: no separators, no dot start, no `..`. Wider than NAME_RE so hand-made folders can be named back. */
19
+ export declare const safeName: (name: string) => boolean;
20
+ export declare const lstatOrNull: (p: string) => Stats | null;
21
+ export declare const statOrNull: (p: string) => Stats | null;
22
+ /** A folder of ours: made 0700 when missing, tightened when it is a real folder; a link is left as it is (never chmod through it). */
23
+ export declare function privateDir(dir: string): void;
24
+ /** The file's text when it is a regular file (links followed) of at most 64 KB; null otherwise. */
25
+ export declare function readCapped(file: string): string | null;
26
+ export declare const skillsDir: (env?: NodeJS.ProcessEnv) => string;
27
+ export declare const heldDir: (env?: NodeJS.ProcessEnv) => string;
28
+ export declare const retiredDir: (env?: NodeJS.ProcessEnv) => string;
29
+ /**
30
+ * Every change to skills/ or held/ runs under one lock (`skills/.store.lock`). Throws when it can't be had in time,
31
+ * and before anything is written when one of Trail's own folders is a link (own-folder.ts).
32
+ */
33
+ export declare function underStoreLock<T>(env: NodeJS.ProcessEnv | undefined, fn: () => T, waitMs?: number): T;
34
+ /** The same lock for a hook's bookkeeping: `{ ok: false }` when busy or when one of Trail's own folders is a link; nothing changed. */
35
+ export declare function tryStoreLock<T>(env: NodeJS.ProcessEnv | undefined, fn: () => T, waitMs?: number): Locked<T>;
36
+ /**
37
+ * A skill's folder, written whole into a folder that must not exist yet (made here, 0700): SKILL.md (0600), each
38
+ * helper in scripts/ (0700), and an empty lessons/ when asked. Throws on a folder already there (a link included),
39
+ * a bad name, or a helper whose file name is not one plain file name.
40
+ */
41
+ export declare function writeSkillFolder(dir: string, c: CompiledSkill, text: string, opts: {
42
+ lessons: boolean;
43
+ }): void;
44
+ export declare function newSkillId(): string;
45
+ /**
46
+ * The id to save under: the compiled one, unless another skill already holds it, a retired one included (restoring
47
+ * it brings its state back under that id, so two skills must never share one).
48
+ */
49
+ export declare function freeId(id: string, name: string, env?: NodeJS.ProcessEnv): string;
50
+ /** Throws unless the name can be a saved skill's: NAME_RE, no `--` or trailing dash, not one of Trail's own words. */
51
+ export declare function checkSaveName(name: string): void;
52
+ /** The skill folders other tools keep in the person's home (`~/.claude/skills`, `~/.agents/skills`, `$CLAUDE_CONFIG_DIR/skills`). */
53
+ export declare function homeSkillDirs(env?: NodeJS.ProcessEnv): string[];
54
+ /** What keeping or restoring a skill would collide with, without a checkout: built in, a personal skill, a host's skill. */
55
+ export declare function takenAtHome(name: string, env?: NodeJS.ProcessEnv): 'built-in' | 'personal' | 'host' | null;
56
+ export declare function personalRef(id: string, name: string, applies: string | null, env?: NodeJS.ProcessEnv): SkillRef;
57
+ /**
58
+ * A new personal skill's state (candidate, uses 0) and its ledger `saved` line. Throws when the state can't be
59
+ * written (its lock busy, as a hook that died holding it leaves it for 10 s): a skill with no state entry would be
60
+ * recalled but could never count a use, so the caller undoes the save.
61
+ */
62
+ export declare function startSkill(id: string, init: {
63
+ name: string;
64
+ from: SkillFrom;
65
+ runId: string | null;
66
+ hash: string;
67
+ source: SkillState['source'];
68
+ version: string;
69
+ consent: 'offer-yes' | 'asked' | 'init';
70
+ stepsVerified: number;
71
+ stepsTotal: number;
72
+ now: Date;
73
+ env?: NodeJS.ProcessEnv;
74
+ }): void;
75
+ /** Compiled steps plus a check that is not itself a step (4.9 step 10). */
76
+ export declare const stepsTotal: (c: Pick<CompiledSkill, "steps" | "check" | "checkIsStep">) => number;
77
+ //# sourceMappingURL=store-fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-fs.d.ts","sourceRoot":"","sources":["../../src/skills/store-fs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The file side of the skill store (store.ts, store-held.ts): private
3
+ * folders that never chmod or write through a link, capped reads, the one
4
+ * store lock, a skill folder written whole, and the state entry and ledger
5
+ * line a new personal skill starts with.
6
+ *
7
+ * A name reaches here from an agent's command line or a person's, so every
8
+ * name is checked to be one folder name before it is joined to a path.
9
+ */
10
+ import { chmodSync, lstatSync, mkdirSync, readFileSync, rmSync, statSync } from 'node:fs';
11
+ import { homedir } from 'node:os';
12
+ import { join } from 'node:path';
13
+ import { trailPath, withLock, writePrivate } from '../util/private-fs.js';
14
+ import { BUILT_IN_NAMES, goodName } from './compile-words.js';
15
+ import { appendLedger } from './ledger.js';
16
+ import { getSkillState, updateSkillState } from './state.js';
17
+ import { localDate } from './settings.js';
18
+ import { randomBytes } from 'node:crypto';
19
+ import { linkedOwnFolder, ownFolder } from './own-folder.js';
20
+ const POSIX = process.platform !== 'win32';
21
+ /** SKILL.md is at most 60 lines; anything this big is not one. */
22
+ export const MAX_SKILL_BYTES = 64 * 1024;
23
+ /** How long a person's command waits for the store; a hook's bookkeeping waits less. */
24
+ export const PERSON_WAIT_MS = 1000;
25
+ export const HOOK_WAIT_MS = 200;
26
+ /** One folder name: no separators, no dot start, no `..`. Wider than NAME_RE so hand-made folders can be named back. */
27
+ export const safeName = (name) => /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(String(name)) && !String(name).includes('..');
28
+ export const lstatOrNull = (p) => {
29
+ try {
30
+ return lstatSync(p);
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ };
36
+ export const statOrNull = (p) => {
37
+ try {
38
+ return statSync(p);
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ };
44
+ /** A folder of ours: made 0700 when missing, tightened when it is a real folder; a link is left as it is (never chmod through it). */
45
+ export function privateDir(dir) {
46
+ if (!lstatOrNull(dir))
47
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
48
+ const st = lstatOrNull(dir);
49
+ if (POSIX && st?.isDirectory()) {
50
+ try {
51
+ chmodSync(dir, 0o700);
52
+ }
53
+ catch { /* not ours to change */ }
54
+ }
55
+ }
56
+ /** The file's text when it is a regular file (links followed) of at most 64 KB; null otherwise. */
57
+ export function readCapped(file) {
58
+ const st = statOrNull(file);
59
+ if (!st?.isFile() || st.size > MAX_SKILL_BYTES)
60
+ return null;
61
+ try {
62
+ return readFileSync(file, 'utf8');
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ export const skillsDir = (env) => trailPath(env, 'skills');
69
+ export const heldDir = (env) => trailPath(env, 'held');
70
+ export const retiredDir = (env) => join(skillsDir(env), '.retired');
71
+ /**
72
+ * Every change to skills/ or held/ runs under one lock (`skills/.store.lock`). Throws when it can't be had in time,
73
+ * and before anything is written when one of Trail's own folders is a link (own-folder.ts).
74
+ */
75
+ export function underStoreLock(env, fn, waitMs = PERSON_WAIT_MS) {
76
+ const linked = linkedOwnFolder(env);
77
+ if (linked)
78
+ ownFolder(trailPath(env, linked));
79
+ const done = tryStoreLock(env, fn, waitMs);
80
+ if (!done.ok)
81
+ throw new Error('trail: the skill store is busy (another trail command is changing it). Try again.');
82
+ return done.value;
83
+ }
84
+ /** The same lock for a hook's bookkeeping: `{ ok: false }` when busy or when one of Trail's own folders is a link; nothing changed. */
85
+ export function tryStoreLock(env, fn, waitMs = HOOK_WAIT_MS) {
86
+ if (linkedOwnFolder(env))
87
+ return { ok: false };
88
+ privateDir(trailPath(env));
89
+ privateDir(skillsDir(env));
90
+ return withLock(join(skillsDir(env), '.store'), fn, waitMs);
91
+ }
92
+ /**
93
+ * A skill's folder, written whole into a folder that must not exist yet (made here, 0700): SKILL.md (0600), each
94
+ * helper in scripts/ (0700), and an empty lessons/ when asked. Throws on a folder already there (a link included),
95
+ * a bad name, or a helper whose file name is not one plain file name.
96
+ */
97
+ export function writeSkillFolder(dir, c, text, opts) {
98
+ for (const h of c.helpers)
99
+ if (!safeName(h.file))
100
+ throw new Error(`trail: a helper script needs a plain file name: ${JSON.stringify(h.file).slice(0, 60)}`);
101
+ try {
102
+ mkdirSync(dir, { mode: 0o700 });
103
+ }
104
+ catch (e) {
105
+ if (e.code === 'EEXIST')
106
+ throw new Error(`trail: a skill folder called ${c.name} is already there`);
107
+ throw e;
108
+ }
109
+ try {
110
+ privateDir(dir);
111
+ writePrivate(join(dir, 'SKILL.md'), text);
112
+ if (c.helpers.length || opts.lessons)
113
+ privateDir(join(dir, 'scripts'));
114
+ for (const h of c.helpers)
115
+ writePrivate(join(dir, 'scripts', h.file), h.content, 0o700);
116
+ if (opts.lessons)
117
+ privateDir(join(dir, 'lessons'));
118
+ }
119
+ catch (e) {
120
+ // Half a skill (a full disk) would hold the name and never list: the folder made above goes.
121
+ rmSync(dir, { recursive: true, force: true });
122
+ throw e;
123
+ }
124
+ }
125
+ export function newSkillId() {
126
+ return `s-${randomBytes(3).toString('hex')}`;
127
+ }
128
+ /**
129
+ * The id to save under: the compiled one, unless another skill already holds it, a retired one included (restoring
130
+ * it brings its state back under that id, so two skills must never share one).
131
+ */
132
+ export function freeId(id, name, env) {
133
+ const held = (x) => {
134
+ const s = getSkillState(x, env);
135
+ return s !== null && s.name !== name;
136
+ };
137
+ let out = id;
138
+ for (let i = 0; i < 64 && held(out); i++)
139
+ out = newSkillId();
140
+ return out;
141
+ }
142
+ /** Throws unless the name can be a saved skill's: NAME_RE, no `--` or trailing dash, not one of Trail's own words. */
143
+ export function checkSaveName(name) {
144
+ if (!goodName(name))
145
+ throw new Error(`trail: not a skill name: ${JSON.stringify(name).slice(0, 60)}`);
146
+ }
147
+ /** The skill folders other tools keep in the person's home (`~/.claude/skills`, `~/.agents/skills`, `$CLAUDE_CONFIG_DIR/skills`). */
148
+ export function homeSkillDirs(env) {
149
+ const e = env ?? process.env;
150
+ const home = e.HOME || homedir();
151
+ const dirs = [join(home, '.claude', 'skills'), join(home, '.agents', 'skills')];
152
+ if (e.CLAUDE_CONFIG_DIR)
153
+ dirs.push(join(e.CLAUDE_CONFIG_DIR, 'skills'));
154
+ return dirs;
155
+ }
156
+ /** What keeping or restoring a skill would collide with, without a checkout: built in, a personal skill, a host's skill. */
157
+ export function takenAtHome(name, env) {
158
+ if (BUILT_IN_NAMES.has(name))
159
+ return 'built-in';
160
+ if (lstatOrNull(join(skillsDir(env), name)))
161
+ return 'personal';
162
+ if (homeSkillDirs(env).some((d) => lstatOrNull(join(d, name))))
163
+ return 'host';
164
+ return null;
165
+ }
166
+ export function personalRef(id, name, applies, env) {
167
+ const dir = join(skillsDir(env), name);
168
+ return { id, name, scope: 'personal', applies, dir, file: join(dir, 'SKILL.md') };
169
+ }
170
+ /**
171
+ * A new personal skill's state (candidate, uses 0) and its ledger `saved` line. Throws when the state can't be
172
+ * written (its lock busy, as a hook that died holding it leaves it for 10 s): a skill with no state entry would be
173
+ * recalled but could never count a use, so the caller undoes the save.
174
+ */
175
+ export function startSkill(id, init) {
176
+ const at = init.now.toISOString();
177
+ const written = updateSkillState(id, () => ({
178
+ name: init.name, scope: 'personal', status: 'candidate', from: init.from, runId: init.runId, addedAt: at,
179
+ lastWorked: init.source ? localDate(init.source.at) : null, lastUsedAt: null, lastUsedRepo: null, uses: 0, checkedUses: 0,
180
+ hash: init.hash, source: init.source, lastFails: [], promoteOffers: {},
181
+ }), init.env);
182
+ if (!written)
183
+ throw new Error('trail: the skill state is busy (a hook is writing it). Try again in a few seconds.');
184
+ try {
185
+ appendLedger(id, {
186
+ at, event: 'saved', skill: id, v: init.version, from: init.from, scope: 'personal',
187
+ receipt: { consent: init.consent, stepsVerified: init.stepsVerified, stepsTotal: init.stepsTotal },
188
+ }, init.env);
189
+ }
190
+ catch { /* the state is the truth; the ledger is its record */ }
191
+ }
192
+ /** Compiled steps plus a check that is not itself a step (4.9 step 10). */
193
+ export const stepsTotal = (c) => c.steps.length + (c.check && !c.checkIsStep ? 1 : 0);
194
+ //# sourceMappingURL=store-fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-fs.js","sourceRoot":"","sources":["../../src/skills/store-fs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { JobClass } from '../trace/types.js';
2
+ import type { CompiledSkill, SkillRef } from './types.js';
3
+ import type { PersonCheck } from './person.js';
4
+ export interface HeldItem {
5
+ name: string;
6
+ why: 'no-yes' | 'host';
7
+ host: string;
8
+ job: JobClass | null;
9
+ repoKey: string;
10
+ at: string;
11
+ shownAt: string | null;
12
+ dir: string;
13
+ /** The run it was compiled from (D65: a live save for the same run drops the held item instead of being refused). Null when held.json lacks it. */
14
+ runId?: string | null;
15
+ /** D93: sha256(sessionId).slice(0, 12) of the session that held it; null when held.json lacks it (written before). */
16
+ session?: string | null;
17
+ }
18
+ /** Every held item Trail wrote, whatever its age, oldest first. */
19
+ export declare function allHeld(env?: NodeJS.ProcessEnv): HeldItem[];
20
+ /** Writes held/<name>/SKILL.md (+ scripts/) and held.json, replacing a held item of the same name. */
21
+ export declare function saveHeld(c: CompiledSkill, why: HeldItem['why'], meta: {
22
+ host: string;
23
+ job: JobClass | null;
24
+ repoKey: string;
25
+ session?: string | null;
26
+ }, env?: NodeJS.ProcessEnv, now?: Date): HeldItem;
27
+ /** Held items not shown yet, and shown ones younger than 24 h (still keepable). */
28
+ export declare function listHeld(env?: NodeJS.ProcessEnv, now?: Date): HeldItem[];
29
+ /** Hook bookkeeping (SessionStart): a busy store leaves it unshown, to be shown next time. */
30
+ export declare function markHeldShown(name: string, env?: NodeJS.ProcessEnv, now?: Date): void;
31
+ export declare function dropHeld(name: string, env?: NodeJS.ProcessEnv): void;
32
+ /**
33
+ * The person keeps a held item: it moves into skills/<name> as a candidate they asked for (ledger `saved`, consent
34
+ * `asked`, no steps verified: the transcript was not read again). Refused for anyone but the person, an unknown or
35
+ * expired item, or a name a personal skill, a host's skill or Trail itself already uses.
36
+ */
37
+ export declare function keepHeld(name: string, person: PersonCheck, env?: NodeJS.ProcessEnv, now?: Date): {
38
+ ok: true;
39
+ ref: SkillRef;
40
+ } | {
41
+ ok: false;
42
+ reason: 'not-a-person' | 'unknown' | 'name-taken';
43
+ };
44
+ //# sourceMappingURL=store-held.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-held.d.ts","sourceRoot":"","sources":["../../src/skills/store-held.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ/C,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAC3I,mJAAmJ;IACnJ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sHAAsH;IACtH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAkCD,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,EAAE,CAW3D;AAED,sGAAsG;AACtG,wBAAgB,QAAQ,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,QAAQ,CAclN;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,QAAQ,EAAE,CAEpF;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI,CAOjG;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAMpE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,GAAE,IAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,GAAG,SAAS,GAAG,YAAY,CAAA;CAAE,CAwC3M"}