@iowarp/clio-coder 0.3.6 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +22 -6
  3. package/dist/{acp-2BEHC4DL.js → acp-U67UHUK2.js} +14 -14
  4. package/dist/{agents-LNNFTM53.js → agents-YU6SGALZ.js} +42 -35
  5. package/dist/assets/codewiki.json +1 -1
  6. package/dist/{auth-KXXFI2VS.js → auth-5ZPJOIVG.js} +32 -24
  7. package/dist/builtins-C6JMZVV6.js +17 -0
  8. package/dist/{chunk-E25LMLRW.js → chunk-26LEYJZH.js} +2 -2
  9. package/dist/{chunk-TSHXZTOQ.js → chunk-2HEJ2F35.js} +5 -5
  10. package/dist/{chunk-PBTHKCPN.js → chunk-2HFZQUHL.js} +7 -7
  11. package/dist/{chunk-FO5ZOVUY.js → chunk-3BINW3FP.js} +5 -5
  12. package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
  13. package/dist/{chunk-CKXWIANG.js → chunk-4SPRNWDE.js} +18 -16
  14. package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
  15. package/dist/{chunk-XF5N4U5A.js → chunk-5DHKRSMQ.js} +9 -8
  16. package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
  17. package/dist/{chunk-EKY57CSP.js → chunk-5H3GB5BO.js} +68 -772
  18. package/dist/{chunk-6XXKFVSN.js → chunk-5Q2VVUKB.js} +4 -4
  19. package/dist/{chunk-DJVECN66.js → chunk-7RFXX52T.js} +295 -3705
  20. package/dist/{chunk-ZXF4XRKW.js → chunk-7RGZWPB6.js} +158 -8
  21. package/dist/{chunk-FYYLNIL5.js → chunk-A2NJGIB3.js} +2 -2
  22. package/dist/{chunk-XXQNGV4M.js → chunk-A3WNZD3P.js} +548 -72
  23. package/dist/{chunk-VEZEGCGW.js → chunk-B5CSFE7B.js} +23 -21
  24. package/dist/{chunk-2SFS6XQE.js → chunk-DGSYXYMX.js} +3 -2
  25. package/dist/chunk-DR52UMZW.js +21 -0
  26. package/dist/{chunk-ZWLZP4ZT.js → chunk-DYIM5TJT.js} +98 -12
  27. package/dist/{chunk-QKMUKYO7.js → chunk-E77JEWSD.js} +270 -125
  28. package/dist/{chunk-LYF7OHWH.js → chunk-EMYUUSFG.js} +12 -467
  29. package/dist/{chunk-4VP4KH3K.js → chunk-EQ63NRB7.js} +8 -8
  30. package/dist/chunk-FBVTI2TJ.js +518 -0
  31. package/dist/{chunk-R46L2BIR.js → chunk-FHJEP5SW.js} +19 -25
  32. package/dist/{chunk-WR67VIZY.js → chunk-GN57SG4G.js} +66 -8
  33. package/dist/{chunk-RD5U66HV.js → chunk-GPIEI3LY.js} +9 -9
  34. package/dist/{chunk-PCZJO5TI.js → chunk-GU2UIAFZ.js} +13 -178
  35. package/dist/chunk-GWS3VEIW.js +195 -0
  36. package/dist/chunk-H7IXIC72.js +103 -0
  37. package/dist/{chunk-3BPUFZDL.js → chunk-HLE42MG7.js} +3 -3
  38. package/dist/{chunk-24I7BN55.js → chunk-IFBNV6H6.js} +3 -3
  39. package/dist/{chunk-QNQHSOLF.js → chunk-IGWKHNIQ.js} +114 -55
  40. package/dist/chunk-IIZWH4XA.js +172 -0
  41. package/dist/{chunk-AD2SYQYC.js → chunk-IJ7RPIYJ.js} +124 -6
  42. package/dist/chunk-J3YUBZWY.js +382 -0
  43. package/dist/{chunk-5JGRAMKL.js → chunk-JOZYP4GM.js} +8 -6
  44. package/dist/{chunk-OH3TOQTB.js → chunk-K4XHGFR5.js} +751 -15
  45. package/dist/{chunk-EYPA3EGJ.js → chunk-KTYTFRMB.js} +178 -14
  46. package/dist/chunk-LU7P4LHA.js +33 -0
  47. package/dist/chunk-ME6CCNFO.js +108 -0
  48. package/dist/chunk-MXKJU4JB.js +1100 -0
  49. package/dist/{chunk-RY3LY4J5.js → chunk-N22QMJKY.js} +21 -18
  50. package/dist/chunk-NMPKI6XL.js +3006 -0
  51. package/dist/chunk-NUGM5KR6.js +165 -0
  52. package/dist/{chunk-22NAGB7X.js → chunk-P43ETTHK.js} +5 -94
  53. package/dist/{chunk-NILBFAPG.js → chunk-PMDBGQSJ.js} +2 -2
  54. package/dist/chunk-PT7HYKEM.js +165 -0
  55. package/dist/chunk-RVG5JXAL.js +41 -0
  56. package/dist/{chunk-GEYXPTRF.js → chunk-RWSI4YD7.js} +2 -2
  57. package/dist/{chunk-4BPJXDWC.js → chunk-TANS5ZJS.js} +35 -19
  58. package/dist/{verifiers-NCBTHHN2.js → chunk-TB5666IT.js} +67 -324
  59. package/dist/{chunk-QM3F2GKX.js → chunk-TLQJPP24.js} +7927 -8088
  60. package/dist/{chunk-G7MUEIGA.js → chunk-TT36MB5S.js} +2 -1
  61. package/dist/chunk-TTHACPOM.js +961 -0
  62. package/dist/{chunk-6US73PDB.js → chunk-TYPGUK6W.js} +7 -7
  63. package/dist/{chunk-MFFY33HR.js → chunk-U6MBIEMB.js} +554 -209
  64. package/dist/chunk-VAWNZU7Z.js +242 -0
  65. package/dist/{chunk-IR4CFBFN.js → chunk-VCBR6CU7.js} +12 -12
  66. package/dist/{chunk-WHJYKASB.js → chunk-VHN4MY6O.js} +2 -2
  67. package/dist/{chunk-XYDYPRZI.js → chunk-VWZOAB7K.js} +10 -10
  68. package/dist/{chunk-ZRGEBJ4T.js → chunk-WLFILSD5.js} +48 -48
  69. package/dist/{chunk-K7T3E2SR.js → chunk-WNIJTQQK.js} +12 -11
  70. package/dist/{chunk-CYQKWTG3.js → chunk-WSB3FPX7.js} +68 -20
  71. package/dist/{chunk-KHSFENX2.js → chunk-WWCZ5F23.js} +116 -14
  72. package/dist/{chunk-XE2VEJHX.js → chunk-WXY7KU3G.js} +2 -2
  73. package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
  74. package/dist/{chunk-KOHPCX4K.js → chunk-XWSF374K.js} +5 -5
  75. package/dist/{chunk-CJUB2JJ2.js → chunk-YS5VLNH5.js} +10 -10
  76. package/dist/{chunk-ZZMN5OM4.js → chunk-ZNLWCMVZ.js} +2 -2
  77. package/dist/{chunk-WHGPSPT5.js → chunk-ZVJ5BLO2.js} +2 -2
  78. package/dist/cli/index.js +33 -31
  79. package/dist/{clio-M2KGYUFZ.js → clio-QVTYJ57A.js} +10 -10
  80. package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +5 -5
  81. package/dist/codewiki/build-worker.js +4 -4
  82. package/dist/{components-5TTYYX6G.js → components-ZFA3SAER.js} +9 -9
  83. package/dist/{config-XUUYQIWO.js → config-LW5IJFQN.js} +65 -55
  84. package/dist/{configure-IHJ7YOMV.js → configure-7XIZCOU4.js} +29 -24
  85. package/dist/{context-75MIWW3U.js → context-L3WL3X7K.js} +54 -43
  86. package/dist/{context-ZQ7SIFJV.js → context-N52ZA626.js} +30 -14
  87. package/dist/{context-74JLXAWD.js → context-Y6Y7QPR6.js} +12 -12
  88. package/dist/{context-clear-GYKWNUML.js → context-clear-MBQRLSDQ.js} +54 -43
  89. package/dist/{context-index-SSR5ECNE.js → context-index-HVMFQHK3.js} +5 -5
  90. package/dist/{context-working-set-UX5KEP4J.js → context-working-set-GS6DSO7F.js} +18 -18
  91. package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-22ZCNOM3.js} +367 -79
  92. package/dist/{docs-6FZSCG5B.js → docs-7LQ23DLM.js} +9 -9
  93. package/dist/{doctor-SVJ5BZCW.js → doctor-M7YEDGAE.js} +27 -23
  94. package/dist/{eval-CG6LLBLD.js → eval-BEC2WHDA.js} +73 -20
  95. package/dist/{evidence-ZYFIEN42.js → evidence-REJUMSKM.js} +70 -59
  96. package/dist/{evolve-QGEXEMDW.js → evolve-PY5ZBA5K.js} +50 -39
  97. package/dist/{extensions-ADGNCJJD.js → extensions-HVKU65YU.js} +7 -7
  98. package/dist/{fleet-S5R4ZOQY.js → fleet-7WZEWRFA.js} +236 -377
  99. package/dist/fleet-commands-UVHWM76J.js +70 -0
  100. package/dist/fleet-graph-6ULH7PES.js +125 -0
  101. package/dist/fleet-new-RDVJLHHH.js +48 -0
  102. package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-J53T6CCE.js} +5 -5
  103. package/dist/fleet-validate-72PC4SLA.js +79 -0
  104. package/dist/{init-5DRU55YR.js → init-OG3TPGQG.js} +69 -57
  105. package/dist/library-CNTMPLRF.js +217 -0
  106. package/dist/{memory-7YKKR6UC.js → memory-6IS7F275.js} +52 -41
  107. package/dist/{models-ZPOLRU2C.js → models-ENRJDA5W.js} +37 -31
  108. package/dist/{monitor-US5F5YGZ.js → monitor-XLDVO7TN.js} +79 -42
  109. package/dist/{orchestrator-E2AL4T5N.js → orchestrator-6KSPYRHA.js} +4126 -762
  110. package/dist/{paths-E7KYAQWE.js → paths-DBXMZMDU.js} +6 -6
  111. package/dist/registry-LG64LTF4.js +11 -0
  112. package/dist/{reset-KZ652EK6.js → reset-RZ4ER727.js} +12 -12
  113. package/dist/{run-SRNBKDWD.js → run-Y2CNK5RU.js} +89 -76
  114. package/dist/{share-CGZE33UP.js → share-A55GYP6Z.js} +37 -13
  115. package/dist/{skills-S2X4DLY5.js → skills-ALC5J6AT.js} +29 -13
  116. package/dist/{skills-eval-W2GGIC4R.js → skills-eval-JPBEBYQU.js} +60 -48
  117. package/dist/support-MIETYA5E.js +38 -0
  118. package/dist/{targets-54SWINWB.js → targets-VGNXIR3S.js} +46 -36
  119. package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WOBR64YA.js} +4 -4
  120. package/dist/{uninstall-BVLWXKBT.js → uninstall-ZJF5H5ZN.js} +9 -9
  121. package/dist/{upgrade-JKAR27XC.js → upgrade-FUSUAGHR.js} +31 -28
  122. package/dist/{usage-MSAWCLX4.js → usage-N4MKVHKD.js} +140 -68
  123. package/dist/verifiers-YAWOJ3H2.js +336 -0
  124. package/dist/{verify-X5HDROLA.js → verify-LTDHYBGY.js} +10 -9
  125. package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-6M7GHTBJ.js} +75 -62
  126. package/dist/worker/entry.js +67 -57
  127. package/docs/README.md +3 -2
  128. package/docs/acp.md +1 -1
  129. package/docs/alcf-provider.md +1 -1
  130. package/docs/architecture.md +2 -2
  131. package/docs/artifact-versions.md +11 -6
  132. package/docs/built-in-agents.md +26 -2
  133. package/docs/capacity-and-scheduling.md +1 -1
  134. package/docs/commands-and-modes.md +83 -3
  135. package/docs/configuration-and-targets.md +86 -4
  136. package/docs/context-engine.md +1 -1
  137. package/docs/development-pipeline.md +1 -1
  138. package/docs/dispatch-architecture-rationale.md +1 -1
  139. package/docs/documentation-coverage.md +3 -3
  140. package/docs/documentation-guide.md +3 -3
  141. package/docs/eval-runner.md +1 -1
  142. package/docs/evals-internal.md +1 -1
  143. package/docs/evidence-and-memory.md +74 -10
  144. package/docs/evolution.md +1 -1
  145. package/docs/exit-codes-and-output.md +4 -1
  146. package/docs/extensions-and-sharing.md +6 -2
  147. package/docs/fleet-demo-runbook.md +2 -2
  148. package/docs/fleet-dispatch.md +228 -16
  149. package/docs/git-commit-provenance.md +2 -2
  150. package/docs/glossary.md +22 -2
  151. package/docs/installation-and-lifecycle.md +2 -2
  152. package/docs/middleware-and-components.md +2 -1
  153. package/docs/model-catalog.md +1 -1
  154. package/docs/observability.md +56 -9
  155. package/docs/proactive-memory.md +1 -1
  156. package/docs/prompt-envelope-and-tools.md +4 -2
  157. package/docs/provider-adapter-cookbook.md +1 -1
  158. package/docs/release-cut-checklist.md +83 -65
  159. package/docs/resource-library.md +59 -0
  160. package/docs/safety-model.md +2 -2
  161. package/docs/scientific-validation.md +3 -3
  162. package/docs/session-lifecycle.md +37 -1
  163. package/docs/skills-marketplace.md +16 -3
  164. package/docs/tool-usage.md +14 -7
  165. package/docs/trace-store.md +1 -1
  166. package/docs/troubleshooting.md +1 -1
  167. package/docs/tui-design.md +1 -1
  168. package/docs/worker-dispatch-mechanics.md +3 -3
  169. package/package.json +1 -2
  170. package/src/cli/argv.ts +5 -0
  171. package/src/cli/configure.ts +107 -23
  172. package/src/cli/doctor.ts +5 -1
  173. package/src/cli/evidence.ts +30 -25
  174. package/src/cli/fleet-commands.ts +37 -0
  175. package/src/cli/fleet-graph.ts +102 -0
  176. package/src/cli/fleet-new.ts +36 -0
  177. package/src/cli/fleet-preflight.ts +111 -0
  178. package/src/cli/fleet-validate.ts +30 -0
  179. package/src/cli/fleet.ts +173 -335
  180. package/src/cli/index.ts +3 -1
  181. package/src/cli/library.ts +190 -0
  182. package/src/cli/share.ts +13 -1
  183. package/src/cli/shared.ts +1 -0
  184. package/src/cli/targets.ts +4 -1
  185. package/src/cli/usage.ts +111 -19
  186. package/src/cli/validate-model.ts +60 -5
  187. package/src/core/bus-events.ts +29 -0
  188. package/src/core/commit-attribution.ts +4 -4
  189. package/src/core/config.ts +130 -0
  190. package/src/core/defaults.ts +81 -0
  191. package/src/core/path-boundary.ts +100 -0
  192. package/src/domains/agents/builtins/architect.md +1 -0
  193. package/src/domains/agents/builtins/oracle.md +33 -0
  194. package/src/domains/agents/catalog.ts +13 -1
  195. package/src/domains/agents/extension.ts +2 -11
  196. package/src/domains/agents/fleet-contract.ts +304 -24
  197. package/src/domains/agents/index.ts +14 -0
  198. package/src/domains/agents/recipe.ts +7 -1
  199. package/src/domains/agents/registry.ts +73 -5
  200. package/src/domains/agents/result-contract.ts +360 -15
  201. package/src/domains/agents/write-boundary.ts +15 -50
  202. package/src/domains/config/classify.ts +4 -0
  203. package/src/domains/context/project-rules.ts +51 -1
  204. package/src/domains/dispatch/active-route-planner.ts +14 -0
  205. package/src/domains/dispatch/assignment-reconcile.ts +22 -5
  206. package/src/domains/dispatch/assignment-store.ts +151 -14
  207. package/src/domains/dispatch/backoff.ts +2 -1
  208. package/src/domains/dispatch/capability-match.ts +1 -0
  209. package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
  210. package/src/domains/dispatch/contract.ts +48 -0
  211. package/src/domains/dispatch/delegation-plan.ts +164 -0
  212. package/src/domains/dispatch/execution-plan.ts +76 -5
  213. package/src/domains/dispatch/execution-role.ts +12 -2
  214. package/src/domains/dispatch/execution-scheduler.ts +183 -67
  215. package/src/domains/dispatch/extension.ts +412 -74
  216. package/src/domains/dispatch/fleet-gate.ts +14 -0
  217. package/src/domains/dispatch/fleet-plan.ts +63 -3
  218. package/src/domains/dispatch/fleet-run.ts +791 -0
  219. package/src/domains/dispatch/gate-role-prompts.ts +47 -0
  220. package/src/domains/dispatch/host-verification.ts +178 -0
  221. package/src/domains/dispatch/index.ts +41 -1
  222. package/src/domains/dispatch/intent-requirements.ts +40 -0
  223. package/src/domains/dispatch/intent.ts +235 -0
  224. package/src/domains/dispatch/path-scope.ts +370 -0
  225. package/src/domains/dispatch/receipt-integrity.ts +9 -4
  226. package/src/domains/dispatch/state.ts +36 -3
  227. package/src/domains/dispatch/types.ts +64 -12
  228. package/src/domains/dispatch/validation.ts +69 -6
  229. package/src/domains/dispatch/write-boundary-enforcer.ts +45 -0
  230. package/src/domains/dispatch/write-boundary.ts +201 -22
  231. package/src/domains/eval/metrics/evidence.ts +79 -2
  232. package/src/domains/eval/runners/clio-run.ts +12 -2
  233. package/src/domains/evidence/build.ts +69 -11
  234. package/src/domains/evidence/index.ts +21 -0
  235. package/src/domains/evidence/provenance.ts +46 -11
  236. package/src/domains/evidence/trust-projection.ts +274 -0
  237. package/src/domains/evidence/trust-status.ts +155 -18
  238. package/src/domains/evidence/types.ts +4 -0
  239. package/src/domains/extensions/discovery.ts +88 -1
  240. package/src/domains/extensions/resources.ts +20 -8
  241. package/src/domains/extensions/state.ts +6 -2
  242. package/src/domains/extensions/types.ts +4 -1
  243. package/src/domains/lifecycle/doctor.ts +140 -1
  244. package/src/domains/middleware/index.ts +15 -0
  245. package/src/domains/middleware/watchdog.ts +281 -0
  246. package/src/domains/observability/contract.ts +3 -1
  247. package/src/domains/observability/cost.ts +12 -1
  248. package/src/domains/observability/extension.ts +2 -2
  249. package/src/domains/observability/index.ts +10 -0
  250. package/src/domains/observability/out-of-turn-usage.ts +223 -0
  251. package/src/domains/prompts/contract.ts +3 -5
  252. package/src/domains/providers/extension.ts +30 -2
  253. package/src/domains/resources/common-loader.ts +3 -0
  254. package/src/domains/resources/index.ts +20 -0
  255. package/src/domains/resources/library.ts +326 -0
  256. package/src/domains/resources/prompts/loader.ts +119 -14
  257. package/src/domains/resources/skills/marketplace.ts +37 -12
  258. package/src/domains/safety/policy-engine.ts +5 -5
  259. package/src/domains/safety/run-effects.ts +64 -1
  260. package/src/domains/safety/scope.ts +7 -12
  261. package/src/domains/session/handoff.ts +629 -0
  262. package/src/domains/share/archive.ts +67 -2
  263. package/src/engine/acp/server.ts +4 -1
  264. package/src/engine/prompt-templates.ts +18 -1
  265. package/src/engine/worker-runtime.ts +6 -3
  266. package/src/entry/orchestrator.ts +37 -0
  267. package/src/interactive/bus-notices.ts +26 -0
  268. package/src/interactive/chat-loop.ts +235 -1
  269. package/src/interactive/chat-renderer.ts +22 -0
  270. package/src/interactive/cost-overlay.ts +31 -3
  271. package/src/interactive/council-dispatch.ts +30 -0
  272. package/src/interactive/council-grid.ts +213 -0
  273. package/src/interactive/council.ts +99 -0
  274. package/src/interactive/dispatch-board.ts +311 -17
  275. package/src/interactive/fleet-run-preview.ts +307 -0
  276. package/src/interactive/footer/notifications.ts +219 -0
  277. package/src/interactive/handoff-round.ts +56 -0
  278. package/src/interactive/interactive-application.ts +43 -1
  279. package/src/interactive/interactive-event-projection.ts +23 -1
  280. package/src/interactive/interactive-slash-runtime.ts +52 -2
  281. package/src/interactive/interactive-subscriptions.ts +14 -2
  282. package/src/interactive/oracle.ts +179 -0
  283. package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
  284. package/src/interactive/overlay-general-openers.ts +190 -1
  285. package/src/interactive/overlay-key-routing.ts +17 -1
  286. package/src/interactive/overlay-lifecycle.ts +41 -1
  287. package/src/interactive/overlay-permission-lifecycle.ts +10 -0
  288. package/src/interactive/overlay-resource-openers.ts +11 -3
  289. package/src/interactive/overlay-session-lifecycle.ts +234 -2
  290. package/src/interactive/overlays/fleet-run-approval.ts +208 -0
  291. package/src/interactive/overlays/handoff-review.ts +185 -0
  292. package/src/interactive/overlays/library-install-confirm.ts +151 -0
  293. package/src/interactive/overlays/list-overlay.ts +168 -2
  294. package/src/interactive/overlays/settings.ts +221 -30
  295. package/src/interactive/overlays/side-question.ts +139 -0
  296. package/src/interactive/overlays/skills-hub.ts +401 -15
  297. package/src/interactive/side-question.ts +171 -0
  298. package/src/interactive/slash-commands.ts +439 -7
  299. package/src/interactive/slash-spec.ts +19 -6
  300. package/src/interactive/theme/tokens.ts +30 -0
  301. package/src/interactive/turn-middleware.ts +15 -1
  302. package/src/interactive/view/artifacts.ts +42 -9
  303. package/src/interactive/view/view-overlay.ts +15 -3
  304. package/src/interactive/watchdog-run.ts +75 -0
  305. package/src/interactive/worker-receipts.ts +14 -2
  306. package/src/interactive/worker-share.ts +56 -1
  307. package/src/interactive/worker-stream.ts +15 -0
  308. package/src/tools/bootstrap.ts +3 -0
  309. package/src/tools/compete-worktrees.ts +13 -79
  310. package/src/tools/dispatch-admission.ts +251 -18
  311. package/src/tools/dispatch-arguments.ts +84 -1
  312. package/src/tools/dispatch-plan.ts +165 -6
  313. package/src/tools/dispatch-runner.ts +364 -23
  314. package/src/tools/dispatch-types.ts +20 -1
  315. package/src/tools/dispatch.ts +72 -2
  316. package/src/tools/monitor.ts +29 -0
  317. package/src/tools/profiles.ts +18 -4
  318. package/src/tools/task-worktree.ts +238 -0
  319. package/src/tools/verify/authoring.ts +61 -1
  320. package/src/tools/verify/scripts.ts +62 -0
  321. package/src/tools/worker-evidence.ts +21 -14
  322. package/src/worker/spec-contract.ts +3 -1
  323. package/dist/chunk-HC4CLZ2Y.js +0 -68
@@ -1,32 +1,565 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
2
  import {
3
+ parseAgentRecipeSchema
4
+ } from "./chunk-FBVTI2TJ.js";
5
+ import {
6
+ discoverMarketplaceSkills,
3
7
  expandSkillInvocationInput,
8
+ installSkill,
4
9
  loadSkills,
10
+ normalizedSkillHash,
5
11
  parsePendingSkillRequests,
6
12
  projectCompatTrusted
7
- } from "./chunk-4BPJXDWC.js";
13
+ } from "./chunk-TANS5ZJS.js";
8
14
  import {
9
15
  COMPAT_RESOURCE_PRECEDENCE,
10
16
  defaultScopedResourceRoots,
11
- readRootEntries,
12
17
  sourceInfoForRoot,
13
18
  splitYamlFrontmatter,
14
19
  stringField
15
- } from "./chunk-2SFS6XQE.js";
20
+ } from "./chunk-DGSYXYMX.js";
21
+ import {
22
+ parseFleetContract,
23
+ parseFrontmatter
24
+ } from "./chunk-E77JEWSD.js";
25
+ import {
26
+ assertAgentSpecPolicy,
27
+ normalizeAgentSpec
28
+ } from "./chunk-AOCYTWAV.js";
16
29
  import {
17
30
  INTEROP_AGENT_KINDS
18
31
  } from "./chunk-IHXBNWMM.js";
32
+ import {
33
+ runCommandVector
34
+ } from "./chunk-B5CSFE7B.js";
35
+ import {
36
+ readSettings,
37
+ updateSettings
38
+ } from "./chunk-IJ7RPIYJ.js";
19
39
  import {
20
40
  expandConfigPath
21
41
  } from "./chunk-SST6Z5JA.js";
22
42
  import {
23
43
  require_dist
24
44
  } from "./chunk-APJ265NV.js";
45
+ import {
46
+ clioConfigDir
47
+ } from "./chunk-BNAZZHFG.js";
48
+ import {
49
+ safeResourceWrite
50
+ } from "./chunk-WEPFGWHJ.js";
25
51
  import {
26
52
  __toESM,
27
53
  init_esm_shims
28
54
  } from "./chunk-3R73A4XB.js";
29
55
 
56
+ // src/domains/resources/library.ts
57
+ init_esm_shims();
58
+ var import_yaml = __toESM(require_dist(), 1);
59
+ import { createHash } from "node:crypto";
60
+ import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
61
+ import path2 from "node:path";
62
+
63
+ // src/domains/resources/prompts/loader.ts
64
+ init_esm_shims();
65
+ import { lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
66
+ import { homedir } from "node:os";
67
+ import path from "node:path";
68
+
69
+ // src/engine/prompt-templates.ts
70
+ init_esm_shims();
71
+ import { parseCommandArgs, substituteArgs as substituteParsedArgs } from "@earendil-works/pi-agent-core";
72
+ var RAW_ARGUMENTS_PLACEHOLDER = /\$ARGUMENTS/g;
73
+ function substituteArgs(content, args, rawArguments) {
74
+ if (rawArguments === void 0) return substituteParsedArgs(content, args);
75
+ return content.split(RAW_ARGUMENTS_PLACEHOLDER).map((segment) => substituteParsedArgs(segment, args)).join(rawArguments);
76
+ }
77
+
78
+ // src/domains/resources/collision.ts
79
+ init_esm_shims();
80
+ var SCOPE_RANK = {
81
+ package: 0,
82
+ user: 1,
83
+ project: 2,
84
+ cli: 3
85
+ };
86
+ function rankOf(info) {
87
+ return info.precedence ?? SCOPE_RANK[info.scope];
88
+ }
89
+ function compareCandidates(a, b) {
90
+ const rankDelta = rankOf(a.source) - rankOf(b.source);
91
+ if (rankDelta !== 0) return rankDelta;
92
+ return a.source.path.localeCompare(b.source.path);
93
+ }
94
+ function resolveResourceCollisions(candidates) {
95
+ const byName = /* @__PURE__ */ new Map();
96
+ for (const candidate of candidates) {
97
+ const key = candidate.name.trim();
98
+ if (key.length === 0) continue;
99
+ const list = byName.get(key) ?? [];
100
+ list.push(candidate);
101
+ byName.set(key, list);
102
+ }
103
+ const winners = [];
104
+ const diagnostics = [];
105
+ for (const [name, entries] of byName.entries()) {
106
+ const sorted = [...entries].sort(compareCandidates);
107
+ const winner = sorted[sorted.length - 1];
108
+ if (!winner) continue;
109
+ winners.push(winner.value);
110
+ for (const loser of sorted.slice(0, -1)) {
111
+ diagnostics.push({
112
+ type: "collision",
113
+ message: `${name} from ${winner.source.scope} overrides ${loser.source.scope}`,
114
+ path: loser.source.path,
115
+ collision: {
116
+ name,
117
+ winnerPath: winner.source.path,
118
+ loserPath: loser.source.path,
119
+ winnerScope: winner.source.scope,
120
+ loserScope: loser.source.scope
121
+ }
122
+ });
123
+ }
124
+ }
125
+ return { winners, diagnostics };
126
+ }
127
+
128
+ // src/domains/resources/prompts/loader.ts
129
+ function defaultPromptTemplateRoots(input = {}) {
130
+ const cwd = input.cwd ?? process.cwd();
131
+ const home = input.home ?? homedir();
132
+ const trustProject = projectCompatTrusted(input.trustProjectCompatRoots);
133
+ const compat = [];
134
+ for (const kind of INTEROP_AGENT_KINDS) {
135
+ if (kind.userPromptRoot !== void 0) {
136
+ compat.push({
137
+ path: path.join(home, kind.userPromptRoot),
138
+ scope: "user",
139
+ source: `${kind.id}-user`,
140
+ precedence: COMPAT_RESOURCE_PRECEDENCE.userCompat,
141
+ trusted: true
142
+ });
143
+ }
144
+ if (kind.projectPromptRoot !== void 0) {
145
+ compat.push({
146
+ path: path.join(cwd, kind.projectPromptRoot),
147
+ scope: "project",
148
+ source: `${kind.id}-project`,
149
+ precedence: COMPAT_RESOURCE_PRECEDENCE.projectCompat,
150
+ trusted: trustProject
151
+ });
152
+ }
153
+ }
154
+ return [...defaultScopedResourceRoots("prompts", cwd), ...compat];
155
+ }
156
+ function splitOptionalFrontmatter(raw, filePath, diagnostics) {
157
+ const split = splitYamlFrontmatter(raw);
158
+ if (split.ok) return split;
159
+ if (split.reason === "missing") return { frontmatter: {}, body: raw };
160
+ const message = split.reason === "missing closing delimiter" ? "prompt template frontmatter is missing a closing delimiter; treating the file as plain markdown" : split.reason === "must be a YAML object" ? "prompt template frontmatter must be a YAML object" : `prompt template frontmatter is ${split.reason}`;
161
+ diagnostics.push({ type: "warning", message, path: filePath });
162
+ return { frontmatter: {}, body: split.body };
163
+ }
164
+ function fallbackDescription(body) {
165
+ const line = body.split(/\r?\n/).map((entry) => entry.trim()).find((entry) => entry.length > 0);
166
+ if (!line) return "Prompt template";
167
+ const normalized = line.replace(/^#{1,6}\s+/, "");
168
+ return normalized.length > 60 ? `${normalized.slice(0, 57)}...` : normalized;
169
+ }
170
+ var EXTENSION_ROOT_REFERENCE = /\$\{extensionRoot\}(\/[A-Za-z0-9._~%+@/-]*)?/g;
171
+ var EXTENSION_ROOT_TOKEN = "${extensionRoot}";
172
+ function contained(root, candidate) {
173
+ const relative = path.relative(root, candidate);
174
+ return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
175
+ }
176
+ function resolveExtensionReferences(body, root, filePath, diagnostics) {
177
+ if (root.rootPath === void 0 || !body.includes(EXTENSION_ROOT_TOKEN)) return body;
178
+ let canonicalRoot;
179
+ try {
180
+ canonicalRoot = realpathSync(root.rootPath);
181
+ } catch (error) {
182
+ diagnostics.push({
183
+ type: "warning",
184
+ message: `extension root could not be resolved: ${error instanceof Error ? error.message : String(error)}`,
185
+ path: filePath
186
+ });
187
+ return null;
188
+ }
189
+ let invalid = null;
190
+ const resolved = body.replace(EXTENSION_ROOT_REFERENCE, (reference, suffix) => {
191
+ const candidate = path.resolve(canonicalRoot, `.${suffix ?? ""}`);
192
+ try {
193
+ const canonicalCandidate = realpathSync(candidate);
194
+ if (!contained(canonicalRoot, canonicalCandidate)) invalid = reference;
195
+ } catch {
196
+ invalid = reference;
197
+ }
198
+ return candidate;
199
+ });
200
+ if (invalid !== null) {
201
+ diagnostics.push({
202
+ type: "warning",
203
+ message: `prompt template has an unresolved or escaping extension reference: ${invalid}`,
204
+ path: filePath
205
+ });
206
+ return null;
207
+ }
208
+ return resolved;
209
+ }
210
+ function loadPromptFile(filePath, root, diagnostics) {
211
+ const ext = path.extname(filePath).toLowerCase();
212
+ if (ext !== ".md") return null;
213
+ let raw;
214
+ try {
215
+ raw = readFileSync(filePath, "utf8");
216
+ } catch (err) {
217
+ const reason = err instanceof Error ? err.message : String(err);
218
+ diagnostics.push({ type: "warning", message: `prompt template could not be read: ${reason}`, path: filePath });
219
+ return null;
220
+ }
221
+ const relativePath = path.relative(root.path, filePath);
222
+ if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePath)) {
223
+ diagnostics.push({ type: "warning", message: "prompt template escaped its discovery root", path: filePath });
224
+ return null;
225
+ }
226
+ const name = relativePath.slice(0, -ext.length).split(path.sep).join(":");
227
+ if (name.trim().length === 0) return null;
228
+ const { frontmatter, body } = splitOptionalFrontmatter(raw, filePath, diagnostics);
229
+ const resolvedBody = resolveExtensionReferences(body, root, filePath, diagnostics);
230
+ if (resolvedBody === null) return null;
231
+ const description = stringField(frontmatter, "description") ?? fallbackDescription(resolvedBody);
232
+ const argumentHint = stringField(frontmatter, "argument-hint") ?? stringField(frontmatter, "argumentHint");
233
+ const sourceInfo = sourceInfoForRoot(root, filePath);
234
+ const template = {
235
+ name,
236
+ description,
237
+ content: resolvedBody.trim(),
238
+ filePath,
239
+ sourceInfo,
240
+ trusted: root.trusted !== false
241
+ };
242
+ if (argumentHint) template.argumentHint = argumentHint;
243
+ return { name, value: template, source: sourceInfo };
244
+ }
245
+ function loadPromptRoot(root, diagnostics) {
246
+ const candidates = [];
247
+ const pending = [root.path];
248
+ while (pending.length > 0) {
249
+ const directory = pending.pop();
250
+ if (!directory) continue;
251
+ let entries;
252
+ try {
253
+ const stat = lstatSync(directory);
254
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
255
+ diagnostics.push({
256
+ type: "warning",
257
+ message: "prompt template root contains a non-directory or symbolic link",
258
+ path: directory
259
+ });
260
+ continue;
261
+ }
262
+ entries = readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
263
+ } catch (error) {
264
+ if (error.code === "ENOENT") continue;
265
+ diagnostics.push({
266
+ type: "warning",
267
+ message: `prompt template directory could not be read: ${error instanceof Error ? error.message : String(error)}`,
268
+ path: directory
269
+ });
270
+ continue;
271
+ }
272
+ for (const entry of [...entries].reverse()) {
273
+ const filePath = path.join(directory, entry.name);
274
+ if (entry.isSymbolicLink()) {
275
+ diagnostics.push({ type: "warning", message: "prompt template symbolic link was ignored", path: filePath });
276
+ } else if (entry.isDirectory()) {
277
+ pending.push(filePath);
278
+ } else if (entry.isFile()) {
279
+ const candidate = loadPromptFile(filePath, root, diagnostics);
280
+ if (candidate) candidates.push(candidate);
281
+ }
282
+ }
283
+ }
284
+ return candidates;
285
+ }
286
+ function loadPromptTemplates(input = {}) {
287
+ const roots = input.roots ?? defaultPromptTemplateRoots(input);
288
+ const diagnostics = [];
289
+ const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
290
+ const resolved = resolveResourceCollisions(candidates);
291
+ const items = [];
292
+ for (const template of resolved.winners) {
293
+ if (input.reservedNames?.has(template.name) === true) {
294
+ diagnostics.push({
295
+ type: "collision",
296
+ message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
297
+ path: template.filePath
298
+ });
299
+ continue;
300
+ }
301
+ items.push(template);
302
+ }
303
+ return {
304
+ items: items.sort((a, b) => a.name.localeCompare(b.name)),
305
+ diagnostics: [...diagnostics, ...resolved.diagnostics]
306
+ };
307
+ }
308
+ function parsePromptCommand(input) {
309
+ const framed = input.trimStart();
310
+ if (!framed.startsWith("/")) return null;
311
+ const withoutSlash = framed.slice(1);
312
+ const separator = withoutSlash.search(/\s/);
313
+ const name = separator === -1 ? withoutSlash : withoutSlash.slice(0, separator);
314
+ if (name.length === 0 || name.includes("/")) return null;
315
+ const delimiterWidth = separator !== -1 && withoutSlash.slice(separator, separator + 2) === "\r\n" ? 2 : 1;
316
+ const rest = separator === -1 ? "" : withoutSlash.slice(separator + delimiterWidth);
317
+ return { name, rest };
318
+ }
319
+ function expandPromptTemplateInput(input, templates) {
320
+ const command = parsePromptCommand(input);
321
+ if (!command) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
322
+ const template = templates.items.find((entry) => entry.name === command.name);
323
+ if (!template) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
324
+ if (!template.trusted) {
325
+ const message = `prompt template ${template.name} comes from an untrusted project root; set skills.trustProjectCompatRoots to use it`;
326
+ return {
327
+ expanded: false,
328
+ text: input,
329
+ args: [],
330
+ diagnostics: [...templates.diagnostics, { type: "warning", message, path: template.filePath }],
331
+ refusal: { template, message }
332
+ };
333
+ }
334
+ const args = parseCommandArgs(command.rest);
335
+ return {
336
+ expanded: true,
337
+ text: substituteArgs(template.content, args, command.rest),
338
+ args,
339
+ template,
340
+ diagnostics: templates.diagnostics
341
+ };
342
+ }
343
+
344
+ // src/domains/resources/library.ts
345
+ function isRecord(value) {
346
+ return typeof value === "object" && value !== null && !Array.isArray(value);
347
+ }
348
+ function catalogPath() {
349
+ const configured = readSettings().library.catalog;
350
+ return path2.resolve(configured ?? path2.join(clioConfigDir(), "library.yaml"));
351
+ }
352
+ function parseCatalog(filePath, diagnostics) {
353
+ if (!existsSync(filePath)) return [];
354
+ try {
355
+ const raw = readFileSync2(filePath, "utf8");
356
+ const parsed = filePath.endsWith(".json") ? JSON.parse(raw) : (0, import_yaml.parse)(raw);
357
+ const rows = Array.isArray(parsed) ? parsed : isRecord(parsed) && Array.isArray(parsed.skills) ? parsed.skills : [];
358
+ return rows.flatMap((value) => {
359
+ if (!isRecord(value) || typeof value.name !== "string" || typeof value.description !== "string" || typeof value.sourceUrl !== "string") {
360
+ diagnostics.push(`library catalog entry malformed: ${filePath}`);
361
+ return [];
362
+ }
363
+ const kind = value.kind === void 0 || value.kind === "skill" ? "skill" : value.kind === "agent" || value.kind === "prompt" || value.kind === "fleet" ? value.kind : "skill";
364
+ if (value.kind !== void 0 && !["skill", "agent", "prompt", "fleet"].includes(String(value.kind))) {
365
+ diagnostics.push(`library catalog entry has unsupported kind: ${value.name}`);
366
+ return [];
367
+ }
368
+ if (value.requires !== void 0 && (!Array.isArray(value.requires) || value.requires.some((item) => typeof item !== "string"))) {
369
+ diagnostics.push(`library_requirement_malformed: ${value.name}`);
370
+ return [];
371
+ }
372
+ const sourceUrl = /^(?:https?:\/\/|git@)/.test(value.sourceUrl) ? value.sourceUrl : path2.resolve(path2.dirname(filePath), value.sourceUrl);
373
+ const requires = Array.isArray(value.requires) ? value.requires.filter((item) => typeof item === "string") : void 0;
374
+ return [
375
+ {
376
+ kind,
377
+ name: value.name.trim(),
378
+ description: value.description.trim(),
379
+ sourceUrl,
380
+ origin: "index",
381
+ ...typeof value.version === "string" ? { version: value.version } : {},
382
+ ...requires ? { requires } : {}
383
+ }
384
+ ];
385
+ });
386
+ } catch (error) {
387
+ diagnostics.push(`library catalog unreadable: ${error instanceof Error ? error.message : String(error)}`);
388
+ return [];
389
+ }
390
+ }
391
+ function libraryEntryRef(entry) {
392
+ return `${entry.kind}:${entry.name}`;
393
+ }
394
+ function discoverLibrary(options = {}) {
395
+ const marketplace = discoverMarketplaceSkills({
396
+ ...options.marketplace ?? {},
397
+ ...options.cwd ? { cwd: options.cwd } : {}
398
+ });
399
+ const diagnostics = [...marketplace.diagnostics.filter((item) => !item.includes("no local skill marketplace"))];
400
+ const privatePath = catalogPath();
401
+ const primary = options.catalog ? parseCatalog(path2.resolve(options.catalog), diagnostics) : [];
402
+ const privateEntries = parseCatalog(privatePath, diagnostics);
403
+ const byRef = /* @__PURE__ */ new Map();
404
+ for (const entry of [...marketplace.skills, ...primary, ...privateEntries]) byRef.set(libraryEntryRef(entry), entry);
405
+ const refusals = {};
406
+ const entries = [...byRef.values()].filter((entry) => {
407
+ try {
408
+ resolveLibraryRequirements(entry, [...byRef.values()]);
409
+ return true;
410
+ } catch (error) {
411
+ const message = error instanceof Error ? error.message : String(error);
412
+ refusals[libraryEntryRef(entry)] = message;
413
+ if (!diagnostics.includes(message)) diagnostics.push(message);
414
+ return false;
415
+ }
416
+ });
417
+ return {
418
+ entries: entries.sort((a, b) => libraryEntryRef(a).localeCompare(libraryEntryRef(b))),
419
+ diagnostics,
420
+ refusals
421
+ };
422
+ }
423
+ var REQUIREMENT_PATTERN = /^(skill|agent|prompt|fleet):([A-Za-z0-9][A-Za-z0-9._-]*)$/;
424
+ function resolveLibraryRequirements(entry, catalog) {
425
+ const byRef = new Map(catalog.map((item) => [libraryEntryRef(item), item]));
426
+ const ordered = [];
427
+ const visiting = [];
428
+ const visited = /* @__PURE__ */ new Set();
429
+ const visit = (current) => {
430
+ const currentRef = libraryEntryRef(current);
431
+ if (visited.has(currentRef)) return;
432
+ const cycleAt = visiting.indexOf(currentRef);
433
+ if (cycleAt >= 0)
434
+ throw new Error(`library_requirement_cycle: ${[...visiting.slice(cycleAt), currentRef].join(" -> ")}`);
435
+ visiting.push(currentRef);
436
+ for (const requirement of current.requires ?? []) {
437
+ if (!REQUIREMENT_PATTERN.test(requirement)) throw new Error("library_requirement_malformed");
438
+ const dependency = byRef.get(requirement);
439
+ if (!dependency) throw new Error(`library_requirement_missing: ${requirement}`);
440
+ visit(dependency);
441
+ }
442
+ visiting.pop();
443
+ visited.add(currentRef);
444
+ ordered.push(current);
445
+ };
446
+ visit(entry);
447
+ return ordered;
448
+ }
449
+ function sourceFile(entry) {
450
+ const source = path2.resolve(entry.sourceUrl);
451
+ if (entry.kind === "skill") return source;
452
+ if (!existsSync(source)) throw new Error(`library source path does not exist: ${source}`);
453
+ return source;
454
+ }
455
+ function validateEntry(entry, raw, filePath) {
456
+ if (entry.kind === "fleet") {
457
+ parseFleetContract(raw, filePath);
458
+ return;
459
+ }
460
+ if (entry.kind === "agent") {
461
+ const parsed = parseFrontmatter(raw, filePath);
462
+ const recipe = parseAgentRecipeSchema({ id: entry.name, source: "user", filepath: filePath, ...parsed });
463
+ assertAgentSpecPolicy(normalizeAgentSpec(recipe));
464
+ return;
465
+ }
466
+ if (entry.kind === "prompt") {
467
+ const loaded = loadPromptTemplates({ roots: [{ path: path2.dirname(filePath), scope: "user", source: "library" }] });
468
+ if (!loaded.items.some((item) => item.filePath === filePath))
469
+ throw new Error(`prompt template is malformed: ${filePath}`);
470
+ }
471
+ }
472
+ function libraryInstallPath(entry) {
473
+ if (entry.kind === "skill") return path2.join(clioConfigDir(), "skills", entry.name, "SKILL.md");
474
+ const root = entry.kind === "agent" ? "agents" : entry.kind === "fleet" ? "fleets" : "prompts";
475
+ return path2.join(clioConfigDir(), root, `${entry.name}.md`);
476
+ }
477
+ function readLibraryPins() {
478
+ const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
479
+ if (!existsSync(pinPath)) return {};
480
+ const parsed = (0, import_yaml.parse)(readFileSync2(pinPath, "utf8"));
481
+ return isRecord(parsed) ? parsed : {};
482
+ }
483
+ function libraryEntryInstalled(entry) {
484
+ return readLibraryPins()[libraryEntryRef(entry)] !== void 0 || existsSync(libraryInstallPath(entry));
485
+ }
486
+ function libraryEntryPin(entry) {
487
+ return readLibraryPins()[libraryEntryRef(entry)];
488
+ }
489
+ function classifyLibraryRequirements(entry, catalog) {
490
+ const ordered = resolveLibraryRequirements(entry, catalog).slice(0, -1);
491
+ const satisfied = ordered.filter((requirement) => libraryEntryInstalled(requirement));
492
+ const satisfiedRefs = new Set(satisfied.map(libraryEntryRef));
493
+ return {
494
+ ordered,
495
+ satisfied,
496
+ unsatisfied: ordered.filter((requirement) => !satisfiedRefs.has(libraryEntryRef(requirement)))
497
+ };
498
+ }
499
+ function planLibraryInstall(entry) {
500
+ if (entry.kind === "skill") {
501
+ const source2 = sourceFile(entry);
502
+ const file = statSync(source2).isDirectory() ? path2.join(source2, "SKILL.md") : source2;
503
+ const raw2 = readFileSync2(file);
504
+ return {
505
+ entry,
506
+ path: libraryInstallPath(entry),
507
+ sha256: normalizedSkillHash(raw2.toString("utf8"))
508
+ };
509
+ }
510
+ const source = sourceFile(entry);
511
+ const raw = readFileSync2(source, "utf8");
512
+ validateEntry(entry, raw, source);
513
+ return {
514
+ entry,
515
+ path: libraryInstallPath(entry),
516
+ sha256: createHash("sha256").update(raw).digest("hex")
517
+ };
518
+ }
519
+ function recordPin(plan) {
520
+ const pinPath = path2.join(clioConfigDir(), "library-pins.yaml");
521
+ const pins = readLibraryPins();
522
+ pins[libraryEntryRef(plan.entry)] = { sha256: plan.sha256, sourceUrl: plan.entry.sourceUrl };
523
+ safeResourceWrite(pinPath, (0, import_yaml.stringify)(Object.fromEntries(Object.entries(pins).sort())), { encoding: "utf8" });
524
+ }
525
+ function installLibraryPlan(plan) {
526
+ if (existsSync(plan.path)) throw new Error(`library destination already exists: ${plan.path}`);
527
+ if (plan.entry.kind === "skill") installSkill({ source: plan.entry.sourceUrl, scope: "user", name: plan.entry.name });
528
+ else safeResourceWrite(plan.path, readFileSync2(sourceFile(plan.entry)));
529
+ recordPin(plan);
530
+ }
531
+ function confirmedRemote() {
532
+ const settings = readSettings().library;
533
+ if (!settings.remote || settings.remote !== settings.confirmedRemote) throw new Error("library_remote_unconfirmed");
534
+ return settings.remote;
535
+ }
536
+ function confirmLibraryRemote(url) {
537
+ const current = readSettings().library.remote;
538
+ if (current !== null && current !== url) throw new Error("library_remote_mismatch");
539
+ updateSettings((settings) => {
540
+ if (settings.library.remote === null) settings.library.remote = url;
541
+ settings.library.confirmedRemote = url;
542
+ });
543
+ }
544
+ async function syncLibrary(direction, runner = runCommandVector) {
545
+ const settings = readSettings().library;
546
+ if (!settings.sync) throw new Error("library_sync_disabled");
547
+ const remote = confirmedRemote();
548
+ const cwd = path2.dirname(catalogPath());
549
+ const remoteResult = await runner("git", ["remote", "get-url", "library"], { cwd, workspaceRoot: cwd });
550
+ if (remoteResult.exitCode !== 0 || remoteResult.stdout.trim() !== remote)
551
+ throw new Error("library_remote_unconfirmed");
552
+ if (direction === "sync") {
553
+ const fetched = await runner("git", ["fetch", "library"], { cwd, workspaceRoot: cwd });
554
+ if (fetched.exitCode !== 0) throw new Error(fetched.stderr.trim() || "library sync failed");
555
+ const advanced = await runner("git", ["merge", "--ff-only", "FETCH_HEAD"], { cwd, workspaceRoot: cwd });
556
+ if (advanced.exitCode !== 0) throw new Error(advanced.stderr.trim() || "library sync failed");
557
+ return;
558
+ }
559
+ const result = await runner("git", ["push", "library"], { cwd, workspaceRoot: cwd });
560
+ if (result.exitCode !== 0) throw new Error(result.stderr.trim() || `library ${direction} failed`);
561
+ }
562
+
30
563
  // src/domains/resources/skills/evals.ts
31
564
  init_esm_shims();
32
565
  var SCENARIO_HEADING = /^##\s+([A-Z])(\d+)\s*[-:–—]\s*(.+?)\s*$/;
@@ -158,23 +691,23 @@ function extractExpected(block) {
158
691
 
159
692
  // src/domains/resources/skills/provenance-pin.ts
160
693
  init_esm_shims();
161
- var import_yaml = __toESM(require_dist(), 1);
162
- import { existsSync, readFileSync } from "node:fs";
163
- import path from "node:path";
694
+ var import_yaml2 = __toESM(require_dist(), 1);
695
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
696
+ import path3 from "node:path";
164
697
  var SKILL_PIN_MANIFEST_FILENAME = "registry.yaml";
165
698
  function isPlainObject(value) {
166
699
  return typeof value === "object" && value !== null && !Array.isArray(value);
167
700
  }
168
701
  function resolveSkillPinManifestPath(cwd) {
169
702
  const fromEnv = process.env.CLIO_CODER_SKILL_CATALOG_DIR;
170
- const catalogDir = fromEnv && fromEnv.trim().length > 0 ? path.resolve(fromEnv.trim()) : path.join(cwd, "skills");
171
- const manifestPath = path.join(catalogDir, SKILL_PIN_MANIFEST_FILENAME);
172
- return existsSync(manifestPath) ? manifestPath : null;
703
+ const catalogDir = fromEnv && fromEnv.trim().length > 0 ? path3.resolve(fromEnv.trim()) : path3.join(cwd, "skills");
704
+ const manifestPath = path3.join(catalogDir, SKILL_PIN_MANIFEST_FILENAME);
705
+ return existsSync2(manifestPath) ? manifestPath : null;
173
706
  }
174
707
  function loadSkillPinManifest(manifestPath) {
175
708
  let parsed;
176
709
  try {
177
- parsed = import_yaml.default.parse(readFileSync(manifestPath, "utf8"));
710
+ parsed = import_yaml2.default.parse(readFileSync3(manifestPath, "utf8"));
178
711
  } catch {
179
712
  return null;
180
713
  }
@@ -224,204 +757,6 @@ init_esm_shims();
224
757
 
225
758
  // src/domains/resources/loader.ts
226
759
  init_esm_shims();
227
-
228
- // src/domains/resources/prompts/loader.ts
229
- init_esm_shims();
230
- import { readFileSync as readFileSync2 } from "node:fs";
231
- import { homedir } from "node:os";
232
- import path2 from "node:path";
233
-
234
- // src/engine/prompt-templates.ts
235
- init_esm_shims();
236
- import { parseCommandArgs, substituteArgs } from "@earendil-works/pi-agent-core";
237
-
238
- // src/domains/resources/collision.ts
239
- init_esm_shims();
240
- var SCOPE_RANK = {
241
- package: 0,
242
- user: 1,
243
- project: 2,
244
- cli: 3
245
- };
246
- function rankOf(info) {
247
- return info.precedence ?? SCOPE_RANK[info.scope];
248
- }
249
- function compareCandidates(a, b) {
250
- const rankDelta = rankOf(a.source) - rankOf(b.source);
251
- if (rankDelta !== 0) return rankDelta;
252
- return a.source.path.localeCompare(b.source.path);
253
- }
254
- function resolveResourceCollisions(candidates) {
255
- const byName = /* @__PURE__ */ new Map();
256
- for (const candidate of candidates) {
257
- const key = candidate.name.trim();
258
- if (key.length === 0) continue;
259
- const list = byName.get(key) ?? [];
260
- list.push(candidate);
261
- byName.set(key, list);
262
- }
263
- const winners = [];
264
- const diagnostics = [];
265
- for (const [name, entries] of byName.entries()) {
266
- const sorted = [...entries].sort(compareCandidates);
267
- const winner = sorted[sorted.length - 1];
268
- if (!winner) continue;
269
- winners.push(winner.value);
270
- for (const loser of sorted.slice(0, -1)) {
271
- diagnostics.push({
272
- type: "collision",
273
- message: `${name} from ${winner.source.scope} overrides ${loser.source.scope}`,
274
- path: loser.source.path,
275
- collision: {
276
- name,
277
- winnerPath: winner.source.path,
278
- loserPath: loser.source.path,
279
- winnerScope: winner.source.scope,
280
- loserScope: loser.source.scope
281
- }
282
- });
283
- }
284
- }
285
- return { winners, diagnostics };
286
- }
287
-
288
- // src/domains/resources/prompts/loader.ts
289
- function defaultPromptTemplateRoots(input = {}) {
290
- const cwd = input.cwd ?? process.cwd();
291
- const home = input.home ?? homedir();
292
- const trustProject = projectCompatTrusted(input.trustProjectCompatRoots);
293
- const compat = [];
294
- for (const kind of INTEROP_AGENT_KINDS) {
295
- if (kind.userPromptRoot !== void 0) {
296
- compat.push({
297
- path: path2.join(home, kind.userPromptRoot),
298
- scope: "user",
299
- source: `${kind.id}-user`,
300
- precedence: COMPAT_RESOURCE_PRECEDENCE.userCompat,
301
- trusted: true
302
- });
303
- }
304
- if (kind.projectPromptRoot !== void 0) {
305
- compat.push({
306
- path: path2.join(cwd, kind.projectPromptRoot),
307
- scope: "project",
308
- source: `${kind.id}-project`,
309
- precedence: COMPAT_RESOURCE_PRECEDENCE.projectCompat,
310
- trusted: trustProject
311
- });
312
- }
313
- }
314
- return [...defaultScopedResourceRoots("prompts", cwd), ...compat];
315
- }
316
- function splitOptionalFrontmatter(raw, filePath, diagnostics) {
317
- const split = splitYamlFrontmatter(raw);
318
- if (split.ok) return split;
319
- if (split.reason === "missing") return { frontmatter: {}, body: raw };
320
- const message = split.reason === "missing closing delimiter" ? "prompt template frontmatter is missing a closing delimiter; treating the file as plain markdown" : split.reason === "must be a YAML object" ? "prompt template frontmatter must be a YAML object" : `prompt template frontmatter is ${split.reason}`;
321
- diagnostics.push({ type: "warning", message, path: filePath });
322
- return { frontmatter: {}, body: split.body };
323
- }
324
- function fallbackDescription(body) {
325
- const line = body.split(/\r?\n/).map((entry) => entry.trim()).find((entry) => entry.length > 0);
326
- if (!line) return "Prompt template";
327
- const normalized = line.replace(/^#{1,6}\s+/, "");
328
- return normalized.length > 60 ? `${normalized.slice(0, 57)}...` : normalized;
329
- }
330
- function loadPromptFile(filePath, root, diagnostics) {
331
- const ext = path2.extname(filePath).toLowerCase();
332
- if (ext !== ".md") return null;
333
- let raw;
334
- try {
335
- raw = readFileSync2(filePath, "utf8");
336
- } catch (err) {
337
- const reason = err instanceof Error ? err.message : String(err);
338
- diagnostics.push({ type: "warning", message: `prompt template could not be read: ${reason}`, path: filePath });
339
- return null;
340
- }
341
- const name = path2.basename(filePath, ext);
342
- if (name.trim().length === 0) return null;
343
- const { frontmatter, body } = splitOptionalFrontmatter(raw, filePath, diagnostics);
344
- const description = stringField(frontmatter, "description") ?? fallbackDescription(body);
345
- const argumentHint = stringField(frontmatter, "argument-hint") ?? stringField(frontmatter, "argumentHint");
346
- const sourceInfo = sourceInfoForRoot(root, filePath);
347
- const template = {
348
- name,
349
- description,
350
- content: body.trim(),
351
- filePath,
352
- sourceInfo,
353
- trusted: root.trusted !== false
354
- };
355
- if (argumentHint) template.argumentHint = argumentHint;
356
- return { name, value: template, source: sourceInfo };
357
- }
358
- function loadPromptRoot(root, diagnostics) {
359
- const candidates = [];
360
- for (const entry of readRootEntries(root, "prompt template", diagnostics)) {
361
- if (!entry.isFile()) continue;
362
- const candidate = loadPromptFile(path2.join(root.path, entry.name), root, diagnostics);
363
- if (candidate) candidates.push(candidate);
364
- }
365
- return candidates;
366
- }
367
- function loadPromptTemplates(input = {}) {
368
- const roots = input.roots ?? defaultPromptTemplateRoots(input);
369
- const diagnostics = [];
370
- const candidates = roots.flatMap((root) => loadPromptRoot(root, diagnostics));
371
- const resolved = resolveResourceCollisions(candidates);
372
- const items = [];
373
- for (const template of resolved.winners) {
374
- if (input.reservedNames?.has(template.name) === true) {
375
- diagnostics.push({
376
- type: "collision",
377
- message: `prompt template /${template.name} conflicts with the built-in slash command /${template.name} and was ignored`,
378
- path: template.filePath
379
- });
380
- continue;
381
- }
382
- items.push(template);
383
- }
384
- return {
385
- items: items.sort((a, b) => a.name.localeCompare(b.name)),
386
- diagnostics: [...diagnostics, ...resolved.diagnostics]
387
- };
388
- }
389
- function parsePromptCommand(input) {
390
- const trimmed = input.trim();
391
- if (!trimmed.startsWith("/")) return null;
392
- const withoutSlash = trimmed.slice(1);
393
- const separator = withoutSlash.search(/\s/);
394
- const name = separator === -1 ? withoutSlash : withoutSlash.slice(0, separator);
395
- if (name.length === 0 || name.includes("/")) return null;
396
- const rest = separator === -1 ? "" : withoutSlash.slice(separator).trim();
397
- return { name, rest };
398
- }
399
- function expandPromptTemplateInput(input, templates) {
400
- const command = parsePromptCommand(input);
401
- if (!command) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
402
- const template = templates.items.find((entry) => entry.name === command.name);
403
- if (!template) return { expanded: false, text: input, args: [], diagnostics: templates.diagnostics };
404
- if (!template.trusted) {
405
- const message = `prompt template ${template.name} comes from an untrusted project root; set skills.trustProjectCompatRoots to use it`;
406
- return {
407
- expanded: false,
408
- text: input,
409
- args: [],
410
- diagnostics: [...templates.diagnostics, { type: "warning", message, path: template.filePath }],
411
- refusal: { template, message }
412
- };
413
- }
414
- const args = parseCommandArgs(command.rest);
415
- return {
416
- expanded: true,
417
- text: substituteArgs(template.content, args),
418
- args,
419
- template,
420
- diagnostics: templates.diagnostics
421
- };
422
- }
423
-
424
- // src/domains/resources/loader.ts
425
760
  function createResourcesLoader(options = {}) {
426
761
  const defaultCwd = options.cwd ?? process.cwd();
427
762
  const skillOptions2 = () => options.skills?.() ?? {};
@@ -527,9 +862,19 @@ function createResourcesDomainModule(options = {}) {
527
862
  }
528
863
 
529
864
  export {
865
+ libraryEntryRef,
866
+ discoverLibrary,
867
+ libraryInstallPath,
868
+ libraryEntryInstalled,
869
+ libraryEntryPin,
870
+ classifyLibraryRequirements,
871
+ planLibraryInstall,
872
+ installLibraryPlan,
873
+ confirmLibraryRemote,
874
+ syncLibrary,
530
875
  parseSkillEvals,
531
876
  checkSkillDrift,
532
877
  ResourcesDomainModule,
533
878
  createResourcesDomainModule
534
879
  };
535
- //# sourceMappingURL=chunk-MFFY33HR.js.map
880
+ //# sourceMappingURL=chunk-U6MBIEMB.js.map