@cleocode/cleo 2026.10.3 → 2026.10.5-rc.ci.672

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 (352) hide show
  1. package/README.md +7 -0
  2. package/bin/cleo.js +11 -1
  3. package/dist/cli/adapter-OUQRSFZL.js +159 -0
  4. package/dist/cli/add-4SRRJL4U.js +443 -0
  5. package/dist/cli/add-batch-TSWICA5J.js +164 -0
  6. package/dist/cli/admin-L3F6CDYH.js +1428 -0
  7. package/dist/cli/admin-YMU55YCU.js +341 -0
  8. package/dist/cli/adr-XESRMFMP.js +172 -0
  9. package/dist/cli/agent-TAFPIYUU.js +2404 -0
  10. package/dist/cli/agent-outputs-HVJJIPS4.js +84 -0
  11. package/dist/cli/analyze-YQ22QVGW.js +49 -0
  12. package/dist/cli/archive-W5XX6AH7.js +65 -0
  13. package/dist/cli/archive-stats-HP2KPAJU.js +101 -0
  14. package/dist/cli/attention-7JBDCRZX.js +124 -0
  15. package/dist/cli/attention-ZXZANHKC.js +168 -0
  16. package/dist/cli/audit-ICA2SEFN.js +122 -0
  17. package/dist/cli/auth-DXIG5OG7.js +491 -0
  18. package/dist/cli/backfill-LBSYBWLR.js +156 -0
  19. package/dist/cli/backup-NUGBZ7NA.js +588 -0
  20. package/dist/cli/backup-inspect-PDRXI45A.js +26 -0
  21. package/dist/cli/backup-recover-TVKAPERB.js +29 -0
  22. package/dist/cli/blockers-ZOPCGHDW.js +55 -0
  23. package/dist/cli/brain-EJOBKL4A.js +397 -0
  24. package/dist/cli/briefing-RDQJ6WHS.js +213 -0
  25. package/dist/cli/caamp-Z3XPKEHB.js +181 -0
  26. package/dist/cli/cancel-S7EHLCJN.js +85 -0
  27. package/dist/cli/canon-NPF5RODM.js +142 -0
  28. package/dist/cli/canon-docs-2GTOLF7Y.js +26 -0
  29. package/dist/cli/cant-CHNN6O57.js +239 -0
  30. package/dist/cli/changeset-RYPHPN2B.js +246 -0
  31. package/dist/cli/check-C67YAU7W.js +759 -0
  32. package/dist/cli/check-DHMURGHC.js +924 -0
  33. package/dist/cli/checkpoint-UWDFOGYQ.js +128 -0
  34. package/dist/cli/chunk-22YPFZYB.js +91 -0
  35. package/dist/cli/chunk-2MGFDMDF.js +272 -0
  36. package/dist/cli/chunk-47JYZAMS.js +30 -0
  37. package/dist/cli/chunk-4JYHPP4C.js +76 -0
  38. package/dist/cli/chunk-4PEODTHY.js +278 -0
  39. package/dist/cli/chunk-4RGSNUUP.js +950 -0
  40. package/dist/cli/chunk-4VASFLUW.js +35 -0
  41. package/dist/cli/chunk-5PNI276X.js +124 -0
  42. package/dist/cli/chunk-6JSJNYH2.js +114 -0
  43. package/dist/cli/chunk-6N6WGLXE.js +63 -0
  44. package/dist/cli/chunk-75UH3BLS.js +210 -0
  45. package/dist/cli/chunk-7ACK4EIN.js +92 -0
  46. package/dist/cli/chunk-7NMKLVMI.js +107 -0
  47. package/dist/cli/chunk-7SINJXB6.js +110 -0
  48. package/dist/cli/chunk-7UARFJYS.js +46 -0
  49. package/dist/cli/chunk-7ZYPQV4N.js +90 -0
  50. package/dist/cli/chunk-AQCYT3L4.js +72 -0
  51. package/dist/cli/chunk-BQK6XTOH.js +57 -0
  52. package/dist/cli/chunk-C3B7C43W.js +16 -0
  53. package/dist/cli/chunk-CAPAGD5E.js +98 -0
  54. package/dist/cli/chunk-CHGEDCKG.js +77 -0
  55. package/dist/cli/chunk-COXFJ3PT.js +74 -0
  56. package/dist/cli/chunk-D7BAQNV2.js +55 -0
  57. package/dist/cli/chunk-EIUXVHNF.js +258 -0
  58. package/dist/cli/chunk-EUGB6P5V.js +173 -0
  59. package/dist/cli/chunk-EW2CKNNZ.js +304 -0
  60. package/dist/cli/chunk-FSKN4DWC.js +108 -0
  61. package/dist/cli/chunk-FVKLULL7.js +48 -0
  62. package/dist/cli/chunk-GAGUBU4Z.js +280 -0
  63. package/dist/cli/chunk-GKRFH2YG.js +171 -0
  64. package/dist/cli/chunk-GRU74UE4.js +270 -0
  65. package/dist/cli/chunk-GZFVDR44.js +320 -0
  66. package/dist/cli/chunk-HFLLZE6A.js +83 -0
  67. package/dist/cli/chunk-HXRXT3XU.js +78 -0
  68. package/dist/cli/chunk-IIOGUY3B.js +258 -0
  69. package/dist/cli/chunk-ILWWL462.js +60 -0
  70. package/dist/cli/chunk-J5USPJKZ.js +48 -0
  71. package/dist/cli/chunk-KEQS36GD.js +88 -0
  72. package/dist/cli/chunk-L7ONYSV6.js +2497 -0
  73. package/dist/cli/chunk-LVGIFMCV.js +163 -0
  74. package/dist/cli/chunk-NEFMQYLE.js +656 -0
  75. package/dist/cli/chunk-NU6CQQVB.js +4501 -0
  76. package/dist/cli/chunk-OILHT47L.js +252 -0
  77. package/dist/cli/chunk-PKKZPOOP.js +352 -0
  78. package/dist/cli/chunk-PN4WW5VX.js +66 -0
  79. package/dist/cli/chunk-PSJ33WVO.js +56 -0
  80. package/dist/cli/chunk-QA6T2LQ5.js +71 -0
  81. package/dist/cli/chunk-QJJWWCIC.js +288 -0
  82. package/dist/cli/chunk-QKMBWYAS.js +93 -0
  83. package/dist/cli/chunk-QWNKLLLG.js +84 -0
  84. package/dist/cli/chunk-QWUFFDL3.js +85 -0
  85. package/dist/cli/chunk-QY76BRUZ.js +35 -0
  86. package/dist/cli/chunk-R45KVF5Y.js +117 -0
  87. package/dist/cli/chunk-RRKP7HLU.js +66 -0
  88. package/dist/cli/chunk-SXXOC6KZ.js +209 -0
  89. package/dist/cli/chunk-T6GZJYL3.js +108 -0
  90. package/dist/cli/chunk-TLQ37HRE.js +67 -0
  91. package/dist/cli/chunk-TPTNEJZJ.js +52 -0
  92. package/dist/cli/chunk-TYC7G5LF.js +100 -0
  93. package/dist/cli/chunk-UWCZY52R.js +766 -0
  94. package/dist/cli/chunk-VB3LDPL5.js +46 -0
  95. package/dist/cli/chunk-VLEYOOPH.js +31 -0
  96. package/dist/cli/chunk-W3JLYKKY.js +140 -0
  97. package/dist/cli/chunk-WWCYZYSN.js +56 -0
  98. package/dist/cli/chunk-XA5WISNV.js +52 -0
  99. package/dist/cli/chunk-XHRZ7OYZ.js +132 -0
  100. package/dist/cli/chunk-XLPMIGJJ.js +148 -0
  101. package/dist/cli/chunk-YY66LFZF.js +29 -0
  102. package/dist/cli/chunk-ZMGDZMSJ.js +210 -0
  103. package/dist/cli/claim-IGOG2QOC.js +97 -0
  104. package/dist/cli/classify-MG4N7GMQ.js +117 -0
  105. package/dist/cli/cli-A23Q335V.js +51 -0
  106. package/dist/cli/cloud-SILYJVKO.js +731 -0
  107. package/dist/cli/cockpit-RZKLGYPN.js +790 -0
  108. package/dist/cli/code-H2FQCVMW.js +178 -0
  109. package/dist/cli/complete-JLX7NBI4.js +35 -0
  110. package/dist/cli/complexity-OKV7PVZH.js +57 -0
  111. package/dist/cli/compliance-QMGZHJNQ.js +277 -0
  112. package/dist/cli/conduit-4H32UYEA.js +308 -0
  113. package/dist/cli/conduit-EY54WTZA.js +535 -0
  114. package/dist/cli/config-TDYOC7XO.js +519 -0
  115. package/dist/cli/consensus-4XCOFPPT.js +122 -0
  116. package/dist/cli/context-FN4YTGHD.js +142 -0
  117. package/dist/cli/contribution-7RWFBJLC.js +112 -0
  118. package/dist/cli/curator-HKZJCVRL.js +139 -0
  119. package/dist/cli/current-B2NU7V3G.js +43 -0
  120. package/dist/cli/daemon-GBD4TVCD.js +452 -0
  121. package/dist/cli/dash-IGDANIE5.js +71 -0
  122. package/dist/cli/decide-26SXC2V6.js +416 -0
  123. package/dist/cli/decompose-LQ76TEZG.js +78 -0
  124. package/dist/cli/decomposition-WFRWNUSJ.js +122 -0
  125. package/dist/cli/delete-T5DUQHOX.js +69 -0
  126. package/dist/cli/deps-UTPZJBXL.js +462 -0
  127. package/dist/cli/detect-FFZSMVDT.js +46 -0
  128. package/dist/cli/detect-drift-TVCJOFYJ.js +408 -0
  129. package/dist/cli/diagnostics-GN5CVD3N.js +93 -0
  130. package/dist/cli/diagnostics-ZNBKH6GX.js +133 -0
  131. package/dist/cli/docs-CLQKEEUK.js +1710 -0
  132. package/dist/cli/docs-DPPDFTWR.js +3098 -0
  133. package/dist/cli/doctor-GPENOP4N.js +1270 -0
  134. package/dist/cli/doctor-ac-bindings-S3IOEFP4.js +26 -0
  135. package/dist/cli/doctor-acceptance-drift-VNFKPBSQ.js +26 -0
  136. package/dist/cli/doctor-credentials-A5H4JMTF.js +26 -0
  137. package/dist/cli/doctor-db-substrate-FGCISE4Z.js +27 -0
  138. package/dist/cli/doctor-dep-cycles-BKKKHHYG.js +26 -0
  139. package/dist/cli/doctor-exodus-ND2DH2KP.js +26 -0
  140. package/dist/cli/doctor-exodus-residue-4EMRYMEQ.js +26 -0
  141. package/dist/cli/doctor-fk-check-VY3RIQV3.js +26 -0
  142. package/dist/cli/doctor-global-delivery-JN6IGHUL.js +26 -0
  143. package/dist/cli/doctor-heavy-command-hook-XSN44WXU.js +26 -0
  144. package/dist/cli/doctor-legacy-backups-QAG5NHYP.js +26 -0
  145. package/dist/cli/doctor-legacy-reaper-CIRGFE6R.js +26 -0
  146. package/dist/cli/doctor-malformed-ids-WL7HT4TB.js +26 -0
  147. package/dist/cli/doctor-manifest-rows-SMQCKJ2T.js +26 -0
  148. package/dist/cli/doctor-memory-guard-LJDOJG76.js +26 -0
  149. package/dist/cli/doctor-migrations-ETQPFNUP.js +26 -0
  150. package/dist/cli/doctor-nexus-residency-A4JMKBEJ.js +26 -0
  151. package/dist/cli/doctor-project-identity-FFQJ5LNX.js +26 -0
  152. package/dist/cli/doctor-projects-MFUTKRHP.js +30 -0
  153. package/dist/cli/doctor-projects-registry-76X6VTGM.js +26 -0
  154. package/dist/cli/doctor-release-readiness-QJCOPFTK.js +26 -0
  155. package/dist/cli/doctor-repair-AU76FIKY.js +26 -0
  156. package/dist/cli/doctor-row-identity-KW6JYZQE.js +26 -0
  157. package/dist/cli/doctor-skill-fixtures-G3T7JUHS.js +26 -0
  158. package/dist/cli/doctor-split-brain-FUW6L7FS.js +26 -0
  159. package/dist/cli/doctor-superseded-store-DUHGSBLC.js +26 -0
  160. package/dist/cli/doctor-sync-journal-SXMUIKF7.js +26 -0
  161. package/dist/cli/doctor-sync-triggers-6WNJZFRM.js +26 -0
  162. package/dist/cli/doctor-tool-locks-66LSLUBN.js +26 -0
  163. package/dist/cli/doctor-twin-collapse-AYBYBFC4.js +26 -0
  164. package/dist/cli/doctor-worktree-stores-C5XEH5OG.js +26 -0
  165. package/dist/cli/done-R64XRZ32.js +196 -0
  166. package/dist/cli/dynamic-RR4HB7BB.js +29 -0
  167. package/dist/cli/entities-3JIHDIOK.js +361 -0
  168. package/dist/cli/event-45KEWV5H.js +372 -0
  169. package/dist/cli/exists-BEDZS5RI.js +65 -0
  170. package/dist/cli/exodus-DUX62344.js +401 -0
  171. package/dist/cli/export-C5PQIQ5O.js +93 -0
  172. package/dist/cli/export-tasks-CUXDZPJB.js +97 -0
  173. package/dist/cli/federation-ESM35EGG.js +145 -0
  174. package/dist/cli/find-5EUZHHQJ.js +178 -0
  175. package/dist/cli/focus-6AH4KLRO.js +368 -0
  176. package/dist/cli/focus-ANKAIRO5.js +56 -0
  177. package/dist/cli/gateway-2GW2KTK3.js +77 -0
  178. package/dist/cli/gateway-auto-start-EDK7XI6E.js +36 -0
  179. package/dist/cli/gc-CTOQLUSA.js +291 -0
  180. package/dist/cli/go-YJPNHHYT.js +206 -0
  181. package/dist/cli/goal-4GW4G77D.js +213 -0
  182. package/dist/cli/grade-25WSZH4X.js +57 -0
  183. package/dist/cli/graph-JUO3TMF3.js +879 -0
  184. package/dist/cli/history-NACNUQTC.js +138 -0
  185. package/dist/cli/hook-UF7J7R6D.js +57 -0
  186. package/dist/cli/hook-entry.js +244 -19
  187. package/dist/cli/hygiene-3QZ2NI7P.js +55 -0
  188. package/dist/cli/import-7ESGL5SS.js +89 -0
  189. package/dist/cli/import-tasks-FLE2RPBR.js +109 -0
  190. package/dist/cli/index.js +601 -94637
  191. package/dist/cli/init-AN4DZ2XO.js +40 -0
  192. package/dist/cli/inject-HQWA5GWY.js +83 -0
  193. package/dist/cli/install-global-YQV4W5OG.js +95 -0
  194. package/dist/cli/intelligence-OFFNQGHE.js +238 -0
  195. package/dist/cli/intelligence-QIC4SN4X.js +182 -0
  196. package/dist/cli/issue-P5RNMRDG.js +159 -0
  197. package/dist/cli/janitor-ZNCFQ7E3.js +111 -0
  198. package/dist/cli/labels-ORBM3T57.js +88 -0
  199. package/dist/cli/lifecycle-MHR22TVI.js +273 -0
  200. package/dist/cli/list-LB6GCYYU.js +109 -0
  201. package/dist/cli/llm-H7LZWQKX.js +130 -0
  202. package/dist/cli/llm-OTJWPMGI.js +704 -0
  203. package/dist/cli/llm-cost-MLMXEAR4.js +25 -0
  204. package/dist/cli/llm-stream-AAEUNKRP.js +27 -0
  205. package/dist/cli/log-W2A5M2NA.js +76 -0
  206. package/dist/cli/login-SIXFFZSP.js +45 -0
  207. package/dist/cli/logout-G3KVLQQM.js +74 -0
  208. package/dist/cli/manifest-G4T6EBSI.js +354 -0
  209. package/dist/cli/map-VU5M72TK.js +53 -0
  210. package/dist/cli/memory-2E27G2G5.js +1952 -0
  211. package/dist/cli/memory-IAEYKXG6.js +1895 -0
  212. package/dist/cli/migrate-agents-v2-A52QIYNJ.js +33 -0
  213. package/dist/cli/migrate-claude-mem-TPDW3R4Z.js +206 -0
  214. package/dist/cli/next-SVH4LIDY.js +57 -0
  215. package/dist/cli/nexus-FPQV2EAF.js +1059 -0
  216. package/dist/cli/nexus-XSFXN5E6.js +2924 -0
  217. package/dist/cli/ops-K6LHY5J6.js +52 -0
  218. package/dist/cli/orchestrate-CZ2J6W3L.js +1650 -0
  219. package/dist/cli/orchestrate-HURUCQFT.js +950 -0
  220. package/dist/cli/otel-JCNPVJLZ.js +188 -0
  221. package/dist/cli/phase-VDFRASSO.js +221 -0
  222. package/dist/cli/pipeline-TCZPOEDR.js +697 -0
  223. package/dist/cli/pivot-V5MSQZ7L.js +88 -0
  224. package/dist/cli/plan-SQUGCKSM.js +49 -0
  225. package/dist/cli/playbook-L47GLDQD.js +230 -0
  226. package/dist/cli/playbook-NJVO4R6P.js +33 -0
  227. package/dist/cli/project-YZEC7GYF.js +331 -0
  228. package/dist/cli/promote-FINF4HVK.js +53 -0
  229. package/dist/cli/provenance-3TUWVBFR.js +141 -0
  230. package/dist/cli/provenance-YZG33JGM.js +129 -0
  231. package/dist/cli/provider-23JVLLG3.js +213 -0
  232. package/dist/cli/reason-FHN54O7O.js +138 -0
  233. package/dist/cli/reconcile-MOM5T4AX.js +128 -0
  234. package/dist/cli/refresh-memory-3OSTRAVK.js +45 -0
  235. package/dist/cli/relates-6FWUFUS2.js +260 -0
  236. package/dist/cli/release-G2DPSG5M.js +347 -0
  237. package/dist/cli/release-URX6JHZ2.js +525 -0
  238. package/dist/cli/remote-VIULU2T5.js +279 -0
  239. package/dist/cli/renderers-TGSW77J4.js +37 -0
  240. package/dist/cli/reorder-UIPN6TQY.js +87 -0
  241. package/dist/cli/reparent-ALOWWUIU.js +59 -0
  242. package/dist/cli/req-RH2Y3H7A.js +130 -0
  243. package/dist/cli/research-G2Y72HRC.js +366 -0
  244. package/dist/cli/restore-VBR5XNML.js +470 -0
  245. package/dist/cli/revert-32LDNSGP.js +240 -0
  246. package/dist/cli/roadmap-LFU3AG7D.js +62 -0
  247. package/dist/cli/run-HXRILSR7.js +245 -0
  248. package/dist/cli/safestop-Z5UC7NGQ.js +89 -0
  249. package/dist/cli/saga-Y6FZS6AM.js +286 -0
  250. package/dist/cli/schema-OOOKLWUE.js +195 -0
  251. package/dist/cli/self-update-26SOTJMH.js +504 -0
  252. package/dist/cli/selfimprove-4SMOCLUV.js +89 -0
  253. package/dist/cli/selfimprove-EB4RQLP4.js +139 -0
  254. package/dist/cli/sentient-QPETVE53.js +254 -0
  255. package/dist/cli/sentient-RGMWR4XJ.js +1088 -0
  256. package/dist/cli/sequence-H7DSAJPF.js +94 -0
  257. package/dist/cli/service-EK5MGB2D.js +156 -0
  258. package/dist/cli/service-GLOMZWPQ.js +437 -0
  259. package/dist/cli/session-HYUXAQGC.js +708 -0
  260. package/dist/cli/session-N5ISU56W.js +568 -0
  261. package/dist/cli/setup-L3YYV53D.js +323 -0
  262. package/dist/cli/show-364V3KY2.js +123 -0
  263. package/dist/cli/skill-F2KR6HW5.js +84 -0
  264. package/dist/cli/skills-FS3DCP6E.js +929 -0
  265. package/dist/cli/smoke-provider-SKUFMZXU.js +218 -0
  266. package/dist/cli/snapshot-EGXEQ5PR.js +120 -0
  267. package/dist/cli/src-LYLXHXHH.js +80 -0
  268. package/dist/cli/start-6DXOCCKL.js +68 -0
  269. package/dist/cli/stats-UVUQEGYC.js +96 -0
  270. package/dist/cli/status-XLKYLN42.js +157 -0
  271. package/dist/cli/sticky-VSTQ2I2O.js +264 -0
  272. package/dist/cli/sticky-XZXZDCFW.js +339 -0
  273. package/dist/cli/stop-VNOAFWNB.js +43 -0
  274. package/dist/cli/sync-YYPARW3A.js +155 -0
  275. package/dist/cli/tasks-C24KHTFF.js +1118 -0
  276. package/dist/cli/tasks-LBJC7CZV.js +175 -0
  277. package/dist/cli/telemetry-CU7W5WAY.js +120 -0
  278. package/dist/cli/templates-G42JBUY4.js +609 -0
  279. package/dist/cli/testing-HSRITHEY.js +147 -0
  280. package/dist/cli/token-J74E7TSU.js +221 -0
  281. package/dist/cli/tools-BI74W7VE.js +652 -0
  282. package/dist/cli/transcript-RGK7RSGQ.js +440 -0
  283. package/dist/cli/tui-BPUFHYKK.js +51 -0
  284. package/dist/cli/update-2KQWA27S.js +478 -0
  285. package/dist/cli/update-check-entry.js +124 -0
  286. package/dist/cli/update-notice-6SQ6WPQG.js +68 -0
  287. package/dist/cli/upgrade-E2MJAPC7.js +136 -0
  288. package/dist/cli/upgrade-XRSQ4RWH.js +243 -0
  289. package/dist/cli/verify-WASRGDBA.js +191 -0
  290. package/dist/cli/web-NJ3P67EU.js +275 -0
  291. package/dist/cli/workgraph-OHJ2VKJD.js +232 -0
  292. package/dist/cli/worktree-FVQLORFY.js +371 -0
  293. package/dist/cli/worktree-ZJ6JTQNG.js +287 -0
  294. package/package.json +13 -13
  295. package/studio-dist/client/_app/immutable/chunks/{DMj27Pxj.js → AH7dIemv.js} +1 -1
  296. package/studio-dist/client/_app/immutable/chunks/{Dc2owyvE.js → BDgH40i3.js} +1 -1
  297. package/studio-dist/client/_app/immutable/chunks/BXDCSJ7U.js +1 -0
  298. package/studio-dist/client/_app/immutable/chunks/{qq3pe1aT.js → Gg4iYl59.js} +1 -1
  299. package/studio-dist/client/_app/immutable/entry/{app.CHWXLeE9.js → app.DUDNK-37.js} +2 -2
  300. package/studio-dist/client/_app/immutable/entry/start.DNmZ0pA4.js +1 -0
  301. package/studio-dist/client/_app/immutable/nodes/{0.DmKQGvFh.js → 0.DWqP3ail.js} +1 -1
  302. package/studio-dist/client/_app/immutable/nodes/{1.DqJk_REO.js → 1.CZGVUP5B.js} +1 -1
  303. package/studio-dist/client/_app/immutable/nodes/{15.GUy6kdW1.js → 15.DGaflZRS.js} +1 -1
  304. package/studio-dist/client/_app/immutable/nodes/{16.CcnKZ8f9.js → 16.uYlarGXl.js} +1 -1
  305. package/studio-dist/client/_app/immutable/nodes/{17.DAlQF3lQ.js → 17.CZMR0E47.js} +1 -1
  306. package/studio-dist/client/_app/immutable/nodes/{18.vQFr-vFj.js → 18.CBC-AKH_.js} +1 -1
  307. package/studio-dist/client/_app/immutable/nodes/{20.GVOj5j_r.js → 20.BGi43MvQ.js} +1 -1
  308. package/studio-dist/client/_app/immutable/nodes/{24.2-wC6DOh.js → 24.Dv8ftCyR.js} +1 -1
  309. package/studio-dist/client/_app/immutable/nodes/25.DQPVlTDQ.js +39 -0
  310. package/studio-dist/client/_app/immutable/nodes/{26.C3rNqzZF.js → 26.Cl800304.js} +1 -1
  311. package/studio-dist/client/_app/immutable/nodes/{3.b-7pzc3M.js → 3.D_fQKj9f.js} +1 -1
  312. package/studio-dist/client/_app/version.json +1 -1
  313. package/studio-dist/server/chunks/{0-BaCce-O1.js → 0-BpOagOst.js} +3 -3
  314. package/studio-dist/server/chunks/1-D0oRGR-C.js +9 -0
  315. package/studio-dist/server/chunks/{15-DRMOSIC9.js → 15-BcjHz7Tv.js} +3 -3
  316. package/studio-dist/server/chunks/{16-BulXhoZZ.js → 16-CXm8TUk7.js} +3 -3
  317. package/studio-dist/server/chunks/{17-DUEOCM0H.js → 17-mSgUK-cp.js} +3 -3
  318. package/studio-dist/server/chunks/{18-DP7Q8zPs.js → 18-BtfnIw1d.js} +3 -3
  319. package/studio-dist/server/chunks/{20-9ta6MI7q.js → 20-By1e4QDS.js} +3 -3
  320. package/studio-dist/server/chunks/{24-DysdL1ab.js → 24-0i2YLVxG.js} +3 -3
  321. package/studio-dist/server/chunks/{dist-CdoCt9zT.js → 25-DPsrqbrh.js} +797 -10736
  322. package/studio-dist/server/chunks/{26-Df4YXgg0.js → 26-P0XkOibm.js} +3 -3
  323. package/studio-dist/server/chunks/{3-BEhOhYpL.js → 3-WudjUK7e.js} +3 -3
  324. package/studio-dist/server/chunks/{_layout.svelte-CnLcXYG-.js → _layout.svelte-D9m81Rle.js} +4 -4
  325. package/studio-dist/server/chunks/{_page.svelte-DGhXqeRc.js → _page.svelte-2PDLOF83.js} +3 -3
  326. package/studio-dist/server/chunks/{_page.svelte-Dv8tmDEC.js → _page.svelte-BjE3jm2K.js} +3 -3
  327. package/studio-dist/server/chunks/{_page.svelte-C0qgUvzA.js → _page.svelte-Clc0vmiZ.js} +4 -4
  328. package/studio-dist/server/chunks/{_page.svelte-ui7LnWkL.js → _page.svelte-DABdRT3h.js} +3 -3
  329. package/studio-dist/server/chunks/{_page.svelte-HUqTICJR.js → _page.svelte-DG3PjiHj.js} +3 -3
  330. package/studio-dist/server/chunks/{_page.svelte-DzcZljiy.js → _page.svelte-Edy9CaE8.js} +20 -7
  331. package/studio-dist/server/chunks/{_page.svelte-DOl0DGOO.js → _page.svelte-Hrf3-ZR8.js} +3 -3
  332. package/studio-dist/server/chunks/{_page.svelte-Da4q5l93.js → _page.svelte-VB4O4Nl5.js} +3 -3
  333. package/studio-dist/server/chunks/{_page.svelte-CbyEPj2j.js → _page.svelte-d3jEgjsI.js} +3 -3
  334. package/studio-dist/server/chunks/{_server.ts-P4wVVksg.js → _server.ts-BcRFsyo3.js} +4 -5
  335. package/studio-dist/server/chunks/{_server.ts-Cr57EKWf.js → _server.ts-CEWpIFrj.js} +6 -5
  336. package/studio-dist/server/chunks/{_server.ts-CnKVmf_s.js → _server.ts-CLVdVIF9.js} +2 -2
  337. package/studio-dist/server/chunks/{_server.ts-C0evMKCk.js → _server.ts-D_j7aSy5.js} +6 -5
  338. package/studio-dist/server/chunks/{_server.ts-2BazvYRP.js → _server.ts-QEZF8h2q.js} +4 -5
  339. package/studio-dist/server/chunks/{client-CPM4LrO2.js → client-Kp1dP1od.js} +2 -2
  340. package/studio-dist/server/chunks/{error.svelte-ShcZo43D.js → error.svelte-WOCioJVX.js} +3 -3
  341. package/studio-dist/server/chunks/{hooks.server-D2qbf3Zp.js → hooks.server-DH9zkIrJ.js} +3 -1
  342. package/studio-dist/server/chunks/{http-BiQjEmVU.js → http-DT5kxaWk.js} +5 -4
  343. package/studio-dist/server/chunks/{internal-Cgsrya1j.js → internal-z0vqd5_u.js} +3 -3
  344. package/studio-dist/server/chunks/operations-registry-DdzmYzqX.js +10584 -0
  345. package/studio-dist/server/chunks/{stores-BGrpEDMK.js → stores-s2kaL315.js} +2 -2
  346. package/studio-dist/server/index.js +1 -1
  347. package/studio-dist/server/manifest.js +17 -17
  348. package/studio-dist/client/_app/immutable/chunks/Bw6J8NDM.js +0 -1
  349. package/studio-dist/client/_app/immutable/entry/start.C9bwPpvc.js +0 -1
  350. package/studio-dist/client/_app/immutable/nodes/25.D1vYaH8g.js +0 -39
  351. package/studio-dist/server/chunks/1-CVo7Nk6d.js +0 -9
  352. package/studio-dist/server/chunks/25-CYsps38R.js +0 -366
@@ -0,0 +1,2404 @@
1
+ (() => {
2
+ const _installed = Symbol.for('cleocode.cli.sqliteWarningFilter');
3
+ if (globalThis[_installed]) return;
4
+ globalThis[_installed] = true;
5
+ const _origEmitWarning = process.emitWarning;
6
+ process.emitWarning = function(warning, type, code, ctor) {
7
+ if (typeof warning === 'object' && warning.name === 'ExperimentalWarning' && typeof warning.message === 'string' && /SQLite is an experimental feature/i.test(warning.message)) {
8
+ return;
9
+ }
10
+ if (typeof warning === 'string' && /SQLite is an experimental feature/i.test(warning)) {
11
+ return;
12
+ }
13
+ return _origEmitWarning.call(process, warning, type, code, ctor);
14
+ };
15
+ })();
16
+ import {
17
+ AGENTS_SUBDIR,
18
+ CANT_AGENTS_SUBDIR,
19
+ CLEO_DIR_NAME
20
+ } from "./chunk-6N6WGLXE.js";
21
+ import {
22
+ defineCommand,
23
+ showUsage
24
+ } from "./chunk-PKKZPOOP.js";
25
+ import {
26
+ cliError,
27
+ cliOutput,
28
+ humanLine,
29
+ humanWarn
30
+ } from "./chunk-4RGSNUUP.js";
31
+ import "./chunk-6JSJNYH2.js";
32
+
33
+ // packages/cleo/src/cli/commands/agent.ts
34
+ import { getProjectRoot } from "@cleocode/core";
35
+ import {
36
+ checkAgentHealth,
37
+ detectCrashedAgents,
38
+ detectStaleAgents,
39
+ getHealthReport,
40
+ STALE_THRESHOLD_MS
41
+ } from "@cleocode/core/agents";
42
+ import {
43
+ cleanupInstallTempDir,
44
+ resolveAgentCantPath
45
+ } from "@cleocode/core/agents/install-pipeline.js";
46
+ import {
47
+ inferTierFromRole,
48
+ scaffoldAgent,
49
+ validateName,
50
+ validateRole,
51
+ validateTier
52
+ } from "@cleocode/core/agents/scaffold.js";
53
+ import { startWorkLoop } from "@cleocode/core/agents/work-loop.js";
54
+ import { openCleoDb } from "@cleocode/core/store/open-cleo-db";
55
+
56
+ // packages/cleo/src/cli/commands/agent-profile-status.ts
57
+ function computeProfileStatus(profile, validation) {
58
+ if (profile === null) return "none";
59
+ if (validation === null) return "loaded (unvalidated)";
60
+ if (validation.valid) return "validated";
61
+ return `invalid (${validation.errors.length} errors)`;
62
+ }
63
+
64
+ // packages/cleo/src/cli/commands/agent.ts
65
+ var registerCommand = defineCommand({
66
+ meta: {
67
+ name: "register",
68
+ description: "Register a new agent credential in the local registry"
69
+ },
70
+ args: {
71
+ id: {
72
+ type: "string",
73
+ description: "Unique agent identifier",
74
+ required: true
75
+ },
76
+ name: {
77
+ type: "string",
78
+ description: "Human-readable display name",
79
+ required: true
80
+ },
81
+ "api-key": {
82
+ type: "string",
83
+ description: "API key (sk_live_...)",
84
+ required: true
85
+ },
86
+ "api-url": {
87
+ type: "string",
88
+ description: "Cloud messaging API base URL (default 'local': messaging stays in the project's conduit store)"
89
+ },
90
+ classification: {
91
+ type: "string",
92
+ description: "Agent classification (e.g. code_dev, orchestrator)"
93
+ },
94
+ privacy: {
95
+ type: "string",
96
+ description: "Privacy tier: public, discoverable, private",
97
+ default: "public"
98
+ }
99
+ },
100
+ async run({ args }) {
101
+ try {
102
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
103
+ const { assertCloudUrlAllowed } = await import("@cleocode/core/conduit/cloud-endpoint.js");
104
+ const apiBaseUrl = args["api-url"] ?? "local";
105
+ assertCloudUrlAllowed(apiBaseUrl);
106
+ await openCleoDb("project");
107
+ const registry = new AgentRegistryAccessor(getProjectRoot());
108
+ const agentId = args.id;
109
+ const displayName = args.name;
110
+ const classification = args.classification;
111
+ const credential = await registry.register({
112
+ agentId,
113
+ displayName,
114
+ apiKey: args["api-key"],
115
+ apiBaseUrl,
116
+ classification,
117
+ privacyTier: args.privacy ?? "public",
118
+ capabilities: [],
119
+ skills: [],
120
+ transportType: "http",
121
+ transportConfig: {},
122
+ isActive: true
123
+ });
124
+ const { existsSync, mkdirSync, writeFileSync } = await import("node:fs");
125
+ const { join } = await import("node:path");
126
+ const cantDir = join(CLEO_DIR_NAME, AGENTS_SUBDIR);
127
+ const cantPath = join(cantDir, `${agentId}.cant`);
128
+ let cantScaffolded = false;
129
+ if (!existsSync(cantPath)) {
130
+ mkdirSync(cantDir, { recursive: true });
131
+ const role = classification ?? "specialist";
132
+ const cantContent = `---
133
+ kind: agent
134
+ version: 2
135
+ ---
136
+
137
+ agent ${agentId}:
138
+ house: none
139
+ allegiance: canon
140
+ role: ${role}
141
+ parent: project-orchestrator
142
+ description: "${displayName}"
143
+
144
+ tone:
145
+ |
146
+ TODO: Describe how this agent communicates.
147
+
148
+ prompt:
149
+ |
150
+ TODO: Write the core behavioral instruction.
151
+
152
+ skills: [ct-cleo]
153
+
154
+ permissions:
155
+ tasks: read
156
+ session: read
157
+ memory: read
158
+
159
+ transport:
160
+ primary: local
161
+ fallback: sse
162
+ cloud: http
163
+ apiBaseUrl: ${apiBaseUrl}
164
+
165
+ lifecycle:
166
+ start: cleo agent start ${agentId}
167
+ stop: cleo agent stop ${agentId}
168
+ status: cleo agent status ${agentId}
169
+
170
+ context:
171
+ active-tasks
172
+ memory-bridge
173
+
174
+ on SessionStart:
175
+ /checkin @all #online
176
+
177
+ enforcement:
178
+ 1: TODO \u2014 what does this agent push back on?
179
+ `;
180
+ writeFileSync(cantPath, cantContent, "utf-8");
181
+ cantScaffolded = true;
182
+ }
183
+ cliOutput(
184
+ {
185
+ success: true,
186
+ data: {
187
+ agentId: credential.agentId,
188
+ displayName: credential.displayName,
189
+ cantFile: cantScaffolded ? cantPath : existsSync(cantPath) ? cantPath : null,
190
+ cantScaffolded
191
+ }
192
+ },
193
+ { command: "agent register" }
194
+ );
195
+ } catch (err) {
196
+ const { isSignalDockRetiredError } = await import("@cleocode/core/conduit/cloud-endpoint.js");
197
+ cliOutput(
198
+ {
199
+ success: false,
200
+ error: {
201
+ code: isSignalDockRetiredError(err) ? err.code : "E_REGISTER",
202
+ message: String(err)
203
+ }
204
+ },
205
+ { command: "agent register" }
206
+ );
207
+ process.exitCode = 1;
208
+ }
209
+ }
210
+ });
211
+ var signinCommand = defineCommand({
212
+ meta: {
213
+ name: "signin",
214
+ description: "Sign in as an agent \u2014 marks active, caches credentials for session"
215
+ },
216
+ args: {
217
+ agentId: {
218
+ type: "positional",
219
+ description: "Agent ID to sign in as",
220
+ required: true
221
+ },
222
+ "api-url": {
223
+ type: "string",
224
+ description: "Override API base URL for cloud status update"
225
+ }
226
+ },
227
+ async run({ args }) {
228
+ try {
229
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
230
+ await openCleoDb("project");
231
+ const registry = new AgentRegistryAccessor(getProjectRoot());
232
+ const credential = await registry.get(args.agentId);
233
+ if (!credential) {
234
+ cliOutput(
235
+ {
236
+ success: false,
237
+ error: {
238
+ code: "E_NOT_FOUND",
239
+ message: `Agent '${args.agentId}' not registered. Run: cleo agent register --id ${args.agentId} --name "..." --api-key sk_live_...`
240
+ }
241
+ },
242
+ { command: "agent signin" }
243
+ );
244
+ process.exitCode = 1;
245
+ return;
246
+ }
247
+ await registry.update(args.agentId, { isActive: true });
248
+ await registry.markUsed(args.agentId);
249
+ const apiUrl = args["api-url"] ?? credential.apiBaseUrl;
250
+ const { conduitFetch } = await import("@cleocode/core/conduit/cloud-endpoint.js");
251
+ try {
252
+ await conduitFetch(`${apiUrl}/agents/${args.agentId}/status`, {
253
+ method: "PUT",
254
+ headers: {
255
+ "Content-Type": "application/json",
256
+ Authorization: `Bearer ${credential.apiKey}`,
257
+ "X-Agent-Id": args.agentId
258
+ },
259
+ body: JSON.stringify({ status: "online" }),
260
+ signal: AbortSignal.timeout(5e3)
261
+ });
262
+ } catch {
263
+ }
264
+ cliOutput(
265
+ {
266
+ success: true,
267
+ data: {
268
+ agentId: credential.agentId,
269
+ displayName: credential.displayName,
270
+ apiBaseUrl: apiUrl,
271
+ status: "online",
272
+ transport: "local"
273
+ }
274
+ },
275
+ { command: "agent signin" }
276
+ );
277
+ } catch (err) {
278
+ cliOutput(
279
+ { success: false, error: { code: "E_SIGNIN", message: String(err) } },
280
+ { command: "agent signin" }
281
+ );
282
+ process.exitCode = 1;
283
+ }
284
+ }
285
+ });
286
+ var startCommand = defineCommand({
287
+ meta: {
288
+ name: "start",
289
+ description: "Start an agent daemon \u2014 polls for messages. Profile is validated for fail-fast feedback only; CANT execution lives in Pi via cant-bridge.ts."
290
+ },
291
+ args: {
292
+ agentId: {
293
+ type: "positional",
294
+ description: "Agent ID to start",
295
+ required: true
296
+ },
297
+ cant: {
298
+ type: "string",
299
+ description: "Path to .cant persona file (validated only, NOT executed by the daemon)"
300
+ },
301
+ "poll-interval": {
302
+ type: "string",
303
+ description: "Poll interval in milliseconds",
304
+ default: "5000"
305
+ },
306
+ heartbeat: {
307
+ type: "boolean",
308
+ description: "Enable heartbeat service (default: true)",
309
+ default: true
310
+ }
311
+ },
312
+ async run({ args }) {
313
+ try {
314
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
315
+ const { createRuntime } = await import("@cleocode/runtime");
316
+ const { existsSync, readFileSync } = await import("node:fs");
317
+ const { join } = await import("node:path");
318
+ await openCleoDb("project");
319
+ const registry = new AgentRegistryAccessor(getProjectRoot());
320
+ const credential = await registry.get(args.agentId);
321
+ if (!credential) {
322
+ cliOutput(
323
+ {
324
+ success: false,
325
+ error: {
326
+ code: "E_NOT_FOUND",
327
+ message: `Agent '${args.agentId}' not registered. Run: cleo agent register --id ${args.agentId} --name "..." --api-key sk_live_...`
328
+ }
329
+ },
330
+ { command: "agent start" }
331
+ );
332
+ process.exitCode = 1;
333
+ return;
334
+ }
335
+ let profile = null;
336
+ let cantValidation = null;
337
+ const cantPath = args.cant ?? join(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
338
+ if (existsSync(cantPath)) {
339
+ profile = readFileSync(cantPath, "utf-8");
340
+ try {
341
+ const cantModule = await import("@cleocode/cant");
342
+ const validate = "validate" in cantModule ? cantModule.validate : null;
343
+ if (validate) {
344
+ const result = validate(profile);
345
+ cantValidation = {
346
+ valid: result.valid,
347
+ errors: result.diagnostics?.map((d) => d.message) ?? []
348
+ };
349
+ }
350
+ } catch {
351
+ cantValidation = null;
352
+ }
353
+ }
354
+ await registry.update(args.agentId, { isActive: true });
355
+ await registry.markUsed(args.agentId);
356
+ const { conduitFetch } = await import("@cleocode/core/conduit/cloud-endpoint.js");
357
+ try {
358
+ await conduitFetch(`${credential.apiBaseUrl}/agents/${args.agentId}/status`, {
359
+ method: "PUT",
360
+ headers: {
361
+ "Content-Type": "application/json",
362
+ Authorization: `Bearer ${credential.apiKey}`,
363
+ "X-Agent-Id": args.agentId
364
+ },
365
+ body: JSON.stringify({ status: "online" }),
366
+ signal: AbortSignal.timeout(5e3)
367
+ });
368
+ } catch {
369
+ }
370
+ const pollInterval = Number.parseInt(args["poll-interval"], 10);
371
+ const runtime = await createRuntime(registry, {
372
+ agentId: args.agentId,
373
+ pollIntervalMs: pollInterval,
374
+ heartbeatIntervalMs: args.heartbeat === false ? 0 : 3e4,
375
+ groupConversationIds: []
376
+ });
377
+ runtime.poller.start();
378
+ cliOutput(
379
+ {
380
+ success: true,
381
+ data: {
382
+ agentId: args.agentId,
383
+ displayName: credential.displayName,
384
+ status: "online",
385
+ transport: runtime.transport.name,
386
+ // Surfaced for operator visibility only — see
387
+ // computeProfileStatus tsdoc for the four possible values.
388
+ profile: computeProfileStatus(profile, cantValidation),
389
+ services: {
390
+ poller: "running",
391
+ heartbeat: runtime.heartbeat ? "running" : "disabled",
392
+ keyRotation: runtime.keyRotation ? "running" : "disabled"
393
+ }
394
+ }
395
+ },
396
+ { command: "agent start" }
397
+ );
398
+ const shutdown = () => {
399
+ runtime.stop();
400
+ void registry.update(args.agentId, { isActive: false }).catch(() => {
401
+ });
402
+ process.exit(0);
403
+ };
404
+ process.on("SIGINT", shutdown);
405
+ process.on("SIGTERM", shutdown);
406
+ if (process.platform === "win32") {
407
+ process.on("message", (msg) => {
408
+ if (msg === "shutdown") shutdown();
409
+ });
410
+ }
411
+ await new Promise(() => {
412
+ });
413
+ } catch (err) {
414
+ const { isSignalDockRetiredError } = await import("@cleocode/core/conduit/cloud-endpoint.js");
415
+ cliOutput(
416
+ {
417
+ success: false,
418
+ error: {
419
+ code: isSignalDockRetiredError(err) ? err.code : "E_START",
420
+ message: String(err)
421
+ }
422
+ },
423
+ { command: "agent start" }
424
+ );
425
+ process.exitCode = 1;
426
+ }
427
+ }
428
+ });
429
+ var stopCommand = defineCommand({
430
+ meta: {
431
+ name: "stop",
432
+ description: "Stop an agent \u2014 mark offline and deactivate"
433
+ },
434
+ args: {
435
+ agentId: {
436
+ type: "positional",
437
+ description: "Agent ID to stop",
438
+ required: true
439
+ }
440
+ },
441
+ async run({ args }) {
442
+ try {
443
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
444
+ await openCleoDb("project");
445
+ const registry = new AgentRegistryAccessor(getProjectRoot());
446
+ const credential = await registry.get(args.agentId);
447
+ if (!credential) {
448
+ cliOutput(
449
+ {
450
+ success: false,
451
+ error: { code: "E_NOT_FOUND", message: `Agent '${args.agentId}' not registered.` }
452
+ },
453
+ { command: "agent stop" }
454
+ );
455
+ process.exitCode = 1;
456
+ return;
457
+ }
458
+ await registry.update(args.agentId, { isActive: false });
459
+ const { conduitFetch } = await import("@cleocode/core/conduit/cloud-endpoint.js");
460
+ try {
461
+ await conduitFetch(`${credential.apiBaseUrl}/agents/${args.agentId}/status`, {
462
+ method: "PUT",
463
+ headers: {
464
+ "Content-Type": "application/json",
465
+ Authorization: `Bearer ${credential.apiKey}`,
466
+ "X-Agent-Id": args.agentId
467
+ },
468
+ body: JSON.stringify({ status: "offline" }),
469
+ signal: AbortSignal.timeout(5e3)
470
+ });
471
+ } catch {
472
+ }
473
+ cliOutput(
474
+ { success: true, data: { agentId: args.agentId, status: "offline" } },
475
+ { command: "agent stop" }
476
+ );
477
+ } catch (err) {
478
+ cliOutput(
479
+ { success: false, error: { code: "E_STOP", message: String(err) } },
480
+ { command: "agent stop" }
481
+ );
482
+ process.exitCode = 1;
483
+ }
484
+ }
485
+ });
486
+ var statusCommand = defineCommand({
487
+ meta: {
488
+ name: "status",
489
+ description: "Show agent status \u2014 all agents or specific agent"
490
+ },
491
+ args: {
492
+ agentId: {
493
+ type: "positional",
494
+ description: "Agent ID to check (optional \u2014 omit for all)",
495
+ required: false
496
+ }
497
+ },
498
+ async run({ args }) {
499
+ try {
500
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
501
+ await openCleoDb("project");
502
+ const registry = new AgentRegistryAccessor(getProjectRoot());
503
+ if (args.agentId) {
504
+ const credential = await registry.get(args.agentId);
505
+ if (!credential) {
506
+ cliOutput(
507
+ {
508
+ success: false,
509
+ error: { code: "E_NOT_FOUND", message: `Agent '${args.agentId}' not registered.` }
510
+ },
511
+ { command: "agent status" }
512
+ );
513
+ process.exitCode = 1;
514
+ return;
515
+ }
516
+ cliOutput(
517
+ {
518
+ success: true,
519
+ data: {
520
+ agentId: credential.agentId,
521
+ displayName: credential.displayName,
522
+ active: credential.isActive,
523
+ lastUsedAt: credential.lastUsedAt,
524
+ transport: credential.transportType
525
+ }
526
+ },
527
+ { command: "agent status" }
528
+ );
529
+ } else {
530
+ const agents = await registry.list();
531
+ cliOutput(
532
+ {
533
+ success: true,
534
+ data: {
535
+ agents: agents.map((a) => ({
536
+ agentId: a.agentId,
537
+ displayName: a.displayName,
538
+ active: a.isActive,
539
+ lastUsedAt: a.lastUsedAt
540
+ })),
541
+ total: agents.length
542
+ }
543
+ },
544
+ { command: "agent status" }
545
+ );
546
+ }
547
+ } catch (err) {
548
+ cliOutput(
549
+ { success: false, error: { code: "E_STATUS", message: String(err) } },
550
+ { command: "agent status" }
551
+ );
552
+ process.exitCode = 1;
553
+ }
554
+ }
555
+ });
556
+ var assignCommand = defineCommand({
557
+ meta: {
558
+ name: "assign",
559
+ description: "Assign a task to an agent via messaging"
560
+ },
561
+ args: {
562
+ agentId: {
563
+ type: "positional",
564
+ description: "Target agent ID",
565
+ required: true
566
+ },
567
+ taskId: {
568
+ type: "positional",
569
+ description: "Task ID to assign",
570
+ required: true
571
+ }
572
+ },
573
+ async run({ args }) {
574
+ try {
575
+ const { AgentRegistryAccessor, createConduit } = await import("@cleocode/core/agents");
576
+ await openCleoDb("project");
577
+ const registry = new AgentRegistryAccessor(getProjectRoot());
578
+ const active = await registry.getActive();
579
+ if (!active) {
580
+ cliOutput(
581
+ {
582
+ success: false,
583
+ error: {
584
+ code: "E_NO_ACTIVE",
585
+ message: "No active agent. Run: cleo agent signin <id>"
586
+ }
587
+ },
588
+ { command: "agent assign" }
589
+ );
590
+ process.exitCode = 1;
591
+ return;
592
+ }
593
+ const conduit = await createConduit(registry);
594
+ await conduit.send(
595
+ args.agentId,
596
+ `/action @${args.agentId} #task-assignment
597
+
598
+ Assigned task ${args.taskId}. Run: cleo show ${args.taskId} && cleo start ${args.taskId}`
599
+ );
600
+ await conduit.disconnect();
601
+ cliOutput(
602
+ {
603
+ success: true,
604
+ data: { agentId: args.agentId, taskId: args.taskId, assignedBy: active.agentId }
605
+ },
606
+ { command: "agent assign" }
607
+ );
608
+ } catch (err) {
609
+ cliOutput(
610
+ { success: false, error: { code: "E_ASSIGN", message: String(err) } },
611
+ { command: "agent assign" }
612
+ );
613
+ process.exitCode = 1;
614
+ }
615
+ }
616
+ });
617
+ var wakeCommand = defineCommand({
618
+ meta: {
619
+ name: "wake",
620
+ description: "Wake an idle agent \u2014 send a prod message"
621
+ },
622
+ args: {
623
+ agentId: {
624
+ type: "positional",
625
+ description: "Agent ID to wake",
626
+ required: true
627
+ }
628
+ },
629
+ async run({ args }) {
630
+ try {
631
+ const { AgentRegistryAccessor, createConduit } = await import("@cleocode/core/agents");
632
+ await openCleoDb("project");
633
+ const registry = new AgentRegistryAccessor(getProjectRoot());
634
+ const active = await registry.getActive();
635
+ if (!active) {
636
+ cliOutput(
637
+ {
638
+ success: false,
639
+ error: {
640
+ code: "E_NO_ACTIVE",
641
+ message: "No active agent. Run: cleo agent signin <id>"
642
+ }
643
+ },
644
+ { command: "agent wake" }
645
+ );
646
+ process.exitCode = 1;
647
+ return;
648
+ }
649
+ const conduit = await createConduit(registry);
650
+ await conduit.send(
651
+ args.agentId,
652
+ `/action @${args.agentId} #wake #prod
653
+
654
+ You are idle. Check your queue: cleo current || cleo next. Report status immediately.`
655
+ );
656
+ await conduit.disconnect();
657
+ cliOutput(
658
+ { success: true, data: { agentId: args.agentId, prodBy: active.agentId } },
659
+ { command: "agent wake" }
660
+ );
661
+ } catch (err) {
662
+ cliOutput(
663
+ { success: false, error: { code: "E_WAKE", message: String(err) } },
664
+ { command: "agent wake" }
665
+ );
666
+ process.exitCode = 1;
667
+ }
668
+ }
669
+ });
670
+ var spawnCommand = defineCommand({
671
+ meta: {
672
+ name: "spawn",
673
+ description: "Spawn a new ephemeral agent for a specific task"
674
+ },
675
+ args: {
676
+ role: {
677
+ type: "string",
678
+ description: "Agent role (e.g. code_dev, research, security)",
679
+ required: true
680
+ },
681
+ task: {
682
+ type: "string",
683
+ description: "Task to assign to the spawned agent"
684
+ },
685
+ model: {
686
+ type: "string",
687
+ description: "Model to use (e.g. opus, sonnet)"
688
+ },
689
+ name: {
690
+ type: "string",
691
+ description: "Display name for the agent"
692
+ }
693
+ },
694
+ async run({ args }) {
695
+ try {
696
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
697
+ await openCleoDb("project");
698
+ const registry = new AgentRegistryAccessor(getProjectRoot());
699
+ const role = args.role;
700
+ const taskId = args.task;
701
+ const model = args.model ?? "sonnet";
702
+ const displayName = args.name ?? `ephemeral-${role}-${Date.now().toString(36)}`;
703
+ const agentId = displayName;
704
+ await registry.register({
705
+ agentId,
706
+ displayName,
707
+ apiKey: "ephemeral-local-only",
708
+ apiBaseUrl: "local",
709
+ classification: role,
710
+ privacyTier: "private",
711
+ capabilities: ["chat", "tools"],
712
+ skills: [role],
713
+ transportType: "http",
714
+ transportConfig: {},
715
+ isActive: true
716
+ });
717
+ cliOutput(
718
+ {
719
+ success: true,
720
+ data: {
721
+ agentId,
722
+ displayName,
723
+ role,
724
+ model,
725
+ taskId: taskId ?? null,
726
+ transport: "local",
727
+ lifecycle: "ephemeral"
728
+ }
729
+ },
730
+ { command: "agent spawn" }
731
+ );
732
+ } catch (err) {
733
+ cliOutput(
734
+ { success: false, error: { code: "E_SPAWN", message: String(err) } },
735
+ { command: "agent spawn" }
736
+ );
737
+ process.exitCode = 1;
738
+ }
739
+ }
740
+ });
741
+ var reassignCommand = defineCommand({
742
+ meta: {
743
+ name: "reassign",
744
+ description: "Reassign a task to another agent via conduit message"
745
+ },
746
+ args: {
747
+ taskId: {
748
+ type: "positional",
749
+ description: "Task ID to reassign",
750
+ required: true
751
+ },
752
+ agentId: {
753
+ type: "positional",
754
+ description: "Target agent ID",
755
+ required: true
756
+ }
757
+ },
758
+ async run({ args }) {
759
+ try {
760
+ const { AgentRegistryAccessor, createConduit } = await import("@cleocode/core/agents");
761
+ await openCleoDb("project");
762
+ const registry = new AgentRegistryAccessor(getProjectRoot());
763
+ const active = await registry.getActive();
764
+ if (!active) {
765
+ cliOutput(
766
+ { success: false, error: { code: "E_NO_ACTIVE", message: "No active agent." } },
767
+ { command: "agent reassign" }
768
+ );
769
+ process.exitCode = 1;
770
+ return;
771
+ }
772
+ const conduit = await createConduit(registry);
773
+ await conduit.send(
774
+ args.agentId,
775
+ `/action @${args.agentId} #task-reassignment
776
+
777
+ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${args.taskId} && cleo start ${args.taskId}`
778
+ );
779
+ await conduit.disconnect();
780
+ cliOutput(
781
+ {
782
+ success: true,
783
+ data: { taskId: args.taskId, newOwner: args.agentId, reassignedBy: active.agentId }
784
+ },
785
+ { command: "agent reassign" }
786
+ );
787
+ } catch (err) {
788
+ cliOutput(
789
+ { success: false, error: { code: "E_REASSIGN", message: String(err) } },
790
+ { command: "agent reassign" }
791
+ );
792
+ process.exitCode = 1;
793
+ }
794
+ }
795
+ });
796
+ var stopAllCommand = defineCommand({
797
+ meta: {
798
+ name: "stop-all",
799
+ description: "Stop all active agents \u2014 mark all offline"
800
+ },
801
+ async run() {
802
+ try {
803
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
804
+ await openCleoDb("project");
805
+ const registry = new AgentRegistryAccessor(getProjectRoot());
806
+ const agents = await registry.list({ active: true });
807
+ const { conduitFetch } = await import("@cleocode/core/conduit/cloud-endpoint.js");
808
+ let stopped = 0;
809
+ for (const a of agents) {
810
+ await registry.update(a.agentId, { isActive: false });
811
+ try {
812
+ await conduitFetch(`${a.apiBaseUrl}/agents/${a.agentId}/status`, {
813
+ method: "PUT",
814
+ headers: {
815
+ "Content-Type": "application/json",
816
+ Authorization: `Bearer ${a.apiKey}`,
817
+ "X-Agent-Id": a.agentId
818
+ },
819
+ body: JSON.stringify({ status: "offline" }),
820
+ signal: AbortSignal.timeout(3e3)
821
+ });
822
+ } catch {
823
+ }
824
+ stopped++;
825
+ }
826
+ cliOutput(
827
+ { success: true, data: { stopped, total: agents.length } },
828
+ { command: "agent stop-all" }
829
+ );
830
+ } catch (err) {
831
+ cliOutput(
832
+ { success: false, error: { code: "E_STOP_ALL", message: String(err) } },
833
+ { command: "agent stop-all" }
834
+ );
835
+ process.exitCode = 1;
836
+ }
837
+ }
838
+ });
839
+ var workCommand = defineCommand({
840
+ meta: {
841
+ name: "work",
842
+ description: "Enter autonomous work loop \u2014 poll tasks, report, optionally execute. --execute enables the Conductor Loop."
843
+ },
844
+ args: {
845
+ agentId: {
846
+ type: "positional",
847
+ description: "Agent ID to run the work loop as",
848
+ required: true
849
+ },
850
+ "poll-interval": {
851
+ type: "string",
852
+ description: "Task check interval in milliseconds",
853
+ default: "30000"
854
+ },
855
+ execute: {
856
+ type: "boolean",
857
+ description: "Autonomously execute ready tasks via orchestrate.spawn.execute (Phase 3 Conductor Loop)"
858
+ },
859
+ adapter: {
860
+ type: "string",
861
+ description: "Adapter id to route spawns through (default: auto-detect from capabilities)"
862
+ },
863
+ epic: {
864
+ type: "string",
865
+ description: "Restrict autonomous execution to a specific epic (default: any ready task)"
866
+ }
867
+ },
868
+ async run({ args }) {
869
+ try {
870
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
871
+ const { createRuntime } = await import("@cleocode/runtime");
872
+ const { existsSync } = await import("node:fs");
873
+ const { join } = await import("node:path");
874
+ await openCleoDb("project");
875
+ const registry = new AgentRegistryAccessor(getProjectRoot());
876
+ const credential = await registry.get(args.agentId);
877
+ if (!credential) {
878
+ cliOutput(
879
+ {
880
+ success: false,
881
+ error: { code: "E_NOT_FOUND", message: `Agent '${args.agentId}' not registered.` }
882
+ },
883
+ { command: "agent work" }
884
+ );
885
+ process.exitCode = 1;
886
+ return;
887
+ }
888
+ await registry.update(args.agentId, { isActive: true });
889
+ await registry.markUsed(args.agentId);
890
+ const cantPath = join(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
891
+ const hasProfile = existsSync(cantPath);
892
+ const runtime = await createRuntime(registry, {
893
+ agentId: args.agentId,
894
+ pollIntervalMs: 5e3,
895
+ heartbeatIntervalMs: 3e4
896
+ });
897
+ runtime.poller.start();
898
+ const executeMode = args.execute === true;
899
+ const epicRestrict = args.epic;
900
+ const adapterRestrict = args.adapter;
901
+ cliOutput(
902
+ {
903
+ success: true,
904
+ data: {
905
+ agentId: args.agentId,
906
+ mode: executeMode ? "conductor-loop" : "watch-only",
907
+ profile: hasProfile ? "loaded" : "none",
908
+ status: "running",
909
+ epic: epicRestrict ?? "any",
910
+ adapter: adapterRestrict ?? "auto"
911
+ }
912
+ },
913
+ { command: "agent work" }
914
+ );
915
+ const taskInterval = Number.parseInt(args["poll-interval"], 10);
916
+ const loop = startWorkLoop(
917
+ {
918
+ agentId: args.agentId,
919
+ pollIntervalMs: taskInterval,
920
+ executeMode,
921
+ epicRestrict,
922
+ adapterRestrict
923
+ },
924
+ {
925
+ onInfo: (msg) => humanLine(msg),
926
+ onWarn: (msg) => humanWarn(msg)
927
+ }
928
+ );
929
+ const shutdown = () => {
930
+ loop.stop();
931
+ runtime.stop();
932
+ void registry.update(args.agentId, { isActive: false }).catch(() => {
933
+ });
934
+ process.exit(0);
935
+ };
936
+ process.on("SIGINT", shutdown);
937
+ process.on("SIGTERM", shutdown);
938
+ if (process.platform === "win32") {
939
+ process.on("message", (msg) => {
940
+ if (msg === "shutdown") shutdown();
941
+ });
942
+ }
943
+ await new Promise(() => {
944
+ });
945
+ } catch (err) {
946
+ cliOutput(
947
+ { success: false, error: { code: "E_WORK", message: String(err) } },
948
+ { command: "agent work" }
949
+ );
950
+ process.exitCode = 1;
951
+ }
952
+ }
953
+ });
954
+ var listCommand = defineCommand({
955
+ meta: {
956
+ name: "list",
957
+ description: "List registered agent credentials"
958
+ },
959
+ args: {
960
+ active: {
961
+ type: "boolean",
962
+ description: "Show only active agents (project-scoped mode only)"
963
+ },
964
+ global: {
965
+ type: "boolean",
966
+ description: "Show all global agents regardless of project attachment (ADR-037 \xA74 Q1=B)"
967
+ },
968
+ "include-disabled": {
969
+ type: "boolean",
970
+ description: "Include detached/disabled agents (enabled=0)"
971
+ }
972
+ },
973
+ async run({ args }) {
974
+ try {
975
+ const { listAgentsForProject } = await import("@cleocode/core/agents");
976
+ await openCleoDb("project");
977
+ const includeGlobal = args.global === true;
978
+ const includeDisabled = args["include-disabled"] === true;
979
+ const agents = await listAgentsForProject(getProjectRoot(), {
980
+ includeGlobal,
981
+ includeDisabled
982
+ });
983
+ const filtered = !includeGlobal && args.active ? agents.filter((a) => a.isActive) : agents;
984
+ cliOutput(
985
+ filtered.map((a) => ({
986
+ agentId: a.agentId,
987
+ name: a.displayName,
988
+ classification: a.classification ?? null,
989
+ transportType: a.transportType,
990
+ isActive: a.isActive,
991
+ lastUsedAt: a.lastUsedAt ?? null,
992
+ attachment: a.projectRef ? a.projectRef.enabled === 1 ? "[attached]" : "[disabled]" : "[global]"
993
+ })),
994
+ { command: "agent list" }
995
+ );
996
+ } catch (err) {
997
+ cliOutput(
998
+ { success: false, error: { code: "E_LIST", message: String(err) } },
999
+ { command: "agent list" }
1000
+ );
1001
+ process.exitCode = 1;
1002
+ }
1003
+ }
1004
+ });
1005
+ var getCommand = defineCommand({
1006
+ meta: {
1007
+ name: "get",
1008
+ description: "Get details for a specific agent credential"
1009
+ },
1010
+ args: {
1011
+ agentId: {
1012
+ type: "positional",
1013
+ description: "Agent ID to look up",
1014
+ required: true
1015
+ },
1016
+ global: {
1017
+ type: "boolean",
1018
+ description: "Perform global identity lookup \u2014 returns agent even if not attached to current project"
1019
+ }
1020
+ },
1021
+ async run({ args }) {
1022
+ try {
1023
+ const { lookupAgent } = await import("@cleocode/core/agents");
1024
+ await openCleoDb("project");
1025
+ const includeGlobal = args.global === true;
1026
+ const agent = await lookupAgent(getProjectRoot(), args.agentId, { includeGlobal });
1027
+ if (!agent) {
1028
+ cliOutput(
1029
+ {
1030
+ success: false,
1031
+ error: { code: "E_NOT_FOUND", message: `Agent not found: ${args.agentId}` }
1032
+ },
1033
+ { command: "agent get" }
1034
+ );
1035
+ process.exitCode = 4;
1036
+ return;
1037
+ }
1038
+ const redactedKey = agent.apiKey.length > 16 ? `${agent.apiKey.substring(0, 12)}...${agent.apiKey.substring(agent.apiKey.length - 4)}` : "***redacted***";
1039
+ cliOutput(
1040
+ {
1041
+ success: true,
1042
+ data: {
1043
+ agentId: agent.agentId,
1044
+ displayName: agent.displayName,
1045
+ apiKey: redactedKey,
1046
+ apiBaseUrl: agent.apiBaseUrl,
1047
+ classification: agent.classification ?? null,
1048
+ transportType: agent.transportType,
1049
+ isActive: agent.isActive,
1050
+ lastUsedAt: agent.lastUsedAt ?? null,
1051
+ createdAt: agent.createdAt,
1052
+ updatedAt: agent.updatedAt,
1053
+ projectRef: agent.projectRef ?? "not attached to current project"
1054
+ }
1055
+ },
1056
+ { command: "agent get" }
1057
+ );
1058
+ } catch (err) {
1059
+ cliOutput(
1060
+ { success: false, error: { code: "E_GET", message: String(err) } },
1061
+ { command: "agent get" }
1062
+ );
1063
+ process.exitCode = 1;
1064
+ }
1065
+ }
1066
+ });
1067
+ var attachCommand = defineCommand({
1068
+ meta: {
1069
+ name: "attach",
1070
+ description: "Attach a global agent to the current project"
1071
+ },
1072
+ args: {
1073
+ agentId: {
1074
+ type: "positional",
1075
+ description: "Agent ID to attach",
1076
+ required: true
1077
+ },
1078
+ role: {
1079
+ type: "string",
1080
+ description: "Per-project role override"
1081
+ },
1082
+ "capabilities-override": {
1083
+ type: "string",
1084
+ description: "JSON blob of capability overrides"
1085
+ }
1086
+ },
1087
+ async run({ args }) {
1088
+ try {
1089
+ const { AgentRegistryAccessor, attachAgentToProject, lookupAgent } = await import("@cleocode/core/agents");
1090
+ await openCleoDb("project");
1091
+ const projectRoot = getProjectRoot();
1092
+ const _registry = new AgentRegistryAccessor(projectRoot);
1093
+ void _registry;
1094
+ const globalAgent = await lookupAgent(projectRoot, args.agentId, { includeGlobal: true });
1095
+ if (!globalAgent) {
1096
+ cliOutput(
1097
+ {
1098
+ success: false,
1099
+ error: { code: "E_NOT_FOUND", message: `Agent not found: ${args.agentId}` }
1100
+ },
1101
+ { command: "agent attach" }
1102
+ );
1103
+ process.exitCode = 4;
1104
+ return;
1105
+ }
1106
+ attachAgentToProject(projectRoot, args.agentId, {
1107
+ role: typeof args.role === "string" ? args.role : null,
1108
+ capabilitiesOverride: typeof args["capabilities-override"] === "string" ? args["capabilities-override"] : null
1109
+ });
1110
+ cliOutput(
1111
+ {
1112
+ success: true,
1113
+ data: {
1114
+ attached: args.agentId,
1115
+ projectRoot,
1116
+ role: typeof args.role === "string" ? args.role : null
1117
+ }
1118
+ },
1119
+ { command: "agent attach" }
1120
+ );
1121
+ } catch (err) {
1122
+ cliOutput(
1123
+ { success: false, error: { code: "E_ATTACH", message: String(err) } },
1124
+ { command: "agent attach" }
1125
+ );
1126
+ process.exitCode = 1;
1127
+ }
1128
+ }
1129
+ });
1130
+ var detachCommand = defineCommand({
1131
+ meta: {
1132
+ name: "detach",
1133
+ description: "Detach an agent from the current project (preserves global identity)"
1134
+ },
1135
+ args: {
1136
+ agentId: {
1137
+ type: "positional",
1138
+ description: "Agent ID to detach",
1139
+ required: true
1140
+ }
1141
+ },
1142
+ async run({ args }) {
1143
+ try {
1144
+ const { AgentRegistryAccessor, detachAgentFromProject, getProjectAgentRef } = await import("@cleocode/core/agents");
1145
+ await openCleoDb("project");
1146
+ const projectRoot = getProjectRoot();
1147
+ const _registry = new AgentRegistryAccessor(projectRoot);
1148
+ void _registry;
1149
+ const ref = getProjectAgentRef(projectRoot, args.agentId);
1150
+ if (!ref) {
1151
+ cliOutput(
1152
+ {
1153
+ success: false,
1154
+ error: {
1155
+ code: "E_NOT_FOUND",
1156
+ message: `Agent ${args.agentId} not attached to current project`
1157
+ }
1158
+ },
1159
+ { command: "agent detach" }
1160
+ );
1161
+ process.exitCode = 4;
1162
+ return;
1163
+ }
1164
+ detachAgentFromProject(projectRoot, args.agentId);
1165
+ cliOutput(
1166
+ { success: true, data: { detached: args.agentId, projectRoot } },
1167
+ { command: "agent detach" }
1168
+ );
1169
+ } catch (err) {
1170
+ cliOutput(
1171
+ { success: false, error: { code: "E_DETACH", message: String(err) } },
1172
+ { command: "agent detach" }
1173
+ );
1174
+ process.exitCode = 1;
1175
+ }
1176
+ }
1177
+ });
1178
+ var removeCommand = defineCommand({
1179
+ meta: {
1180
+ name: "remove",
1181
+ description: "Detach agent from current project (default) or remove global identity with --global"
1182
+ },
1183
+ args: {
1184
+ agentId: {
1185
+ type: "positional",
1186
+ description: "Agent ID to remove",
1187
+ required: true
1188
+ },
1189
+ global: {
1190
+ type: "boolean",
1191
+ description: "Remove from global signaldock.db (destructive, irreversible)"
1192
+ },
1193
+ "force-global": {
1194
+ type: "boolean",
1195
+ description: "Force global removal even when the current project still has an active reference"
1196
+ }
1197
+ },
1198
+ async run({ args }) {
1199
+ try {
1200
+ const { AgentRegistryAccessor, detachAgentFromProject, getProjectAgentRef } = await import("@cleocode/core/agents");
1201
+ await openCleoDb("project");
1202
+ const projectRoot = getProjectRoot();
1203
+ if (!args.global) {
1204
+ const _registry = new AgentRegistryAccessor(projectRoot);
1205
+ void _registry;
1206
+ const ref = getProjectAgentRef(projectRoot, args.agentId);
1207
+ if (!ref) {
1208
+ cliOutput(
1209
+ {
1210
+ success: false,
1211
+ error: {
1212
+ code: "E_NOT_FOUND",
1213
+ message: `Agent ${args.agentId} not attached to current project`
1214
+ }
1215
+ },
1216
+ { command: "agent remove" }
1217
+ );
1218
+ process.exitCode = 4;
1219
+ return;
1220
+ }
1221
+ detachAgentFromProject(projectRoot, args.agentId);
1222
+ cliOutput(
1223
+ { success: true, data: { removed: args.agentId, scope: "project", projectRoot } },
1224
+ { command: "agent remove" }
1225
+ );
1226
+ return;
1227
+ }
1228
+ const _registry2 = new AgentRegistryAccessor(projectRoot);
1229
+ void _registry2;
1230
+ const activeRef = getProjectAgentRef(projectRoot, args.agentId);
1231
+ if (activeRef && !args["force-global"]) {
1232
+ humanWarn(
1233
+ `NOTE: Safety scan is limited to the current project. Other projects may have dangling references after global removal.`
1234
+ );
1235
+ cliOutput(
1236
+ {
1237
+ success: false,
1238
+ error: {
1239
+ code: "E_VALIDATION",
1240
+ message: `Agent "${args.agentId}" is still attached to current project. Detach first or pass --force-global to proceed anyway.`,
1241
+ fix: `cleo agent detach ${args.agentId} # detach first, then retry OR cleo agent remove ${args.agentId} --global --force-global`
1242
+ }
1243
+ },
1244
+ { command: "agent remove" }
1245
+ );
1246
+ process.exitCode = 6;
1247
+ return;
1248
+ }
1249
+ humanWarn(
1250
+ `NOTE: Safety scan is limited to the current project. Other projects may have dangling references after global removal.`
1251
+ );
1252
+ const registry = new AgentRegistryAccessor(projectRoot);
1253
+ await registry.removeGlobal(args.agentId, { force: args["force-global"] === true });
1254
+ cliOutput(
1255
+ { success: true, data: { removed: args.agentId, scope: "global" } },
1256
+ { command: "agent remove" }
1257
+ );
1258
+ } catch (err) {
1259
+ cliOutput(
1260
+ { success: false, error: { code: "E_REMOVE", message: String(err) } },
1261
+ { command: "agent remove" }
1262
+ );
1263
+ process.exitCode = 1;
1264
+ }
1265
+ }
1266
+ });
1267
+ var rotateKeyCommand = defineCommand({
1268
+ meta: {
1269
+ name: "rotate-key",
1270
+ description: "Rotate an agent API key (generates new key on cloud, re-encrypts locally)"
1271
+ },
1272
+ args: {
1273
+ agentId: {
1274
+ type: "positional",
1275
+ description: "Agent ID whose key should be rotated",
1276
+ required: true
1277
+ }
1278
+ },
1279
+ async run({ args }) {
1280
+ try {
1281
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
1282
+ await openCleoDb("project");
1283
+ const registry = new AgentRegistryAccessor(getProjectRoot());
1284
+ const result = await registry.rotateKey(args.agentId);
1285
+ cliOutput(
1286
+ {
1287
+ success: true,
1288
+ data: {
1289
+ agentId: result.agentId,
1290
+ newApiKey: `${result.newApiKey.substring(0, 12)}...`,
1291
+ message: "API key rotated. Old key is invalidated."
1292
+ }
1293
+ },
1294
+ { command: "agent rotate-key" }
1295
+ );
1296
+ } catch (err) {
1297
+ const { isSignalDockRetiredError } = await import("@cleocode/core/conduit/cloud-endpoint.js");
1298
+ cliOutput(
1299
+ {
1300
+ success: false,
1301
+ error: {
1302
+ code: isSignalDockRetiredError(err) ? err.code : "E_ROTATE",
1303
+ message: String(err)
1304
+ }
1305
+ },
1306
+ { command: "agent rotate-key" }
1307
+ );
1308
+ process.exitCode = 1;
1309
+ }
1310
+ }
1311
+ });
1312
+ var claimCodeCommand = defineCommand({
1313
+ meta: {
1314
+ name: "claim-code",
1315
+ description: "Generate a claim code for human ownership of an agent"
1316
+ },
1317
+ args: {
1318
+ agentId: {
1319
+ type: "positional",
1320
+ description: "Agent ID to generate a claim code for",
1321
+ required: true
1322
+ }
1323
+ },
1324
+ async run({ args }) {
1325
+ try {
1326
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
1327
+ await openCleoDb("project");
1328
+ const registry = new AgentRegistryAccessor(getProjectRoot());
1329
+ const credential = await registry.get(args.agentId);
1330
+ if (!credential) {
1331
+ cliOutput(
1332
+ {
1333
+ success: false,
1334
+ error: { code: "E_NOT_FOUND", message: `Agent not found: ${args.agentId}` }
1335
+ },
1336
+ { command: "agent claim-code" }
1337
+ );
1338
+ process.exitCode = 4;
1339
+ return;
1340
+ }
1341
+ const { conduitFetch } = await import("@cleocode/core/conduit/cloud-endpoint.js");
1342
+ const response = await conduitFetch(
1343
+ `${credential.apiBaseUrl}/agents/${args.agentId}/claim-code`,
1344
+ {
1345
+ method: "POST",
1346
+ headers: {
1347
+ "Content-Type": "application/json",
1348
+ Authorization: `Bearer ${credential.apiKey}`,
1349
+ "X-Agent-Id": args.agentId
1350
+ }
1351
+ }
1352
+ );
1353
+ if (!response.ok) {
1354
+ const text = await response.text().catch(() => "");
1355
+ throw new Error(`Failed to generate claim code: ${response.status} ${text}`);
1356
+ }
1357
+ const data = await response.json();
1358
+ cliOutput(
1359
+ {
1360
+ success: true,
1361
+ data: {
1362
+ agentId: args.agentId,
1363
+ claimCode: data.data?.claimCode,
1364
+ claimUrl: data.data?.claimUrl ?? null,
1365
+ expiresAt: data.data?.expiresAt,
1366
+ message: "Share this claim code with the human owner to verify agent ownership."
1367
+ }
1368
+ },
1369
+ { command: "agent claim-code" }
1370
+ );
1371
+ } catch (err) {
1372
+ const { isSignalDockRetiredError } = await import("@cleocode/core/conduit/cloud-endpoint.js");
1373
+ cliOutput(
1374
+ {
1375
+ success: false,
1376
+ error: {
1377
+ code: isSignalDockRetiredError(err) ? err.code : "E_CLAIM",
1378
+ message: String(err)
1379
+ }
1380
+ },
1381
+ { command: "agent claim-code" }
1382
+ );
1383
+ process.exitCode = 1;
1384
+ }
1385
+ }
1386
+ });
1387
+ var watchCommand = defineCommand({
1388
+ meta: {
1389
+ name: "watch",
1390
+ description: "Start continuous message polling for the active agent (long-running)"
1391
+ },
1392
+ args: {
1393
+ agent: {
1394
+ type: "string",
1395
+ description: "Agent ID to watch as (defaults to most recently used)",
1396
+ alias: "a"
1397
+ },
1398
+ interval: {
1399
+ type: "string",
1400
+ description: "Poll interval in milliseconds",
1401
+ default: "5000"
1402
+ },
1403
+ group: {
1404
+ type: "string",
1405
+ description: "Comma-separated group conversation IDs to monitor"
1406
+ }
1407
+ },
1408
+ async run({ args }) {
1409
+ try {
1410
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
1411
+ const { createRuntime } = await import("@cleocode/runtime");
1412
+ await openCleoDb("project");
1413
+ const registry = new AgentRegistryAccessor(getProjectRoot());
1414
+ const groupIds = args.group ? args.group.split(",").map((s) => s.trim()) : void 0;
1415
+ const handle = await createRuntime(registry, {
1416
+ agentId: args.agent,
1417
+ pollIntervalMs: Number(args.interval) || 5e3,
1418
+ groupConversationIds: groupIds
1419
+ });
1420
+ handle.poller.onMessage((msg) => {
1421
+ cliOutput(
1422
+ {
1423
+ success: true,
1424
+ data: {
1425
+ event: "message",
1426
+ id: msg.id,
1427
+ from: msg.from,
1428
+ content: msg.content,
1429
+ threadId: msg.threadId,
1430
+ timestamp: msg.timestamp
1431
+ }
1432
+ },
1433
+ { command: "agent watch" }
1434
+ );
1435
+ });
1436
+ handle.poller.start();
1437
+ cliOutput(
1438
+ {
1439
+ success: true,
1440
+ data: {
1441
+ event: "started",
1442
+ agentId: handle.agentId,
1443
+ pollIntervalMs: Number(args.interval) || 5e3,
1444
+ groupConversationIds: groupIds ?? [],
1445
+ message: "Watching for messages. Press Ctrl+C to stop."
1446
+ }
1447
+ },
1448
+ { command: "agent watch" }
1449
+ );
1450
+ const shutdown = () => {
1451
+ handle.stop();
1452
+ cliOutput(
1453
+ { success: true, data: { event: "stopped", agentId: handle.agentId } },
1454
+ { command: "agent watch" }
1455
+ );
1456
+ process.exit(0);
1457
+ };
1458
+ process.on("SIGINT", shutdown);
1459
+ process.on("SIGTERM", shutdown);
1460
+ if (process.platform === "win32") {
1461
+ process.on("message", (msg) => {
1462
+ if (msg === "shutdown") shutdown();
1463
+ });
1464
+ }
1465
+ } catch (err) {
1466
+ cliOutput(
1467
+ { success: false, error: { code: "E_WATCH", message: String(err) } },
1468
+ { command: "agent watch" }
1469
+ );
1470
+ process.exitCode = 1;
1471
+ }
1472
+ }
1473
+ });
1474
+ var pollCommand = defineCommand({
1475
+ meta: {
1476
+ name: "poll",
1477
+ description: "One-shot message check for the active agent"
1478
+ },
1479
+ args: {
1480
+ agent: {
1481
+ type: "string",
1482
+ description: "Agent ID to poll as (defaults to most recently used)",
1483
+ alias: "a"
1484
+ },
1485
+ limit: {
1486
+ type: "string",
1487
+ description: "Max messages to fetch",
1488
+ default: "20"
1489
+ }
1490
+ },
1491
+ async run({ args }) {
1492
+ try {
1493
+ const { AgentRegistryAccessor, createConduit } = await import("@cleocode/core/agents");
1494
+ await openCleoDb("project");
1495
+ const registry = new AgentRegistryAccessor(getProjectRoot());
1496
+ const agentId = args.agent;
1497
+ const conduit = await createConduit(registry, agentId);
1498
+ const limit = Number(args.limit) || 20;
1499
+ const messages = await conduit.poll({ limit });
1500
+ cliOutput(
1501
+ {
1502
+ success: true,
1503
+ data: { agentId: conduit.agentId, messages, count: messages.length, limit }
1504
+ },
1505
+ { command: "agent poll" }
1506
+ );
1507
+ await conduit.disconnect();
1508
+ } catch (err) {
1509
+ cliOutput(
1510
+ { success: false, error: { code: "E_POLL", message: String(err) } },
1511
+ { command: "agent poll" }
1512
+ );
1513
+ process.exitCode = 1;
1514
+ }
1515
+ }
1516
+ });
1517
+ var sendCommand = defineCommand({
1518
+ meta: {
1519
+ name: "send",
1520
+ description: "Send a message to an agent or conversation"
1521
+ },
1522
+ args: {
1523
+ message: {
1524
+ type: "positional",
1525
+ description: "Message content to send",
1526
+ required: true
1527
+ },
1528
+ to: {
1529
+ type: "string",
1530
+ description: "Target agent ID"
1531
+ },
1532
+ conv: {
1533
+ type: "string",
1534
+ description: "Target conversation ID"
1535
+ },
1536
+ agent: {
1537
+ type: "string",
1538
+ description: "Send as this agent (defaults to most recently used)",
1539
+ alias: "a"
1540
+ }
1541
+ },
1542
+ async run({ args }) {
1543
+ try {
1544
+ const { AgentRegistryAccessor, createConduit } = await import("@cleocode/core/agents");
1545
+ await openCleoDb("project");
1546
+ const registry = new AgentRegistryAccessor(getProjectRoot());
1547
+ const agentId = args.agent;
1548
+ const to = args.to;
1549
+ const conv = args.conv;
1550
+ if (!to && !conv) {
1551
+ cliOutput(
1552
+ { success: false, error: { code: "E_ARGS", message: "Must specify --to or --conv" } },
1553
+ { command: "agent send" }
1554
+ );
1555
+ process.exitCode = 1;
1556
+ return;
1557
+ }
1558
+ const conduit = await createConduit(registry, agentId);
1559
+ const result = await conduit.send(to ?? conv ?? "", args.message, {
1560
+ threadId: conv
1561
+ });
1562
+ cliOutput(
1563
+ {
1564
+ success: true,
1565
+ // gh#1316: `acceptedAt` is what a send knows; `deliveredAt` is null
1566
+ // until delivery is confirmed. Reporting only the latter would hand
1567
+ // the caller a null where a real timestamp used to be, and drop the
1568
+ // fact that is actually true.
1569
+ data: {
1570
+ messageId: result.messageId,
1571
+ acceptedAt: result.acceptedAt,
1572
+ deliveredAt: result.deliveredAt
1573
+ }
1574
+ },
1575
+ { command: "agent send" }
1576
+ );
1577
+ await conduit.disconnect();
1578
+ } catch (err) {
1579
+ cliOutput(
1580
+ { success: false, error: { code: "E_SEND", message: String(err) } },
1581
+ { command: "agent send" }
1582
+ );
1583
+ process.exitCode = 1;
1584
+ }
1585
+ }
1586
+ });
1587
+ var healthCommand = defineCommand({
1588
+ meta: {
1589
+ name: "health",
1590
+ description: "Check agent health and detect stale or crashed agents"
1591
+ },
1592
+ args: {
1593
+ id: {
1594
+ type: "string",
1595
+ description: "Check health for a specific agent ID"
1596
+ },
1597
+ threshold: {
1598
+ type: "string",
1599
+ description: "Staleness threshold in milliseconds (default: 180000 = 3 minutes)",
1600
+ default: String(STALE_THRESHOLD_MS)
1601
+ },
1602
+ "detect-crashed": {
1603
+ type: "boolean",
1604
+ description: "Detect and mark crashed agents (write operation)"
1605
+ }
1606
+ },
1607
+ async run({ args }) {
1608
+ const thresholdMs = Number(args.threshold);
1609
+ const agentId = args.id;
1610
+ const detectCrashed = args["detect-crashed"] === true;
1611
+ if (agentId) {
1612
+ const health = await checkAgentHealth(agentId, thresholdMs);
1613
+ if (!health) {
1614
+ cliOutput(
1615
+ {
1616
+ success: false,
1617
+ error: { code: "E_NOT_FOUND", message: `Agent not found: ${agentId}` }
1618
+ },
1619
+ { command: "agent health" }
1620
+ );
1621
+ process.exitCode = 4;
1622
+ return;
1623
+ }
1624
+ cliOutput({ success: true, data: health }, { command: "agent health" });
1625
+ return;
1626
+ }
1627
+ if (detectCrashed) {
1628
+ const crashed = await detectCrashedAgents(thresholdMs);
1629
+ cliOutput(
1630
+ {
1631
+ success: true,
1632
+ data: {
1633
+ detectedCrashed: crashed.length,
1634
+ agents: crashed.map((a) => ({
1635
+ id: a.id,
1636
+ agentType: a.agentType,
1637
+ lastHeartbeat: a.lastHeartbeat,
1638
+ status: a.status
1639
+ }))
1640
+ }
1641
+ },
1642
+ { command: "agent health" }
1643
+ );
1644
+ return;
1645
+ }
1646
+ const [report, stale] = await Promise.all([
1647
+ getHealthReport(thresholdMs),
1648
+ detectStaleAgents(thresholdMs)
1649
+ ]);
1650
+ cliOutput(
1651
+ {
1652
+ success: true,
1653
+ data: {
1654
+ summary: {
1655
+ total: report.total,
1656
+ active: report.active,
1657
+ idle: report.idle,
1658
+ starting: report.starting,
1659
+ error: report.error,
1660
+ crashed: report.crashed,
1661
+ stopped: report.stopped,
1662
+ totalErrors: report.totalErrors
1663
+ },
1664
+ staleAgents: stale.map((s) => ({
1665
+ id: s.agentId,
1666
+ status: s.status,
1667
+ heartbeatAgeMs: s.heartbeatAgeMs,
1668
+ lastHeartbeat: s.lastHeartbeat,
1669
+ thresholdMs: s.thresholdMs
1670
+ })),
1671
+ thresholdMs
1672
+ }
1673
+ },
1674
+ { command: "agent health" }
1675
+ );
1676
+ }
1677
+ });
1678
+ var installCommand = defineCommand({
1679
+ meta: {
1680
+ name: "install",
1681
+ description: "Install an agent from a .cant file or .cantz archive"
1682
+ },
1683
+ args: {
1684
+ path: {
1685
+ type: "positional",
1686
+ description: "Path to the .cant file, .cantz archive, or agent directory",
1687
+ required: true
1688
+ },
1689
+ global: {
1690
+ type: "boolean",
1691
+ description: "Install to global tier (~/.local/share/cleo/cant/agents/)"
1692
+ },
1693
+ strict: {
1694
+ type: "boolean",
1695
+ description: "Fail on warnings (e.g. unknown skill slugs)"
1696
+ },
1697
+ attach: {
1698
+ type: "boolean",
1699
+ description: "Attach to the current project after install"
1700
+ },
1701
+ force: {
1702
+ type: "boolean",
1703
+ description: "Overwrite existing agent row / file"
1704
+ },
1705
+ resync: {
1706
+ type: "boolean",
1707
+ description: "Drop + reinstall the agents row, keeping the on-disk .cant"
1708
+ }
1709
+ },
1710
+ async run({ args }) {
1711
+ let tempDir = null;
1712
+ try {
1713
+ const { existsSync } = await import("node:fs");
1714
+ const { basename, resolve } = await import("node:path");
1715
+ const resolvedPath = resolve(args.path);
1716
+ if (!existsSync(resolvedPath)) {
1717
+ cliOutput(
1718
+ {
1719
+ success: false,
1720
+ error: {
1721
+ code: "E_NOT_FOUND",
1722
+ message: `Path does not exist: ${resolvedPath}`
1723
+ }
1724
+ },
1725
+ { command: "agent install" }
1726
+ );
1727
+ process.exitCode = 4;
1728
+ return;
1729
+ }
1730
+ let resolved;
1731
+ try {
1732
+ resolved = resolveAgentCantPath({ resolvedPath });
1733
+ } catch (resolveErr) {
1734
+ const message = resolveErr instanceof Error ? resolveErr.message : String(resolveErr);
1735
+ cliOutput(
1736
+ { success: false, error: { code: "E_VALIDATION", message } },
1737
+ { command: "agent install" }
1738
+ );
1739
+ process.exitCode = 6;
1740
+ return;
1741
+ }
1742
+ const { cantPath, tempDir: resolvedTempDir } = resolved;
1743
+ tempDir = resolvedTempDir;
1744
+ const { installAgentFromCant, attachAgentToProject } = await import("@cleocode/core/agents");
1745
+ const { ensureGlobalAgentRegistryDb, getGlobalAgentRegistryNativeDb } = await import("@cleocode/core/internal");
1746
+ await ensureGlobalAgentRegistryDb();
1747
+ const db = getGlobalAgentRegistryNativeDb();
1748
+ const isGlobal = args.global === true;
1749
+ const targetTier = isGlobal ? "global" : "project";
1750
+ const projectRoot = getProjectRoot();
1751
+ try {
1752
+ if (args.resync) {
1753
+ const parsedName = basename(cantPath, ".cant");
1754
+ const row = db.prepare("SELECT id FROM agents WHERE agent_id = ?").get(parsedName);
1755
+ if (row) {
1756
+ db.exec("BEGIN IMMEDIATE TRANSACTION");
1757
+ try {
1758
+ db.prepare("DELETE FROM agent_skills WHERE agent_id = ?").run(row.id);
1759
+ db.prepare("DELETE FROM agents WHERE id = ?").run(row.id);
1760
+ db.exec("COMMIT");
1761
+ } catch (resyncErr) {
1762
+ db.exec("ROLLBACK");
1763
+ throw resyncErr;
1764
+ }
1765
+ }
1766
+ }
1767
+ const result = installAgentFromCant(db, {
1768
+ cantSource: cantPath,
1769
+ targetTier,
1770
+ installedFrom: "user",
1771
+ projectRoot: targetTier === "project" ? projectRoot : void 0,
1772
+ force: args.force === true || args.resync === true
1773
+ });
1774
+ if (args.strict && result.warnings.length > 0) {
1775
+ cliOutput(
1776
+ {
1777
+ success: false,
1778
+ error: {
1779
+ code: "E_VALIDATION",
1780
+ message: `Install produced warnings in --strict mode: ${result.warnings.join("; ")}`
1781
+ },
1782
+ data: {
1783
+ agentId: result.agentId,
1784
+ tier: result.tier,
1785
+ warnings: result.warnings
1786
+ }
1787
+ },
1788
+ { command: "agent install" }
1789
+ );
1790
+ process.exitCode = 6;
1791
+ return;
1792
+ }
1793
+ let attached = false;
1794
+ if (args.attach && targetTier === "global") {
1795
+ attachAgentToProject(projectRoot, result.agentId);
1796
+ attached = true;
1797
+ }
1798
+ cliOutput(
1799
+ {
1800
+ success: true,
1801
+ data: {
1802
+ agentId: result.agentId,
1803
+ tier: result.tier,
1804
+ cantPath: result.cantPath,
1805
+ cantSha256: result.cantSha256,
1806
+ inserted: result.inserted,
1807
+ skillsAttached: result.skillsAttached,
1808
+ warnings: result.warnings,
1809
+ attached
1810
+ }
1811
+ },
1812
+ { command: "agent install" }
1813
+ );
1814
+ } finally {
1815
+ db.close();
1816
+ }
1817
+ } catch (err) {
1818
+ const message = err instanceof Error ? err.message : String(err);
1819
+ const code = /E_AGENT_ALREADY_INSTALLED/.test(message) ? "E_AGENT_ALREADY_INSTALLED" : "E_INSTALL";
1820
+ cliOutput({ success: false, error: { code, message } }, { command: "agent install" });
1821
+ process.exitCode = 1;
1822
+ } finally {
1823
+ cleanupInstallTempDir(tempDir);
1824
+ }
1825
+ }
1826
+ });
1827
+ var packCommand = defineCommand({
1828
+ meta: {
1829
+ name: "pack",
1830
+ description: "Package an agent directory as a .cantz archive"
1831
+ },
1832
+ args: {
1833
+ dir: {
1834
+ type: "positional",
1835
+ description: "Agent directory to package",
1836
+ required: true
1837
+ }
1838
+ },
1839
+ async run({ args }) {
1840
+ try {
1841
+ const { existsSync, statSync } = await import("node:fs");
1842
+ const { resolve, basename, dirname } = await import("node:path");
1843
+ const { execFileSync } = await import("node:child_process");
1844
+ const resolvedDir = resolve(args.dir);
1845
+ if (!existsSync(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
1846
+ cliOutput(
1847
+ {
1848
+ success: false,
1849
+ error: {
1850
+ code: "E_NOT_FOUND",
1851
+ message: `Directory does not exist: ${resolvedDir}`
1852
+ }
1853
+ },
1854
+ { command: "agent pack" }
1855
+ );
1856
+ process.exitCode = 4;
1857
+ return;
1858
+ }
1859
+ const { join } = await import("node:path");
1860
+ const personaPath = join(resolvedDir, "persona.cant");
1861
+ if (!existsSync(personaPath)) {
1862
+ cliOutput(
1863
+ {
1864
+ success: false,
1865
+ error: {
1866
+ code: "E_VALIDATION",
1867
+ message: `Agent directory must contain persona.cant: ${personaPath}`
1868
+ }
1869
+ },
1870
+ { command: "agent pack" }
1871
+ );
1872
+ process.exitCode = 6;
1873
+ return;
1874
+ }
1875
+ const agentName = basename(resolvedDir);
1876
+ const archiveName = `${agentName}.cantz`;
1877
+ const archivePath = resolve(archiveName);
1878
+ const parentDir = dirname(resolvedDir);
1879
+ try {
1880
+ execFileSync("zip", ["-r", archivePath, agentName], {
1881
+ cwd: parentDir,
1882
+ encoding: "utf-8",
1883
+ timeout: 3e4
1884
+ });
1885
+ } catch (zipErr) {
1886
+ cliOutput(
1887
+ {
1888
+ success: false,
1889
+ error: {
1890
+ code: "E_PACK",
1891
+ message: `Failed to create archive: ${String(zipErr)}`
1892
+ }
1893
+ },
1894
+ { command: "agent pack" }
1895
+ );
1896
+ process.exitCode = 1;
1897
+ return;
1898
+ }
1899
+ const archiveStats = statSync(archivePath);
1900
+ const { readdirSync } = await import("node:fs");
1901
+ let fileCount = 0;
1902
+ const countFiles = (dirPath) => {
1903
+ const entries = readdirSync(dirPath, { withFileTypes: true });
1904
+ for (const entry of entries) {
1905
+ if (entry.isFile()) {
1906
+ fileCount++;
1907
+ } else if (entry.isDirectory()) {
1908
+ countFiles(join(dirPath, entry.name));
1909
+ }
1910
+ }
1911
+ };
1912
+ countFiles(resolvedDir);
1913
+ cliOutput(
1914
+ {
1915
+ success: true,
1916
+ data: {
1917
+ archive: archivePath,
1918
+ agent: agentName,
1919
+ files: fileCount,
1920
+ size: archiveStats.size
1921
+ }
1922
+ },
1923
+ { command: "agent pack" }
1924
+ );
1925
+ } catch (err) {
1926
+ cliOutput(
1927
+ { success: false, error: { code: "E_PACK", message: String(err) } },
1928
+ { command: "agent pack" }
1929
+ );
1930
+ process.exitCode = 1;
1931
+ }
1932
+ }
1933
+ });
1934
+ var createCommand = defineCommand({
1935
+ meta: {
1936
+ name: "create",
1937
+ description: "Scaffold a new agent package with persona.cant and manifest.json"
1938
+ },
1939
+ args: {
1940
+ name: {
1941
+ type: "string",
1942
+ description: "Agent name (kebab-case)",
1943
+ required: true
1944
+ },
1945
+ role: {
1946
+ type: "string",
1947
+ description: "Agent role: orchestrator, lead, worker, or docs-worker",
1948
+ required: true
1949
+ },
1950
+ tier: {
1951
+ type: "string",
1952
+ description: "Agent tier: low, mid, or high (defaults based on role)"
1953
+ },
1954
+ team: {
1955
+ type: "string",
1956
+ description: "Team this agent belongs to"
1957
+ },
1958
+ domain: {
1959
+ type: "string",
1960
+ description: "Domain description for file permissions and context"
1961
+ },
1962
+ global: {
1963
+ type: "boolean",
1964
+ description: "Create in global tier (~/.local/share/cleo/cant/agents/)"
1965
+ },
1966
+ "seed-brain": {
1967
+ type: "boolean",
1968
+ description: "Create expertise/mental-model-seed.md and seed a BRAIN observation"
1969
+ },
1970
+ parent: {
1971
+ type: "string",
1972
+ description: "Parent agent name in the hierarchy"
1973
+ }
1974
+ },
1975
+ async run({ args }) {
1976
+ try {
1977
+ const name = args.name;
1978
+ const role = args.role;
1979
+ const tier = args.tier ?? inferTierFromRole(role);
1980
+ const team = args.team;
1981
+ const domain = args.domain;
1982
+ const isGlobal = args.global === true;
1983
+ const seedBrain = args["seed-brain"] === true;
1984
+ const parent = args.parent;
1985
+ try {
1986
+ validateRole(role);
1987
+ } catch (e) {
1988
+ cliOutput(
1989
+ {
1990
+ success: false,
1991
+ error: {
1992
+ code: "E_VALIDATION",
1993
+ message: String(e instanceof Error ? e.message : e),
1994
+ fix: `cleo agent create --name ${name} --role worker`
1995
+ }
1996
+ },
1997
+ { command: "agent create" }
1998
+ );
1999
+ process.exitCode = 6;
2000
+ return;
2001
+ }
2002
+ try {
2003
+ validateTier(tier);
2004
+ } catch (e) {
2005
+ cliOutput(
2006
+ {
2007
+ success: false,
2008
+ error: {
2009
+ code: "E_VALIDATION",
2010
+ message: String(e instanceof Error ? e.message : e),
2011
+ fix: `cleo agent create --name ${name} --role ${role} --tier mid`
2012
+ }
2013
+ },
2014
+ { command: "agent create" }
2015
+ );
2016
+ process.exitCode = 6;
2017
+ return;
2018
+ }
2019
+ try {
2020
+ validateName(name);
2021
+ } catch (e) {
2022
+ cliOutput(
2023
+ {
2024
+ success: false,
2025
+ error: {
2026
+ code: "E_VALIDATION",
2027
+ message: String(e instanceof Error ? e.message : e),
2028
+ fix: "Use lowercase letters, numbers, and hyphens. Must start with a letter."
2029
+ }
2030
+ },
2031
+ { command: "agent create" }
2032
+ );
2033
+ process.exitCode = 6;
2034
+ return;
2035
+ }
2036
+ let scaffoldResult;
2037
+ try {
2038
+ scaffoldResult = scaffoldAgent({
2039
+ name,
2040
+ role,
2041
+ tier,
2042
+ team,
2043
+ domain,
2044
+ parent,
2045
+ global: isGlobal,
2046
+ seedBrain,
2047
+ projectRoot: isGlobal ? void 0 : getProjectRoot(),
2048
+ cleoDirName: CLEO_DIR_NAME,
2049
+ cantAgentsSubdir: CANT_AGENTS_SUBDIR
2050
+ });
2051
+ } catch (e) {
2052
+ cliOutput(
2053
+ {
2054
+ success: false,
2055
+ error: {
2056
+ code: "E_VALIDATION",
2057
+ message: String(e instanceof Error ? e.message : e),
2058
+ fix: "Remove the existing directory or choose a different name."
2059
+ }
2060
+ },
2061
+ { command: "agent create" }
2062
+ );
2063
+ process.exitCode = 6;
2064
+ return;
2065
+ }
2066
+ if (seedBrain) {
2067
+ try {
2068
+ const { execFile } = await import("node:child_process");
2069
+ const { promisify } = await import("node:util");
2070
+ const execFileAsync = promisify(execFile);
2071
+ await execFileAsync(
2072
+ "cleo",
2073
+ [
2074
+ "observe",
2075
+ `Agent ${name} created with role ${role}`,
2076
+ "--title",
2077
+ `Agent creation: ${name}`
2078
+ ],
2079
+ { encoding: "utf-8", timeout: 1e4 }
2080
+ ).catch(() => {
2081
+ });
2082
+ } catch {
2083
+ }
2084
+ }
2085
+ let registered = false;
2086
+ try {
2087
+ const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
2088
+ await openCleoDb("project");
2089
+ const registry = new AgentRegistryAccessor(getProjectRoot());
2090
+ const existing = await registry.get(name);
2091
+ if (!existing) {
2092
+ await registry.register({
2093
+ agentId: name,
2094
+ displayName: name,
2095
+ apiKey: "local-created",
2096
+ apiBaseUrl: "local",
2097
+ classification: role,
2098
+ privacyTier: "private",
2099
+ capabilities: [],
2100
+ skills: [],
2101
+ transportType: "http",
2102
+ transportConfig: {},
2103
+ isActive: false
2104
+ });
2105
+ registered = true;
2106
+ }
2107
+ } catch {
2108
+ }
2109
+ cliOutput(
2110
+ {
2111
+ success: true,
2112
+ data: {
2113
+ ...scaffoldResult,
2114
+ registered
2115
+ }
2116
+ },
2117
+ { command: "agent create" }
2118
+ );
2119
+ } catch (err) {
2120
+ cliOutput(
2121
+ { success: false, error: { code: "E_CREATE", message: String(err) } },
2122
+ { command: "agent create" }
2123
+ );
2124
+ process.exitCode = 1;
2125
+ }
2126
+ }
2127
+ });
2128
+ var mintCommand = defineCommand({
2129
+ meta: {
2130
+ name: "mint",
2131
+ description: "Synthesize a project-specific agent from a .cant spec using agent-architect meta-agent"
2132
+ },
2133
+ args: {
2134
+ spec: {
2135
+ type: "positional",
2136
+ description: "Path to the .cant spec file describing the agent to synthesize",
2137
+ required: true
2138
+ },
2139
+ "output-dir": {
2140
+ type: "string",
2141
+ description: "Directory to write synthesized .cant files (defaults to .cleo/cant/agents/)"
2142
+ },
2143
+ "dry-run": {
2144
+ type: "boolean",
2145
+ description: "Preview invocation tokens without invoking agent-architect",
2146
+ default: false
2147
+ },
2148
+ json: {
2149
+ type: "boolean",
2150
+ description: "Emit result as LAFS JSON envelope",
2151
+ default: false
2152
+ }
2153
+ },
2154
+ async run({ args }) {
2155
+ try {
2156
+ const { existsSync, readFileSync, mkdirSync } = await import("node:fs");
2157
+ const { resolve, join } = await import("node:path");
2158
+ const specPath = resolve(args.spec);
2159
+ if (!existsSync(specPath)) {
2160
+ cliError(`spec file not found: ${specPath}`, 4, { name: "E_NOT_FOUND" });
2161
+ process.exitCode = 4;
2162
+ return;
2163
+ }
2164
+ const specContent = readFileSync(specPath, "utf-8");
2165
+ const projectRoot = getProjectRoot();
2166
+ const outputDir = args["output-dir"] ? resolve(args["output-dir"]) : join(projectRoot, ".cleo", "cant", "agents");
2167
+ mkdirSync(outputDir, { recursive: true });
2168
+ if (args["dry-run"]) {
2169
+ cliOutput(
2170
+ {
2171
+ dryRun: true,
2172
+ agentName: "agent-architect",
2173
+ specPath,
2174
+ outputDir,
2175
+ projectRoot,
2176
+ message: "Dry-run: would invoke agent-architect with the above tokens"
2177
+ },
2178
+ { command: "agent", operation: "agent.mint" }
2179
+ );
2180
+ return;
2181
+ }
2182
+ const { invokeMetaAgent } = await import("@cleocode/core/agents/invoke-meta-agent");
2183
+ const result = await invokeMetaAgent({
2184
+ agentName: "agent-architect",
2185
+ projectRoot,
2186
+ tokens: {
2187
+ CANT_AGENTS_DIR: outputDir,
2188
+ // Pass spec content as PROJECT_CONTEXT to let agent-architect read it
2189
+ PROJECT_CONTEXT: specContent
2190
+ }
2191
+ });
2192
+ if (result.invoked) {
2193
+ cliOutput(
2194
+ {
2195
+ invoked: true,
2196
+ outputs: result.outputs ?? [],
2197
+ outputDir,
2198
+ message: `agent-architect synthesized ${result.outputs?.length ?? 0} agent(s)`
2199
+ },
2200
+ { command: "agent", operation: "agent.mint" }
2201
+ );
2202
+ } else {
2203
+ const fallbackMsg = `agent-architect unavailable: ${result.reason ?? "unknown"}. Run 'cleo agent create' for static scaffolding.`;
2204
+ cliError(fallbackMsg, 1, { name: "E_META_AGENT_UNAVAILABLE" });
2205
+ process.exitCode = 1;
2206
+ }
2207
+ } catch (err) {
2208
+ const message = err instanceof Error ? err.message : String(err);
2209
+ cliError(`agent mint failed: ${message}`, 1, { name: "E_AGENT_MINT" });
2210
+ process.exitCode = 1;
2211
+ }
2212
+ }
2213
+ });
2214
+ var pruneOrphansCommand = defineCommand({
2215
+ meta: {
2216
+ name: "prune-orphans",
2217
+ description: "Delete orphan registry rows whose .cant path no longer exists (cross-project safe)"
2218
+ },
2219
+ args: {
2220
+ json: { type: "boolean", description: "Emit raw JSON" },
2221
+ "dry-run": { type: "boolean", description: "Report without making changes" }
2222
+ },
2223
+ async run({ args }) {
2224
+ try {
2225
+ const { buildDoctorReport, reconcileDoctor } = await import("@cleocode/core/agents");
2226
+ const { ensureGlobalAgentRegistryDb, getGlobalAgentRegistryNativeDb } = await import("@cleocode/core/internal");
2227
+ await ensureGlobalAgentRegistryDb();
2228
+ const db = getGlobalAgentRegistryNativeDb();
2229
+ try {
2230
+ const report = await buildDoctorReport(db, {});
2231
+ const d002 = report.findings.filter((f) => f.code === "D-002");
2232
+ const dryRun = args["dry-run"] === true;
2233
+ let repaired = [], skipped = [];
2234
+ if (!dryRun && d002.length > 0) {
2235
+ const r = await reconcileDoctor(db, d002, {});
2236
+ repaired = r.repaired;
2237
+ skipped = r.skipped;
2238
+ }
2239
+ const msg = d002.length === 0 ? "No orphan rows found." : `Found ${d002.length} orphan(s)${dryRun ? " (dry-run)" : ": pruned=" + repaired.length}`;
2240
+ cliOutput(
2241
+ {
2242
+ success: true,
2243
+ data: {
2244
+ message: msg,
2245
+ found: d002.length,
2246
+ repaired: dryRun ? 0 : repaired.length,
2247
+ skipped: dryRun ? 0 : skipped.length,
2248
+ dryRun
2249
+ }
2250
+ },
2251
+ { command: "agent prune-orphans" }
2252
+ );
2253
+ if (!dryRun && skipped.length > 0) process.exitCode = 1;
2254
+ } finally {
2255
+ db.close();
2256
+ }
2257
+ } catch (err) {
2258
+ cliOutput(
2259
+ { success: false, error: { code: "E_PRUNE_ORPHANS", message: String(err) } },
2260
+ { command: "agent prune-orphans" }
2261
+ );
2262
+ process.exitCode = 1;
2263
+ }
2264
+ }
2265
+ });
2266
+ var doctorCommand = defineCommand({
2267
+ meta: {
2268
+ name: "doctor",
2269
+ description: "Reconcile .cant files on disk against the registry and report drift"
2270
+ },
2271
+ args: {
2272
+ repair: {
2273
+ type: "boolean",
2274
+ description: "Apply safe repairs (D-002 orphan-row delete, D-003 hash refresh)"
2275
+ },
2276
+ "import-legacy-json": {
2277
+ type: "boolean",
2278
+ description: "When used with --repair, import a discovered ~/.cleo/agent-registry.json"
2279
+ },
2280
+ "migrate-path": {
2281
+ type: "boolean",
2282
+ description: "When used with --repair, migrate legacy .cleo/agents/ rows to .cleo/cant/agents/"
2283
+ },
2284
+ json: {
2285
+ type: "boolean",
2286
+ description: "Emit the raw DoctorReport envelope as JSON instead of a human table"
2287
+ }
2288
+ },
2289
+ async run({ args }) {
2290
+ try {
2291
+ const { buildDoctorReport, reconcileDoctor } = await import("@cleocode/core/agents");
2292
+ const { ensureGlobalAgentRegistryDb, getGlobalAgentRegistryNativeDb } = await import("@cleocode/core/internal");
2293
+ await ensureGlobalAgentRegistryDb();
2294
+ const db = getGlobalAgentRegistryNativeDb();
2295
+ try {
2296
+ const report = await buildDoctorReport(db, { projectRoot: getProjectRoot() });
2297
+ const repairFlag = args.repair === true;
2298
+ let reconciled;
2299
+ if (repairFlag) {
2300
+ reconciled = await reconcileDoctor(db, report.findings, {
2301
+ importLegacyJson: args["import-legacy-json"] === true,
2302
+ allowPathMigration: args["migrate-path"] === true
2303
+ });
2304
+ }
2305
+ if (args.json === true) {
2306
+ cliOutput(
2307
+ { success: true, data: { report, reconciled: reconciled ?? null } },
2308
+ { command: "agent doctor" }
2309
+ );
2310
+ } else {
2311
+ const lines = [];
2312
+ if (report.findings.length === 0) {
2313
+ lines.push("No drift detected \u2014 registry and filesystem are in sync.");
2314
+ } else {
2315
+ lines.push(
2316
+ `Findings: ${report.summary.error} error(s), ${report.summary.warn} warning(s), ${report.summary.info} info`
2317
+ );
2318
+ lines.push("");
2319
+ for (const f of report.findings) {
2320
+ lines.push(`[${f.code}] ${f.severity.toUpperCase()} ${f.subject} \u2014 ${f.message}`);
2321
+ if (f.fixCommand) lines.push(` fix: ${f.fixCommand}`);
2322
+ }
2323
+ if (reconciled) {
2324
+ lines.push("");
2325
+ lines.push(
2326
+ `Repaired: ${reconciled.repaired.length > 0 ? reconciled.repaired.join(", ") : "(none)"}`
2327
+ );
2328
+ lines.push(
2329
+ `Skipped: ${reconciled.skipped.length > 0 ? reconciled.skipped.join(", ") : "(none)"}`
2330
+ );
2331
+ }
2332
+ }
2333
+ cliOutput(
2334
+ {
2335
+ success: true,
2336
+ data: {
2337
+ message: lines.join("\n"),
2338
+ summary: report.summary,
2339
+ generatedAt: report.generatedAt,
2340
+ findings: report.findings.length,
2341
+ repaired: reconciled?.repaired.length ?? 0,
2342
+ skipped: reconciled?.skipped.length ?? 0
2343
+ }
2344
+ },
2345
+ { command: "agent doctor" }
2346
+ );
2347
+ }
2348
+ if (report.summary.error > 0) {
2349
+ process.exitCode = 1;
2350
+ }
2351
+ } finally {
2352
+ db.close();
2353
+ }
2354
+ } catch (err) {
2355
+ cliOutput(
2356
+ { success: false, error: { code: "E_DOCTOR", message: String(err) } },
2357
+ { command: "agent doctor" }
2358
+ );
2359
+ process.exitCode = 1;
2360
+ }
2361
+ }
2362
+ });
2363
+ var agentCommand = defineCommand({
2364
+ meta: { name: "agent", description: "Agent lifecycle, credentials, and messaging" },
2365
+ subCommands: {
2366
+ doctor: doctorCommand,
2367
+ "prune-orphans": pruneOrphansCommand,
2368
+ register: registerCommand,
2369
+ signin: signinCommand,
2370
+ start: startCommand,
2371
+ stop: stopCommand,
2372
+ status: statusCommand,
2373
+ assign: assignCommand,
2374
+ wake: wakeCommand,
2375
+ spawn: spawnCommand,
2376
+ reassign: reassignCommand,
2377
+ "stop-all": stopAllCommand,
2378
+ work: workCommand,
2379
+ list: listCommand,
2380
+ get: getCommand,
2381
+ attach: attachCommand,
2382
+ detach: detachCommand,
2383
+ remove: removeCommand,
2384
+ "rotate-key": rotateKeyCommand,
2385
+ "claim-code": claimCodeCommand,
2386
+ watch: watchCommand,
2387
+ poll: pollCommand,
2388
+ send: sendCommand,
2389
+ health: healthCommand,
2390
+ install: installCommand,
2391
+ pack: packCommand,
2392
+ create: createCommand,
2393
+ mint: mintCommand
2394
+ },
2395
+ async run({ cmd, rawArgs }) {
2396
+ const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
2397
+ if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
2398
+ await showUsage(cmd);
2399
+ }
2400
+ });
2401
+ export {
2402
+ agentCommand
2403
+ };
2404
+ //# sourceMappingURL=agent-TAFPIYUU.js.map