@cleocode/cleo 2026.4.10 → 2026.4.11
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.
- package/dist/cli/commander-shim.d.ts +112 -0
- package/dist/cli/commander-shim.d.ts.map +1 -0
- package/dist/cli/commander-shim.js +233 -0
- package/dist/cli/commander-shim.js.map +1 -0
- package/dist/cli/commands/add.d.ts +12 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +98 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +12 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +59 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cli/commands/adr.d.ts +27 -0
- package/dist/cli/commands/adr.d.ts.map +1 -0
- package/dist/cli/commands/adr.js +79 -0
- package/dist/cli/commands/adr.js.map +1 -0
- package/dist/cli/commands/agent-profile-status.d.ts +98 -0
- package/dist/cli/commands/agent-profile-status.d.ts.map +1 -0
- package/dist/cli/commands/agent-profile-status.js +71 -0
- package/dist/cli/commands/agent-profile-status.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +38 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +1125 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +17 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +20 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +12 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +20 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/archive-stats.d.ts +18 -0
- package/dist/cli/commands/archive-stats.d.ts.map +1 -0
- package/dist/cli/commands/archive-stats.js +49 -0
- package/dist/cli/commands/archive-stats.js.map +1 -0
- package/dist/cli/commands/archive.d.ts +12 -0
- package/dist/cli/commands/archive.d.ts.map +1 -0
- package/dist/cli/commands/archive.js +32 -0
- package/dist/cli/commands/archive.js.map +1 -0
- package/dist/cli/commands/backfill.d.ts +38 -0
- package/dist/cli/commands/backfill.d.ts.map +1 -0
- package/dist/cli/commands/backfill.js +147 -0
- package/dist/cli/commands/backfill.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +8 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +35 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/blockers.d.ts +7 -0
- package/dist/cli/commands/blockers.d.ts.map +1 -0
- package/dist/cli/commands/blockers.js +16 -0
- package/dist/cli/commands/blockers.js.map +1 -0
- package/dist/cli/commands/brain.d.ts +29 -0
- package/dist/cli/commands/brain.d.ts.map +1 -0
- package/dist/cli/commands/brain.js +107 -0
- package/dist/cli/commands/brain.js.map +1 -0
- package/dist/cli/commands/briefing.d.ts +22 -0
- package/dist/cli/commands/briefing.d.ts.map +1 -0
- package/dist/cli/commands/briefing.js +45 -0
- package/dist/cli/commands/briefing.js.map +1 -0
- package/dist/cli/commands/bug.d.ts +12 -0
- package/dist/cli/commands/bug.d.ts.map +1 -0
- package/dist/cli/commands/bug.js +81 -0
- package/dist/cli/commands/bug.js.map +1 -0
- package/dist/cli/commands/cant.d.ts +32 -0
- package/dist/cli/commands/cant.d.ts.map +1 -0
- package/dist/cli/commands/cant.js +281 -0
- package/dist/cli/commands/cant.js.map +1 -0
- package/dist/cli/commands/check.d.ts +22 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +164 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/checkpoint.d.ts +15 -0
- package/dist/cli/commands/checkpoint.d.ts.map +1 -0
- package/dist/cli/commands/checkpoint.js +91 -0
- package/dist/cli/commands/checkpoint.js.map +1 -0
- package/dist/cli/commands/code.d.ts +11 -0
- package/dist/cli/commands/code.d.ts.map +1 -0
- package/dist/cli/commands/code.js +114 -0
- package/dist/cli/commands/code.js.map +1 -0
- package/dist/cli/commands/commands.d.ts +13 -0
- package/dist/cli/commands/commands.d.ts.map +1 -0
- package/dist/cli/commands/commands.js +29 -0
- package/dist/cli/commands/commands.js.map +1 -0
- package/dist/cli/commands/complete.d.ts +12 -0
- package/dist/cli/commands/complete.d.ts.map +1 -0
- package/dist/cli/commands/complete.js +43 -0
- package/dist/cli/commands/complete.js.map +1 -0
- package/dist/cli/commands/compliance.d.ts +8 -0
- package/dist/cli/commands/compliance.d.ts.map +1 -0
- package/dist/cli/commands/compliance.js +85 -0
- package/dist/cli/commands/compliance.js.map +1 -0
- package/dist/cli/commands/config.d.ts +10 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +69 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/consensus.d.ts +13 -0
- package/dist/cli/commands/consensus.d.ts.map +1 -0
- package/dist/cli/commands/consensus.js +45 -0
- package/dist/cli/commands/consensus.js.map +1 -0
- package/dist/cli/commands/context.d.ts +8 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +40 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/contribution.d.ts +13 -0
- package/dist/cli/commands/contribution.d.ts.map +1 -0
- package/dist/cli/commands/contribution.js +41 -0
- package/dist/cli/commands/contribution.js.map +1 -0
- package/dist/cli/commands/current.d.ts +13 -0
- package/dist/cli/commands/current.d.ts.map +1 -0
- package/dist/cli/commands/current.js +20 -0
- package/dist/cli/commands/current.js.map +1 -0
- package/dist/cli/commands/dash.d.ts +12 -0
- package/dist/cli/commands/dash.d.ts.map +1 -0
- package/dist/cli/commands/dash.js +24 -0
- package/dist/cli/commands/dash.js.map +1 -0
- package/dist/cli/commands/decomposition.d.ts +13 -0
- package/dist/cli/commands/decomposition.d.ts.map +1 -0
- package/dist/cli/commands/decomposition.js +45 -0
- package/dist/cli/commands/decomposition.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +12 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +37 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/deps.d.ts +24 -0
- package/dist/cli/commands/deps.d.ts.map +1 -0
- package/dist/cli/commands/deps.js +98 -0
- package/dist/cli/commands/deps.js.map +1 -0
- package/dist/cli/commands/detect-drift.d.ts +15 -0
- package/dist/cli/commands/detect-drift.d.ts.map +1 -0
- package/dist/cli/commands/detect-drift.js +424 -0
- package/dist/cli/commands/detect-drift.js.map +1 -0
- package/dist/cli/commands/detect.d.ts +10 -0
- package/dist/cli/commands/detect.d.ts.map +1 -0
- package/dist/cli/commands/detect.js +24 -0
- package/dist/cli/commands/detect.js.map +1 -0
- package/dist/cli/commands/docs.d.ts +13 -0
- package/dist/cli/commands/docs.d.ts.map +1 -0
- package/dist/cli/commands/docs.js +169 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +15 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +133 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/dynamic.d.ts +24 -0
- package/dist/cli/commands/dynamic.d.ts.map +1 -0
- package/dist/cli/commands/dynamic.js +27 -0
- package/dist/cli/commands/dynamic.js.map +1 -0
- package/dist/cli/commands/env.d.ts +12 -0
- package/dist/cli/commands/env.d.ts.map +1 -0
- package/dist/cli/commands/env.js +44 -0
- package/dist/cli/commands/env.js.map +1 -0
- package/dist/cli/commands/exists.d.ts +22 -0
- package/dist/cli/commands/exists.d.ts.map +1 -0
- package/dist/cli/commands/exists.js +51 -0
- package/dist/cli/commands/exists.js.map +1 -0
- package/dist/cli/commands/export-tasks.d.ts +10 -0
- package/dist/cli/commands/export-tasks.d.ts.map +1 -0
- package/dist/cli/commands/export-tasks.js +47 -0
- package/dist/cli/commands/export-tasks.js.map +1 -0
- package/dist/cli/commands/export.d.ts +9 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +46 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/find.d.ts +14 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +70 -0
- package/dist/cli/commands/find.js.map +1 -0
- package/dist/cli/commands/generate-changelog.d.ts +14 -0
- package/dist/cli/commands/generate-changelog.d.ts.map +1 -0
- package/dist/cli/commands/generate-changelog.js +252 -0
- package/dist/cli/commands/generate-changelog.js.map +1 -0
- package/dist/cli/commands/grade.d.ts +13 -0
- package/dist/cli/commands/grade.d.ts.map +1 -0
- package/dist/cli/commands/grade.js +26 -0
- package/dist/cli/commands/grade.js.map +1 -0
- package/dist/cli/commands/history.d.ts +9 -0
- package/dist/cli/commands/history.d.ts.map +1 -0
- package/dist/cli/commands/history.js +30 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/implementation.d.ts +13 -0
- package/dist/cli/commands/implementation.d.ts.map +1 -0
- package/dist/cli/commands/implementation.js +41 -0
- package/dist/cli/commands/implementation.js.map +1 -0
- package/dist/cli/commands/import-tasks.d.ts +10 -0
- package/dist/cli/commands/import-tasks.d.ts.map +1 -0
- package/dist/cli/commands/import-tasks.js +38 -0
- package/dist/cli/commands/import-tasks.js.map +1 -0
- package/dist/cli/commands/import.d.ts +9 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +28 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/init.d.ts +34 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +96 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/inject.d.ts +8 -0
- package/dist/cli/commands/inject.d.ts.map +1 -0
- package/dist/cli/commands/inject.js +28 -0
- package/dist/cli/commands/inject.js.map +1 -0
- package/dist/cli/commands/issue.d.ts +17 -0
- package/dist/cli/commands/issue.d.ts.map +1 -0
- package/dist/cli/commands/issue.js +107 -0
- package/dist/cli/commands/issue.js.map +1 -0
- package/dist/cli/commands/labels.d.ts +13 -0
- package/dist/cli/commands/labels.d.ts.map +1 -0
- package/dist/cli/commands/labels.js +44 -0
- package/dist/cli/commands/labels.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +8 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +84 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/list.d.ts +14 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +71 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/log.d.ts +12 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +30 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/map.d.ts +10 -0
- package/dist/cli/commands/map.d.ts.map +1 -0
- package/dist/cli/commands/map.js +23 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/memory-brain.d.ts +14 -0
- package/dist/cli/commands/memory-brain.d.ts.map +1 -0
- package/dist/cli/commands/memory-brain.js +157 -0
- package/dist/cli/commands/memory-brain.js.map +1 -0
- package/dist/cli/commands/migrate-claude-mem.d.ts +18 -0
- package/dist/cli/commands/migrate-claude-mem.d.ts.map +1 -0
- package/dist/cli/commands/migrate-claude-mem.js +60 -0
- package/dist/cli/commands/migrate-claude-mem.js.map +1 -0
- package/dist/cli/commands/next.d.ts +9 -0
- package/dist/cli/commands/next.d.ts.map +1 -0
- package/dist/cli/commands/next.js +20 -0
- package/dist/cli/commands/next.js.map +1 -0
- package/dist/cli/commands/nexus.d.ts +16 -0
- package/dist/cli/commands/nexus.d.ts.map +1 -0
- package/dist/cli/commands/nexus.js +155 -0
- package/dist/cli/commands/nexus.js.map +1 -0
- package/dist/cli/commands/observe.d.ts +9 -0
- package/dist/cli/commands/observe.d.ts.map +1 -0
- package/dist/cli/commands/observe.js +39 -0
- package/dist/cli/commands/observe.js.map +1 -0
- package/dist/cli/commands/ops.d.ts +10 -0
- package/dist/cli/commands/ops.d.ts.map +1 -0
- package/dist/cli/commands/ops.js +19 -0
- package/dist/cli/commands/ops.js.map +1 -0
- package/dist/cli/commands/orchestrate.d.ts +8 -0
- package/dist/cli/commands/orchestrate.d.ts.map +1 -0
- package/dist/cli/commands/orchestrate.js +58 -0
- package/dist/cli/commands/orchestrate.js.map +1 -0
- package/dist/cli/commands/otel.d.ts +12 -0
- package/dist/cli/commands/otel.d.ts.map +1 -0
- package/dist/cli/commands/otel.js +128 -0
- package/dist/cli/commands/otel.js.map +1 -0
- package/dist/cli/commands/phase.d.ts +12 -0
- package/dist/cli/commands/phase.d.ts.map +1 -0
- package/dist/cli/commands/phase.js +91 -0
- package/dist/cli/commands/phase.js.map +1 -0
- package/dist/cli/commands/phases.d.ts +12 -0
- package/dist/cli/commands/phases.d.ts.map +1 -0
- package/dist/cli/commands/phases.js +37 -0
- package/dist/cli/commands/phases.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +8 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +15 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/promote.d.ts +7 -0
- package/dist/cli/commands/promote.d.ts.map +1 -0
- package/dist/cli/commands/promote.js +15 -0
- package/dist/cli/commands/promote.js.map +1 -0
- package/dist/cli/commands/reason.d.ts +35 -0
- package/dist/cli/commands/reason.d.ts.map +1 -0
- package/dist/cli/commands/reason.js +104 -0
- package/dist/cli/commands/reason.js.map +1 -0
- package/dist/cli/commands/refresh-memory.d.ts +9 -0
- package/dist/cli/commands/refresh-memory.d.ts.map +1 -0
- package/dist/cli/commands/refresh-memory.js +24 -0
- package/dist/cli/commands/refresh-memory.js.map +1 -0
- package/dist/cli/commands/relates.d.ts +12 -0
- package/dist/cli/commands/relates.d.ts.map +1 -0
- package/dist/cli/commands/relates.js +53 -0
- package/dist/cli/commands/relates.js.map +1 -0
- package/dist/cli/commands/release.d.ts +8 -0
- package/dist/cli/commands/release.d.ts.map +1 -0
- package/dist/cli/commands/release.js +72 -0
- package/dist/cli/commands/release.js.map +1 -0
- package/dist/cli/commands/remote.d.ts +12 -0
- package/dist/cli/commands/remote.d.ts.map +1 -0
- package/dist/cli/commands/remote.js +207 -0
- package/dist/cli/commands/remote.js.map +1 -0
- package/dist/cli/commands/reorder.d.ts +7 -0
- package/dist/cli/commands/reorder.d.ts.map +1 -0
- package/dist/cli/commands/reorder.js +20 -0
- package/dist/cli/commands/reorder.js.map +1 -0
- package/dist/cli/commands/reparent.d.ts +10 -0
- package/dist/cli/commands/reparent.d.ts.map +1 -0
- package/dist/cli/commands/reparent.js +19 -0
- package/dist/cli/commands/reparent.js.map +1 -0
- package/dist/cli/commands/research.d.ts +8 -0
- package/dist/cli/commands/research.d.ts.map +1 -0
- package/dist/cli/commands/research.js +129 -0
- package/dist/cli/commands/research.js.map +1 -0
- package/dist/cli/commands/restore.d.ts +11 -0
- package/dist/cli/commands/restore.d.ts.map +1 -0
- package/dist/cli/commands/restore.js +224 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/roadmap.d.ts +8 -0
- package/dist/cli/commands/roadmap.d.ts.map +1 -0
- package/dist/cli/commands/roadmap.js +21 -0
- package/dist/cli/commands/roadmap.js.map +1 -0
- package/dist/cli/commands/safestop.d.ts +14 -0
- package/dist/cli/commands/safestop.d.ts.map +1 -0
- package/dist/cli/commands/safestop.js +32 -0
- package/dist/cli/commands/safestop.js.map +1 -0
- package/dist/cli/commands/self-update.d.ts +15 -0
- package/dist/cli/commands/self-update.d.ts.map +1 -0
- package/dist/cli/commands/self-update.js +329 -0
- package/dist/cli/commands/self-update.js.map +1 -0
- package/dist/cli/commands/sequence.d.ts +8 -0
- package/dist/cli/commands/sequence.d.ts.map +1 -0
- package/dist/cli/commands/sequence.js +30 -0
- package/dist/cli/commands/sequence.js.map +1 -0
- package/dist/cli/commands/session.d.ts +12 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +175 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/show.d.ts +13 -0
- package/dist/cli/commands/show.d.ts.map +1 -0
- package/dist/cli/commands/show.js +20 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +13 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +131 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +9 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +50 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/specification.d.ts +13 -0
- package/dist/cli/commands/specification.d.ts.map +1 -0
- package/dist/cli/commands/specification.js +45 -0
- package/dist/cli/commands/specification.js.map +1 -0
- package/dist/cli/commands/start.d.ts +13 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +20 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +12 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +35 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/sticky.d.ts +16 -0
- package/dist/cli/commands/sticky.d.ts.map +1 -0
- package/dist/cli/commands/sticky.js +211 -0
- package/dist/cli/commands/sticky.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +13 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +20 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/testing.d.ts +13 -0
- package/dist/cli/commands/testing.d.ts.map +1 -0
- package/dist/cli/commands/testing.js +64 -0
- package/dist/cli/commands/testing.js.map +1 -0
- package/dist/cli/commands/token.d.ts +10 -0
- package/dist/cli/commands/token.d.ts.map +1 -0
- package/dist/cli/commands/token.js +135 -0
- package/dist/cli/commands/token.js.map +1 -0
- package/dist/cli/commands/update.d.ts +12 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +83 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +18 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +103 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +12 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +23 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +8 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +28 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/web.d.ts +13 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +277 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/field-context.d.ts +32 -0
- package/dist/cli/field-context.d.ts.map +1 -0
- package/dist/cli/field-context.js +47 -0
- package/dist/cli/field-context.js.map +1 -0
- package/dist/cli/format-context.d.ts +32 -0
- package/dist/cli/format-context.d.ts.map +1 -0
- package/dist/cli/format-context.js +50 -0
- package/dist/cli/format-context.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +3767 -3387
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/logger-bootstrap.d.ts +6 -0
- package/dist/cli/logger-bootstrap.d.ts.map +1 -0
- package/dist/cli/logger-bootstrap.js +10 -0
- package/dist/cli/logger-bootstrap.js.map +1 -0
- package/dist/cli/middleware/output-format.d.ts +30 -0
- package/dist/cli/middleware/output-format.d.ts.map +1 -0
- package/dist/cli/middleware/output-format.js +35 -0
- package/dist/cli/middleware/output-format.js.map +1 -0
- package/dist/cli/progress.d.ts +84 -0
- package/dist/cli/progress.d.ts.map +1 -0
- package/dist/cli/progress.js +169 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/cli/renderers/colors.d.ts +32 -0
- package/dist/cli/renderers/colors.d.ts.map +1 -0
- package/dist/cli/renderers/colors.js +141 -0
- package/dist/cli/renderers/colors.js.map +1 -0
- package/dist/cli/renderers/error.d.ts +13 -0
- package/dist/cli/renderers/error.d.ts.map +1 -0
- package/dist/cli/renderers/error.js +42 -0
- package/dist/cli/renderers/error.js.map +1 -0
- package/dist/cli/renderers/index.d.ts +59 -0
- package/dist/cli/renderers/index.d.ts.map +1 -0
- package/dist/cli/renderers/index.js +208 -0
- package/dist/cli/renderers/index.js.map +1 -0
- package/dist/cli/renderers/lafs-validator.d.ts +97 -0
- package/dist/cli/renderers/lafs-validator.d.ts.map +1 -0
- package/dist/cli/renderers/lafs-validator.js +229 -0
- package/dist/cli/renderers/lafs-validator.js.map +1 -0
- package/dist/cli/renderers/normalizer.d.ts +21 -0
- package/dist/cli/renderers/normalizer.d.ts.map +1 -0
- package/dist/cli/renderers/normalizer.js +106 -0
- package/dist/cli/renderers/normalizer.js.map +1 -0
- package/dist/cli/renderers/system.d.ts +25 -0
- package/dist/cli/renderers/system.d.ts.map +1 -0
- package/dist/cli/renderers/system.js +416 -0
- package/dist/cli/renderers/system.js.map +1 -0
- package/dist/cli/renderers/tasks.d.ts +28 -0
- package/dist/cli/renderers/tasks.d.ts.map +1 -0
- package/dist/cli/renderers/tasks.js +306 -0
- package/dist/cli/renderers/tasks.js.map +1 -0
- package/dist/dispatch/adapters/cli.d.ts +67 -0
- package/dist/dispatch/adapters/cli.d.ts.map +1 -0
- package/dist/dispatch/adapters/cli.js +262 -0
- package/dist/dispatch/adapters/cli.js.map +1 -0
- package/dist/dispatch/context/session-context.d.ts +54 -0
- package/dist/dispatch/context/session-context.d.ts.map +1 -0
- package/dist/dispatch/context/session-context.js +61 -0
- package/dist/dispatch/context/session-context.js.map +1 -0
- package/dist/dispatch/dispatcher.d.ts +23 -0
- package/dist/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/dispatch/dispatcher.js +84 -0
- package/dist/dispatch/dispatcher.js.map +1 -0
- package/dist/dispatch/domains/_base.d.ts +59 -0
- package/dist/dispatch/domains/_base.d.ts.map +1 -0
- package/dist/dispatch/domains/_base.js +77 -0
- package/dist/dispatch/domains/_base.js.map +1 -0
- package/dist/dispatch/domains/_meta.d.ts +23 -0
- package/dist/dispatch/domains/_meta.d.ts.map +1 -0
- package/dist/dispatch/domains/_meta.js +25 -0
- package/dist/dispatch/domains/_meta.js.map +1 -0
- package/dist/dispatch/domains/_routing.d.ts +8 -0
- package/dist/dispatch/domains/_routing.d.ts.map +1 -0
- package/dist/dispatch/domains/_routing.js +20 -0
- package/dist/dispatch/domains/_routing.js.map +1 -0
- package/dist/dispatch/domains/admin.d.ts +25 -0
- package/dist/dispatch/domains/admin.d.ts.map +1 -0
- package/dist/dispatch/domains/admin.js +719 -0
- package/dist/dispatch/domains/admin.js.map +1 -0
- package/dist/dispatch/domains/check.d.ts +22 -0
- package/dist/dispatch/domains/check.d.ts.map +1 -0
- package/dist/dispatch/domains/check.js +360 -0
- package/dist/dispatch/domains/check.js.map +1 -0
- package/dist/dispatch/domains/conduit.d.ts +38 -0
- package/dist/dispatch/domains/conduit.d.ts.map +1 -0
- package/dist/dispatch/domains/conduit.js +247 -0
- package/dist/dispatch/domains/conduit.js.map +1 -0
- package/dist/dispatch/domains/index.d.ts +27 -0
- package/dist/dispatch/domains/index.d.ts.map +1 -0
- package/dist/dispatch/domains/index.js +40 -0
- package/dist/dispatch/domains/index.js.map +1 -0
- package/dist/dispatch/domains/memory.d.ts +22 -0
- package/dist/dispatch/domains/memory.d.ts.map +1 -0
- package/dist/dispatch/domains/memory.js +303 -0
- package/dist/dispatch/domains/memory.js.map +1 -0
- package/dist/dispatch/domains/nexus.d.ts +22 -0
- package/dist/dispatch/domains/nexus.d.ts.map +1 -0
- package/dist/dispatch/domains/nexus.js +286 -0
- package/dist/dispatch/domains/nexus.js.map +1 -0
- package/dist/dispatch/domains/orchestrate.d.ts +19 -0
- package/dist/dispatch/domains/orchestrate.d.ts.map +1 -0
- package/dist/dispatch/domains/orchestrate.js +259 -0
- package/dist/dispatch/domains/orchestrate.js.map +1 -0
- package/dist/dispatch/domains/pipeline.d.ts +35 -0
- package/dist/dispatch/domains/pipeline.d.ts.map +1 -0
- package/dist/dispatch/domains/pipeline.js +593 -0
- package/dist/dispatch/domains/pipeline.js.map +1 -0
- package/dist/dispatch/domains/session.d.ts +22 -0
- package/dist/dispatch/domains/session.d.ts.map +1 -0
- package/dist/dispatch/domains/session.js +257 -0
- package/dist/dispatch/domains/session.js.map +1 -0
- package/dist/dispatch/domains/sticky.d.ts +20 -0
- package/dist/dispatch/domains/sticky.d.ts.map +1 -0
- package/dist/dispatch/domains/sticky.js +164 -0
- package/dist/dispatch/domains/sticky.js.map +1 -0
- package/dist/dispatch/domains/tasks.d.ts +25 -0
- package/dist/dispatch/domains/tasks.d.ts.map +1 -0
- package/dist/dispatch/domains/tasks.js +361 -0
- package/dist/dispatch/domains/tasks.js.map +1 -0
- package/dist/dispatch/domains/tools.d.ts +37 -0
- package/dist/dispatch/domains/tools.d.ts.map +1 -0
- package/dist/dispatch/domains/tools.js +481 -0
- package/dist/dispatch/domains/tools.js.map +1 -0
- package/dist/dispatch/engines/_error.d.ts +85 -0
- package/dist/dispatch/engines/_error.d.ts.map +1 -0
- package/dist/dispatch/engines/_error.js +244 -0
- package/dist/dispatch/engines/_error.js.map +1 -0
- package/dist/dispatch/engines/code-engine.d.ts +18 -0
- package/dist/dispatch/engines/code-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/code-engine.js +71 -0
- package/dist/dispatch/engines/code-engine.js.map +1 -0
- package/dist/dispatch/engines/codebase-map-engine.d.ts +31 -0
- package/dist/dispatch/engines/codebase-map-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/codebase-map-engine.js +43 -0
- package/dist/dispatch/engines/codebase-map-engine.js.map +1 -0
- package/dist/dispatch/engines/config-engine.d.ts +32 -0
- package/dist/dispatch/engines/config-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/config-engine.js +70 -0
- package/dist/dispatch/engines/config-engine.js.map +1 -0
- package/dist/dispatch/engines/hooks-engine.d.ts +96 -0
- package/dist/dispatch/engines/hooks-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/hooks-engine.js +144 -0
- package/dist/dispatch/engines/hooks-engine.js.map +1 -0
- package/dist/dispatch/engines/init-engine.d.ts +56 -0
- package/dist/dispatch/engines/init-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/init-engine.js +78 -0
- package/dist/dispatch/engines/init-engine.js.map +1 -0
- package/dist/dispatch/engines/lifecycle-engine.d.ts +66 -0
- package/dist/dispatch/engines/lifecycle-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/lifecycle-engine.js +224 -0
- package/dist/dispatch/engines/lifecycle-engine.js.map +1 -0
- package/dist/dispatch/engines/memory-engine.d.ts +10 -0
- package/dist/dispatch/engines/memory-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/memory-engine.js +10 -0
- package/dist/dispatch/engines/memory-engine.js.map +1 -0
- package/dist/dispatch/engines/nexus-engine.d.ts +167 -0
- package/dist/dispatch/engines/nexus-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/nexus-engine.js +356 -0
- package/dist/dispatch/engines/nexus-engine.js.map +1 -0
- package/dist/dispatch/engines/orchestrate-engine.d.ts +133 -0
- package/dist/dispatch/engines/orchestrate-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/orchestrate-engine.js +769 -0
- package/dist/dispatch/engines/orchestrate-engine.js.map +1 -0
- package/dist/dispatch/engines/pipeline-engine.d.ts +51 -0
- package/dist/dispatch/engines/pipeline-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/pipeline-engine.js +191 -0
- package/dist/dispatch/engines/pipeline-engine.js.map +1 -0
- package/dist/dispatch/engines/release-engine.d.ts +94 -0
- package/dist/dispatch/engines/release-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/release-engine.js +763 -0
- package/dist/dispatch/engines/release-engine.js.map +1 -0
- package/dist/dispatch/engines/session-engine.d.ts +383 -0
- package/dist/dispatch/engines/session-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/session-engine.js +960 -0
- package/dist/dispatch/engines/session-engine.js.map +1 -0
- package/dist/dispatch/engines/sticky-engine.d.ts +100 -0
- package/dist/dispatch/engines/sticky-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/sticky-engine.js +181 -0
- package/dist/dispatch/engines/sticky-engine.js.map +1 -0
- package/dist/dispatch/engines/system-engine.d.ts +539 -0
- package/dist/dispatch/engines/system-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/system-engine.js +1266 -0
- package/dist/dispatch/engines/system-engine.js.map +1 -0
- package/dist/dispatch/engines/task-engine.d.ts +1055 -0
- package/dist/dispatch/engines/task-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/task-engine.js +1387 -0
- package/dist/dispatch/engines/task-engine.js.map +1 -0
- package/dist/dispatch/engines/template-parser.d.ts +85 -0
- package/dist/dispatch/engines/template-parser.d.ts.map +1 -0
- package/dist/dispatch/engines/template-parser.js +108 -0
- package/dist/dispatch/engines/template-parser.js.map +1 -0
- package/dist/dispatch/engines/tools-engine.d.ts +270 -0
- package/dist/dispatch/engines/tools-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/tools-engine.js +636 -0
- package/dist/dispatch/engines/tools-engine.js.map +1 -0
- package/dist/dispatch/engines/validate-engine.d.ts +218 -0
- package/dist/dispatch/engines/validate-engine.d.ts.map +1 -0
- package/dist/dispatch/engines/validate-engine.js +737 -0
- package/dist/dispatch/engines/validate-engine.js.map +1 -0
- package/dist/dispatch/index.d.ts +20 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/index.js +19 -0
- package/dist/dispatch/index.js.map +1 -0
- package/dist/dispatch/lib/background-jobs.d.ts +86 -0
- package/dist/dispatch/lib/background-jobs.d.ts.map +1 -0
- package/dist/dispatch/lib/background-jobs.js +183 -0
- package/dist/dispatch/lib/background-jobs.js.map +1 -0
- package/dist/dispatch/lib/budget.d.ts +35 -0
- package/dist/dispatch/lib/budget.d.ts.map +1 -0
- package/dist/dispatch/lib/budget.js +102 -0
- package/dist/dispatch/lib/budget.js.map +1 -0
- package/dist/dispatch/lib/capability-matrix.d.ts +11 -0
- package/dist/dispatch/lib/capability-matrix.d.ts.map +1 -0
- package/dist/dispatch/lib/capability-matrix.js +10 -0
- package/dist/dispatch/lib/capability-matrix.js.map +1 -0
- package/dist/dispatch/lib/config-loader.d.ts +42 -0
- package/dist/dispatch/lib/config-loader.d.ts.map +1 -0
- package/dist/dispatch/lib/config-loader.js +217 -0
- package/dist/dispatch/lib/config-loader.js.map +1 -0
- package/dist/dispatch/lib/config.d.ts +11 -0
- package/dist/dispatch/lib/config.d.ts.map +1 -0
- package/dist/dispatch/lib/config.js +10 -0
- package/dist/dispatch/lib/config.js.map +1 -0
- package/dist/dispatch/lib/defaults.d.ts +117 -0
- package/dist/dispatch/lib/defaults.d.ts.map +1 -0
- package/dist/dispatch/lib/defaults.js +58 -0
- package/dist/dispatch/lib/defaults.js.map +1 -0
- package/dist/dispatch/lib/engine.d.ts +26 -0
- package/dist/dispatch/lib/engine.d.ts.map +1 -0
- package/dist/dispatch/lib/engine.js +46 -0
- package/dist/dispatch/lib/engine.js.map +1 -0
- package/dist/dispatch/lib/gateway-meta.d.ts +37 -0
- package/dist/dispatch/lib/gateway-meta.d.ts.map +1 -0
- package/dist/dispatch/lib/gateway-meta.js +50 -0
- package/dist/dispatch/lib/gateway-meta.js.map +1 -0
- package/dist/dispatch/lib/job-manager-accessor.d.ts +9 -0
- package/dist/dispatch/lib/job-manager-accessor.d.ts.map +1 -0
- package/dist/dispatch/lib/job-manager-accessor.js +13 -0
- package/dist/dispatch/lib/job-manager-accessor.js.map +1 -0
- package/dist/dispatch/lib/meta.d.ts +26 -0
- package/dist/dispatch/lib/meta.d.ts.map +1 -0
- package/dist/dispatch/lib/meta.js +37 -0
- package/dist/dispatch/lib/meta.js.map +1 -0
- package/dist/dispatch/lib/param-utils.d.ts +11 -0
- package/dist/dispatch/lib/param-utils.d.ts.map +1 -0
- package/dist/dispatch/lib/param-utils.js +10 -0
- package/dist/dispatch/lib/param-utils.js.map +1 -0
- package/dist/dispatch/lib/projections.d.ts +56 -0
- package/dist/dispatch/lib/projections.d.ts.map +1 -0
- package/dist/dispatch/lib/projections.js +65 -0
- package/dist/dispatch/lib/projections.js.map +1 -0
- package/dist/dispatch/lib/schema-utils.d.ts +39 -0
- package/dist/dispatch/lib/schema-utils.d.ts.map +1 -0
- package/dist/dispatch/lib/schema-utils.js +88 -0
- package/dist/dispatch/lib/schema-utils.js.map +1 -0
- package/dist/dispatch/lib/security.d.ts +11 -0
- package/dist/dispatch/lib/security.d.ts.map +1 -0
- package/dist/dispatch/lib/security.js +10 -0
- package/dist/dispatch/lib/security.js.map +1 -0
- package/dist/dispatch/middleware/audit.d.ts +23 -0
- package/dist/dispatch/middleware/audit.d.ts.map +1 -0
- package/dist/dispatch/middleware/audit.js +169 -0
- package/dist/dispatch/middleware/audit.js.map +1 -0
- package/dist/dispatch/middleware/field-filter.d.ts +24 -0
- package/dist/dispatch/middleware/field-filter.d.ts.map +1 -0
- package/dist/dispatch/middleware/field-filter.js +65 -0
- package/dist/dispatch/middleware/field-filter.js.map +1 -0
- package/dist/dispatch/middleware/pipeline.d.ts +33 -0
- package/dist/dispatch/middleware/pipeline.d.ts.map +1 -0
- package/dist/dispatch/middleware/pipeline.js +60 -0
- package/dist/dispatch/middleware/pipeline.js.map +1 -0
- package/dist/dispatch/middleware/projection.d.ts +35 -0
- package/dist/dispatch/middleware/projection.d.ts.map +1 -0
- package/dist/dispatch/middleware/projection.js +146 -0
- package/dist/dispatch/middleware/projection.js.map +1 -0
- package/dist/dispatch/middleware/protocol-enforcement.d.ts +27 -0
- package/dist/dispatch/middleware/protocol-enforcement.d.ts.map +1 -0
- package/dist/dispatch/middleware/protocol-enforcement.js +45 -0
- package/dist/dispatch/middleware/protocol-enforcement.js.map +1 -0
- package/dist/dispatch/middleware/rate-limiter.d.ts +72 -0
- package/dist/dispatch/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/dispatch/middleware/rate-limiter.js +127 -0
- package/dist/dispatch/middleware/rate-limiter.js.map +1 -0
- package/dist/dispatch/middleware/sanitizer.d.ts +24 -0
- package/dist/dispatch/middleware/sanitizer.d.ts.map +1 -0
- package/dist/dispatch/middleware/sanitizer.js +56 -0
- package/dist/dispatch/middleware/sanitizer.js.map +1 -0
- package/dist/dispatch/middleware/session-resolver.d.ts +26 -0
- package/dist/dispatch/middleware/session-resolver.d.ts.map +1 -0
- package/dist/dispatch/middleware/session-resolver.js +65 -0
- package/dist/dispatch/middleware/session-resolver.js.map +1 -0
- package/dist/dispatch/middleware/verification-gates.d.ts +22 -0
- package/dist/dispatch/middleware/verification-gates.d.ts.map +1 -0
- package/dist/dispatch/middleware/verification-gates.js +59 -0
- package/dist/dispatch/middleware/verification-gates.js.map +1 -0
- package/dist/dispatch/registry.d.ts +91 -0
- package/dist/dispatch/registry.d.ts.map +1 -0
- package/dist/dispatch/registry.js +3133 -0
- package/dist/dispatch/registry.js.map +1 -0
- package/dist/dispatch/types.d.ts +202 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/dispatch/types.js +26 -0
- package/dist/dispatch/types.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,1125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI agent command group — agent credential management (unified registry).
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* cleo agent register — register a new agent credential
|
|
6
|
+
* cleo agent list — list all registered agent credentials
|
|
7
|
+
* cleo agent get <id> — get a specific agent credential
|
|
8
|
+
* cleo agent remove <id> — remove an agent credential
|
|
9
|
+
* cleo agent rotate-key <id> — rotate an agent's API key
|
|
10
|
+
* cleo agent poll — one-shot message check
|
|
11
|
+
* cleo agent send — send a message to an agent or conversation
|
|
12
|
+
* cleo agent start — start the daemon poller for an agent
|
|
13
|
+
*
|
|
14
|
+
* **Daemon vs. Pi session — important distinction.** The daemon spawned
|
|
15
|
+
* by `cleo agent start` ONLY polls SignalDock for inbound messages and
|
|
16
|
+
* keeps the cloud status indicator green. It does NOT execute CANT
|
|
17
|
+
* workflow profiles inside the daemon process. CANT workflow execution
|
|
18
|
+
* (sessions, parallel arms, conditionals, approval gates, discretion
|
|
19
|
+
* evaluation, etc.) lives entirely inside the
|
|
20
|
+
* `cant-bridge.ts` Pi extension at
|
|
21
|
+
* `packages/cleo/templates/cleoos-hub/pi-extensions/cant-bridge.ts`,
|
|
22
|
+
* which interprets `.cant` files via shell-out to the `cleo cant`
|
|
23
|
+
* command family. Operators who want profile-driven behaviour should
|
|
24
|
+
* start a Pi session and use `/cant:load <file>` followed by
|
|
25
|
+
* `/cant:run <file> <workflowName>`. The daemon and the Pi session are
|
|
26
|
+
* distinct runtimes with distinct purposes, by design (see ADR-035 §D5
|
|
27
|
+
* "Option Y" addendum).
|
|
28
|
+
*
|
|
29
|
+
* @see docs/specs/SIGNALDOCK-UNIFIED-AGENT-REGISTRY.md Section 3.4
|
|
30
|
+
* @see .cleo/adrs/ADR-035-pi-v2-v3-harness.md §D5 + Addendum
|
|
31
|
+
* @task T178
|
|
32
|
+
*/
|
|
33
|
+
import { checkAgentHealth, detectCrashedAgents, detectStaleAgents, getHealthReport, STALE_THRESHOLD_MS, } from '@cleocode/core/internal';
|
|
34
|
+
import { cliOutput } from '../renderers/index.js';
|
|
35
|
+
import { computeProfileStatus } from './agent-profile-status.js';
|
|
36
|
+
/**
|
|
37
|
+
* Register the `cleo agent` command group.
|
|
38
|
+
*/
|
|
39
|
+
export function registerAgentCommand(program) {
|
|
40
|
+
const agent = program.command('agent').description('Agent lifecycle, credentials, and messaging');
|
|
41
|
+
// --- cleo agent register ---
|
|
42
|
+
agent
|
|
43
|
+
.command('register')
|
|
44
|
+
.description('Register a new agent credential in the local registry')
|
|
45
|
+
.requiredOption('--id <agentId>', 'Unique agent identifier')
|
|
46
|
+
.requiredOption('--name <displayName>', 'Human-readable display name')
|
|
47
|
+
.requiredOption('--api-key <apiKey>', 'API key (sk_live_...)')
|
|
48
|
+
.option('--api-url <url>', 'API base URL', 'https://api.signaldock.io')
|
|
49
|
+
.option('--classification <class>', 'Agent classification (e.g. code_dev, orchestrator)')
|
|
50
|
+
.option('--privacy <tier>', 'Privacy tier: public, discoverable, private', 'public')
|
|
51
|
+
.action(async (opts) => {
|
|
52
|
+
try {
|
|
53
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
54
|
+
await getDb();
|
|
55
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
56
|
+
const agentId = opts['id'];
|
|
57
|
+
const displayName = opts['name'];
|
|
58
|
+
const classification = opts['classification'];
|
|
59
|
+
const credential = await registry.register({
|
|
60
|
+
agentId,
|
|
61
|
+
displayName,
|
|
62
|
+
apiKey: opts['apiKey'],
|
|
63
|
+
apiBaseUrl: opts['apiUrl'] ?? 'https://api.signaldock.io',
|
|
64
|
+
classification,
|
|
65
|
+
privacyTier: opts['privacy'] ?? 'public',
|
|
66
|
+
capabilities: [],
|
|
67
|
+
skills: [],
|
|
68
|
+
transportType: 'http',
|
|
69
|
+
transportConfig: {},
|
|
70
|
+
isActive: true,
|
|
71
|
+
});
|
|
72
|
+
// Scaffold .cant persona file if it doesn't exist
|
|
73
|
+
const { existsSync, mkdirSync, writeFileSync } = await import('node:fs');
|
|
74
|
+
const { join } = await import('node:path');
|
|
75
|
+
const cantDir = join('.cleo', 'agents');
|
|
76
|
+
const cantPath = join(cantDir, `${agentId}.cant`);
|
|
77
|
+
let cantScaffolded = false;
|
|
78
|
+
if (!existsSync(cantPath)) {
|
|
79
|
+
mkdirSync(cantDir, { recursive: true });
|
|
80
|
+
const role = classification ?? 'specialist';
|
|
81
|
+
const cantContent = `---
|
|
82
|
+
kind: agent
|
|
83
|
+
version: 2
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
agent ${agentId}:
|
|
87
|
+
house: none
|
|
88
|
+
allegiance: canon
|
|
89
|
+
role: ${role}
|
|
90
|
+
parent: cleoos-opus-orchestrator
|
|
91
|
+
description: "${displayName}"
|
|
92
|
+
|
|
93
|
+
tone:
|
|
94
|
+
|
|
|
95
|
+
TODO: Describe how this agent communicates.
|
|
96
|
+
|
|
97
|
+
prompt:
|
|
98
|
+
|
|
|
99
|
+
TODO: Write the core behavioral instruction.
|
|
100
|
+
|
|
101
|
+
skills: [ct-cleo]
|
|
102
|
+
|
|
103
|
+
permissions:
|
|
104
|
+
tasks: read
|
|
105
|
+
session: read
|
|
106
|
+
memory: read
|
|
107
|
+
|
|
108
|
+
transport:
|
|
109
|
+
primary: local
|
|
110
|
+
fallback: sse
|
|
111
|
+
cloud: http
|
|
112
|
+
apiBaseUrl: https://api.signaldock.io
|
|
113
|
+
|
|
114
|
+
lifecycle:
|
|
115
|
+
start: cleo agent start ${agentId}
|
|
116
|
+
stop: cleo agent stop ${agentId}
|
|
117
|
+
status: cleo agent status ${agentId}
|
|
118
|
+
|
|
119
|
+
context:
|
|
120
|
+
active-tasks
|
|
121
|
+
memory-bridge
|
|
122
|
+
|
|
123
|
+
on SessionStart:
|
|
124
|
+
/checkin @all #online
|
|
125
|
+
|
|
126
|
+
enforcement:
|
|
127
|
+
1: TODO — what does this agent push back on?
|
|
128
|
+
`;
|
|
129
|
+
writeFileSync(cantPath, cantContent, 'utf-8');
|
|
130
|
+
cantScaffolded = true;
|
|
131
|
+
}
|
|
132
|
+
cliOutput({
|
|
133
|
+
success: true,
|
|
134
|
+
data: {
|
|
135
|
+
agentId: credential.agentId,
|
|
136
|
+
displayName: credential.displayName,
|
|
137
|
+
cantFile: cantScaffolded ? cantPath : existsSync(cantPath) ? cantPath : null,
|
|
138
|
+
cantScaffolded,
|
|
139
|
+
},
|
|
140
|
+
}, { command: 'agent register' });
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
cliOutput({ success: false, error: { code: 'E_REGISTER', message: String(err) } }, { command: 'agent register' });
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// --- cleo agent signin ---
|
|
148
|
+
agent
|
|
149
|
+
.command('signin <agentId>')
|
|
150
|
+
.description('Sign in as an agent — marks active, caches credentials for session')
|
|
151
|
+
.option('--api-url <url>', 'Override API base URL for cloud status update')
|
|
152
|
+
.action(async (agentId, opts) => {
|
|
153
|
+
try {
|
|
154
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
155
|
+
await getDb();
|
|
156
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
157
|
+
// Look up the credential
|
|
158
|
+
const credential = await registry.get(agentId);
|
|
159
|
+
if (!credential) {
|
|
160
|
+
cliOutput({
|
|
161
|
+
success: false,
|
|
162
|
+
error: {
|
|
163
|
+
code: 'E_NOT_FOUND',
|
|
164
|
+
message: `Agent '${agentId}' not registered. Run: cleo agent register --id ${agentId} --name "..." --api-key sk_live_...`,
|
|
165
|
+
},
|
|
166
|
+
}, { command: 'agent signin' });
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Mark as active + update lastUsedAt
|
|
171
|
+
await registry.update(agentId, { isActive: true });
|
|
172
|
+
await registry.markUsed(agentId);
|
|
173
|
+
// Attempt to set online status on cloud (best-effort, don't fail if offline)
|
|
174
|
+
const apiUrl = opts['apiUrl'] ?? credential.apiBaseUrl;
|
|
175
|
+
try {
|
|
176
|
+
await fetch(`${apiUrl}/agents/${agentId}/status`, {
|
|
177
|
+
method: 'PUT',
|
|
178
|
+
headers: {
|
|
179
|
+
'Content-Type': 'application/json',
|
|
180
|
+
Authorization: `Bearer ${credential.apiKey}`,
|
|
181
|
+
'X-Agent-Id': agentId,
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({ status: 'online' }),
|
|
184
|
+
signal: AbortSignal.timeout(5000),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Offline is fine — LocalTransport works without cloud
|
|
189
|
+
}
|
|
190
|
+
cliOutput({
|
|
191
|
+
success: true,
|
|
192
|
+
data: {
|
|
193
|
+
agentId: credential.agentId,
|
|
194
|
+
displayName: credential.displayName,
|
|
195
|
+
apiBaseUrl: apiUrl,
|
|
196
|
+
status: 'online',
|
|
197
|
+
transport: 'local',
|
|
198
|
+
},
|
|
199
|
+
}, { command: 'agent signin' });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
cliOutput({ success: false, error: { code: 'E_SIGNIN', message: String(err) } }, { command: 'agent signin' });
|
|
203
|
+
process.exitCode = 1;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
// --- cleo agent start ---
|
|
207
|
+
// Boot the SignalDock-poller daemon for an agent.
|
|
208
|
+
//
|
|
209
|
+
// Profile handling:
|
|
210
|
+
// The `--cant <file>` option (or the default
|
|
211
|
+
// `.cleo/agents/<agentId>.cant` lookup) is read for two reasons:
|
|
212
|
+
//
|
|
213
|
+
// 1. **Fail-fast validation**: if the file exists and the optional
|
|
214
|
+
// `@cleocode/cant` validator is available in this build, the
|
|
215
|
+
// file is parsed so malformed profiles surface as a status
|
|
216
|
+
// string rather than blowing up later.
|
|
217
|
+
// 2. **Status surface**: the resulting status (`validated`,
|
|
218
|
+
// `invalid (N errors)`, `loaded (unvalidated)`, or `none`) is
|
|
219
|
+
// reported in the LAFS envelope so operators know the daemon
|
|
220
|
+
// saw the file they expected.
|
|
221
|
+
//
|
|
222
|
+
// The profile string is then DROPPED. The daemon does NOT execute
|
|
223
|
+
// workflow profiles. Profile-driven behaviour (sessions, parallel
|
|
224
|
+
// arms, conditionals, approval gates, discretion evaluation) runs
|
|
225
|
+
// inside Pi sessions through the `cant-bridge.ts` Pi extension at
|
|
226
|
+
// `packages/cleo/templates/cleoos-hub/pi-extensions/cant-bridge.ts`.
|
|
227
|
+
// Operators who want profile execution should start a Pi session
|
|
228
|
+
// and run `/cant:load <file>` followed by
|
|
229
|
+
// `/cant:run <file> <workflowName>`.
|
|
230
|
+
//
|
|
231
|
+
// See ADR-035 §D5 (Option Y addendum) for the architectural
|
|
232
|
+
// rationale: there is exactly ONE workflow execution engine in
|
|
233
|
+
// CleoOS — `cant-bridge.ts` — and it lives inside Pi by design.
|
|
234
|
+
agent
|
|
235
|
+
.command('start <agentId>')
|
|
236
|
+
.description('Start an agent daemon — polls SignalDock for messages. Profile is validated for fail-fast feedback only; CANT execution lives in Pi via cant-bridge.ts.')
|
|
237
|
+
.option('--cant <file>', 'Path to .cant persona file (validated only, NOT executed by the daemon)')
|
|
238
|
+
.option('--poll-interval <ms>', 'Poll interval in milliseconds', '5000')
|
|
239
|
+
.option('--no-heartbeat', 'Disable heartbeat service')
|
|
240
|
+
.action(async (agentId, opts) => {
|
|
241
|
+
try {
|
|
242
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
243
|
+
const { createRuntime } = await import('@cleocode/runtime');
|
|
244
|
+
const { existsSync, readFileSync } = await import('node:fs');
|
|
245
|
+
const { join } = await import('node:path');
|
|
246
|
+
await getDb();
|
|
247
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
248
|
+
// 1. Look up credential
|
|
249
|
+
const credential = await registry.get(agentId);
|
|
250
|
+
if (!credential) {
|
|
251
|
+
cliOutput({
|
|
252
|
+
success: false,
|
|
253
|
+
error: {
|
|
254
|
+
code: 'E_NOT_FOUND',
|
|
255
|
+
message: `Agent '${agentId}' not registered. Run: cleo agent register --id ${agentId} --name "..." --api-key sk_live_...`,
|
|
256
|
+
},
|
|
257
|
+
}, { command: 'agent start' });
|
|
258
|
+
process.exitCode = 1;
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// 2. Read and (best-effort) validate the .cant profile.
|
|
262
|
+
// This is FAIL-FAST GUARDING ONLY. The profile string is
|
|
263
|
+
// used to compute a status field below, then dropped. The
|
|
264
|
+
// daemon does not interpret the workflow body — see the
|
|
265
|
+
// block comment above this command for why.
|
|
266
|
+
let profile = null;
|
|
267
|
+
let cantValidation = null;
|
|
268
|
+
const cantPath = opts['cant'] ?? join('.cleo', 'agents', `${agentId}.cant`);
|
|
269
|
+
if (existsSync(cantPath)) {
|
|
270
|
+
profile = readFileSync(cantPath, 'utf-8');
|
|
271
|
+
try {
|
|
272
|
+
const cantModule = await import('@cleocode/cant');
|
|
273
|
+
// validate() may not be available in all builds of @cleocode/cant
|
|
274
|
+
const validate = 'validate' in cantModule
|
|
275
|
+
? cantModule.validate
|
|
276
|
+
: null;
|
|
277
|
+
if (validate) {
|
|
278
|
+
const result = validate(profile);
|
|
279
|
+
cantValidation = {
|
|
280
|
+
valid: result.valid,
|
|
281
|
+
errors: result.diagnostics?.map((d) => d.message) ?? [],
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// cant-napi not available — profile loaded but unvalidated
|
|
287
|
+
cantValidation = null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// 3. Mark active + update lastUsedAt
|
|
291
|
+
await registry.update(agentId, { isActive: true });
|
|
292
|
+
await registry.markUsed(agentId);
|
|
293
|
+
// 4. Set cloud status (best-effort)
|
|
294
|
+
try {
|
|
295
|
+
await fetch(`${credential.apiBaseUrl}/agents/${agentId}/status`, {
|
|
296
|
+
method: 'PUT',
|
|
297
|
+
headers: {
|
|
298
|
+
'Content-Type': 'application/json',
|
|
299
|
+
Authorization: `Bearer ${credential.apiKey}`,
|
|
300
|
+
'X-Agent-Id': agentId,
|
|
301
|
+
},
|
|
302
|
+
body: JSON.stringify({ status: 'online' }),
|
|
303
|
+
signal: AbortSignal.timeout(5000),
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// Offline is fine — LocalTransport works without cloud
|
|
308
|
+
}
|
|
309
|
+
// 5. Start runtime services (transport auto-resolved: Local > SSE > HTTP).
|
|
310
|
+
// Note: createRuntime() does NOT receive the profile. The
|
|
311
|
+
// daemon's job is purely SignalDock polling + cloud status.
|
|
312
|
+
const pollInterval = Number(opts['pollInterval'] ?? 5000);
|
|
313
|
+
const runtime = await createRuntime(registry, {
|
|
314
|
+
agentId,
|
|
315
|
+
pollIntervalMs: pollInterval,
|
|
316
|
+
heartbeatIntervalMs: opts['heartbeat'] === false ? 0 : 30000,
|
|
317
|
+
groupConversationIds: [],
|
|
318
|
+
});
|
|
319
|
+
runtime.poller.start();
|
|
320
|
+
cliOutput({
|
|
321
|
+
success: true,
|
|
322
|
+
data: {
|
|
323
|
+
agentId,
|
|
324
|
+
displayName: credential.displayName,
|
|
325
|
+
status: 'online',
|
|
326
|
+
transport: runtime.transport.name,
|
|
327
|
+
// Surfaced for operator visibility only — see
|
|
328
|
+
// computeProfileStatus tsdoc for the four possible values.
|
|
329
|
+
profile: computeProfileStatus(profile, cantValidation),
|
|
330
|
+
services: {
|
|
331
|
+
poller: 'running',
|
|
332
|
+
heartbeat: runtime.heartbeat ? 'running' : 'disabled',
|
|
333
|
+
keyRotation: runtime.keyRotation ? 'running' : 'disabled',
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
}, { command: 'agent start' });
|
|
337
|
+
// 6. Keep process alive until shutdown signal (cross-platform)
|
|
338
|
+
const shutdown = () => {
|
|
339
|
+
runtime.stop();
|
|
340
|
+
void registry.update(agentId, { isActive: false }).catch(() => { });
|
|
341
|
+
process.exit(0);
|
|
342
|
+
};
|
|
343
|
+
process.on('SIGINT', shutdown);
|
|
344
|
+
process.on('SIGTERM', shutdown);
|
|
345
|
+
// Windows: listen for 'message' from parent process managers (PM2, etc.)
|
|
346
|
+
if (process.platform === 'win32') {
|
|
347
|
+
process.on('message', (msg) => {
|
|
348
|
+
if (msg === 'shutdown')
|
|
349
|
+
shutdown();
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
// Keep alive
|
|
353
|
+
await new Promise(() => { });
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
cliOutput({ success: false, error: { code: 'E_START', message: String(err) } }, { command: 'agent start' });
|
|
357
|
+
process.exitCode = 1;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
// --- cleo agent stop ---
|
|
361
|
+
agent
|
|
362
|
+
.command('stop <agentId>')
|
|
363
|
+
.description('Stop an agent — mark offline and deactivate')
|
|
364
|
+
.action(async (agentId) => {
|
|
365
|
+
try {
|
|
366
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
367
|
+
await getDb();
|
|
368
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
369
|
+
const credential = await registry.get(agentId);
|
|
370
|
+
if (!credential) {
|
|
371
|
+
cliOutput({
|
|
372
|
+
success: false,
|
|
373
|
+
error: { code: 'E_NOT_FOUND', message: `Agent '${agentId}' not registered.` },
|
|
374
|
+
}, { command: 'agent stop' });
|
|
375
|
+
process.exitCode = 1;
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
// Mark inactive
|
|
379
|
+
await registry.update(agentId, { isActive: false });
|
|
380
|
+
// Set cloud status offline (best-effort)
|
|
381
|
+
try {
|
|
382
|
+
await fetch(`${credential.apiBaseUrl}/agents/${agentId}/status`, {
|
|
383
|
+
method: 'PUT',
|
|
384
|
+
headers: {
|
|
385
|
+
'Content-Type': 'application/json',
|
|
386
|
+
Authorization: `Bearer ${credential.apiKey}`,
|
|
387
|
+
'X-Agent-Id': agentId,
|
|
388
|
+
},
|
|
389
|
+
body: JSON.stringify({ status: 'offline' }),
|
|
390
|
+
signal: AbortSignal.timeout(5000),
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
// Offline is fine
|
|
395
|
+
}
|
|
396
|
+
cliOutput({ success: true, data: { agentId, status: 'offline' } }, { command: 'agent stop' });
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
cliOutput({ success: false, error: { code: 'E_STOP', message: String(err) } }, { command: 'agent stop' });
|
|
400
|
+
process.exitCode = 1;
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
// --- cleo agent status ---
|
|
404
|
+
agent
|
|
405
|
+
.command('status [agentId]')
|
|
406
|
+
.description('Show agent status — all agents or specific agent')
|
|
407
|
+
.action(async (agentId) => {
|
|
408
|
+
try {
|
|
409
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
410
|
+
await getDb();
|
|
411
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
412
|
+
if (agentId) {
|
|
413
|
+
const credential = await registry.get(agentId);
|
|
414
|
+
if (!credential) {
|
|
415
|
+
cliOutput({
|
|
416
|
+
success: false,
|
|
417
|
+
error: { code: 'E_NOT_FOUND', message: `Agent '${agentId}' not registered.` },
|
|
418
|
+
}, { command: 'agent status' });
|
|
419
|
+
process.exitCode = 1;
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
cliOutput({
|
|
423
|
+
success: true,
|
|
424
|
+
data: {
|
|
425
|
+
agentId: credential.agentId,
|
|
426
|
+
displayName: credential.displayName,
|
|
427
|
+
active: credential.isActive,
|
|
428
|
+
lastUsedAt: credential.lastUsedAt,
|
|
429
|
+
transport: credential.transportType,
|
|
430
|
+
},
|
|
431
|
+
}, { command: 'agent status' });
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
const agents = await registry.list();
|
|
435
|
+
cliOutput({
|
|
436
|
+
success: true,
|
|
437
|
+
data: {
|
|
438
|
+
agents: agents.map((a) => ({
|
|
439
|
+
agentId: a.agentId,
|
|
440
|
+
displayName: a.displayName,
|
|
441
|
+
active: a.isActive,
|
|
442
|
+
lastUsedAt: a.lastUsedAt,
|
|
443
|
+
})),
|
|
444
|
+
total: agents.length,
|
|
445
|
+
},
|
|
446
|
+
}, { command: 'agent status' });
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch (err) {
|
|
450
|
+
cliOutput({ success: false, error: { code: 'E_STATUS', message: String(err) } }, { command: 'agent status' });
|
|
451
|
+
process.exitCode = 1;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
// --- cleo agent assign ---
|
|
455
|
+
agent
|
|
456
|
+
.command('assign <agentId> <taskId>')
|
|
457
|
+
.description('Assign a task to an agent via messaging')
|
|
458
|
+
.action(async (agentId, taskId) => {
|
|
459
|
+
try {
|
|
460
|
+
const { AgentRegistryAccessor, getDb, createConduit } = await import('@cleocode/core/internal');
|
|
461
|
+
await getDb();
|
|
462
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
463
|
+
const active = await registry.getActive();
|
|
464
|
+
if (!active) {
|
|
465
|
+
cliOutput({
|
|
466
|
+
success: false,
|
|
467
|
+
error: {
|
|
468
|
+
code: 'E_NO_ACTIVE',
|
|
469
|
+
message: 'No active agent. Run: cleo agent signin <id>',
|
|
470
|
+
},
|
|
471
|
+
}, { command: 'agent assign' });
|
|
472
|
+
process.exitCode = 1;
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const conduit = await createConduit(registry);
|
|
476
|
+
await conduit.send(agentId, `/action @${agentId} #task-assignment\n\nAssigned task ${taskId}. Run: cleo show ${taskId} && cleo start ${taskId}`);
|
|
477
|
+
await conduit.disconnect();
|
|
478
|
+
cliOutput({
|
|
479
|
+
success: true,
|
|
480
|
+
data: { agentId, taskId, assignedBy: active.agentId },
|
|
481
|
+
}, { command: 'agent assign' });
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
cliOutput({ success: false, error: { code: 'E_ASSIGN', message: String(err) } }, { command: 'agent assign' });
|
|
485
|
+
process.exitCode = 1;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
// --- cleo agent wake ---
|
|
489
|
+
agent
|
|
490
|
+
.command('wake <agentId>')
|
|
491
|
+
.description('Wake an idle agent — send a prod message')
|
|
492
|
+
.action(async (agentId) => {
|
|
493
|
+
try {
|
|
494
|
+
const { AgentRegistryAccessor, getDb, createConduit } = await import('@cleocode/core/internal');
|
|
495
|
+
await getDb();
|
|
496
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
497
|
+
const active = await registry.getActive();
|
|
498
|
+
if (!active) {
|
|
499
|
+
cliOutput({
|
|
500
|
+
success: false,
|
|
501
|
+
error: {
|
|
502
|
+
code: 'E_NO_ACTIVE',
|
|
503
|
+
message: 'No active agent. Run: cleo agent signin <id>',
|
|
504
|
+
},
|
|
505
|
+
}, { command: 'agent wake' });
|
|
506
|
+
process.exitCode = 1;
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
const conduit = await createConduit(registry);
|
|
510
|
+
await conduit.send(agentId, `/action @${agentId} #wake #prod\n\nYou are idle. Check your queue: cleo current || cleo next. Report status immediately.`);
|
|
511
|
+
await conduit.disconnect();
|
|
512
|
+
cliOutput({ success: true, data: { agentId, prodBy: active.agentId } }, { command: 'agent wake' });
|
|
513
|
+
}
|
|
514
|
+
catch (err) {
|
|
515
|
+
cliOutput({ success: false, error: { code: 'E_WAKE', message: String(err) } }, { command: 'agent wake' });
|
|
516
|
+
process.exitCode = 1;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
// --- cleo agent spawn ---
|
|
520
|
+
agent
|
|
521
|
+
.command('spawn')
|
|
522
|
+
.description('Spawn a new ephemeral agent for a specific task')
|
|
523
|
+
.requiredOption('--role <role>', 'Agent role (e.g. code_dev, research, security)')
|
|
524
|
+
.option('--task <taskId>', 'Task to assign to the spawned agent')
|
|
525
|
+
.option('--model <model>', 'Model to use (e.g. opus, sonnet)')
|
|
526
|
+
.option('--name <name>', 'Display name for the agent')
|
|
527
|
+
.action(async (opts) => {
|
|
528
|
+
try {
|
|
529
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
530
|
+
await getDb();
|
|
531
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
532
|
+
const role = opts['role'];
|
|
533
|
+
const taskId = opts['task'];
|
|
534
|
+
const model = opts['model'] ?? 'sonnet';
|
|
535
|
+
const displayName = opts['name'] ?? `ephemeral-${role}-${Date.now().toString(36)}`;
|
|
536
|
+
const agentId = displayName;
|
|
537
|
+
// Register the ephemeral agent locally (no cloud registration)
|
|
538
|
+
await registry.register({
|
|
539
|
+
agentId,
|
|
540
|
+
displayName,
|
|
541
|
+
apiKey: 'ephemeral-local-only',
|
|
542
|
+
apiBaseUrl: 'local',
|
|
543
|
+
classification: role,
|
|
544
|
+
privacyTier: 'private',
|
|
545
|
+
capabilities: ['chat', 'tools'],
|
|
546
|
+
skills: [role],
|
|
547
|
+
transportType: 'http',
|
|
548
|
+
transportConfig: {},
|
|
549
|
+
isActive: true,
|
|
550
|
+
});
|
|
551
|
+
cliOutput({
|
|
552
|
+
success: true,
|
|
553
|
+
data: {
|
|
554
|
+
agentId,
|
|
555
|
+
displayName,
|
|
556
|
+
role,
|
|
557
|
+
model,
|
|
558
|
+
taskId: taskId ?? null,
|
|
559
|
+
transport: 'local',
|
|
560
|
+
lifecycle: 'ephemeral',
|
|
561
|
+
},
|
|
562
|
+
}, { command: 'agent spawn' });
|
|
563
|
+
}
|
|
564
|
+
catch (err) {
|
|
565
|
+
cliOutput({ success: false, error: { code: 'E_SPAWN', message: String(err) } }, { command: 'agent spawn' });
|
|
566
|
+
process.exitCode = 1;
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
// --- cleo agent reassign ---
|
|
570
|
+
agent
|
|
571
|
+
.command('reassign <taskId> <agentId>')
|
|
572
|
+
.description('Reassign a task to another agent via conduit message')
|
|
573
|
+
.action(async (taskId, agentId) => {
|
|
574
|
+
try {
|
|
575
|
+
const { AgentRegistryAccessor, getDb, createConduit } = await import('@cleocode/core/internal');
|
|
576
|
+
await getDb();
|
|
577
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
578
|
+
const active = await registry.getActive();
|
|
579
|
+
if (!active) {
|
|
580
|
+
cliOutput({ success: false, error: { code: 'E_NO_ACTIVE', message: 'No active agent.' } }, { command: 'agent reassign' });
|
|
581
|
+
process.exitCode = 1;
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
const conduit = await createConduit(registry);
|
|
585
|
+
await conduit.send(agentId, `/action @${agentId} #task-reassignment\n\nTask ${taskId} reassigned to you by ${active.agentId}. Run: cleo show ${taskId} && cleo start ${taskId}`);
|
|
586
|
+
await conduit.disconnect();
|
|
587
|
+
cliOutput({ success: true, data: { taskId, newOwner: agentId, reassignedBy: active.agentId } }, { command: 'agent reassign' });
|
|
588
|
+
}
|
|
589
|
+
catch (err) {
|
|
590
|
+
cliOutput({ success: false, error: { code: 'E_REASSIGN', message: String(err) } }, { command: 'agent reassign' });
|
|
591
|
+
process.exitCode = 1;
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
// --- cleo agent stop-all ---
|
|
595
|
+
agent
|
|
596
|
+
.command('stop-all')
|
|
597
|
+
.description('Stop all active agents — mark all offline')
|
|
598
|
+
.action(async () => {
|
|
599
|
+
try {
|
|
600
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
601
|
+
await getDb();
|
|
602
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
603
|
+
const agents = await registry.list({ active: true });
|
|
604
|
+
let stopped = 0;
|
|
605
|
+
for (const a of agents) {
|
|
606
|
+
await registry.update(a.agentId, { isActive: false });
|
|
607
|
+
try {
|
|
608
|
+
await fetch(`${a.apiBaseUrl}/agents/${a.agentId}/status`, {
|
|
609
|
+
method: 'PUT',
|
|
610
|
+
headers: {
|
|
611
|
+
'Content-Type': 'application/json',
|
|
612
|
+
Authorization: `Bearer ${a.apiKey}`,
|
|
613
|
+
'X-Agent-Id': a.agentId,
|
|
614
|
+
},
|
|
615
|
+
body: JSON.stringify({ status: 'offline' }),
|
|
616
|
+
signal: AbortSignal.timeout(3000),
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
catch {
|
|
620
|
+
/* best-effort */
|
|
621
|
+
}
|
|
622
|
+
stopped++;
|
|
623
|
+
}
|
|
624
|
+
cliOutput({ success: true, data: { stopped, total: agents.length } }, { command: 'agent stop-all' });
|
|
625
|
+
}
|
|
626
|
+
catch (err) {
|
|
627
|
+
cliOutput({ success: false, error: { code: 'E_STOP_ALL', message: String(err) } }, { command: 'agent stop-all' });
|
|
628
|
+
process.exitCode = 1;
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
// --- cleo agent work ---
|
|
632
|
+
agent
|
|
633
|
+
.command('work <agentId>')
|
|
634
|
+
.description('Enter autonomous work loop — poll tasks, report, optionally execute. Phase 3: --execute enables the Conductor Loop.')
|
|
635
|
+
.option('--poll-interval <ms>', 'Task check interval in milliseconds', '30000')
|
|
636
|
+
.option('--execute', 'Autonomously execute ready tasks via orchestrate.spawn.execute (Phase 3 Conductor Loop)')
|
|
637
|
+
.option('--adapter <id>', 'Adapter id to route spawns through (default: auto-detect from capabilities)')
|
|
638
|
+
.option('--epic <id>', 'Restrict autonomous execution to a specific epic (default: any ready task)')
|
|
639
|
+
.action(async (agentId, opts) => {
|
|
640
|
+
try {
|
|
641
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
642
|
+
const { createRuntime } = await import('@cleocode/runtime');
|
|
643
|
+
const { existsSync } = await import('node:fs');
|
|
644
|
+
const { join } = await import('node:path');
|
|
645
|
+
const { execFile } = await import('node:child_process');
|
|
646
|
+
const { promisify } = await import('node:util');
|
|
647
|
+
const execFileAsync = promisify(execFile);
|
|
648
|
+
await getDb();
|
|
649
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
650
|
+
const credential = await registry.get(agentId);
|
|
651
|
+
if (!credential) {
|
|
652
|
+
cliOutput({
|
|
653
|
+
success: false,
|
|
654
|
+
error: { code: 'E_NOT_FOUND', message: `Agent '${agentId}' not registered.` },
|
|
655
|
+
}, { command: 'agent work' });
|
|
656
|
+
process.exitCode = 1;
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
await registry.update(agentId, { isActive: true });
|
|
660
|
+
await registry.markUsed(agentId);
|
|
661
|
+
const cantPath = join('.cleo', 'agents', `${agentId}.cant`);
|
|
662
|
+
const hasProfile = existsSync(cantPath);
|
|
663
|
+
const runtime = await createRuntime(registry, {
|
|
664
|
+
agentId,
|
|
665
|
+
pollIntervalMs: 5000,
|
|
666
|
+
heartbeatIntervalMs: 30000,
|
|
667
|
+
});
|
|
668
|
+
runtime.poller.start();
|
|
669
|
+
const executeMode = opts['execute'] === true;
|
|
670
|
+
const epicRestrict = typeof opts['epic'] === 'string' ? opts['epic'] : undefined;
|
|
671
|
+
const adapterRestrict = typeof opts['adapter'] === 'string' ? opts['adapter'] : undefined;
|
|
672
|
+
cliOutput({
|
|
673
|
+
success: true,
|
|
674
|
+
data: {
|
|
675
|
+
agentId,
|
|
676
|
+
mode: executeMode ? 'conductor-loop' : 'watch-only',
|
|
677
|
+
profile: hasProfile ? 'loaded' : 'none',
|
|
678
|
+
status: 'running',
|
|
679
|
+
epic: epicRestrict ?? 'any',
|
|
680
|
+
adapter: adapterRestrict ?? 'auto',
|
|
681
|
+
},
|
|
682
|
+
}, { command: 'agent work' });
|
|
683
|
+
// Parse LAFS envelope from CLI stdout (handles both minimal and full shapes)
|
|
684
|
+
const parseLafs = (raw) => {
|
|
685
|
+
const lines = raw.trim().split('\n');
|
|
686
|
+
const envLine = [...lines].reverse().find((l) => l.startsWith('{'));
|
|
687
|
+
if (!envLine)
|
|
688
|
+
return undefined;
|
|
689
|
+
try {
|
|
690
|
+
const env = JSON.parse(envLine);
|
|
691
|
+
if (env.ok === true)
|
|
692
|
+
return env.r;
|
|
693
|
+
if (env.success === true)
|
|
694
|
+
return (env.result ?? env.data);
|
|
695
|
+
return undefined;
|
|
696
|
+
}
|
|
697
|
+
catch {
|
|
698
|
+
return undefined;
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
const runCleo = async (args, timeoutMs = 15000) => {
|
|
702
|
+
const { stdout } = await execFileAsync('cleo', args, {
|
|
703
|
+
encoding: 'utf-8',
|
|
704
|
+
timeout: timeoutMs,
|
|
705
|
+
});
|
|
706
|
+
return stdout;
|
|
707
|
+
};
|
|
708
|
+
const taskInterval = Number(opts['pollInterval'] ?? 30000);
|
|
709
|
+
let inFlight = false;
|
|
710
|
+
let iterations = 0;
|
|
711
|
+
const workLoop = setInterval(async () => {
|
|
712
|
+
if (inFlight)
|
|
713
|
+
return;
|
|
714
|
+
inFlight = true;
|
|
715
|
+
iterations += 1;
|
|
716
|
+
try {
|
|
717
|
+
const currentRaw = await runCleo(['current']).catch(() => '');
|
|
718
|
+
if (currentRaw.trim()) {
|
|
719
|
+
// A task is already in progress — skip
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
// Resolve next ready task (respect epic restriction when set)
|
|
723
|
+
const nextArgs = epicRestrict ? ['orchestrate', 'next', epicRestrict] : ['next'];
|
|
724
|
+
const nextRaw = await runCleo(nextArgs).catch(() => '');
|
|
725
|
+
if (!nextRaw.trim())
|
|
726
|
+
return;
|
|
727
|
+
const nextData = parseLafs(nextRaw);
|
|
728
|
+
const taskId = nextData?.nextTask?.id ??
|
|
729
|
+
(typeof nextData?.id === 'string' ? nextData.id : undefined);
|
|
730
|
+
if (!taskId)
|
|
731
|
+
return;
|
|
732
|
+
if (!executeMode) {
|
|
733
|
+
// Watch-only legacy behaviour: advertise availability
|
|
734
|
+
console.log(`[${agentId}] Task available: ${taskId}. Pass --execute to run autonomously.`);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
// Phase 3 Conductor Loop: actually execute via orchestrate.spawn.execute
|
|
738
|
+
const spawnArgs = ['orchestrate', 'spawn', taskId];
|
|
739
|
+
if (adapterRestrict) {
|
|
740
|
+
spawnArgs.push('--adapter', adapterRestrict);
|
|
741
|
+
}
|
|
742
|
+
const spawnRaw = await runCleo(spawnArgs, 60000).catch((e) => {
|
|
743
|
+
console.error(`[${agentId}] conductor-loop: spawn failed for ${taskId}: ${String(e)}`);
|
|
744
|
+
return '';
|
|
745
|
+
});
|
|
746
|
+
const spawnData = parseLafs(spawnRaw);
|
|
747
|
+
if (spawnData?.instanceId) {
|
|
748
|
+
console.log(`[${agentId}] conductor-loop spawned task=${taskId} instance=${spawnData.instanceId} status=${spawnData.status ?? 'unknown'}`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
catch {
|
|
752
|
+
/* non-fatal — loop continues */
|
|
753
|
+
}
|
|
754
|
+
finally {
|
|
755
|
+
inFlight = false;
|
|
756
|
+
}
|
|
757
|
+
}, taskInterval);
|
|
758
|
+
const shutdown = () => {
|
|
759
|
+
clearInterval(workLoop);
|
|
760
|
+
runtime.stop();
|
|
761
|
+
void registry.update(agentId, { isActive: false }).catch(() => { });
|
|
762
|
+
if (executeMode) {
|
|
763
|
+
console.log(`[${agentId}] conductor-loop shutdown after ${iterations} iterations.`);
|
|
764
|
+
}
|
|
765
|
+
process.exit(0);
|
|
766
|
+
};
|
|
767
|
+
process.on('SIGINT', shutdown);
|
|
768
|
+
process.on('SIGTERM', shutdown);
|
|
769
|
+
if (process.platform === 'win32') {
|
|
770
|
+
process.on('message', (msg) => {
|
|
771
|
+
if (msg === 'shutdown')
|
|
772
|
+
shutdown();
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
await new Promise(() => { });
|
|
776
|
+
}
|
|
777
|
+
catch (err) {
|
|
778
|
+
cliOutput({ success: false, error: { code: 'E_WORK', message: String(err) } }, { command: 'agent work' });
|
|
779
|
+
process.exitCode = 1;
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
// --- cleo agent list ---
|
|
783
|
+
agent
|
|
784
|
+
.command('list')
|
|
785
|
+
.description('List all registered agent credentials')
|
|
786
|
+
.option('--active', 'Show only active agents')
|
|
787
|
+
.action(async (opts) => {
|
|
788
|
+
try {
|
|
789
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
790
|
+
await getDb();
|
|
791
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
792
|
+
const filter = opts['active'] ? { active: true } : undefined;
|
|
793
|
+
const agents = await registry.list(filter);
|
|
794
|
+
cliOutput({
|
|
795
|
+
success: true,
|
|
796
|
+
data: agents.map((a) => ({
|
|
797
|
+
agentId: a.agentId,
|
|
798
|
+
displayName: a.displayName,
|
|
799
|
+
apiBaseUrl: a.apiBaseUrl,
|
|
800
|
+
classification: a.classification,
|
|
801
|
+
isActive: a.isActive,
|
|
802
|
+
lastUsedAt: a.lastUsedAt,
|
|
803
|
+
})),
|
|
804
|
+
}, { command: 'agent list' });
|
|
805
|
+
}
|
|
806
|
+
catch (err) {
|
|
807
|
+
cliOutput({ success: false, error: { code: 'E_LIST', message: String(err) } }, { command: 'agent list' });
|
|
808
|
+
process.exitCode = 1;
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
// --- cleo agent get <id> ---
|
|
812
|
+
agent
|
|
813
|
+
.command('get <agentId>')
|
|
814
|
+
.description('Get details for a specific agent credential')
|
|
815
|
+
.action(async (agentId) => {
|
|
816
|
+
try {
|
|
817
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
818
|
+
await getDb();
|
|
819
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
820
|
+
const credential = await registry.get(agentId);
|
|
821
|
+
if (!credential) {
|
|
822
|
+
cliOutput({
|
|
823
|
+
success: false,
|
|
824
|
+
error: { code: 'E_NOT_FOUND', message: `Agent not found: ${agentId}` },
|
|
825
|
+
}, { command: 'agent get' });
|
|
826
|
+
process.exitCode = 4;
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
// Redact API key in output
|
|
830
|
+
cliOutput({
|
|
831
|
+
success: true,
|
|
832
|
+
data: {
|
|
833
|
+
...credential,
|
|
834
|
+
apiKey: credential.apiKey.length > 16
|
|
835
|
+
? `${credential.apiKey.substring(0, 12)}...${credential.apiKey.substring(credential.apiKey.length - 4)}`
|
|
836
|
+
: '***redacted***',
|
|
837
|
+
},
|
|
838
|
+
}, { command: 'agent get' });
|
|
839
|
+
}
|
|
840
|
+
catch (err) {
|
|
841
|
+
cliOutput({ success: false, error: { code: 'E_GET', message: String(err) } }, { command: 'agent get' });
|
|
842
|
+
process.exitCode = 1;
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
// --- cleo agent remove <id> ---
|
|
846
|
+
agent
|
|
847
|
+
.command('remove <agentId>')
|
|
848
|
+
.description('Remove an agent credential from the local registry')
|
|
849
|
+
.action(async (agentId) => {
|
|
850
|
+
try {
|
|
851
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
852
|
+
await getDb();
|
|
853
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
854
|
+
await registry.remove(agentId);
|
|
855
|
+
cliOutput({ success: true, data: { agentId, removed: true } }, { command: 'agent remove' });
|
|
856
|
+
}
|
|
857
|
+
catch (err) {
|
|
858
|
+
cliOutput({ success: false, error: { code: 'E_REMOVE', message: String(err) } }, { command: 'agent remove' });
|
|
859
|
+
process.exitCode = 1;
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
// --- cleo agent rotate-key <id> ---
|
|
863
|
+
agent
|
|
864
|
+
.command('rotate-key <agentId>')
|
|
865
|
+
.description('Rotate an agent API key (generates new key on cloud, re-encrypts locally)')
|
|
866
|
+
.action(async (agentId) => {
|
|
867
|
+
try {
|
|
868
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
869
|
+
await getDb();
|
|
870
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
871
|
+
const result = await registry.rotateKey(agentId);
|
|
872
|
+
cliOutput({
|
|
873
|
+
success: true,
|
|
874
|
+
data: {
|
|
875
|
+
agentId: result.agentId,
|
|
876
|
+
newApiKey: `${result.newApiKey.substring(0, 12)}...`,
|
|
877
|
+
message: 'API key rotated. Old key is invalidated.',
|
|
878
|
+
},
|
|
879
|
+
}, { command: 'agent rotate-key' });
|
|
880
|
+
}
|
|
881
|
+
catch (err) {
|
|
882
|
+
cliOutput({ success: false, error: { code: 'E_ROTATE', message: String(err) } }, { command: 'agent rotate-key' });
|
|
883
|
+
process.exitCode = 1;
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
// --- cleo agent claim-code <id> ---
|
|
887
|
+
agent
|
|
888
|
+
.command('claim-code <agentId>')
|
|
889
|
+
.description('Generate a claim code for human ownership of an agent')
|
|
890
|
+
.action(async (agentId) => {
|
|
891
|
+
try {
|
|
892
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
893
|
+
await getDb();
|
|
894
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
895
|
+
const credential = await registry.get(agentId);
|
|
896
|
+
if (!credential) {
|
|
897
|
+
cliOutput({
|
|
898
|
+
success: false,
|
|
899
|
+
error: { code: 'E_NOT_FOUND', message: `Agent not found: ${agentId}` },
|
|
900
|
+
}, { command: 'agent claim-code' });
|
|
901
|
+
process.exitCode = 4;
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
const response = await fetch(`${credential.apiBaseUrl}/agents/${agentId}/claim-code`, {
|
|
905
|
+
method: 'POST',
|
|
906
|
+
headers: {
|
|
907
|
+
'Content-Type': 'application/json',
|
|
908
|
+
Authorization: `Bearer ${credential.apiKey}`,
|
|
909
|
+
'X-Agent-Id': agentId,
|
|
910
|
+
},
|
|
911
|
+
});
|
|
912
|
+
if (!response.ok) {
|
|
913
|
+
const text = await response.text().catch(() => '');
|
|
914
|
+
throw new Error(`Failed to generate claim code: ${response.status} ${text}`);
|
|
915
|
+
}
|
|
916
|
+
const data = (await response.json());
|
|
917
|
+
cliOutput({
|
|
918
|
+
success: true,
|
|
919
|
+
data: {
|
|
920
|
+
agentId,
|
|
921
|
+
claimCode: data.data?.claimCode,
|
|
922
|
+
claimUrl: data.data?.claimUrl ?? `https://signaldock.io/claim/${data.data?.claimCode}`,
|
|
923
|
+
expiresAt: data.data?.expiresAt,
|
|
924
|
+
message: 'Share this claim code with the human owner to verify agent ownership.',
|
|
925
|
+
},
|
|
926
|
+
}, { command: 'agent claim-code' });
|
|
927
|
+
}
|
|
928
|
+
catch (err) {
|
|
929
|
+
cliOutput({ success: false, error: { code: 'E_CLAIM', message: String(err) } }, { command: 'agent claim-code' });
|
|
930
|
+
process.exitCode = 1;
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
// --- cleo agent watch ---
|
|
934
|
+
agent
|
|
935
|
+
.command('watch')
|
|
936
|
+
.description('Start continuous message polling for the active agent (long-running)')
|
|
937
|
+
.option('--agent <id>', 'Agent ID to watch as (defaults to most recently used)')
|
|
938
|
+
.option('--interval <ms>', 'Poll interval in milliseconds', '5000')
|
|
939
|
+
.option('--group <ids>', 'Comma-separated group conversation IDs to monitor')
|
|
940
|
+
.action(async (opts) => {
|
|
941
|
+
try {
|
|
942
|
+
const { AgentRegistryAccessor, getDb } = await import('@cleocode/core/internal');
|
|
943
|
+
const { createRuntime } = await import('@cleocode/runtime');
|
|
944
|
+
await getDb();
|
|
945
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
946
|
+
const groupIds = opts['group']
|
|
947
|
+
? opts['group'].split(',').map((s) => s.trim())
|
|
948
|
+
: undefined;
|
|
949
|
+
const handle = await createRuntime(registry, {
|
|
950
|
+
agentId: opts['agent'],
|
|
951
|
+
pollIntervalMs: Number(opts['interval']) || 5000,
|
|
952
|
+
groupConversationIds: groupIds,
|
|
953
|
+
});
|
|
954
|
+
handle.poller.onMessage((msg) => {
|
|
955
|
+
cliOutput({
|
|
956
|
+
success: true,
|
|
957
|
+
data: {
|
|
958
|
+
event: 'message',
|
|
959
|
+
id: msg.id,
|
|
960
|
+
from: msg.from,
|
|
961
|
+
content: msg.content,
|
|
962
|
+
threadId: msg.threadId,
|
|
963
|
+
timestamp: msg.timestamp,
|
|
964
|
+
},
|
|
965
|
+
}, { command: 'agent watch' });
|
|
966
|
+
});
|
|
967
|
+
handle.poller.start();
|
|
968
|
+
cliOutput({
|
|
969
|
+
success: true,
|
|
970
|
+
data: {
|
|
971
|
+
event: 'started',
|
|
972
|
+
agentId: handle.agentId,
|
|
973
|
+
pollIntervalMs: Number(opts['interval']) || 5000,
|
|
974
|
+
groupConversationIds: groupIds ?? [],
|
|
975
|
+
message: 'Watching for messages. Press Ctrl+C to stop.',
|
|
976
|
+
},
|
|
977
|
+
}, { command: 'agent watch' });
|
|
978
|
+
// Keep alive until SIGINT/SIGTERM
|
|
979
|
+
const shutdown = () => {
|
|
980
|
+
handle.stop();
|
|
981
|
+
cliOutput({ success: true, data: { event: 'stopped', agentId: handle.agentId } }, { command: 'agent watch' });
|
|
982
|
+
process.exit(0);
|
|
983
|
+
};
|
|
984
|
+
process.on('SIGINT', shutdown);
|
|
985
|
+
process.on('SIGTERM', shutdown);
|
|
986
|
+
if (process.platform === 'win32') {
|
|
987
|
+
process.on('message', (msg) => {
|
|
988
|
+
if (msg === 'shutdown')
|
|
989
|
+
shutdown();
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
catch (err) {
|
|
994
|
+
cliOutput({ success: false, error: { code: 'E_WATCH', message: String(err) } }, { command: 'agent watch' });
|
|
995
|
+
process.exitCode = 1;
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
// --- cleo agent poll ---
|
|
999
|
+
agent
|
|
1000
|
+
.command('poll')
|
|
1001
|
+
.description('One-shot message check for the active agent')
|
|
1002
|
+
.option('--agent <id>', 'Agent ID to poll as (defaults to most recently used)')
|
|
1003
|
+
.option('--limit <n>', 'Max messages to fetch', '20')
|
|
1004
|
+
.action(async (opts) => {
|
|
1005
|
+
try {
|
|
1006
|
+
const { AgentRegistryAccessor, createConduit, getDb } = await import('@cleocode/core/internal');
|
|
1007
|
+
await getDb();
|
|
1008
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
1009
|
+
const agentId = opts['agent'];
|
|
1010
|
+
const conduit = await createConduit(registry, agentId);
|
|
1011
|
+
const limit = Number(opts['limit']) || 20;
|
|
1012
|
+
const messages = await conduit.poll({ limit });
|
|
1013
|
+
cliOutput({
|
|
1014
|
+
success: true,
|
|
1015
|
+
data: { agentId: conduit.agentId, messages, count: messages.length, limit },
|
|
1016
|
+
}, { command: 'agent poll' });
|
|
1017
|
+
await conduit.disconnect();
|
|
1018
|
+
}
|
|
1019
|
+
catch (err) {
|
|
1020
|
+
cliOutput({ success: false, error: { code: 'E_POLL', message: String(err) } }, { command: 'agent poll' });
|
|
1021
|
+
process.exitCode = 1;
|
|
1022
|
+
}
|
|
1023
|
+
});
|
|
1024
|
+
// --- cleo agent send ---
|
|
1025
|
+
agent
|
|
1026
|
+
.command('send <message>')
|
|
1027
|
+
.description('Send a message to an agent or conversation')
|
|
1028
|
+
.option('--to <agentId>', 'Target agent ID')
|
|
1029
|
+
.option('--conv <conversationId>', 'Target conversation ID')
|
|
1030
|
+
.option('--agent <id>', 'Send as this agent (defaults to most recently used)')
|
|
1031
|
+
.action(async (message, opts) => {
|
|
1032
|
+
try {
|
|
1033
|
+
const { AgentRegistryAccessor, createConduit, getDb } = await import('@cleocode/core/internal');
|
|
1034
|
+
await getDb();
|
|
1035
|
+
const registry = new AgentRegistryAccessor(process.cwd());
|
|
1036
|
+
const agentId = opts['agent'];
|
|
1037
|
+
const to = opts['to'];
|
|
1038
|
+
const conv = opts['conv'];
|
|
1039
|
+
if (!to && !conv) {
|
|
1040
|
+
cliOutput({ success: false, error: { code: 'E_ARGS', message: 'Must specify --to or --conv' } }, { command: 'agent send' });
|
|
1041
|
+
process.exitCode = 1;
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
const conduit = await createConduit(registry, agentId);
|
|
1045
|
+
const result = await conduit.send(to ?? conv ?? '', message, {
|
|
1046
|
+
threadId: conv,
|
|
1047
|
+
});
|
|
1048
|
+
cliOutput({ success: true, data: { messageId: result.messageId, deliveredAt: result.deliveredAt } }, { command: 'agent send' });
|
|
1049
|
+
await conduit.disconnect();
|
|
1050
|
+
}
|
|
1051
|
+
catch (err) {
|
|
1052
|
+
cliOutput({ success: false, error: { code: 'E_SEND', message: String(err) } }, { command: 'agent send' });
|
|
1053
|
+
process.exitCode = 1;
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
1056
|
+
// --- cleo agent health ---
|
|
1057
|
+
agent
|
|
1058
|
+
.command('health')
|
|
1059
|
+
.description('Check agent health and detect stale or crashed agents')
|
|
1060
|
+
.option('--id <agentId>', 'Check health for a specific agent ID')
|
|
1061
|
+
.option('--threshold <ms>', 'Staleness threshold in milliseconds (default: 180000 = 3 minutes)', String(STALE_THRESHOLD_MS))
|
|
1062
|
+
.option('--detect-crashed', 'Detect and mark crashed agents (write operation)')
|
|
1063
|
+
.action(async (opts) => {
|
|
1064
|
+
const thresholdMs = typeof opts['threshold'] === 'string' ? Number(opts['threshold']) : STALE_THRESHOLD_MS;
|
|
1065
|
+
const agentId = opts['id'];
|
|
1066
|
+
const detectCrashed = Boolean(opts['detectCrashed']);
|
|
1067
|
+
if (agentId) {
|
|
1068
|
+
const health = await checkAgentHealth(agentId, thresholdMs);
|
|
1069
|
+
if (!health) {
|
|
1070
|
+
cliOutput({
|
|
1071
|
+
success: false,
|
|
1072
|
+
error: { code: 'E_NOT_FOUND', message: `Agent not found: ${agentId}` },
|
|
1073
|
+
}, { command: 'agent health' });
|
|
1074
|
+
process.exitCode = 4;
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
cliOutput({ success: true, data: health }, { command: 'agent health' });
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
if (detectCrashed) {
|
|
1081
|
+
const crashed = await detectCrashedAgents(thresholdMs);
|
|
1082
|
+
cliOutput({
|
|
1083
|
+
success: true,
|
|
1084
|
+
data: {
|
|
1085
|
+
detectedCrashed: crashed.length,
|
|
1086
|
+
agents: crashed.map((a) => ({
|
|
1087
|
+
id: a.id,
|
|
1088
|
+
agentType: a.agentType,
|
|
1089
|
+
lastHeartbeat: a.lastHeartbeat,
|
|
1090
|
+
status: a.status,
|
|
1091
|
+
})),
|
|
1092
|
+
},
|
|
1093
|
+
}, { command: 'agent health' });
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
const [report, stale] = await Promise.all([
|
|
1097
|
+
getHealthReport(thresholdMs),
|
|
1098
|
+
detectStaleAgents(thresholdMs),
|
|
1099
|
+
]);
|
|
1100
|
+
cliOutput({
|
|
1101
|
+
success: true,
|
|
1102
|
+
data: {
|
|
1103
|
+
summary: {
|
|
1104
|
+
total: report.total,
|
|
1105
|
+
active: report.active,
|
|
1106
|
+
idle: report.idle,
|
|
1107
|
+
starting: report.starting,
|
|
1108
|
+
error: report.error,
|
|
1109
|
+
crashed: report.crashed,
|
|
1110
|
+
stopped: report.stopped,
|
|
1111
|
+
totalErrors: report.totalErrors,
|
|
1112
|
+
},
|
|
1113
|
+
staleAgents: stale.map((s) => ({
|
|
1114
|
+
id: s.agentId,
|
|
1115
|
+
status: s.status,
|
|
1116
|
+
heartbeatAgeMs: s.heartbeatAgeMs,
|
|
1117
|
+
lastHeartbeat: s.lastHeartbeat,
|
|
1118
|
+
thresholdMs: s.thresholdMs,
|
|
1119
|
+
})),
|
|
1120
|
+
thresholdMs,
|
|
1121
|
+
},
|
|
1122
|
+
}, { command: 'agent health' });
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
//# sourceMappingURL=agent.js.map
|