@cleocode/cleo 2026.10.3 → 2026.10.4

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