@cleocode/cleo 2026.5.4 → 2026.5.6
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/index.js +96 -101
- package/dist/cli/index.js.map +3 -3
- package/package.json +9 -9
- package/dist/backfill/audit-columns.d.ts +0 -105
- package/dist/backfill/audit-columns.d.ts.map +0 -1
- package/dist/backfill/audit-columns.js +0 -258
- package/dist/backfill/audit-columns.js.map +0 -1
- package/dist/cli/commands/adapter.d.ts +0 -28
- package/dist/cli/commands/adapter.d.ts.map +0 -1
- package/dist/cli/commands/adapter.js +0 -119
- package/dist/cli/commands/adapter.js.map +0 -1
- package/dist/cli/commands/add-batch.d.ts +0 -33
- package/dist/cli/commands/add-batch.d.ts.map +0 -1
- package/dist/cli/commands/add-batch.js +0 -148
- package/dist/cli/commands/add-batch.js.map +0 -1
- package/dist/cli/commands/add.d.ts +0 -162
- package/dist/cli/commands/add.d.ts.map +0 -1
- package/dist/cli/commands/add.js +0 -279
- package/dist/cli/commands/add.js.map +0 -1
- package/dist/cli/commands/admin.d.ts +0 -24
- package/dist/cli/commands/admin.d.ts.map +0 -1
- package/dist/cli/commands/admin.js +0 -283
- package/dist/cli/commands/admin.js.map +0 -1
- package/dist/cli/commands/adr.d.ts +0 -33
- package/dist/cli/commands/adr.d.ts.map +0 -1
- package/dist/cli/commands/adr.js +0 -147
- package/dist/cli/commands/adr.js.map +0 -1
- package/dist/cli/commands/agent-profile-status.d.ts +0 -98
- package/dist/cli/commands/agent-profile-status.d.ts.map +0 -1
- package/dist/cli/commands/agent-profile-status.js +0 -71
- package/dist/cli/commands/agent-profile-status.js.map +0 -1
- package/dist/cli/commands/agent.d.ts +0 -47
- package/dist/cli/commands/agent.d.ts.map +0 -1
- package/dist/cli/commands/agent.js +0 -2976
- package/dist/cli/commands/agent.js.map +0 -1
- package/dist/cli/commands/analyze.d.ts +0 -21
- package/dist/cli/commands/analyze.d.ts.map +0 -1
- package/dist/cli/commands/analyze.js +0 -32
- package/dist/cli/commands/analyze.js.map +0 -1
- package/dist/cli/commands/archive-stats.d.ts +0 -66
- package/dist/cli/commands/archive-stats.d.ts.map +0 -1
- package/dist/cli/commands/archive-stats.js +0 -93
- package/dist/cli/commands/archive-stats.js.map +0 -1
- package/dist/cli/commands/archive.d.ts +0 -42
- package/dist/cli/commands/archive.d.ts.map +0 -1
- package/dist/cli/commands/archive.js +0 -59
- package/dist/cli/commands/archive.js.map +0 -1
- package/dist/cli/commands/audit.d.ts +0 -22
- package/dist/cli/commands/audit.d.ts.map +0 -1
- package/dist/cli/commands/audit.js +0 -137
- package/dist/cli/commands/audit.js.map +0 -1
- package/dist/cli/commands/backfill.d.ts +0 -56
- package/dist/cli/commands/backfill.d.ts.map +0 -1
- package/dist/cli/commands/backfill.js +0 -161
- package/dist/cli/commands/backfill.js.map +0 -1
- package/dist/cli/commands/backup-inspect.d.ts +0 -33
- package/dist/cli/commands/backup-inspect.d.ts.map +0 -1
- package/dist/cli/commands/backup-inspect.js +0 -430
- package/dist/cli/commands/backup-inspect.js.map +0 -1
- package/dist/cli/commands/backup.d.ts +0 -23
- package/dist/cli/commands/backup.d.ts.map +0 -1
- package/dist/cli/commands/backup.js +0 -564
- package/dist/cli/commands/backup.js.map +0 -1
- package/dist/cli/commands/blockers.d.ts +0 -20
- package/dist/cli/commands/blockers.d.ts.map +0 -1
- package/dist/cli/commands/blockers.js +0 -31
- package/dist/cli/commands/blockers.js.map +0 -1
- package/dist/cli/commands/brain.d.ts +0 -37
- package/dist/cli/commands/brain.d.ts.map +0 -1
- package/dist/cli/commands/brain.js +0 -445
- package/dist/cli/commands/brain.js.map +0 -1
- package/dist/cli/commands/briefing.d.ts +0 -52
- package/dist/cli/commands/briefing.d.ts.map +0 -1
- package/dist/cli/commands/briefing.js +0 -69
- package/dist/cli/commands/briefing.js.map +0 -1
- package/dist/cli/commands/bug.d.ts +0 -61
- package/dist/cli/commands/bug.d.ts.map +0 -1
- package/dist/cli/commands/bug.js +0 -198
- package/dist/cli/commands/bug.js.map +0 -1
- package/dist/cli/commands/cancel.d.ts +0 -26
- package/dist/cli/commands/cancel.d.ts.map +0 -1
- package/dist/cli/commands/cancel.js +0 -40
- package/dist/cli/commands/cancel.js.map +0 -1
- package/dist/cli/commands/cant.d.ts +0 -13
- package/dist/cli/commands/cant.d.ts.map +0 -1
- package/dist/cli/commands/cant.js +0 -245
- package/dist/cli/commands/cant.js.map +0 -1
- package/dist/cli/commands/chain.d.ts +0 -24
- package/dist/cli/commands/chain.d.ts.map +0 -1
- package/dist/cli/commands/chain.js +0 -116
- package/dist/cli/commands/chain.js.map +0 -1
- package/dist/cli/commands/check.d.ts +0 -18
- package/dist/cli/commands/check.d.ts.map +0 -1
- package/dist/cli/commands/check.js +0 -280
- package/dist/cli/commands/check.js.map +0 -1
- package/dist/cli/commands/checkpoint.d.ts +0 -27
- package/dist/cli/commands/checkpoint.d.ts.map +0 -1
- package/dist/cli/commands/checkpoint.js +0 -105
- package/dist/cli/commands/checkpoint.js.map +0 -1
- package/dist/cli/commands/claim.d.ts +0 -35
- package/dist/cli/commands/claim.d.ts.map +0 -1
- package/dist/cli/commands/claim.js +0 -35
- package/dist/cli/commands/claim.js.map +0 -1
- package/dist/cli/commands/code.d.ts +0 -22
- package/dist/cli/commands/code.d.ts.map +0 -1
- package/dist/cli/commands/code.js +0 -161
- package/dist/cli/commands/code.js.map +0 -1
- package/dist/cli/commands/complete.d.ts +0 -58
- package/dist/cli/commands/complete.d.ts.map +0 -1
- package/dist/cli/commands/complete.js +0 -83
- package/dist/cli/commands/complete.js.map +0 -1
- package/dist/cli/commands/complexity.d.ts +0 -13
- package/dist/cli/commands/complexity.d.ts.map +0 -1
- package/dist/cli/commands/complexity.js +0 -32
- package/dist/cli/commands/complexity.js.map +0 -1
- package/dist/cli/commands/compliance.d.ts +0 -27
- package/dist/cli/commands/compliance.d.ts.map +0 -1
- package/dist/cli/commands/compliance.js +0 -233
- package/dist/cli/commands/compliance.js.map +0 -1
- package/dist/cli/commands/conduit.d.ts +0 -28
- package/dist/cli/commands/conduit.d.ts.map +0 -1
- package/dist/cli/commands/conduit.js +0 -279
- package/dist/cli/commands/conduit.js.map +0 -1
- package/dist/cli/commands/config.d.ts +0 -25
- package/dist/cli/commands/config.d.ts.map +0 -1
- package/dist/cli/commands/config.js +0 -132
- package/dist/cli/commands/config.js.map +0 -1
- package/dist/cli/commands/consensus.d.ts +0 -21
- package/dist/cli/commands/consensus.d.ts.map +0 -1
- package/dist/cli/commands/consensus.js +0 -100
- package/dist/cli/commands/consensus.js.map +0 -1
- package/dist/cli/commands/context.d.ts +0 -19
- package/dist/cli/commands/context.d.ts.map +0 -1
- package/dist/cli/commands/context.js +0 -111
- package/dist/cli/commands/context.js.map +0 -1
- package/dist/cli/commands/contribution.d.ts +0 -21
- package/dist/cli/commands/contribution.d.ts.map +0 -1
- package/dist/cli/commands/contribution.js +0 -90
- package/dist/cli/commands/contribution.js.map +0 -1
- package/dist/cli/commands/current.d.ts +0 -18
- package/dist/cli/commands/current.d.ts.map +0 -1
- package/dist/cli/commands/current.js +0 -28
- package/dist/cli/commands/current.js.map +0 -1
- package/dist/cli/commands/daemon.d.ts +0 -36
- package/dist/cli/commands/daemon.d.ts.map +0 -1
- package/dist/cli/commands/daemon.js +0 -223
- package/dist/cli/commands/daemon.js.map +0 -1
- package/dist/cli/commands/dash.d.ts +0 -23
- package/dist/cli/commands/dash.d.ts.map +0 -1
- package/dist/cli/commands/dash.js +0 -38
- package/dist/cli/commands/dash.js.map +0 -1
- package/dist/cli/commands/decomposition.d.ts +0 -13
- package/dist/cli/commands/decomposition.d.ts.map +0 -1
- package/dist/cli/commands/decomposition.js +0 -92
- package/dist/cli/commands/decomposition.js.map +0 -1
- package/dist/cli/commands/delete.d.ts +0 -29
- package/dist/cli/commands/delete.d.ts.map +0 -1
- package/dist/cli/commands/delete.js +0 -55
- package/dist/cli/commands/delete.js.map +0 -1
- package/dist/cli/commands/deps.d.ts +0 -45
- package/dist/cli/commands/deps.d.ts.map +0 -1
- package/dist/cli/commands/deps.js +0 -170
- package/dist/cli/commands/deps.js.map +0 -1
- package/dist/cli/commands/detect-drift.d.ts +0 -23
- package/dist/cli/commands/detect-drift.d.ts.map +0 -1
- package/dist/cli/commands/detect-drift.js +0 -440
- package/dist/cli/commands/detect-drift.js.map +0 -1
- package/dist/cli/commands/detect.d.ts +0 -3
- package/dist/cli/commands/detect.d.ts.map +0 -1
- package/dist/cli/commands/detect.js +0 -14
- package/dist/cli/commands/detect.js.map +0 -1
- package/dist/cli/commands/diagnostics.d.ts +0 -19
- package/dist/cli/commands/diagnostics.d.ts.map +0 -1
- package/dist/cli/commands/diagnostics.js +0 -109
- package/dist/cli/commands/diagnostics.js.map +0 -1
- package/dist/cli/commands/docs.d.ts +0 -25
- package/dist/cli/commands/docs.d.ts.map +0 -1
- package/dist/cli/commands/docs.js +0 -798
- package/dist/cli/commands/docs.js.map +0 -1
- package/dist/cli/commands/doctor-projects.d.ts +0 -101
- package/dist/cli/commands/doctor-projects.d.ts.map +0 -1
- package/dist/cli/commands/doctor-projects.js +0 -188
- package/dist/cli/commands/doctor-projects.js.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -66
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/doctor.js +0 -178
- package/dist/cli/commands/doctor.js.map +0 -1
- package/dist/cli/commands/dynamic.d.ts +0 -15
- package/dist/cli/commands/dynamic.d.ts.map +0 -1
- package/dist/cli/commands/dynamic.js +0 -21
- package/dist/cli/commands/dynamic.js.map +0 -1
- package/dist/cli/commands/exists.d.ts +0 -13
- package/dist/cli/commands/exists.d.ts.map +0 -1
- package/dist/cli/commands/exists.js +0 -40
- package/dist/cli/commands/exists.js.map +0 -1
- package/dist/cli/commands/export-tasks.d.ts +0 -46
- package/dist/cli/commands/export-tasks.d.ts.map +0 -1
- package/dist/cli/commands/export-tasks.js +0 -81
- package/dist/cli/commands/export-tasks.js.map +0 -1
- package/dist/cli/commands/export.d.ts +0 -35
- package/dist/cli/commands/export.d.ts.map +0 -1
- package/dist/cli/commands/export.js +0 -68
- package/dist/cli/commands/export.js.map +0 -1
- package/dist/cli/commands/find.d.ts +0 -54
- package/dist/cli/commands/find.d.ts.map +0 -1
- package/dist/cli/commands/find.js +0 -92
- package/dist/cli/commands/find.js.map +0 -1
- package/dist/cli/commands/gc.d.ts +0 -25
- package/dist/cli/commands/gc.d.ts.map +0 -1
- package/dist/cli/commands/gc.js +0 -165
- package/dist/cli/commands/gc.js.map +0 -1
- package/dist/cli/commands/generate-changelog.d.ts +0 -30
- package/dist/cli/commands/generate-changelog.d.ts.map +0 -1
- package/dist/cli/commands/generate-changelog.js +0 -270
- package/dist/cli/commands/generate-changelog.js.map +0 -1
- package/dist/cli/commands/grade.d.ts +0 -13
- package/dist/cli/commands/grade.d.ts.map +0 -1
- package/dist/cli/commands/grade.js +0 -27
- package/dist/cli/commands/grade.js.map +0 -1
- package/dist/cli/commands/history.d.ts +0 -13
- package/dist/cli/commands/history.d.ts.map +0 -1
- package/dist/cli/commands/history.js +0 -65
- package/dist/cli/commands/history.js.map +0 -1
- package/dist/cli/commands/import-tasks.d.ts +0 -60
- package/dist/cli/commands/import-tasks.d.ts.map +0 -1
- package/dist/cli/commands/import-tasks.js +0 -83
- package/dist/cli/commands/import-tasks.js.map +0 -1
- package/dist/cli/commands/import.d.ts +0 -42
- package/dist/cli/commands/import.d.ts.map +0 -1
- package/dist/cli/commands/import.js +0 -64
- package/dist/cli/commands/import.js.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -65
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -122
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/inject.d.ts +0 -41
- package/dist/cli/commands/inject.d.ts.map +0 -1
- package/dist/cli/commands/inject.js +0 -56
- package/dist/cli/commands/inject.js.map +0 -1
- package/dist/cli/commands/install-global.d.ts +0 -48
- package/dist/cli/commands/install-global.d.ts.map +0 -1
- package/dist/cli/commands/install-global.js +0 -104
- package/dist/cli/commands/install-global.js.map +0 -1
- package/dist/cli/commands/intelligence.d.ts +0 -21
- package/dist/cli/commands/intelligence.d.ts.map +0 -1
- package/dist/cli/commands/intelligence.js +0 -145
- package/dist/cli/commands/intelligence.js.map +0 -1
- package/dist/cli/commands/issue.d.ts +0 -23
- package/dist/cli/commands/issue.d.ts.map +0 -1
- package/dist/cli/commands/issue.js +0 -152
- package/dist/cli/commands/issue.js.map +0 -1
- package/dist/cli/commands/labels.d.ts +0 -21
- package/dist/cli/commands/labels.d.ts.map +0 -1
- package/dist/cli/commands/labels.js +0 -65
- package/dist/cli/commands/labels.js.map +0 -1
- package/dist/cli/commands/lifecycle.d.ts +0 -25
- package/dist/cli/commands/lifecycle.d.ts.map +0 -1
- package/dist/cli/commands/lifecycle.js +0 -221
- package/dist/cli/commands/lifecycle.js.map +0 -1
- package/dist/cli/commands/list.d.ts +0 -28
- package/dist/cli/commands/list.d.ts.map +0 -1
- package/dist/cli/commands/list.js +0 -81
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/log.d.ts +0 -36
- package/dist/cli/commands/log.d.ts.map +0 -1
- package/dist/cli/commands/log.js +0 -50
- package/dist/cli/commands/log.js.map +0 -1
- package/dist/cli/commands/manifest.d.ts +0 -15
- package/dist/cli/commands/manifest.d.ts.map +0 -1
- package/dist/cli/commands/manifest.js +0 -334
- package/dist/cli/commands/manifest.js.map +0 -1
- package/dist/cli/commands/map.d.ts +0 -25
- package/dist/cli/commands/map.d.ts.map +0 -1
- package/dist/cli/commands/map.js +0 -37
- package/dist/cli/commands/map.js.map +0 -1
- package/dist/cli/commands/memory.d.ts +0 -48
- package/dist/cli/commands/memory.d.ts.map +0 -1
- package/dist/cli/commands/memory.js +0 -2439
- package/dist/cli/commands/memory.js.map +0 -1
- package/dist/cli/commands/migrate-claude-mem.d.ts +0 -23
- package/dist/cli/commands/migrate-claude-mem.d.ts.map +0 -1
- package/dist/cli/commands/migrate-claude-mem.js +0 -181
- package/dist/cli/commands/migrate-claude-mem.js.map +0 -1
- package/dist/cli/commands/next.d.ts +0 -27
- package/dist/cli/commands/next.d.ts.map +0 -1
- package/dist/cli/commands/next.js +0 -40
- package/dist/cli/commands/next.js.map +0 -1
- package/dist/cli/commands/nexus.d.ts +0 -15
- package/dist/cli/commands/nexus.d.ts.map +0 -1
- package/dist/cli/commands/nexus.js +0 -3377
- package/dist/cli/commands/nexus.js.map +0 -1
- package/dist/cli/commands/ops.d.ts +0 -23
- package/dist/cli/commands/ops.d.ts.map +0 -1
- package/dist/cli/commands/ops.js +0 -35
- package/dist/cli/commands/ops.js.map +0 -1
- package/dist/cli/commands/orchestrate.d.ts +0 -48
- package/dist/cli/commands/orchestrate.d.ts.map +0 -1
- package/dist/cli/commands/orchestrate.js +0 -774
- package/dist/cli/commands/orchestrate.js.map +0 -1
- package/dist/cli/commands/otel.d.ts +0 -30
- package/dist/cli/commands/otel.d.ts.map +0 -1
- package/dist/cli/commands/otel.js +0 -193
- package/dist/cli/commands/otel.js.map +0 -1
- package/dist/cli/commands/phase.d.ts +0 -29
- package/dist/cli/commands/phase.d.ts.map +0 -1
- package/dist/cli/commands/phase.js +0 -189
- package/dist/cli/commands/phase.js.map +0 -1
- package/dist/cli/commands/pivot.d.ts +0 -34
- package/dist/cli/commands/pivot.d.ts.map +0 -1
- package/dist/cli/commands/pivot.js +0 -50
- package/dist/cli/commands/pivot.js.map +0 -1
- package/dist/cli/commands/plan.d.ts +0 -17
- package/dist/cli/commands/plan.d.ts.map +0 -1
- package/dist/cli/commands/plan.js +0 -27
- package/dist/cli/commands/plan.js.map +0 -1
- package/dist/cli/commands/playbook.d.ts +0 -26
- package/dist/cli/commands/playbook.d.ts.map +0 -1
- package/dist/cli/commands/playbook.js +0 -220
- package/dist/cli/commands/playbook.js.map +0 -1
- package/dist/cli/commands/promote.d.ts +0 -19
- package/dist/cli/commands/promote.d.ts.map +0 -1
- package/dist/cli/commands/promote.js +0 -27
- package/dist/cli/commands/promote.js.map +0 -1
- package/dist/cli/commands/provider.d.ts +0 -23
- package/dist/cli/commands/provider.d.ts.map +0 -1
- package/dist/cli/commands/provider.js +0 -168
- package/dist/cli/commands/provider.js.map +0 -1
- package/dist/cli/commands/reason.d.ts +0 -18
- package/dist/cli/commands/reason.d.ts.map +0 -1
- package/dist/cli/commands/reason.js +0 -102
- package/dist/cli/commands/reason.js.map +0 -1
- package/dist/cli/commands/reconcile.d.ts +0 -35
- package/dist/cli/commands/reconcile.d.ts.map +0 -1
- package/dist/cli/commands/reconcile.js +0 -102
- package/dist/cli/commands/reconcile.js.map +0 -1
- package/dist/cli/commands/refresh-memory.d.ts +0 -16
- package/dist/cli/commands/refresh-memory.d.ts.map +0 -1
- package/dist/cli/commands/refresh-memory.js +0 -34
- package/dist/cli/commands/refresh-memory.js.map +0 -1
- package/dist/cli/commands/relates.d.ts +0 -19
- package/dist/cli/commands/relates.d.ts.map +0 -1
- package/dist/cli/commands/relates.js +0 -129
- package/dist/cli/commands/relates.js.map +0 -1
- package/dist/cli/commands/release.d.ts +0 -27
- package/dist/cli/commands/release.d.ts.map +0 -1
- package/dist/cli/commands/release.js +0 -300
- package/dist/cli/commands/release.js.map +0 -1
- package/dist/cli/commands/remote.d.ts +0 -49
- package/dist/cli/commands/remote.d.ts.map +0 -1
- package/dist/cli/commands/remote.js +0 -265
- package/dist/cli/commands/remote.js.map +0 -1
- package/dist/cli/commands/reorder.d.ts +0 -31
- package/dist/cli/commands/reorder.d.ts.map +0 -1
- package/dist/cli/commands/reorder.js +0 -57
- package/dist/cli/commands/reorder.js.map +0 -1
- package/dist/cli/commands/reparent.d.ts +0 -27
- package/dist/cli/commands/reparent.d.ts.map +0 -1
- package/dist/cli/commands/reparent.js +0 -36
- package/dist/cli/commands/reparent.js.map +0 -1
- package/dist/cli/commands/req.d.ts +0 -37
- package/dist/cli/commands/req.d.ts.map +0 -1
- package/dist/cli/commands/req.js +0 -121
- package/dist/cli/commands/req.js.map +0 -1
- package/dist/cli/commands/research.d.ts +0 -25
- package/dist/cli/commands/research.d.ts.map +0 -1
- package/dist/cli/commands/research.js +0 -327
- package/dist/cli/commands/research.js.map +0 -1
- package/dist/cli/commands/restore.d.ts +0 -64
- package/dist/cli/commands/restore.d.ts.map +0 -1
- package/dist/cli/commands/restore.js +0 -539
- package/dist/cli/commands/restore.js.map +0 -1
- package/dist/cli/commands/revert.d.ts +0 -79
- package/dist/cli/commands/revert.d.ts.map +0 -1
- package/dist/cli/commands/revert.js +0 -300
- package/dist/cli/commands/revert.js.map +0 -1
- package/dist/cli/commands/roadmap.d.ts +0 -29
- package/dist/cli/commands/roadmap.d.ts.map +0 -1
- package/dist/cli/commands/roadmap.js +0 -43
- package/dist/cli/commands/roadmap.js.map +0 -1
- package/dist/cli/commands/safestop.d.ts +0 -41
- package/dist/cli/commands/safestop.d.ts.map +0 -1
- package/dist/cli/commands/safestop.js +0 -62
- package/dist/cli/commands/safestop.js.map +0 -1
- package/dist/cli/commands/schema.d.ts +0 -44
- package/dist/cli/commands/schema.d.ts.map +0 -1
- package/dist/cli/commands/schema.js +0 -177
- package/dist/cli/commands/schema.js.map +0 -1
- package/dist/cli/commands/self-update.d.ts +0 -81
- package/dist/cli/commands/self-update.d.ts.map +0 -1
- package/dist/cli/commands/self-update.js +0 -483
- package/dist/cli/commands/self-update.js.map +0 -1
- package/dist/cli/commands/sentient.d.ts +0 -44
- package/dist/cli/commands/sentient.d.ts.map +0 -1
- package/dist/cli/commands/sentient.js +0 -687
- package/dist/cli/commands/sentient.js.map +0 -1
- package/dist/cli/commands/sequence.d.ts +0 -15
- package/dist/cli/commands/sequence.d.ts.map +0 -1
- package/dist/cli/commands/sequence.js +0 -68
- package/dist/cli/commands/sequence.js.map +0 -1
- package/dist/cli/commands/session.d.ts +0 -32
- package/dist/cli/commands/session.d.ts.map +0 -1
- package/dist/cli/commands/session.js +0 -583
- package/dist/cli/commands/session.js.map +0 -1
- package/dist/cli/commands/show.d.ts +0 -21
- package/dist/cli/commands/show.d.ts.map +0 -1
- package/dist/cli/commands/show.js +0 -37
- package/dist/cli/commands/show.js.map +0 -1
- package/dist/cli/commands/skills.d.ts +0 -31
- package/dist/cli/commands/skills.d.ts.map +0 -1
- package/dist/cli/commands/skills.js +0 -303
- package/dist/cli/commands/skills.js.map +0 -1
- package/dist/cli/commands/snapshot.d.ts +0 -17
- package/dist/cli/commands/snapshot.d.ts.map +0 -1
- package/dist/cli/commands/snapshot.js +0 -95
- package/dist/cli/commands/snapshot.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -21
- package/dist/cli/commands/start.d.ts.map +0 -1
- package/dist/cli/commands/start.js +0 -32
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/stats.d.ts +0 -30
- package/dist/cli/commands/stats.d.ts.map +0 -1
- package/dist/cli/commands/stats.js +0 -71
- package/dist/cli/commands/stats.js.map +0 -1
- package/dist/cli/commands/sticky.d.ts +0 -23
- package/dist/cli/commands/sticky.d.ts.map +0 -1
- package/dist/cli/commands/sticky.js +0 -315
- package/dist/cli/commands/sticky.js.map +0 -1
- package/dist/cli/commands/stop.d.ts +0 -15
- package/dist/cli/commands/stop.d.ts.map +0 -1
- package/dist/cli/commands/stop.js +0 -25
- package/dist/cli/commands/stop.js.map +0 -1
- package/dist/cli/commands/sync.d.ts +0 -25
- package/dist/cli/commands/sync.d.ts.map +0 -1
- package/dist/cli/commands/sync.js +0 -125
- package/dist/cli/commands/sync.js.map +0 -1
- package/dist/cli/commands/testing.d.ts +0 -22
- package/dist/cli/commands/testing.d.ts.map +0 -1
- package/dist/cli/commands/testing.js +0 -111
- package/dist/cli/commands/testing.js.map +0 -1
- package/dist/cli/commands/token.d.ts +0 -22
- package/dist/cli/commands/token.d.ts.map +0 -1
- package/dist/cli/commands/token.js +0 -197
- package/dist/cli/commands/token.js.map +0 -1
- package/dist/cli/commands/transcript.d.ts +0 -32
- package/dist/cli/commands/transcript.d.ts.map +0 -1
- package/dist/cli/commands/transcript.js +0 -526
- package/dist/cli/commands/transcript.js.map +0 -1
- package/dist/cli/commands/update.d.ts +0 -164
- package/dist/cli/commands/update.d.ts.map +0 -1
- package/dist/cli/commands/update.js +0 -234
- package/dist/cli/commands/update.js.map +0 -1
- package/dist/cli/commands/upgrade.d.ts +0 -76
- package/dist/cli/commands/upgrade.d.ts.map +0 -1
- package/dist/cli/commands/upgrade.js +0 -154
- package/dist/cli/commands/upgrade.js.map +0 -1
- package/dist/cli/commands/verify.d.ts +0 -83
- package/dist/cli/commands/verify.d.ts.map +0 -1
- package/dist/cli/commands/verify.js +0 -108
- package/dist/cli/commands/verify.js.map +0 -1
- package/dist/cli/commands/web.d.ts +0 -27
- package/dist/cli/commands/web.d.ts.map +0 -1
- package/dist/cli/commands/web.js +0 -414
- package/dist/cli/commands/web.js.map +0 -1
- package/dist/cli/field-context.d.ts +0 -32
- package/dist/cli/field-context.d.ts.map +0 -1
- package/dist/cli/field-context.js +0 -47
- package/dist/cli/field-context.js.map +0 -1
- package/dist/cli/format-context.d.ts +0 -32
- package/dist/cli/format-context.d.ts.map +0 -1
- package/dist/cli/format-context.js +0 -50
- package/dist/cli/format-context.js.map +0 -1
- package/dist/cli/help-renderer.d.ts +0 -40
- package/dist/cli/help-renderer.d.ts.map +0 -1
- package/dist/cli/help-renderer.js +0 -325
- package/dist/cli/help-renderer.js.map +0 -1
- package/dist/cli/index.d.ts +0 -14
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/infer-files-via-gitnexus.d.ts +0 -12
- package/dist/cli/infer-files-via-gitnexus.d.ts.map +0 -1
- package/dist/cli/infer-files-via-gitnexus.js +0 -12
- package/dist/cli/infer-files-via-gitnexus.js.map +0 -1
- package/dist/cli/lib/did-you-mean.d.ts +0 -30
- package/dist/cli/lib/did-you-mean.d.ts.map +0 -1
- package/dist/cli/lib/did-you-mean.js +0 -63
- package/dist/cli/lib/did-you-mean.js.map +0 -1
- package/dist/cli/lib/registry-args.d.ts +0 -36
- package/dist/cli/lib/registry-args.d.ts.map +0 -1
- package/dist/cli/lib/registry-args.js +0 -37
- package/dist/cli/lib/registry-args.js.map +0 -1
- package/dist/cli/lib/subcommand-guard.d.ts +0 -45
- package/dist/cli/lib/subcommand-guard.d.ts.map +0 -1
- package/dist/cli/lib/subcommand-guard.js +0 -55
- package/dist/cli/lib/subcommand-guard.js.map +0 -1
- package/dist/cli/logger-bootstrap.d.ts +0 -6
- package/dist/cli/logger-bootstrap.d.ts.map +0 -1
- package/dist/cli/logger-bootstrap.js +0 -10
- package/dist/cli/logger-bootstrap.js.map +0 -1
- package/dist/cli/middleware/output-format.d.ts +0 -30
- package/dist/cli/middleware/output-format.d.ts.map +0 -1
- package/dist/cli/middleware/output-format.js +0 -35
- package/dist/cli/middleware/output-format.js.map +0 -1
- package/dist/cli/paths.d.ts +0 -85
- package/dist/cli/paths.d.ts.map +0 -1
- package/dist/cli/paths.js +0 -108
- package/dist/cli/paths.js.map +0 -1
- package/dist/cli/progress.d.ts +0 -89
- package/dist/cli/progress.d.ts.map +0 -1
- package/dist/cli/progress.js +0 -185
- package/dist/cli/progress.js.map +0 -1
- package/dist/cli/renderers/colors.d.ts +0 -32
- package/dist/cli/renderers/colors.d.ts.map +0 -1
- package/dist/cli/renderers/colors.js +0 -141
- package/dist/cli/renderers/colors.js.map +0 -1
- package/dist/cli/renderers/error.d.ts +0 -13
- package/dist/cli/renderers/error.d.ts.map +0 -1
- package/dist/cli/renderers/error.js +0 -42
- package/dist/cli/renderers/error.js.map +0 -1
- package/dist/cli/renderers/index.d.ts +0 -90
- package/dist/cli/renderers/index.d.ts.map +0 -1
- package/dist/cli/renderers/index.js +0 -268
- package/dist/cli/renderers/index.js.map +0 -1
- package/dist/cli/renderers/lafs-validator.d.ts +0 -91
- package/dist/cli/renderers/lafs-validator.d.ts.map +0 -1
- package/dist/cli/renderers/lafs-validator.js +0 -176
- package/dist/cli/renderers/lafs-validator.js.map +0 -1
- package/dist/cli/renderers/normalizer.d.ts +0 -21
- package/dist/cli/renderers/normalizer.d.ts.map +0 -1
- package/dist/cli/renderers/normalizer.js +0 -106
- package/dist/cli/renderers/normalizer.js.map +0 -1
- package/dist/cli/renderers/system.d.ts +0 -110
- package/dist/cli/renderers/system.d.ts.map +0 -1
- package/dist/cli/renderers/system.js +0 -662
- package/dist/cli/renderers/system.js.map +0 -1
- package/dist/cli/renderers/tasks.d.ts +0 -28
- package/dist/cli/renderers/tasks.d.ts.map +0 -1
- package/dist/cli/renderers/tasks.js +0 -306
- package/dist/cli/renderers/tasks.js.map +0 -1
- package/dist/cli/tree-context.d.ts +0 -53
- package/dist/cli/tree-context.d.ts.map +0 -1
- package/dist/cli/tree-context.js +0 -43
- package/dist/cli/tree-context.js.map +0 -1
- package/dist/dispatch/adapters/cli.d.ts +0 -67
- package/dist/dispatch/adapters/cli.d.ts.map +0 -1
- package/dist/dispatch/adapters/cli.js +0 -331
- package/dist/dispatch/adapters/cli.js.map +0 -1
- package/dist/dispatch/adapters/typed.d.ts +0 -362
- package/dist/dispatch/adapters/typed.d.ts.map +0 -1
- package/dist/dispatch/adapters/typed.js +0 -278
- package/dist/dispatch/adapters/typed.js.map +0 -1
- package/dist/dispatch/context/session-context.d.ts +0 -108
- package/dist/dispatch/context/session-context.d.ts.map +0 -1
- package/dist/dispatch/context/session-context.js +0 -111
- package/dist/dispatch/context/session-context.js.map +0 -1
- package/dist/dispatch/dispatcher.d.ts +0 -37
- package/dist/dispatch/dispatcher.d.ts.map +0 -1
- package/dist/dispatch/dispatcher.js +0 -172
- package/dist/dispatch/dispatcher.js.map +0 -1
- package/dist/dispatch/domains/_base.d.ts +0 -104
- package/dist/dispatch/domains/_base.d.ts.map +0 -1
- package/dist/dispatch/domains/_base.js +0 -147
- package/dist/dispatch/domains/_base.js.map +0 -1
- package/dist/dispatch/domains/_meta.d.ts +0 -23
- package/dist/dispatch/domains/_meta.d.ts.map +0 -1
- package/dist/dispatch/domains/_meta.js +0 -25
- package/dist/dispatch/domains/_meta.js.map +0 -1
- package/dist/dispatch/domains/_routing.d.ts +0 -8
- package/dist/dispatch/domains/_routing.d.ts.map +0 -1
- package/dist/dispatch/domains/_routing.js +0 -20
- package/dist/dispatch/domains/_routing.js.map +0 -1
- package/dist/dispatch/domains/admin/smoke-provider.d.ts +0 -54
- package/dist/dispatch/domains/admin/smoke-provider.d.ts.map +0 -1
- package/dist/dispatch/domains/admin/smoke-provider.js +0 -309
- package/dist/dispatch/domains/admin/smoke-provider.js.map +0 -1
- package/dist/dispatch/domains/admin.d.ts +0 -51
- package/dist/dispatch/domains/admin.d.ts.map +0 -1
- package/dist/dispatch/domains/admin.js +0 -1163
- package/dist/dispatch/domains/admin.js.map +0 -1
- package/dist/dispatch/domains/check/canon.d.ts +0 -65
- package/dist/dispatch/domains/check/canon.d.ts.map +0 -1
- package/dist/dispatch/domains/check/canon.js +0 -193
- package/dist/dispatch/domains/check/canon.js.map +0 -1
- package/dist/dispatch/domains/check.d.ts +0 -37
- package/dist/dispatch/domains/check.d.ts.map +0 -1
- package/dist/dispatch/domains/check.js +0 -562
- package/dist/dispatch/domains/check.js.map +0 -1
- package/dist/dispatch/domains/conduit.d.ts +0 -61
- package/dist/dispatch/domains/conduit.d.ts.map +0 -1
- package/dist/dispatch/domains/conduit.js +0 -609
- package/dist/dispatch/domains/conduit.js.map +0 -1
- package/dist/dispatch/domains/diagnostics.d.ts +0 -25
- package/dist/dispatch/domains/diagnostics.d.ts.map +0 -1
- package/dist/dispatch/domains/diagnostics.js +0 -82
- package/dist/dispatch/domains/diagnostics.js.map +0 -1
- package/dist/dispatch/domains/docs.d.ts +0 -63
- package/dist/dispatch/domains/docs.d.ts.map +0 -1
- package/dist/dispatch/domains/docs.js +0 -539
- package/dist/dispatch/domains/docs.js.map +0 -1
- package/dist/dispatch/domains/index.d.ts +0 -33
- package/dist/dispatch/domains/index.d.ts.map +0 -1
- package/dist/dispatch/domains/index.js +0 -58
- package/dist/dispatch/domains/index.js.map +0 -1
- package/dist/dispatch/domains/intelligence.d.ts +0 -26
- package/dist/dispatch/domains/intelligence.d.ts.map +0 -1
- package/dist/dispatch/domains/intelligence.js +0 -154
- package/dist/dispatch/domains/intelligence.js.map +0 -1
- package/dist/dispatch/domains/ivtr.d.ts +0 -182
- package/dist/dispatch/domains/ivtr.d.ts.map +0 -1
- package/dist/dispatch/domains/ivtr.js +0 -430
- package/dist/dispatch/domains/ivtr.js.map +0 -1
- package/dist/dispatch/domains/memory.d.ts +0 -22
- package/dist/dispatch/domains/memory.d.ts.map +0 -1
- package/dist/dispatch/domains/memory.js +0 -1281
- package/dist/dispatch/domains/memory.js.map +0 -1
- package/dist/dispatch/domains/nexus.d.ts +0 -78
- package/dist/dispatch/domains/nexus.d.ts.map +0 -1
- package/dist/dispatch/domains/nexus.js +0 -938
- package/dist/dispatch/domains/nexus.js.map +0 -1
- package/dist/dispatch/domains/orchestrate.d.ts +0 -307
- package/dist/dispatch/domains/orchestrate.d.ts.map +0 -1
- package/dist/dispatch/domains/orchestrate.js +0 -986
- package/dist/dispatch/domains/orchestrate.js.map +0 -1
- package/dist/dispatch/domains/pipeline.d.ts +0 -276
- package/dist/dispatch/domains/pipeline.d.ts.map +0 -1
- package/dist/dispatch/domains/pipeline.js +0 -689
- package/dist/dispatch/domains/pipeline.js.map +0 -1
- package/dist/dispatch/domains/playbook.d.ts +0 -131
- package/dist/dispatch/domains/playbook.d.ts.map +0 -1
- package/dist/dispatch/domains/playbook.js +0 -633
- package/dist/dispatch/domains/playbook.js.map +0 -1
- package/dist/dispatch/domains/release.d.ts +0 -97
- package/dist/dispatch/domains/release.d.ts.map +0 -1
- package/dist/dispatch/domains/release.js +0 -177
- package/dist/dispatch/domains/release.js.map +0 -1
- package/dist/dispatch/domains/sentient.d.ts +0 -60
- package/dist/dispatch/domains/sentient.d.ts.map +0 -1
- package/dist/dispatch/domains/sentient.js +0 -270
- package/dist/dispatch/domains/sentient.js.map +0 -1
- package/dist/dispatch/domains/session.d.ts +0 -49
- package/dist/dispatch/domains/session.d.ts.map +0 -1
- package/dist/dispatch/domains/session.js +0 -459
- package/dist/dispatch/domains/session.js.map +0 -1
- package/dist/dispatch/domains/sticky.d.ts +0 -82
- package/dist/dispatch/domains/sticky.d.ts.map +0 -1
- package/dist/dispatch/domains/sticky.js +0 -287
- package/dist/dispatch/domains/sticky.js.map +0 -1
- package/dist/dispatch/domains/tasks.d.ts +0 -58
- package/dist/dispatch/domains/tasks.d.ts.map +0 -1
- package/dist/dispatch/domains/tasks.js +0 -497
- package/dist/dispatch/domains/tasks.js.map +0 -1
- package/dist/dispatch/domains/tools.d.ts +0 -37
- package/dist/dispatch/domains/tools.d.ts.map +0 -1
- package/dist/dispatch/domains/tools.js +0 -481
- package/dist/dispatch/domains/tools.js.map +0 -1
- package/dist/dispatch/engines/_error.d.ts +0 -114
- package/dist/dispatch/engines/_error.d.ts.map +0 -1
- package/dist/dispatch/engines/_error.js +0 -290
- package/dist/dispatch/engines/_error.js.map +0 -1
- package/dist/dispatch/engines/admin-engine.d.ts +0 -386
- package/dist/dispatch/engines/admin-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/admin-engine.js +0 -270
- package/dist/dispatch/engines/admin-engine.js.map +0 -1
- package/dist/dispatch/engines/code-engine.d.ts +0 -14
- package/dist/dispatch/engines/code-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/code-engine.js +0 -14
- package/dist/dispatch/engines/code-engine.js.map +0 -1
- package/dist/dispatch/engines/codebase-map-engine.d.ts +0 -31
- package/dist/dispatch/engines/codebase-map-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/codebase-map-engine.js +0 -43
- package/dist/dispatch/engines/codebase-map-engine.js.map +0 -1
- package/dist/dispatch/engines/config-engine.d.ts +0 -14
- package/dist/dispatch/engines/config-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/config-engine.js +0 -14
- package/dist/dispatch/engines/config-engine.js.map +0 -1
- package/dist/dispatch/engines/diagnostics-engine.d.ts +0 -13
- package/dist/dispatch/engines/diagnostics-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/diagnostics-engine.js +0 -12
- package/dist/dispatch/engines/diagnostics-engine.js.map +0 -1
- package/dist/dispatch/engines/hooks-engine.d.ts +0 -13
- package/dist/dispatch/engines/hooks-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/hooks-engine.js +0 -12
- package/dist/dispatch/engines/hooks-engine.js.map +0 -1
- package/dist/dispatch/engines/init-engine.d.ts +0 -14
- package/dist/dispatch/engines/init-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/init-engine.js +0 -14
- package/dist/dispatch/engines/init-engine.js.map +0 -1
- package/dist/dispatch/engines/lifecycle-engine.d.ts +0 -13
- package/dist/dispatch/engines/lifecycle-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/lifecycle-engine.js +0 -12
- package/dist/dispatch/engines/lifecycle-engine.js.map +0 -1
- package/dist/dispatch/engines/memory-engine.d.ts +0 -10
- package/dist/dispatch/engines/memory-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/memory-engine.js +0 -10
- package/dist/dispatch/engines/memory-engine.js.map +0 -1
- package/dist/dispatch/engines/nexus-engine.d.ts +0 -603
- package/dist/dispatch/engines/nexus-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/nexus-engine.js +0 -1438
- package/dist/dispatch/engines/nexus-engine.js.map +0 -1
- package/dist/dispatch/engines/orchestrate-engine.d.ts +0 -252
- package/dist/dispatch/engines/orchestrate-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/orchestrate-engine.js +0 -1526
- package/dist/dispatch/engines/orchestrate-engine.js.map +0 -1
- package/dist/dispatch/engines/pipeline-engine.d.ts +0 -13
- package/dist/dispatch/engines/pipeline-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/pipeline-engine.js +0 -12
- package/dist/dispatch/engines/pipeline-engine.js.map +0 -1
- package/dist/dispatch/engines/release-engine.d.ts +0 -13
- package/dist/dispatch/engines/release-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/release-engine.js +0 -13
- package/dist/dispatch/engines/release-engine.js.map +0 -1
- package/dist/dispatch/engines/session-engine.d.ts +0 -15
- package/dist/dispatch/engines/session-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/session-engine.js +0 -12
- package/dist/dispatch/engines/session-engine.js.map +0 -1
- package/dist/dispatch/engines/sticky-engine.d.ts +0 -13
- package/dist/dispatch/engines/sticky-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/sticky-engine.js +0 -12
- package/dist/dispatch/engines/sticky-engine.js.map +0 -1
- package/dist/dispatch/engines/system-engine.d.ts +0 -543
- package/dist/dispatch/engines/system-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/system-engine.js +0 -1278
- package/dist/dispatch/engines/system-engine.js.map +0 -1
- package/dist/dispatch/engines/task-engine.d.ts +0 -1161
- package/dist/dispatch/engines/task-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/task-engine.js +0 -1599
- package/dist/dispatch/engines/task-engine.js.map +0 -1
- package/dist/dispatch/engines/template-parser.d.ts +0 -85
- package/dist/dispatch/engines/template-parser.d.ts.map +0 -1
- package/dist/dispatch/engines/template-parser.js +0 -114
- package/dist/dispatch/engines/template-parser.js.map +0 -1
- package/dist/dispatch/engines/tools-engine.d.ts +0 -13
- package/dist/dispatch/engines/tools-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/tools-engine.js +0 -12
- package/dist/dispatch/engines/tools-engine.js.map +0 -1
- package/dist/dispatch/engines/validate-engine.d.ts +0 -13
- package/dist/dispatch/engines/validate-engine.d.ts.map +0 -1
- package/dist/dispatch/engines/validate-engine.js +0 -13
- package/dist/dispatch/engines/validate-engine.js.map +0 -1
- package/dist/dispatch/index.d.ts +0 -20
- package/dist/dispatch/index.d.ts.map +0 -1
- package/dist/dispatch/index.js +0 -19
- package/dist/dispatch/index.js.map +0 -1
- package/dist/dispatch/lib/background-jobs.d.ts +0 -162
- package/dist/dispatch/lib/background-jobs.d.ts.map +0 -1
- package/dist/dispatch/lib/background-jobs.js +0 -360
- package/dist/dispatch/lib/background-jobs.js.map +0 -1
- package/dist/dispatch/lib/budget.d.ts +0 -36
- package/dist/dispatch/lib/budget.d.ts.map +0 -1
- package/dist/dispatch/lib/budget.js +0 -109
- package/dist/dispatch/lib/budget.js.map +0 -1
- package/dist/dispatch/lib/capability-matrix.d.ts +0 -11
- package/dist/dispatch/lib/capability-matrix.d.ts.map +0 -1
- package/dist/dispatch/lib/capability-matrix.js +0 -10
- package/dist/dispatch/lib/capability-matrix.js.map +0 -1
- package/dist/dispatch/lib/config-loader.d.ts +0 -42
- package/dist/dispatch/lib/config-loader.d.ts.map +0 -1
- package/dist/dispatch/lib/config-loader.js +0 -218
- package/dist/dispatch/lib/config-loader.js.map +0 -1
- package/dist/dispatch/lib/config.d.ts +0 -11
- package/dist/dispatch/lib/config.d.ts.map +0 -1
- package/dist/dispatch/lib/config.js +0 -10
- package/dist/dispatch/lib/config.js.map +0 -1
- package/dist/dispatch/lib/defaults.d.ts +0 -115
- package/dist/dispatch/lib/defaults.d.ts.map +0 -1
- package/dist/dispatch/lib/defaults.js +0 -61
- package/dist/dispatch/lib/defaults.js.map +0 -1
- package/dist/dispatch/lib/engine.d.ts +0 -17
- package/dist/dispatch/lib/engine.d.ts.map +0 -1
- package/dist/dispatch/lib/engine.js +0 -36
- package/dist/dispatch/lib/engine.js.map +0 -1
- package/dist/dispatch/lib/exit-codes.d.ts +0 -35
- package/dist/dispatch/lib/exit-codes.d.ts.map +0 -1
- package/dist/dispatch/lib/exit-codes.js +0 -60
- package/dist/dispatch/lib/exit-codes.js.map +0 -1
- package/dist/dispatch/lib/gateway-meta.d.ts +0 -37
- package/dist/dispatch/lib/gateway-meta.d.ts.map +0 -1
- package/dist/dispatch/lib/gateway-meta.js +0 -50
- package/dist/dispatch/lib/gateway-meta.js.map +0 -1
- package/dist/dispatch/lib/job-manager-accessor.d.ts +0 -9
- package/dist/dispatch/lib/job-manager-accessor.d.ts.map +0 -1
- package/dist/dispatch/lib/job-manager-accessor.js +0 -13
- package/dist/dispatch/lib/job-manager-accessor.js.map +0 -1
- package/dist/dispatch/lib/meta.d.ts +0 -26
- package/dist/dispatch/lib/meta.d.ts.map +0 -1
- package/dist/dispatch/lib/meta.js +0 -37
- package/dist/dispatch/lib/meta.js.map +0 -1
- package/dist/dispatch/lib/param-utils.d.ts +0 -11
- package/dist/dispatch/lib/param-utils.d.ts.map +0 -1
- package/dist/dispatch/lib/param-utils.js +0 -10
- package/dist/dispatch/lib/param-utils.js.map +0 -1
- package/dist/dispatch/lib/projections.d.ts +0 -56
- package/dist/dispatch/lib/projections.d.ts.map +0 -1
- package/dist/dispatch/lib/projections.js +0 -65
- package/dist/dispatch/lib/projections.js.map +0 -1
- package/dist/dispatch/lib/proto-envelope.d.ts +0 -56
- package/dist/dispatch/lib/proto-envelope.d.ts.map +0 -1
- package/dist/dispatch/lib/proto-envelope.js +0 -17
- package/dist/dispatch/lib/proto-envelope.js.map +0 -1
- package/dist/dispatch/lib/schema-utils.d.ts +0 -39
- package/dist/dispatch/lib/schema-utils.d.ts.map +0 -1
- package/dist/dispatch/lib/schema-utils.js +0 -88
- package/dist/dispatch/lib/schema-utils.js.map +0 -1
- package/dist/dispatch/lib/security.d.ts +0 -11
- package/dist/dispatch/lib/security.d.ts.map +0 -1
- package/dist/dispatch/lib/security.js +0 -10
- package/dist/dispatch/lib/security.js.map +0 -1
- package/dist/dispatch/middleware/audit.d.ts +0 -23
- package/dist/dispatch/middleware/audit.d.ts.map +0 -1
- package/dist/dispatch/middleware/audit.js +0 -169
- package/dist/dispatch/middleware/audit.js.map +0 -1
- package/dist/dispatch/middleware/field-filter.d.ts +0 -25
- package/dist/dispatch/middleware/field-filter.d.ts.map +0 -1
- package/dist/dispatch/middleware/field-filter.js +0 -70
- package/dist/dispatch/middleware/field-filter.js.map +0 -1
- package/dist/dispatch/middleware/pipeline.d.ts +0 -33
- package/dist/dispatch/middleware/pipeline.d.ts.map +0 -1
- package/dist/dispatch/middleware/pipeline.js +0 -60
- package/dist/dispatch/middleware/pipeline.js.map +0 -1
- package/dist/dispatch/middleware/projection.d.ts +0 -35
- package/dist/dispatch/middleware/projection.d.ts.map +0 -1
- package/dist/dispatch/middleware/projection.js +0 -146
- package/dist/dispatch/middleware/projection.js.map +0 -1
- package/dist/dispatch/middleware/protocol-enforcement.d.ts +0 -30
- package/dist/dispatch/middleware/protocol-enforcement.d.ts.map +0 -1
- package/dist/dispatch/middleware/protocol-enforcement.js +0 -56
- package/dist/dispatch/middleware/protocol-enforcement.js.map +0 -1
- package/dist/dispatch/middleware/rate-limiter.d.ts +0 -72
- package/dist/dispatch/middleware/rate-limiter.d.ts.map +0 -1
- package/dist/dispatch/middleware/rate-limiter.js +0 -127
- package/dist/dispatch/middleware/rate-limiter.js.map +0 -1
- package/dist/dispatch/middleware/sanitizer.d.ts +0 -24
- package/dist/dispatch/middleware/sanitizer.d.ts.map +0 -1
- package/dist/dispatch/middleware/sanitizer.js +0 -56
- package/dist/dispatch/middleware/sanitizer.js.map +0 -1
- package/dist/dispatch/middleware/session-resolver.d.ts +0 -26
- package/dist/dispatch/middleware/session-resolver.d.ts.map +0 -1
- package/dist/dispatch/middleware/session-resolver.js +0 -65
- package/dist/dispatch/middleware/session-resolver.js.map +0 -1
- package/dist/dispatch/middleware/telemetry.d.ts +0 -21
- package/dist/dispatch/middleware/telemetry.d.ts.map +0 -1
- package/dist/dispatch/middleware/telemetry.js +0 -50
- package/dist/dispatch/middleware/telemetry.js.map +0 -1
- package/dist/dispatch/middleware/verification-gates.d.ts +0 -22
- package/dist/dispatch/middleware/verification-gates.d.ts.map +0 -1
- package/dist/dispatch/middleware/verification-gates.js +0 -59
- package/dist/dispatch/middleware/verification-gates.js.map +0 -1
- package/dist/dispatch/registry.d.ts +0 -91
- package/dist/dispatch/registry.d.ts.map +0 -1
- package/dist/dispatch/registry.js +0 -6430
- package/dist/dispatch/registry.js.map +0 -1
- package/dist/dispatch/types.d.ts +0 -150
- package/dist/dispatch/types.d.ts.map +0 -1
- package/dist/dispatch/types.js +0 -38
- package/dist/dispatch/types.js.map +0 -1
- package/dist/migrations/2026-04-25-t991-parent-link-repair.d.ts +0 -88
- package/dist/migrations/2026-04-25-t991-parent-link-repair.d.ts.map +0 -1
- package/dist/migrations/2026-04-25-t991-parent-link-repair.js +0 -76
- package/dist/migrations/2026-04-25-t991-parent-link-repair.js.map +0 -1
|
@@ -1,1526 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Orchestrate Engine
|
|
3
|
-
*
|
|
4
|
-
* Thin wrapper layer that delegates to core modules.
|
|
5
|
-
* All business logic lives in src/core/orchestration/.
|
|
6
|
-
*
|
|
7
|
-
* Wave 7a (T432): composeSpawnPayload from @cleocode/cant is now wired into
|
|
8
|
-
* the orchestrateSpawnExecute path. Before the Pi adapter spawn call, the
|
|
9
|
-
* composer runs JIT context assembly (context_sources from BRAIN + mental model)
|
|
10
|
-
* and produces a token-budgeted systemPrompt. The resulting prompt replaces the
|
|
11
|
-
* raw prepareSpawn prompt so subagents receive fully-composed context at spawn
|
|
12
|
-
* time. This unblocks the ULTRAPLAN Wave 5 empirical gate (T432 blocker).
|
|
13
|
-
*
|
|
14
|
-
* @task T4478
|
|
15
|
-
* @task T4784
|
|
16
|
-
* @task T432
|
|
17
|
-
*/
|
|
18
|
-
import { createHash } from 'node:crypto';
|
|
19
|
-
import { createRequire } from 'node:module';
|
|
20
|
-
// Core module imports
|
|
21
|
-
import { AgentNotFoundError, orchestrationAnalyzeDependencies as analyzeDependencies, analyzeEpic, buildBrainState, composeSpawnPayload, computeEpicStatus, computeOverallStatus, computeProgress, computeStartupSummary, endParallelExecution, ensureGlobalSignaldockDb, estimateContext, getAccessor, orchestrationGetCriticalPath as getCriticalPath, getEnrichedWaves, getGlobalSignaldockDbPath, getLifecycleStatus, getLogger, orchestrationGetNextTask as getNextTask, getParallelStatus, orchestrationGetReadyTasks as getReadyTasks, getSkillContent, getUnblockOpportunities, recordStageProgress, resolveAgent, resolveEffectiveTier, resolveProjectRoot, selectHarnessSpawnProvider, startParallelExecution, validateSpawnReadiness, } from '@cleocode/core/internal';
|
|
22
|
-
import { cleoErrorToEngineError, engineError } from './_error.js';
|
|
23
|
-
import { sessionContextInject, sessionEnd, sessionStatus } from './session-engine.js';
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// node:sqlite interop — matches the pattern used inside @cleocode/core so the
|
|
26
|
-
// plan engine can open a short-lived handle to the global signaldock.db for
|
|
27
|
-
// resolver lookups without routing through a long-lived cache.
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
const _engineRequire = createRequire(import.meta.url);
|
|
30
|
-
const { DatabaseSync: _DatabaseSyncCtor } = _engineRequire('node:sqlite');
|
|
31
|
-
/**
|
|
32
|
-
* Send a structured orchestration event to conduit.db via the active agent
|
|
33
|
-
* credential. Failures are silently swallowed — conduit events MUST NOT block
|
|
34
|
-
* or alter orchestration outcomes.
|
|
35
|
-
*
|
|
36
|
-
* @param cwd - Project root used to locate conduit.db and the agent registry.
|
|
37
|
-
* @param to - Recipient agent ID (e.g. 'cleo-core').
|
|
38
|
-
* @param event - Structured event payload (LAFS-shaped JSON).
|
|
39
|
-
*/
|
|
40
|
-
async function sendConduitEvent(cwd, to, event) {
|
|
41
|
-
try {
|
|
42
|
-
const { AgentRegistryAccessor, createConduit } = await import('@cleocode/core/internal');
|
|
43
|
-
const registry = new AgentRegistryAccessor(cwd);
|
|
44
|
-
const conduit = await createConduit(registry);
|
|
45
|
-
try {
|
|
46
|
-
await conduit.send(to, JSON.stringify(event));
|
|
47
|
-
}
|
|
48
|
-
finally {
|
|
49
|
-
await conduit.disconnect();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// Best-effort: conduit failures must never surface to callers
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Load all tasks from task data.
|
|
58
|
-
*/
|
|
59
|
-
async function loadTasks(projectRoot) {
|
|
60
|
-
const root = projectRoot || resolveProjectRoot();
|
|
61
|
-
try {
|
|
62
|
-
const accessor = await getAccessor(root);
|
|
63
|
-
const result = await accessor.queryTasks({});
|
|
64
|
-
return result?.tasks ?? [];
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* orchestrate.status - Get orchestrator status
|
|
72
|
-
* @task T4478
|
|
73
|
-
*/
|
|
74
|
-
export async function orchestrateStatus(epicId, projectRoot) {
|
|
75
|
-
try {
|
|
76
|
-
const root = projectRoot || resolveProjectRoot();
|
|
77
|
-
const tasks = await loadTasks(root);
|
|
78
|
-
if (epicId) {
|
|
79
|
-
const epic = tasks.find((t) => t.id === epicId);
|
|
80
|
-
if (!epic) {
|
|
81
|
-
return engineError('E_NOT_FOUND', `Epic ${epicId} not found`);
|
|
82
|
-
}
|
|
83
|
-
const children = tasks.filter((t) => t.parentId === epicId);
|
|
84
|
-
const status = computeEpicStatus(epicId, epic.title, children);
|
|
85
|
-
return { success: true, data: status };
|
|
86
|
-
}
|
|
87
|
-
// No epicId - return overall status
|
|
88
|
-
const status = computeOverallStatus(tasks);
|
|
89
|
-
return { success: true, data: status };
|
|
90
|
-
}
|
|
91
|
-
catch (err) {
|
|
92
|
-
return engineError('E_GENERAL', err.message);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* orchestrate.analyze - Dependency analysis
|
|
97
|
-
* @task T4478
|
|
98
|
-
*/
|
|
99
|
-
export async function orchestrateAnalyze(epicId, projectRoot, mode) {
|
|
100
|
-
// Mode: critical-path (delegates to critical path engine)
|
|
101
|
-
if (mode === 'critical-path') {
|
|
102
|
-
return orchestrateCriticalPath(projectRoot);
|
|
103
|
-
}
|
|
104
|
-
// Default mode: analysis (requires epicId)
|
|
105
|
-
if (!epicId) {
|
|
106
|
-
return engineError('E_INVALID_INPUT', 'epicId is required for standard analysis');
|
|
107
|
-
}
|
|
108
|
-
try {
|
|
109
|
-
const root = projectRoot || resolveProjectRoot();
|
|
110
|
-
const accessor = await getAccessor(root);
|
|
111
|
-
const result = await analyzeEpic(epicId, root, accessor);
|
|
112
|
-
// Add dependency graph and circular dep detection via core analyze module
|
|
113
|
-
const tasks = await loadTasks(root);
|
|
114
|
-
const children = tasks.filter((t) => t.parentId === epicId);
|
|
115
|
-
const depAnalysis = analyzeDependencies(children, tasks);
|
|
116
|
-
return {
|
|
117
|
-
success: true,
|
|
118
|
-
data: {
|
|
119
|
-
epicId: result.epicId,
|
|
120
|
-
epicTitle: tasks.find((t) => t.id === epicId)?.title || epicId,
|
|
121
|
-
totalTasks: result.totalTasks,
|
|
122
|
-
waves: result.waves,
|
|
123
|
-
circularDependencies: depAnalysis.circularDependencies,
|
|
124
|
-
missingDependencies: depAnalysis.missingDependencies,
|
|
125
|
-
dependencyGraph: depAnalysis.dependencyGraph,
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
const code = err.code ?? 'E_GENERAL';
|
|
131
|
-
return engineError(code, err.message);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* orchestrate.ready - Get parallel-safe tasks (ready to execute)
|
|
136
|
-
* @task T4478
|
|
137
|
-
*/
|
|
138
|
-
export async function orchestrateReady(epicId, projectRoot) {
|
|
139
|
-
if (!epicId) {
|
|
140
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const root = projectRoot || resolveProjectRoot();
|
|
144
|
-
// T929: verify the epic exists before computing the ready-set so that a
|
|
145
|
-
// nonexistent epicId returns E_NOT_FOUND (exit 4) instead of success:{total:0}.
|
|
146
|
-
const tasks = await loadTasks(root);
|
|
147
|
-
const epic = tasks.find((t) => t.id === epicId);
|
|
148
|
-
if (!epic) {
|
|
149
|
-
return engineError('E_NOT_FOUND', `Epic ${epicId} not found`);
|
|
150
|
-
}
|
|
151
|
-
const accessor = await getAccessor(root);
|
|
152
|
-
const readyTasks = await getReadyTasks(epicId, root, accessor);
|
|
153
|
-
const ready = readyTasks.filter((t) => t.ready);
|
|
154
|
-
// T929: when no tasks are ready, include a diagnostic reason so callers
|
|
155
|
-
// can distinguish "all done" from "all blocked" without a second query.
|
|
156
|
-
let reason;
|
|
157
|
-
if (ready.length === 0) {
|
|
158
|
-
const all = readyTasks;
|
|
159
|
-
const blockedCount = all.filter((t) => !t.ready && t.blockers.length > 0).length;
|
|
160
|
-
if (all.length === 0) {
|
|
161
|
-
reason = 'epic has no children';
|
|
162
|
-
}
|
|
163
|
-
else if (blockedCount === all.length) {
|
|
164
|
-
reason = 'all children have unmet dependencies';
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
reason = 'no tasks with unmet dependencies found; check child task statuses';
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
success: true,
|
|
172
|
-
data: {
|
|
173
|
-
epicId,
|
|
174
|
-
readyTasks: ready.map((t) => ({
|
|
175
|
-
id: t.taskId,
|
|
176
|
-
title: t.title,
|
|
177
|
-
priority: 'medium', // getReadyTasks doesn't return priority
|
|
178
|
-
depends: t.blockers,
|
|
179
|
-
})),
|
|
180
|
-
total: ready.length,
|
|
181
|
-
...(reason !== undefined && { reason }),
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
catch (err) {
|
|
186
|
-
const code = err.code ?? 'E_GENERAL';
|
|
187
|
-
return engineError(code, err.message);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* orchestrate.next - Next task to spawn
|
|
192
|
-
* @task T4478
|
|
193
|
-
*/
|
|
194
|
-
export async function orchestrateNext(epicId, projectRoot) {
|
|
195
|
-
if (!epicId) {
|
|
196
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
197
|
-
}
|
|
198
|
-
try {
|
|
199
|
-
const root = projectRoot || resolveProjectRoot();
|
|
200
|
-
const accessor = await getAccessor(root);
|
|
201
|
-
const nextTask = await getNextTask(epicId, root, accessor);
|
|
202
|
-
if (!nextTask) {
|
|
203
|
-
return {
|
|
204
|
-
success: true,
|
|
205
|
-
data: {
|
|
206
|
-
epicId,
|
|
207
|
-
nextTask: null,
|
|
208
|
-
message: 'No tasks ready to spawn. All pending tasks may have unmet dependencies.',
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
// Get all ready tasks for alternatives
|
|
213
|
-
const readyTasks = await getReadyTasks(epicId, root, accessor);
|
|
214
|
-
const ready = readyTasks.filter((t) => t.ready);
|
|
215
|
-
return {
|
|
216
|
-
success: true,
|
|
217
|
-
data: {
|
|
218
|
-
epicId,
|
|
219
|
-
nextTask: { id: nextTask.taskId, title: nextTask.title, priority: 'medium' },
|
|
220
|
-
alternatives: ready
|
|
221
|
-
.slice(1, 4)
|
|
222
|
-
.map((t) => ({ id: t.taskId, title: t.title, priority: 'medium' })),
|
|
223
|
-
totalReady: ready.length,
|
|
224
|
-
},
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
catch (err) {
|
|
228
|
-
const code = err.code ?? 'E_GENERAL';
|
|
229
|
-
return engineError(code, err.message);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* orchestrate.waves - Compute dependency waves
|
|
234
|
-
* @task T4478
|
|
235
|
-
*/
|
|
236
|
-
export async function orchestrateWaves(epicId, projectRoot) {
|
|
237
|
-
if (!epicId) {
|
|
238
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
239
|
-
}
|
|
240
|
-
try {
|
|
241
|
-
const root = projectRoot || resolveProjectRoot();
|
|
242
|
-
const accessor = await getAccessor(root);
|
|
243
|
-
const result = await getEnrichedWaves(epicId, root, accessor);
|
|
244
|
-
return { success: true, data: result };
|
|
245
|
-
}
|
|
246
|
-
catch (err) {
|
|
247
|
-
const code = err.code ?? 'E_GENERAL';
|
|
248
|
-
return engineError(code, err.message);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* orchestrate.context - Context usage check
|
|
253
|
-
* @task T4478
|
|
254
|
-
*/
|
|
255
|
-
export async function orchestrateContext(epicId, projectRoot) {
|
|
256
|
-
try {
|
|
257
|
-
const root = projectRoot || resolveProjectRoot();
|
|
258
|
-
const tasks = await loadTasks(root);
|
|
259
|
-
let taskCount = tasks.length;
|
|
260
|
-
if (epicId) {
|
|
261
|
-
taskCount = tasks.filter((t) => t.parentId === epicId).length;
|
|
262
|
-
}
|
|
263
|
-
const contextData = estimateContext(taskCount, root, epicId);
|
|
264
|
-
return { success: true, data: contextData };
|
|
265
|
-
}
|
|
266
|
-
catch (err) {
|
|
267
|
-
return engineError('E_GENERAL', err.message);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* orchestrate.validate - Validate spawn readiness for a task
|
|
272
|
-
* @task T4478
|
|
273
|
-
*/
|
|
274
|
-
export async function orchestrateValidate(taskId, projectRoot) {
|
|
275
|
-
if (!taskId) {
|
|
276
|
-
return engineError('E_INVALID_INPUT', 'taskId is required');
|
|
277
|
-
}
|
|
278
|
-
try {
|
|
279
|
-
const root = projectRoot || resolveProjectRoot();
|
|
280
|
-
const accessor = await getAccessor(root);
|
|
281
|
-
const result = await validateSpawnReadiness(taskId, root, accessor);
|
|
282
|
-
return { success: true, data: result };
|
|
283
|
-
}
|
|
284
|
-
catch (err) {
|
|
285
|
-
return engineError('E_VALIDATION', err.message);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* orchestrate.spawn.select - Select best provider for spawn based on required capabilities
|
|
290
|
-
* @task T5236
|
|
291
|
-
*/
|
|
292
|
-
export async function orchestrateSpawnSelectProvider(capabilities, _projectRoot) {
|
|
293
|
-
return selectHarnessSpawnProvider(capabilities);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* orchestrate.spawn.execute - Execute spawn for a task using adapter registry
|
|
297
|
-
* @task T5236
|
|
298
|
-
*/
|
|
299
|
-
export async function orchestrateSpawnExecute(taskId, adapterId, protocolType, projectRoot, tier) {
|
|
300
|
-
const cwd = projectRoot ?? process.cwd();
|
|
301
|
-
try {
|
|
302
|
-
// Get spawn registry
|
|
303
|
-
const { initializeDefaultAdapters, spawnRegistry } = await import('@cleocode/core/internal');
|
|
304
|
-
await initializeDefaultAdapters();
|
|
305
|
-
// Find adapter
|
|
306
|
-
let adapter;
|
|
307
|
-
if (adapterId) {
|
|
308
|
-
adapter = spawnRegistry.get(adapterId);
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
// Auto-select first capable adapter
|
|
312
|
-
const capable = await spawnRegistry.listSpawnCapable();
|
|
313
|
-
adapter = capable[0];
|
|
314
|
-
}
|
|
315
|
-
if (!adapter) {
|
|
316
|
-
return {
|
|
317
|
-
success: false,
|
|
318
|
-
error: {
|
|
319
|
-
code: 'E_SPAWN_NO_ADAPTER',
|
|
320
|
-
message: 'No spawn adapter available for this provider',
|
|
321
|
-
exitCode: 60,
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
// Verify provider supports subagents using providerSupportsById
|
|
326
|
-
const { providerSupportsById } = await import('@cleocode/caamp');
|
|
327
|
-
if (!providerSupportsById(adapter.providerId, 'spawn.supportsSubagents')) {
|
|
328
|
-
return {
|
|
329
|
-
success: false,
|
|
330
|
-
error: {
|
|
331
|
-
code: 'E_SPAWN_CAPABILITY_UNSUPPORTED',
|
|
332
|
-
message: `Provider ${adapter.providerId} does not support spawning subagents`,
|
|
333
|
-
exitCode: 60,
|
|
334
|
-
},
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
// Route the spawn through the canonical composer (T932). This activates
|
|
338
|
-
// atomicity, harness dedup, resolved-agent metadata, and traceability
|
|
339
|
-
// meta — all returned in a single SpawnPayload envelope.
|
|
340
|
-
const { getActiveSession } = await import('@cleocode/core/internal');
|
|
341
|
-
let activeSessionId = null;
|
|
342
|
-
try {
|
|
343
|
-
const active = await getActiveSession(cwd);
|
|
344
|
-
activeSessionId = active?.id ?? null;
|
|
345
|
-
}
|
|
346
|
-
catch {
|
|
347
|
-
activeSessionId = null;
|
|
348
|
-
}
|
|
349
|
-
const payload = await composeSpawnForTask(taskId, cwd, {
|
|
350
|
-
tier,
|
|
351
|
-
sessionId: activeSessionId,
|
|
352
|
-
protocol: protocolType,
|
|
353
|
-
});
|
|
354
|
-
// Atomicity violations short-circuit the spawn so the adapter never sees
|
|
355
|
-
// a rejected payload. Full verdict is preserved under `error.details`.
|
|
356
|
-
if (!payload.atomicity.allowed) {
|
|
357
|
-
return {
|
|
358
|
-
success: false,
|
|
359
|
-
error: {
|
|
360
|
-
code: payload.atomicity.code ?? 'E_ATOMICITY_VIOLATION',
|
|
361
|
-
message: payload.atomicity.message ?? 'Atomicity gate rejected spawn',
|
|
362
|
-
exitCode: 69,
|
|
363
|
-
details: {
|
|
364
|
-
taskId,
|
|
365
|
-
atomicity: payload.atomicity,
|
|
366
|
-
meta: payload.meta,
|
|
367
|
-
fix: payload.atomicity.fixHint,
|
|
368
|
-
},
|
|
369
|
-
},
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
// Build CLEO spawn context from core spawn payload
|
|
373
|
-
const { getSpawnCapableProviders } = await import('@cleocode/caamp');
|
|
374
|
-
const providers = getSpawnCapableProviders();
|
|
375
|
-
const provider = providers.find((p) => p.id === adapter.providerId);
|
|
376
|
-
if (!provider) {
|
|
377
|
-
return {
|
|
378
|
-
success: false,
|
|
379
|
-
error: {
|
|
380
|
-
code: 'E_SPAWN_NO_PROVIDER',
|
|
381
|
-
message: `Provider ${adapter.providerId} not found`,
|
|
382
|
-
exitCode: 60,
|
|
383
|
-
},
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
// T1238 — Apply mustache `{{var}}` substitution to the resolved CANT
|
|
387
|
-
// agent body BEFORE it becomes part of the spawn prompt. The substitution
|
|
388
|
-
// engine loads `.cleo/project-context.json` (via core paths) and merges
|
|
389
|
-
// it with the orchestrator's session context; bindings are left empty
|
|
390
|
-
// for now (T891 will thread classifier-produced overrides here).
|
|
391
|
-
//
|
|
392
|
-
// Best-effort: missing agent file / unresolved variables degrade to a
|
|
393
|
-
// lenient substitution — the original prompt still flows to the adapter
|
|
394
|
-
// and the diagnostics are surfaced under `data.meta.templateSubstitution`.
|
|
395
|
-
const templateSubstitution = await applyCantBodySubstitution(payload, cwd, {
|
|
396
|
-
taskId,
|
|
397
|
-
sessionId: activeSessionId,
|
|
398
|
-
protocol: protocolType ?? payload.meta.protocol,
|
|
399
|
-
});
|
|
400
|
-
// The raw prompt from the composer is passed to the adapter unchanged.
|
|
401
|
-
// CANT bundle compilation, mental model injection, and identity bootstrap
|
|
402
|
-
// are all handled inside buildCantEnrichedPrompt() at the adapter layer
|
|
403
|
-
// (packages/adapters/src/cant-context.ts). When a resolved CANT agent
|
|
404
|
-
// body was substituted (T1238), it is prepended to the composer prompt
|
|
405
|
-
// so subagents receive the fully-resolved template alongside the
|
|
406
|
-
// standard spawn context.
|
|
407
|
-
const rawPrompt = templateSubstitution.resolvedBody
|
|
408
|
-
? `${templateSubstitution.resolvedBody}\n\n${payload.prompt}`
|
|
409
|
-
: payload.prompt;
|
|
410
|
-
const cleoSpawnContext = {
|
|
411
|
-
taskId: payload.taskId,
|
|
412
|
-
protocol: protocolType || payload.meta.protocol,
|
|
413
|
-
prompt: rawPrompt,
|
|
414
|
-
provider: provider.id,
|
|
415
|
-
options: {
|
|
416
|
-
prompt: rawPrompt,
|
|
417
|
-
},
|
|
418
|
-
workingDirectory: cwd,
|
|
419
|
-
tokenResolution: {
|
|
420
|
-
resolved: [],
|
|
421
|
-
unresolved: [],
|
|
422
|
-
totalTokens: 0,
|
|
423
|
-
},
|
|
424
|
-
};
|
|
425
|
-
// Wave 6-C/D: Capacity-aware routing — find the least-loaded agent and
|
|
426
|
-
// attach it as a preferred routing hint on the spawn options.
|
|
427
|
-
// Best-effort: if no agents are registered or the check throws, fall
|
|
428
|
-
// through to default spawn behavior without blocking.
|
|
429
|
-
try {
|
|
430
|
-
const { findLeastLoadedAgent } = await import('@cleocode/core/internal');
|
|
431
|
-
const leastLoaded = await findLeastLoadedAgent(undefined, cwd);
|
|
432
|
-
if (leastLoaded) {
|
|
433
|
-
cleoSpawnContext.options = {
|
|
434
|
-
...cleoSpawnContext.options,
|
|
435
|
-
preferredAgent: leastLoaded.id,
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
catch {
|
|
440
|
-
// Capacity check is best-effort — never block spawn
|
|
441
|
-
}
|
|
442
|
-
// Dispatch SubagentStart hook BEFORE spawning — triggers brain observation
|
|
443
|
-
// recording and conduit messaging for the agent lifecycle (T555).
|
|
444
|
-
try {
|
|
445
|
-
const { hooks } = await import('@cleocode/core/internal');
|
|
446
|
-
await hooks
|
|
447
|
-
.dispatch('SubagentStart', cwd, {
|
|
448
|
-
timestamp: new Date().toISOString(),
|
|
449
|
-
taskId,
|
|
450
|
-
agentId: cleoSpawnContext.options?.preferredAgent ?? `worker-${taskId}`,
|
|
451
|
-
role: protocolType || 'worker',
|
|
452
|
-
providerId: adapter.providerId,
|
|
453
|
-
})
|
|
454
|
-
.catch(() => {
|
|
455
|
-
/* Hooks are best-effort — never block spawn */
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
catch {
|
|
459
|
-
/* Hook registry unavailable — non-fatal */
|
|
460
|
-
}
|
|
461
|
-
// Execute spawn
|
|
462
|
-
const result = await adapter.spawn(cleoSpawnContext);
|
|
463
|
-
// Dispatch SubagentStop hook AFTER spawn returns — records completion
|
|
464
|
-
// status in brain and conduit (T555).
|
|
465
|
-
try {
|
|
466
|
-
const { hooks } = await import('@cleocode/core/internal');
|
|
467
|
-
await hooks
|
|
468
|
-
.dispatch('SubagentStop', cwd, {
|
|
469
|
-
timestamp: new Date().toISOString(),
|
|
470
|
-
taskId,
|
|
471
|
-
agentId: cleoSpawnContext.options?.preferredAgent ?? `worker-${taskId}`,
|
|
472
|
-
status: result.status,
|
|
473
|
-
instanceId: result.instanceId,
|
|
474
|
-
})
|
|
475
|
-
.catch(() => {
|
|
476
|
-
/* Hooks are best-effort — never block spawn */
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
catch {
|
|
480
|
-
/* Hook registry unavailable — non-fatal */
|
|
481
|
-
}
|
|
482
|
-
// Best-effort: record spawn event in conduit.db so agents can observe
|
|
483
|
-
// orchestration activity. Never awaited in a blocking way — fires and
|
|
484
|
-
// the main return path continues regardless of conduit outcome.
|
|
485
|
-
void sendConduitEvent(cwd, 'cleo-core', {
|
|
486
|
-
event: 'agent.spawned',
|
|
487
|
-
taskId,
|
|
488
|
-
instanceId: result.instanceId,
|
|
489
|
-
status: result.status,
|
|
490
|
-
providerId: adapter.providerId,
|
|
491
|
-
adapterId: adapter.id,
|
|
492
|
-
tier: tier ?? null,
|
|
493
|
-
spawnedAt: new Date().toISOString(),
|
|
494
|
-
});
|
|
495
|
-
return {
|
|
496
|
-
success: true,
|
|
497
|
-
data: {
|
|
498
|
-
instanceId: result.instanceId,
|
|
499
|
-
status: result.status,
|
|
500
|
-
providerId: adapter.providerId,
|
|
501
|
-
taskId,
|
|
502
|
-
timing: result.timing,
|
|
503
|
-
tier: tier ?? null,
|
|
504
|
-
atomicity: payload.atomicity,
|
|
505
|
-
meta: {
|
|
506
|
-
...payload.meta,
|
|
507
|
-
// T1238 — variable substitution diagnostics surfaced for audit.
|
|
508
|
-
templateSubstitution: {
|
|
509
|
-
applied: templateSubstitution.applied,
|
|
510
|
-
resolvedCount: templateSubstitution.resolvedCount,
|
|
511
|
-
missing: templateSubstitution.missing,
|
|
512
|
-
projectContextLoaded: templateSubstitution.projectContextLoaded,
|
|
513
|
-
...(templateSubstitution.reason !== undefined
|
|
514
|
-
? { reason: templateSubstitution.reason }
|
|
515
|
-
: {}),
|
|
516
|
-
},
|
|
517
|
-
},
|
|
518
|
-
agentId: payload.agentId,
|
|
519
|
-
role: payload.role,
|
|
520
|
-
harnessHint: payload.harnessHint,
|
|
521
|
-
},
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
catch (error) {
|
|
525
|
-
return {
|
|
526
|
-
success: false,
|
|
527
|
-
error: {
|
|
528
|
-
code: 'E_SPAWN_FAILED',
|
|
529
|
-
message: error instanceof Error ? error.message : 'Unknown spawn error',
|
|
530
|
-
exitCode: 60,
|
|
531
|
-
},
|
|
532
|
-
};
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Apply T1238 mustache `{{var}}` substitution to the resolved CANT agent body.
|
|
537
|
-
*
|
|
538
|
-
* This is the integration hook for the spawn-time substitution contract: the
|
|
539
|
-
* orchestrate engine calls it AFTER `composeSpawnPayload` has resolved the
|
|
540
|
-
* agent from the 4-tier registry and BEFORE the adapter receives the spawn
|
|
541
|
-
* prompt. Failures degrade to a no-op so the spawn path remains resilient.
|
|
542
|
-
*
|
|
543
|
-
* Resolver context assembled here:
|
|
544
|
-
* - `projectContext`: `.cleo/project-context.json` (loaded by the SDK).
|
|
545
|
-
* - `sessionContext`: `{ taskId, epicId, sessionId, protocol, harnessHint }`.
|
|
546
|
-
* - `bindings`: reserved for T891 classifier-produced overrides (currently empty).
|
|
547
|
-
* - `env`: `process.env` (CLEO_ and CANT_ prefixed lookups).
|
|
548
|
-
*
|
|
549
|
-
* @param payload - Spawn payload produced by `composeSpawnForTask`.
|
|
550
|
-
* @param cwd - Project root for resolving `.cleo/project-context.json`.
|
|
551
|
-
* @param ctx - Session-scoped context injected into the resolver.
|
|
552
|
-
* @returns Diagnostic envelope with resolved body + missing-var report.
|
|
553
|
-
* @task T1238
|
|
554
|
-
*/
|
|
555
|
-
async function applyCantBodySubstitution(payload, cwd, ctx) {
|
|
556
|
-
const empty = {
|
|
557
|
-
applied: false,
|
|
558
|
-
resolvedCount: 0,
|
|
559
|
-
missing: [],
|
|
560
|
-
projectContextLoaded: false,
|
|
561
|
-
resolvedBody: null,
|
|
562
|
-
};
|
|
563
|
-
const cantPath = payload.resolvedAgent?.cantPath;
|
|
564
|
-
if (!cantPath) {
|
|
565
|
-
return { ...empty, reason: 'resolved agent has no cantPath' };
|
|
566
|
-
}
|
|
567
|
-
// Dynamic import keeps the dispatch bundle free of fs/path unless we
|
|
568
|
-
// actually run substitution.
|
|
569
|
-
const [{ existsSync, readFileSync }, { substituteCantAgentBody }] = await Promise.all([
|
|
570
|
-
import('node:fs'),
|
|
571
|
-
import('@cleocode/core/internal'),
|
|
572
|
-
]);
|
|
573
|
-
if (!existsSync(cantPath)) {
|
|
574
|
-
return { ...empty, reason: `cant file not found at ${cantPath}` };
|
|
575
|
-
}
|
|
576
|
-
let body;
|
|
577
|
-
try {
|
|
578
|
-
body = readFileSync(cantPath, 'utf-8');
|
|
579
|
-
}
|
|
580
|
-
catch (err) {
|
|
581
|
-
return {
|
|
582
|
-
...empty,
|
|
583
|
-
reason: `Failed to read cant body: ${err instanceof Error ? err.message : String(err)}`,
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
const sessionContext = {
|
|
587
|
-
taskId: ctx.taskId,
|
|
588
|
-
sessionId: ctx.sessionId,
|
|
589
|
-
protocol: ctx.protocol,
|
|
590
|
-
agentId: payload.agentId,
|
|
591
|
-
role: payload.role,
|
|
592
|
-
tier: payload.tier,
|
|
593
|
-
harnessHint: payload.harnessHint,
|
|
594
|
-
};
|
|
595
|
-
if (payload.taskId)
|
|
596
|
-
sessionContext.spawnTaskId = payload.taskId;
|
|
597
|
-
const result = substituteCantAgentBody(body, {
|
|
598
|
-
projectRoot: cwd,
|
|
599
|
-
sessionContext,
|
|
600
|
-
env: process.env,
|
|
601
|
-
options: { strict: false, warnMissing: false },
|
|
602
|
-
});
|
|
603
|
-
return {
|
|
604
|
-
applied: result.resolved.length > 0,
|
|
605
|
-
resolvedCount: result.resolved.length,
|
|
606
|
-
missing: result.missing,
|
|
607
|
-
projectContextLoaded: result.projectContextLoaded,
|
|
608
|
-
resolvedBody: result.text,
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Open a short-lived signaldock db handle for composer lookups.
|
|
613
|
-
*
|
|
614
|
-
* Mirrors the pattern used by {@link orchestratePlan}: we intentionally do
|
|
615
|
-
* NOT cache this handle — the resolver contract owns its own lifecycle and
|
|
616
|
-
* callers must close the returned handle when the batch completes.
|
|
617
|
-
*
|
|
618
|
-
* @returns Open {@link _SignaldockDbHandle} bound to the global signaldock.db.
|
|
619
|
-
* @task T932
|
|
620
|
-
*/
|
|
621
|
-
async function openSignaldockDbForComposer() {
|
|
622
|
-
await ensureGlobalSignaldockDb();
|
|
623
|
-
const dbPath = getGlobalSignaldockDbPath();
|
|
624
|
-
const db = new _DatabaseSyncCtor(dbPath);
|
|
625
|
-
db.exec('PRAGMA foreign_keys = ON');
|
|
626
|
-
return db;
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* Compose a spawn payload through {@link composeSpawnPayload} with a task-id
|
|
630
|
-
* lookup shortcut.
|
|
631
|
-
*
|
|
632
|
-
* Centralizes the composer invocation used by both {@link orchestrateSpawn}
|
|
633
|
-
* and {@link orchestrateSpawnExecute} so every spawn emit path in the engine
|
|
634
|
-
* routes through the same canonical composer.
|
|
635
|
-
*
|
|
636
|
-
* @param taskId - Task to render the spawn for.
|
|
637
|
-
* @param root - Absolute project root.
|
|
638
|
-
* @param options - Composer overrides (tier, sessionId, role, …).
|
|
639
|
-
* @returns Full {@link SpawnPayload} envelope with atomicity + meta surfaced.
|
|
640
|
-
* @task T932
|
|
641
|
-
*/
|
|
642
|
-
async function composeSpawnForTask(taskId, root, options = {}) {
|
|
643
|
-
const accessor = await getAccessor(root);
|
|
644
|
-
const task = await accessor.loadSingleTask(taskId);
|
|
645
|
-
if (!task) {
|
|
646
|
-
throw new Error(`Task ${taskId} not found`);
|
|
647
|
-
}
|
|
648
|
-
// T1014: Auto-promote epics to lead role so atomicity file-scope check is
|
|
649
|
-
// bypassed. Epics coordinate atomic workers — they are inherently broad in
|
|
650
|
-
// scope and must not be blocked by the worker file-scope gate.
|
|
651
|
-
const inferredRole = options.role ?? (task.type === 'epic' ? 'lead' : undefined);
|
|
652
|
-
// T892: When no explicit tier is supplied, apply the auto-tier heuristics
|
|
653
|
-
// (role matrix + size/type/label overrides) instead of the default role-only
|
|
654
|
-
// mapping. Callers that pass an explicit tier always win.
|
|
655
|
-
const effectiveTier = options.tier !== undefined
|
|
656
|
-
? options.tier
|
|
657
|
-
: resolveEffectiveTier(task, inferredRole ?? 'worker', undefined);
|
|
658
|
-
const db = await openSignaldockDbForComposer();
|
|
659
|
-
try {
|
|
660
|
-
return await composeSpawnPayload(db, task, {
|
|
661
|
-
tier: effectiveTier,
|
|
662
|
-
projectRoot: root,
|
|
663
|
-
sessionId: options.sessionId ?? null,
|
|
664
|
-
role: inferredRole,
|
|
665
|
-
protocol: options.protocol,
|
|
666
|
-
skipAtomicityCheck: options.skipAtomicityCheck ?? false,
|
|
667
|
-
worktreePath: options.worktreePath,
|
|
668
|
-
worktreeBranch: options.worktreeBranch,
|
|
669
|
-
conduitSubscription: options.conduitSubscription,
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
finally {
|
|
673
|
-
db.close();
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* orchestrate.spawn - Generate spawn prompt for a task.
|
|
678
|
-
*
|
|
679
|
-
* Every spawn emit in the engine routes through
|
|
680
|
-
* {@link composeSpawnPayload} (T932) so atomicity, harness-hint dedup, and
|
|
681
|
-
* traceability metadata are active on every orchestrate spawn. Legacy
|
|
682
|
-
* {@link prepareSpawn} is no longer called directly from this path.
|
|
683
|
-
*
|
|
684
|
-
* The response envelope surfaces:
|
|
685
|
-
*
|
|
686
|
-
* - `atomicity` — the worker file-scope gate verdict
|
|
687
|
-
* - `meta.composerVersion` — pinned to `'3.0.0'` for the T932 composer path
|
|
688
|
-
* - `meta.dedupSavedChars` — characters saved via harness-hint dedup
|
|
689
|
-
* - `meta.promptChars` — total rendered prompt length
|
|
690
|
-
* - `meta.sourceTier` — registry tier the resolved agent was sourced from
|
|
691
|
-
*
|
|
692
|
-
* Atomicity violations return an `E_ATOMICITY_VIOLATION` error envelope with
|
|
693
|
-
* the full verdict attached to `error.details.atomicity` so callers can
|
|
694
|
-
* inspect the rejection reason before retrying.
|
|
695
|
-
*
|
|
696
|
-
* @task T4478
|
|
697
|
-
* @task T932
|
|
698
|
-
*/
|
|
699
|
-
export async function orchestrateSpawn(taskId, protocolType, projectRoot, tier, noWorktree) {
|
|
700
|
-
if (!taskId) {
|
|
701
|
-
return engineError('E_INVALID_INPUT', 'taskId is required');
|
|
702
|
-
}
|
|
703
|
-
try {
|
|
704
|
-
const root = projectRoot || resolveProjectRoot();
|
|
705
|
-
// Validate readiness first.
|
|
706
|
-
// T929: a V_NOT_FOUND issue means the task ID doesn't exist in the DB —
|
|
707
|
-
// surface E_NOT_FOUND (exit 4) so callers get a clear, actionable error
|
|
708
|
-
// instead of a generic spawn-validation failure that obscures the root cause.
|
|
709
|
-
const accessor = await getAccessor(root);
|
|
710
|
-
const validation = await validateSpawnReadiness(taskId, root, accessor);
|
|
711
|
-
if (!validation.ready) {
|
|
712
|
-
const notFound = validation.issues.some((i) => i.code === 'V_NOT_FOUND');
|
|
713
|
-
if (notFound) {
|
|
714
|
-
return engineError('E_NOT_FOUND', `Task ${taskId} not found`, {
|
|
715
|
-
fix: `cleo find "${taskId}"`,
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
return engineError('E_SPAWN_VALIDATION_FAILED', `Task ${taskId} is not ready to spawn`, {
|
|
719
|
-
details: { issues: validation.issues },
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
// Thread the orchestrator's active session id into the spawn prompt so
|
|
723
|
-
// the subagent logs every mutation against the same session. Failure to
|
|
724
|
-
// load the session is non-fatal — the prompt degrades gracefully with a
|
|
725
|
-
// "no active session" notice.
|
|
726
|
-
let activeSessionId = null;
|
|
727
|
-
try {
|
|
728
|
-
const { getActiveSession } = await import('@cleocode/core/internal');
|
|
729
|
-
const active = await getActiveSession(root);
|
|
730
|
-
activeSessionId = active?.id ?? null;
|
|
731
|
-
}
|
|
732
|
-
catch {
|
|
733
|
-
activeSessionId = null;
|
|
734
|
-
}
|
|
735
|
-
// T1253 — Derive CONDUIT subscription config from the task's parent epic.
|
|
736
|
-
//
|
|
737
|
-
// For tier-1+ spawns, the spawn prompt gains a `## CONDUIT Subscription`
|
|
738
|
-
// section so the subagent knows which wave and coordination topics to use.
|
|
739
|
-
// Derivation is best-effort: failures are silently swallowed so spawn is
|
|
740
|
-
// never blocked by a CONDUIT config read error.
|
|
741
|
-
//
|
|
742
|
-
// Topic naming convention (per T1252 spec):
|
|
743
|
-
// wave topic : "epic-<epicId>.wave-<taskId>" (taskId as waveId proxy)
|
|
744
|
-
// coord topic : "epic-<epicId>.coordination"
|
|
745
|
-
//
|
|
746
|
-
// For top-level tasks (no parentId) the section is omitted entirely.
|
|
747
|
-
let conduitSubscription;
|
|
748
|
-
const effectiveTierForConduit = tier ?? 1; // default before composeSpawnForTask resolves it
|
|
749
|
-
if (effectiveTierForConduit >= 1) {
|
|
750
|
-
try {
|
|
751
|
-
const taskRecord = await accessor.loadSingleTask(taskId);
|
|
752
|
-
if (taskRecord?.parentId) {
|
|
753
|
-
const epicId = taskRecord.parentId;
|
|
754
|
-
conduitSubscription = {
|
|
755
|
-
epicId,
|
|
756
|
-
waveId: Number.parseInt(taskId.replace(/\D/g, '').slice(-4) || '1', 10),
|
|
757
|
-
peerId: `cleo-agent-${taskId.toLowerCase()}`,
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
catch {
|
|
762
|
-
// Best-effort: CONDUIT config derivation must never block spawn.
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
// T1140 — Worktree provisioning (SDK-first per D023 / ADR-055).
|
|
766
|
-
//
|
|
767
|
-
// Worktrees are created by default for every spawn. The `--no-worktree`
|
|
768
|
-
// flag opts out and logs an audit entry so the choice is traceable.
|
|
769
|
-
//
|
|
770
|
-
// When provisioning fails (non-git repo, git not installed, etc.) we
|
|
771
|
-
// degrade gracefully — spawn continues without isolation, same as T1118.
|
|
772
|
-
let sdkWorktreeResult = null;
|
|
773
|
-
let worktreePath;
|
|
774
|
-
let worktreeBranch;
|
|
775
|
-
if (noWorktree) {
|
|
776
|
-
// Explicit opt-out — log to audit so it's always traceable.
|
|
777
|
-
getLogger('engine:orchestrate').info({ taskId }, 'T1140 --no-worktree: worktree provisioning skipped (audit logged)');
|
|
778
|
-
try {
|
|
779
|
-
const accessor = await getAccessor(root);
|
|
780
|
-
await accessor.appendLog({
|
|
781
|
-
action: 'orchestrate.spawn.no-worktree',
|
|
782
|
-
taskId,
|
|
783
|
-
actor: 'orchestrate-engine',
|
|
784
|
-
details: { reason: '--no-worktree flag set by caller', taskId },
|
|
785
|
-
});
|
|
786
|
-
}
|
|
787
|
-
catch {
|
|
788
|
-
// Audit log is best-effort — never block spawn.
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
// Default: provision via the SDK dispatch layer (worktree-dispatch.ts).
|
|
793
|
-
// Routes through @cleocode/worktree per D023 SDK-first contract.
|
|
794
|
-
try {
|
|
795
|
-
const { spawnWorktree } = await import('@cleocode/core/internal');
|
|
796
|
-
sdkWorktreeResult = await spawnWorktree(root, { taskId });
|
|
797
|
-
worktreePath = sdkWorktreeResult.path;
|
|
798
|
-
worktreeBranch = sdkWorktreeResult.branch;
|
|
799
|
-
}
|
|
800
|
-
catch (wtErr) {
|
|
801
|
-
getLogger('engine:orchestrate').warn({ taskId, err: wtErr }, `T1140 worktree creation failed for ${taskId} — spawning without isolation: ${wtErr instanceof Error ? wtErr.message : String(wtErr)}`);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
// Route every spawn through the canonical composer (T932). Atomicity,
|
|
805
|
-
// harness-hint dedup, resolved-agent metadata, and traceability meta are
|
|
806
|
-
// all populated here — prepareSpawn/buildSpawnPrompt are NOT called
|
|
807
|
-
// directly from this path anymore.
|
|
808
|
-
//
|
|
809
|
-
// T1140: worktreePath and worktreeBranch are passed through so the
|
|
810
|
-
// composer can emit the `## Worktree Setup (REQUIRED)` section in the
|
|
811
|
-
// prompt body (replacing the old preamble prepend pattern from T1118).
|
|
812
|
-
//
|
|
813
|
-
// T1253: conduitSubscription derived above from task.parentId is threaded
|
|
814
|
-
// through so the `## CONDUIT Subscription` section appears on tier-1+ prompts.
|
|
815
|
-
const payload = await composeSpawnForTask(taskId, root, {
|
|
816
|
-
tier,
|
|
817
|
-
sessionId: activeSessionId,
|
|
818
|
-
protocol: protocolType,
|
|
819
|
-
worktreePath,
|
|
820
|
-
worktreeBranch,
|
|
821
|
-
conduitSubscription,
|
|
822
|
-
});
|
|
823
|
-
// Surface atomicity violations as a first-class error envelope so callers
|
|
824
|
-
// can react programmatically. The full verdict is attached to
|
|
825
|
-
// `error.details.atomicity` so diagnostics are preserved.
|
|
826
|
-
if (!payload.atomicity.allowed) {
|
|
827
|
-
return engineError(payload.atomicity.code ?? 'E_ATOMICITY_VIOLATION', payload.atomicity.message ?? 'Atomicity gate rejected spawn', {
|
|
828
|
-
details: {
|
|
829
|
-
taskId,
|
|
830
|
-
atomicity: payload.atomicity,
|
|
831
|
-
meta: payload.meta,
|
|
832
|
-
},
|
|
833
|
-
fix: payload.atomicity.fixHint,
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
// T1140: The worktree section is now emitted by buildSpawnPrompt (inside
|
|
837
|
-
// composeSpawnForTask above) as `## Worktree Setup (REQUIRED)`. The prompt
|
|
838
|
-
// is used as-is — no legacy preamble prepend needed for SDK results.
|
|
839
|
-
const finalPrompt = payload.prompt;
|
|
840
|
-
// Build a WorktreeSpawnResult-compatible envelope from the SDK result so
|
|
841
|
-
// harness adapters that read worktree/worktreeEnv/worktreeCwd continue to
|
|
842
|
-
// work without modification (backward-compat shim).
|
|
843
|
-
const worktreeAdapterResult = sdkWorktreeResult
|
|
844
|
-
? {
|
|
845
|
-
worktree: {
|
|
846
|
-
path: sdkWorktreeResult.path,
|
|
847
|
-
branch: sdkWorktreeResult.branch,
|
|
848
|
-
taskId: sdkWorktreeResult.taskId,
|
|
849
|
-
baseRef: sdkWorktreeResult.baseRef,
|
|
850
|
-
projectHash: sdkWorktreeResult.projectHash,
|
|
851
|
-
createdAt: sdkWorktreeResult.createdAt,
|
|
852
|
-
locked: sdkWorktreeResult.locked,
|
|
853
|
-
},
|
|
854
|
-
envVars: sdkWorktreeResult.envVars,
|
|
855
|
-
cwd: sdkWorktreeResult.path,
|
|
856
|
-
preamble: sdkWorktreeResult.preamble,
|
|
857
|
-
}
|
|
858
|
-
: null;
|
|
859
|
-
// Return shape: `prompt` at the top level is the primary payload every
|
|
860
|
-
// caller should consume. `atomicity` + `meta` surface the T932 composer
|
|
861
|
-
// guarantees. `spawnContext` mirrors the prompt for legacy readers.
|
|
862
|
-
return {
|
|
863
|
-
success: true,
|
|
864
|
-
data: {
|
|
865
|
-
taskId,
|
|
866
|
-
prompt: finalPrompt,
|
|
867
|
-
agentId: payload.agentId,
|
|
868
|
-
role: payload.role,
|
|
869
|
-
tier: payload.tier,
|
|
870
|
-
harnessHint: payload.harnessHint,
|
|
871
|
-
atomicity: payload.atomicity,
|
|
872
|
-
meta: payload.meta,
|
|
873
|
-
// T1118 L1+L2 / T1140 — worktree binding for harness adapters.
|
|
874
|
-
worktree: worktreeAdapterResult?.worktree ?? null,
|
|
875
|
-
worktreeEnv: worktreeAdapterResult?.envVars ?? null,
|
|
876
|
-
worktreeCwd: worktreeAdapterResult?.cwd ?? null,
|
|
877
|
-
spawnContext: {
|
|
878
|
-
taskId: payload.taskId,
|
|
879
|
-
protocol: payload.meta.protocol,
|
|
880
|
-
protocolType: protocolType || payload.meta.protocol,
|
|
881
|
-
tier: payload.tier,
|
|
882
|
-
prompt: finalPrompt,
|
|
883
|
-
},
|
|
884
|
-
protocolType: protocolType || payload.meta.protocol,
|
|
885
|
-
sessionId: activeSessionId,
|
|
886
|
-
},
|
|
887
|
-
};
|
|
888
|
-
}
|
|
889
|
-
catch (err) {
|
|
890
|
-
const code = err.code ?? 'E_GENERAL';
|
|
891
|
-
return engineError(code, err.message);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* orchestrate.startup - Initialize orchestration for an epic.
|
|
896
|
-
*
|
|
897
|
-
* Auto-initializes the RCASD-IVTR lifecycle at the 'research' stage if the
|
|
898
|
-
* epic has not already been initialized. This is idempotent — a second call
|
|
899
|
-
* detects the existing pipeline and skips re-initialization.
|
|
900
|
-
*
|
|
901
|
-
* Result data includes:
|
|
902
|
-
* - `autoInitialized` — true if this call created the lifecycle pipeline
|
|
903
|
-
* - `currentStage` — 'research' when newly initialized, 'already-initialized' otherwise
|
|
904
|
-
*
|
|
905
|
-
* @task T4478
|
|
906
|
-
* @task T785
|
|
907
|
-
*/
|
|
908
|
-
export async function orchestrateStartup(epicId, projectRoot) {
|
|
909
|
-
if (!epicId) {
|
|
910
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
911
|
-
}
|
|
912
|
-
try {
|
|
913
|
-
const root = projectRoot || resolveProjectRoot();
|
|
914
|
-
const accessor = await getAccessor(root);
|
|
915
|
-
const tasks = await loadTasks(root);
|
|
916
|
-
const epic = tasks.find((t) => t.id === epicId);
|
|
917
|
-
if (!epic) {
|
|
918
|
-
return engineError('E_NOT_FOUND', `Epic ${epicId} not found`);
|
|
919
|
-
}
|
|
920
|
-
const children = tasks.filter((t) => t.parentId === epicId);
|
|
921
|
-
const readyTasks = await getReadyTasks(epicId, root, accessor);
|
|
922
|
-
const ready = readyTasks.filter((t) => t.ready);
|
|
923
|
-
// Auto-initialize lifecycle at 'research' stage if not already initialized.
|
|
924
|
-
// getLifecycleStatus returns initialized:false when no pipeline exists.
|
|
925
|
-
// recordStageProgress creates the pipeline + stage record idempotently via
|
|
926
|
-
// ensureLifecycleContext, so re-invoking orchestrateStartup is safe.
|
|
927
|
-
const lifecycleStatus = await getLifecycleStatus(root, { epicId });
|
|
928
|
-
let autoInitialized = false;
|
|
929
|
-
let currentStage;
|
|
930
|
-
if (!lifecycleStatus.initialized) {
|
|
931
|
-
await recordStageProgress(root, { taskId: epicId, stage: 'research', status: 'in_progress' });
|
|
932
|
-
autoInitialized = true;
|
|
933
|
-
currentStage = 'research';
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
currentStage = 'already-initialized';
|
|
937
|
-
}
|
|
938
|
-
const summary = computeStartupSummary(epicId, epic.title, children, ready.length);
|
|
939
|
-
return { success: true, data: { ...summary, autoInitialized, currentStage } };
|
|
940
|
-
}
|
|
941
|
-
catch (err) {
|
|
942
|
-
const code = err.code ?? 'E_GENERAL';
|
|
943
|
-
return engineError(code, err.message);
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* orchestrate.bootstrap - Load brain state for agent bootstrapping
|
|
948
|
-
* @task T4478
|
|
949
|
-
* @task T4657
|
|
950
|
-
*/
|
|
951
|
-
export async function orchestrateBootstrap(projectRoot, params) {
|
|
952
|
-
try {
|
|
953
|
-
const root = projectRoot || resolveProjectRoot();
|
|
954
|
-
const accessor = await getAccessor(root);
|
|
955
|
-
const brain = await buildBrainState(root, params, accessor);
|
|
956
|
-
return { success: true, data: brain };
|
|
957
|
-
}
|
|
958
|
-
catch (err) {
|
|
959
|
-
return engineError('E_GENERAL', err.message);
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
/**
|
|
963
|
-
* orchestrate.critical-path - Find the longest dependency chain
|
|
964
|
-
* @task T4478
|
|
965
|
-
*/
|
|
966
|
-
export async function orchestrateCriticalPath(projectRoot) {
|
|
967
|
-
try {
|
|
968
|
-
const root = projectRoot || resolveProjectRoot();
|
|
969
|
-
const accessor = await getAccessor(root);
|
|
970
|
-
const result = await getCriticalPath(root, accessor);
|
|
971
|
-
return { success: true, data: result };
|
|
972
|
-
}
|
|
973
|
-
catch (err) {
|
|
974
|
-
return engineError('E_GENERAL', err.message);
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
/**
|
|
978
|
-
* orchestrate.unblock-opportunities - Analyze dependency graph for unblocking opportunities
|
|
979
|
-
* @task T4478
|
|
980
|
-
*/
|
|
981
|
-
export async function orchestrateUnblockOpportunities(projectRoot) {
|
|
982
|
-
try {
|
|
983
|
-
const root = projectRoot || resolveProjectRoot();
|
|
984
|
-
const accessor = await getAccessor(root);
|
|
985
|
-
const result = await getUnblockOpportunities(root, accessor);
|
|
986
|
-
return { success: true, data: result };
|
|
987
|
-
}
|
|
988
|
-
catch (err) {
|
|
989
|
-
return engineError('E_GENERAL', err.message);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
* orchestrate.parallel - Manage parallel execution (start/end)
|
|
994
|
-
* @task T4632
|
|
995
|
-
*/
|
|
996
|
-
export async function orchestrateParallel(action, epicId, wave, projectRoot) {
|
|
997
|
-
if (action === 'start') {
|
|
998
|
-
if (wave === undefined || wave === null) {
|
|
999
|
-
return engineError('E_INVALID_INPUT', 'wave number is required for start action');
|
|
1000
|
-
}
|
|
1001
|
-
return orchestrateParallelStart(epicId, wave, projectRoot);
|
|
1002
|
-
}
|
|
1003
|
-
if (action === 'end') {
|
|
1004
|
-
// wave is technically optional for end if we want to end ANY parallel execution,
|
|
1005
|
-
// but the current implementation expects wave.
|
|
1006
|
-
// However, endParallelExecution calls endParallelExecution(epicId, wave, root)
|
|
1007
|
-
if (wave === undefined || wave === null) {
|
|
1008
|
-
// If wave is not provided, maybe we can find the active one?
|
|
1009
|
-
// For now, let's require it to match the underlying signature or default to 0/current?
|
|
1010
|
-
// The underlying `endParallelExecution` signature is `(epicId: string, wave: number, root: string)`.
|
|
1011
|
-
// Let's require it for now to be safe, or check if we can improve this.
|
|
1012
|
-
return engineError('E_INVALID_INPUT', 'wave number is required for end action');
|
|
1013
|
-
}
|
|
1014
|
-
return orchestrateParallelEnd(epicId, wave, projectRoot);
|
|
1015
|
-
}
|
|
1016
|
-
return engineError('E_INVALID_INPUT', `Unknown parallel action: ${action}`);
|
|
1017
|
-
}
|
|
1018
|
-
/**
|
|
1019
|
-
* orchestrate.parallel.start - Start parallel execution for a wave
|
|
1020
|
-
* @task T4632
|
|
1021
|
-
*/
|
|
1022
|
-
export async function orchestrateParallelStart(epicId, wave, projectRoot) {
|
|
1023
|
-
if (!epicId) {
|
|
1024
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
1025
|
-
}
|
|
1026
|
-
if (wave === undefined || wave === null) {
|
|
1027
|
-
return engineError('E_INVALID_INPUT', 'wave number is required');
|
|
1028
|
-
}
|
|
1029
|
-
try {
|
|
1030
|
-
const root = projectRoot || resolveProjectRoot();
|
|
1031
|
-
const accessor = await getAccessor(root);
|
|
1032
|
-
const result = await startParallelExecution(epicId, wave, root, accessor);
|
|
1033
|
-
return { success: true, data: result };
|
|
1034
|
-
}
|
|
1035
|
-
catch (err) {
|
|
1036
|
-
return cleoErrorToEngineError(err, 'E_GENERAL', 'Failed to start parallel execution');
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
/**
|
|
1040
|
-
* orchestrate.parallel.end - End parallel execution for a wave
|
|
1041
|
-
* @task T4632
|
|
1042
|
-
*/
|
|
1043
|
-
export async function orchestrateParallelEnd(epicId, wave, projectRoot) {
|
|
1044
|
-
if (!epicId) {
|
|
1045
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
1046
|
-
}
|
|
1047
|
-
try {
|
|
1048
|
-
const root = projectRoot || resolveProjectRoot();
|
|
1049
|
-
const result = await endParallelExecution(epicId, wave, root);
|
|
1050
|
-
if (result.alreadyEnded) {
|
|
1051
|
-
return {
|
|
1052
|
-
success: true,
|
|
1053
|
-
data: {
|
|
1054
|
-
epicId,
|
|
1055
|
-
wave,
|
|
1056
|
-
message: 'No parallel execution was active',
|
|
1057
|
-
alreadyEnded: true,
|
|
1058
|
-
},
|
|
1059
|
-
};
|
|
1060
|
-
}
|
|
1061
|
-
return { success: true, data: result };
|
|
1062
|
-
}
|
|
1063
|
-
catch (err) {
|
|
1064
|
-
return cleoErrorToEngineError(err, 'E_GENERAL', 'Failed to end parallel execution');
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* orchestrate.check - Check current orchestration state
|
|
1069
|
-
* @task T4632
|
|
1070
|
-
*/
|
|
1071
|
-
export async function orchestrateCheck(projectRoot) {
|
|
1072
|
-
try {
|
|
1073
|
-
const root = projectRoot || resolveProjectRoot();
|
|
1074
|
-
const parallelState = await getParallelStatus(root);
|
|
1075
|
-
const tasks = await loadTasks(root);
|
|
1076
|
-
const activeTasks = tasks.filter((t) => t.status === 'active');
|
|
1077
|
-
const progress = computeProgress(tasks);
|
|
1078
|
-
return {
|
|
1079
|
-
success: true,
|
|
1080
|
-
data: {
|
|
1081
|
-
parallelExecution: {
|
|
1082
|
-
active: parallelState.active,
|
|
1083
|
-
epicId: parallelState.epicId || null,
|
|
1084
|
-
wave: parallelState.wave || null,
|
|
1085
|
-
tasks: parallelState.tasks || [],
|
|
1086
|
-
startedAt: parallelState.startedAt || null,
|
|
1087
|
-
},
|
|
1088
|
-
activeTasks: activeTasks.map((t) => ({ id: t.id, title: t.title, status: t.status })),
|
|
1089
|
-
progress,
|
|
1090
|
-
},
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
|
-
catch (err) {
|
|
1094
|
-
return engineError('E_GENERAL', err.message);
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* orchestrate.skill.inject - Read skill content for injection into agent context
|
|
1099
|
-
* @task T4632
|
|
1100
|
-
*/
|
|
1101
|
-
export function orchestrateSkillInject(skillName, projectRoot) {
|
|
1102
|
-
try {
|
|
1103
|
-
const root = projectRoot || resolveProjectRoot();
|
|
1104
|
-
const result = getSkillContent(skillName, root);
|
|
1105
|
-
return { success: true, data: result };
|
|
1106
|
-
}
|
|
1107
|
-
catch (err) {
|
|
1108
|
-
const code = err.code ?? 'E_GENERAL';
|
|
1109
|
-
return engineError(code, err.message);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
/**
|
|
1113
|
-
* orchestrate.handoff - Composite session handoff + successor spawn
|
|
1114
|
-
*
|
|
1115
|
-
* Step order is explicit and fixed:
|
|
1116
|
-
* 1) session.context.inject
|
|
1117
|
-
* 2) session.end
|
|
1118
|
-
* 3) orchestrate.spawn
|
|
1119
|
-
*
|
|
1120
|
-
* Idempotency policy:
|
|
1121
|
-
* - Non-idempotent overall. A retry after step 2 can duplicate spawn output.
|
|
1122
|
-
* - Failures include exact step state and a safe retry entry point.
|
|
1123
|
-
*/
|
|
1124
|
-
export async function orchestrateHandoff(params, projectRoot) {
|
|
1125
|
-
if (!params.taskId) {
|
|
1126
|
-
return engineError('E_INVALID_INPUT', 'taskId is required');
|
|
1127
|
-
}
|
|
1128
|
-
if (!params.protocolType) {
|
|
1129
|
-
return engineError('E_INVALID_INPUT', 'protocolType is required');
|
|
1130
|
-
}
|
|
1131
|
-
const root = projectRoot || resolveProjectRoot();
|
|
1132
|
-
const steps = {
|
|
1133
|
-
contextInject: { status: 'pending', operation: 'session.context.inject' },
|
|
1134
|
-
sessionEnd: { status: 'pending', operation: 'session.end' },
|
|
1135
|
-
spawn: { status: 'pending', operation: 'orchestrate.spawn' },
|
|
1136
|
-
};
|
|
1137
|
-
const idempotency = {
|
|
1138
|
-
key: params.idempotencyKey ?? null,
|
|
1139
|
-
policy: 'non-idempotent',
|
|
1140
|
-
safeRetryFrom: 'start',
|
|
1141
|
-
reason: 'session.end and orchestrate.spawn mutate state and may be executed independently on retry',
|
|
1142
|
-
};
|
|
1143
|
-
let activeSessionId = null;
|
|
1144
|
-
let endedSessionId = null;
|
|
1145
|
-
const failWithStep = (code, message, failedStep, safeRetryFrom) => {
|
|
1146
|
-
idempotency.safeRetryFrom = safeRetryFrom;
|
|
1147
|
-
return engineError(code, message, {
|
|
1148
|
-
details: {
|
|
1149
|
-
failedStep,
|
|
1150
|
-
activeSessionId,
|
|
1151
|
-
endedSessionId,
|
|
1152
|
-
idempotency,
|
|
1153
|
-
steps,
|
|
1154
|
-
},
|
|
1155
|
-
fix: safeRetryFrom === 'orchestrate.spawn'
|
|
1156
|
-
? 'Retry only step 3 with mutate orchestrate spawn'
|
|
1157
|
-
: 'Retry from step 1 with mutate orchestrate handoff',
|
|
1158
|
-
alternatives: [
|
|
1159
|
-
{
|
|
1160
|
-
action: 'Run canonical multi-op fallback manually',
|
|
1161
|
-
command: 'mutate session context.inject -> mutate session end -> mutate orchestrate spawn',
|
|
1162
|
-
},
|
|
1163
|
-
],
|
|
1164
|
-
});
|
|
1165
|
-
};
|
|
1166
|
-
const preflight = await sessionStatus(root);
|
|
1167
|
-
if (!preflight.success) {
|
|
1168
|
-
return failWithStep(preflight.error?.code ?? 'E_NOT_INITIALIZED', preflight.error?.message ?? 'Unable to load session status', 'session.context.inject', 'start');
|
|
1169
|
-
}
|
|
1170
|
-
if (!preflight.data?.hasActiveSession || !preflight.data.session?.id) {
|
|
1171
|
-
steps.contextInject.status = 'skipped';
|
|
1172
|
-
steps.contextInject.message = 'No active session available for handoff';
|
|
1173
|
-
steps.sessionEnd.status = 'skipped';
|
|
1174
|
-
steps.sessionEnd.message = 'No active session available for handoff';
|
|
1175
|
-
steps.spawn.status = 'skipped';
|
|
1176
|
-
steps.spawn.message = 'No active session available for handoff';
|
|
1177
|
-
return failWithStep('E_SESSION_REQUIRED', 'orchestrate.handoff requires an active session', 'session.end', 'start');
|
|
1178
|
-
}
|
|
1179
|
-
activeSessionId = preflight.data.session.id;
|
|
1180
|
-
const injectResult = sessionContextInject(params.protocolType, { taskId: params.taskId, variant: params.variant }, root);
|
|
1181
|
-
if (!injectResult.success) {
|
|
1182
|
-
steps.contextInject.status = 'failed';
|
|
1183
|
-
steps.contextInject.message = injectResult.error?.message;
|
|
1184
|
-
steps.sessionEnd.status = 'skipped';
|
|
1185
|
-
steps.sessionEnd.message = 'Blocked by session.context.inject failure';
|
|
1186
|
-
steps.spawn.status = 'skipped';
|
|
1187
|
-
steps.spawn.message = 'Blocked by session.context.inject failure';
|
|
1188
|
-
return failWithStep(injectResult.error?.code ?? 'E_GENERAL', injectResult.error?.message ?? 'Failed to inject handoff context', 'session.context.inject', 'start');
|
|
1189
|
-
}
|
|
1190
|
-
steps.contextInject.status = 'completed';
|
|
1191
|
-
steps.contextInject.message = 'Handoff context injected';
|
|
1192
|
-
const endResult = await sessionEnd(root, params.note);
|
|
1193
|
-
if (!endResult.success) {
|
|
1194
|
-
steps.sessionEnd.status = 'failed';
|
|
1195
|
-
steps.sessionEnd.message = endResult.error?.message;
|
|
1196
|
-
steps.spawn.status = 'skipped';
|
|
1197
|
-
steps.spawn.message = 'Blocked by session.end failure';
|
|
1198
|
-
return failWithStep(endResult.error?.code ?? 'E_GENERAL', endResult.error?.message ?? 'Failed to end predecessor session', 'session.end', 'start');
|
|
1199
|
-
}
|
|
1200
|
-
endedSessionId = endResult.data?.sessionId ?? null;
|
|
1201
|
-
if (endedSessionId !== activeSessionId) {
|
|
1202
|
-
steps.sessionEnd.status = 'failed';
|
|
1203
|
-
steps.sessionEnd.message = `Ended session '${endedSessionId ?? 'null'}' does not match active session '${activeSessionId}'`;
|
|
1204
|
-
steps.spawn.status = 'skipped';
|
|
1205
|
-
steps.spawn.message = 'Blocked by session mismatch';
|
|
1206
|
-
return failWithStep('E_CONCURRENT_SESSION', 'Active session changed during orchestrate.handoff', 'session.end', 'start');
|
|
1207
|
-
}
|
|
1208
|
-
steps.sessionEnd.status = 'completed';
|
|
1209
|
-
steps.sessionEnd.message = `Ended session ${endedSessionId}`;
|
|
1210
|
-
const spawnResult = await orchestrateSpawn(params.taskId, params.protocolType, root, params.tier);
|
|
1211
|
-
if (!spawnResult.success) {
|
|
1212
|
-
steps.spawn.status = 'failed';
|
|
1213
|
-
steps.spawn.message = spawnResult.error?.message;
|
|
1214
|
-
return failWithStep(spawnResult.error?.code ?? 'E_GENERAL', spawnResult.error?.message ?? 'Failed to prepare successor spawn context', 'orchestrate.spawn', 'orchestrate.spawn');
|
|
1215
|
-
}
|
|
1216
|
-
steps.spawn.status = 'completed';
|
|
1217
|
-
steps.spawn.message = `Spawn prepared for ${params.taskId}`;
|
|
1218
|
-
// Best-effort: record handoff event in conduit.db so orchestrators and
|
|
1219
|
-
// observers can track session transitions. Never blocks the return.
|
|
1220
|
-
void sendConduitEvent(root, 'cleo-core', {
|
|
1221
|
-
event: 'orchestrate.handoff',
|
|
1222
|
-
taskId: params.taskId,
|
|
1223
|
-
protocolType: params.protocolType,
|
|
1224
|
-
predecessorSessionId: activeSessionId,
|
|
1225
|
-
endedSessionId,
|
|
1226
|
-
note: params.note ?? null,
|
|
1227
|
-
nextAction: params.nextAction ?? null,
|
|
1228
|
-
handoffAt: new Date().toISOString(),
|
|
1229
|
-
});
|
|
1230
|
-
return {
|
|
1231
|
-
success: true,
|
|
1232
|
-
data: {
|
|
1233
|
-
taskId: params.taskId,
|
|
1234
|
-
predecessorSessionId: activeSessionId,
|
|
1235
|
-
endedSessionId,
|
|
1236
|
-
protocolType: params.protocolType,
|
|
1237
|
-
note: params.note ?? null,
|
|
1238
|
-
nextAction: params.nextAction ?? null,
|
|
1239
|
-
idempotency,
|
|
1240
|
-
steps,
|
|
1241
|
-
contextInject: injectResult.data,
|
|
1242
|
-
spawn: spawnResult.data,
|
|
1243
|
-
},
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
/**
|
|
1247
|
-
* Prefix-based classifier stub used until T891 wires the CANT team registry.
|
|
1248
|
-
*
|
|
1249
|
-
* Mapping: task-id or title prefix → agentId. The lookup is conservative — if
|
|
1250
|
-
* nothing matches, the caller receives `'cleo-subagent'` so resolution still
|
|
1251
|
-
* succeeds at the fallback tier.
|
|
1252
|
-
*
|
|
1253
|
-
* @task T889 / W3-6
|
|
1254
|
-
*/
|
|
1255
|
-
const CLASSIFIER_RULES = [
|
|
1256
|
-
{ test: /^(docs?|doc)[:\s-]/i, agentId: 'docs-worker' },
|
|
1257
|
-
{ test: /^tests?[:\s-]/i, agentId: 'tests-worker' },
|
|
1258
|
-
{ test: /^release[:\s-]/i, agentId: 'release-worker' },
|
|
1259
|
-
{ test: /^security[:\s-]/i, agentId: 'security-worker' },
|
|
1260
|
-
];
|
|
1261
|
-
/**
|
|
1262
|
-
* Derive the agentId to classify a task against. Applied before resolver
|
|
1263
|
-
* lookup so graceful fallback can swap in `'cleo-subagent'` when the row
|
|
1264
|
-
* is absent.
|
|
1265
|
-
*
|
|
1266
|
-
* @param task - Task whose title/labels guide the classifier.
|
|
1267
|
-
* @returns Agent business id to resolve.
|
|
1268
|
-
* @task T889 / W3-6
|
|
1269
|
-
*/
|
|
1270
|
-
function classifyTaskToAgent(task) {
|
|
1271
|
-
const title = task.title ?? '';
|
|
1272
|
-
for (const rule of CLASSIFIER_RULES) {
|
|
1273
|
-
if (rule.test.test(title))
|
|
1274
|
-
return rule.agentId;
|
|
1275
|
-
}
|
|
1276
|
-
// Label-based fallback: honour the first label that names a known worker.
|
|
1277
|
-
for (const label of task.labels ?? []) {
|
|
1278
|
-
for (const rule of CLASSIFIER_RULES) {
|
|
1279
|
-
if (rule.test.test(label))
|
|
1280
|
-
return rule.agentId;
|
|
1281
|
-
}
|
|
1282
|
-
}
|
|
1283
|
-
return 'cleo-subagent';
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
* Map an `orchLevel` integer to a {@link PlanWorkerEntry.role} label.
|
|
1287
|
-
*
|
|
1288
|
-
* @param orchLevel - 0 (orchestrator), 1 (lead), or 2+ (worker).
|
|
1289
|
-
* @returns Role string.
|
|
1290
|
-
* @task T889 / W3-6
|
|
1291
|
-
*/
|
|
1292
|
-
function orchLevelToRole(orchLevel) {
|
|
1293
|
-
if (orchLevel <= 0)
|
|
1294
|
-
return 'orchestrator';
|
|
1295
|
-
if (orchLevel === 1)
|
|
1296
|
-
return 'lead';
|
|
1297
|
-
return 'worker';
|
|
1298
|
-
}
|
|
1299
|
-
/**
|
|
1300
|
-
* Map a role to its canonical protocol tier.
|
|
1301
|
-
*
|
|
1302
|
-
* Per W3-6 spec: orchestrator → 2, lead → 1, worker → 0. This inversion of
|
|
1303
|
-
* the `orchLevel` numbering keeps higher-privilege roles on higher tiers
|
|
1304
|
-
* (tier 2 = full protocol, tier 0 = minimal prompt).
|
|
1305
|
-
*
|
|
1306
|
-
* @param role - Role label.
|
|
1307
|
-
* @returns Tier 0, 1, or 2.
|
|
1308
|
-
* @task T889 / W3-6
|
|
1309
|
-
*/
|
|
1310
|
-
function roleToTier(role) {
|
|
1311
|
-
if (role === 'orchestrator')
|
|
1312
|
-
return 2;
|
|
1313
|
-
if (role === 'lead')
|
|
1314
|
-
return 1;
|
|
1315
|
-
return 0;
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* Compute a deterministic sha256 over the plan's input snapshot so callers
|
|
1319
|
-
* can detect whether identical inputs produced the same plan.
|
|
1320
|
-
*
|
|
1321
|
-
* Hashed tuple: `(taskId, status, updatedAt || '', dependsOn.sort().join(','))`
|
|
1322
|
-
* for every child in lexicographic task-id order, then the `epicId` as a
|
|
1323
|
-
* trailing component. `generatedAt` is intentionally excluded — it would
|
|
1324
|
-
* make every plan non-deterministic by construction.
|
|
1325
|
-
*
|
|
1326
|
-
* @param epicId - Epic id the plan targets.
|
|
1327
|
-
* @param children - Child tasks considered (snapshot).
|
|
1328
|
-
* @returns Hex-encoded sha256 digest.
|
|
1329
|
-
* @task T889 / W3-6
|
|
1330
|
-
*/
|
|
1331
|
-
function computePlanInputHash(epicId, children) {
|
|
1332
|
-
const sorted = [...children].sort((a, b) => a.id.localeCompare(b.id));
|
|
1333
|
-
const parts = sorted.map((t) => {
|
|
1334
|
-
const depends = (t.depends ?? []).slice().sort().join(',');
|
|
1335
|
-
return `${t.id}|${t.status ?? ''}|${t.updatedAt ?? ''}|${depends}`;
|
|
1336
|
-
});
|
|
1337
|
-
parts.push(`epic:${epicId}`);
|
|
1338
|
-
return createHash('sha256').update(parts.join('\n')).digest('hex');
|
|
1339
|
-
}
|
|
1340
|
-
/**
|
|
1341
|
-
* Resolve a task's agent row with graceful fallback.
|
|
1342
|
-
*
|
|
1343
|
-
* On success returns the `ResolvedAgent`. On `AgentNotFoundError` (or any
|
|
1344
|
-
* other resolver failure), returns `null` so the caller can substitute
|
|
1345
|
-
* `'cleo-subagent'` and emit a warning.
|
|
1346
|
-
*
|
|
1347
|
-
* @param db - Open global signaldock.db handle (caller owns lifecycle).
|
|
1348
|
-
* @param agentId - Business id from the classifier.
|
|
1349
|
-
* @param preferTier - Optional preferred registry tier.
|
|
1350
|
-
* @returns Resolved row or `null` when unresolved.
|
|
1351
|
-
* @task T889 / W3-6
|
|
1352
|
-
*/
|
|
1353
|
-
function resolveAgentGraceful(db, agentId, preferTier) {
|
|
1354
|
-
try {
|
|
1355
|
-
return resolveAgent(db, agentId, preferTier ? { preferTier } : {});
|
|
1356
|
-
}
|
|
1357
|
-
catch (err) {
|
|
1358
|
-
if (err instanceof AgentNotFoundError)
|
|
1359
|
-
return null;
|
|
1360
|
-
throw err;
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
/**
|
|
1364
|
-
* Generate a deterministic, machine-readable execution plan for an epic.
|
|
1365
|
-
*
|
|
1366
|
-
* The plan groups children into waves via the same topological sort used by
|
|
1367
|
-
* `orchestrate ready --epic` and `orchestrate waves` (`getEnrichedWaves`),
|
|
1368
|
-
* then enriches every task with a classifier agent id, resolved persona,
|
|
1369
|
-
* atomic scope (AC.files), and role/tier derived from the resolved agent's
|
|
1370
|
-
* `orchLevel`. Each wave exposes a `leadTaskId` (first lead or, failing
|
|
1371
|
-
* that, the first orchestrator) to simplify downstream spawn dispatch.
|
|
1372
|
-
*
|
|
1373
|
-
* Determinism: given identical inputs (task snapshot + epic id), the
|
|
1374
|
-
* function returns the same `inputHash`. `generatedAt` is NOT part of the
|
|
1375
|
-
* hash so two back-to-back invocations confirm reproducibility by hash
|
|
1376
|
-
* equality.
|
|
1377
|
-
*
|
|
1378
|
-
* Validation: rejects non-epic ids (`type !== 'epic'` AND no children) with
|
|
1379
|
-
* `E_VALIDATION`; rejects missing epics with `E_NOT_FOUND`.
|
|
1380
|
-
*
|
|
1381
|
-
* @param input - {@link OrchestratePlanInput} envelope.
|
|
1382
|
-
* @returns Engine result wrapping {@link OrchestratePlanResult}.
|
|
1383
|
-
* @task T889 / W3-6
|
|
1384
|
-
*/
|
|
1385
|
-
export async function orchestratePlan(input) {
|
|
1386
|
-
if (!input?.epicId) {
|
|
1387
|
-
return engineError('E_INVALID_INPUT', 'epicId is required');
|
|
1388
|
-
}
|
|
1389
|
-
const root = input.projectRoot || resolveProjectRoot();
|
|
1390
|
-
try {
|
|
1391
|
-
const tasks = await loadTasks(root);
|
|
1392
|
-
const epic = tasks.find((t) => t.id === input.epicId);
|
|
1393
|
-
if (!epic) {
|
|
1394
|
-
return engineError('E_NOT_FOUND', `Epic ${input.epicId} not found`);
|
|
1395
|
-
}
|
|
1396
|
-
const children = tasks.filter((t) => t.parentId === input.epicId);
|
|
1397
|
-
const isEpic = epic.type === 'epic' || children.length > 0;
|
|
1398
|
-
if (!isEpic) {
|
|
1399
|
-
return engineError('E_VALIDATION', `Task ${input.epicId} is not an epic (type=${epic.type ?? 'unknown'}, children=${children.length})`, {
|
|
1400
|
-
fix: `Run 'cleo add --parent ${input.epicId}' to add children, or select a real epic id.`,
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
// Reuse the canonical wave computation used by orchestrate ready / waves.
|
|
1404
|
-
const accessor = await getAccessor(root);
|
|
1405
|
-
const enriched = await getEnrichedWaves(input.epicId, root, accessor);
|
|
1406
|
-
// Open a short-lived handle to the global signaldock.db for resolver lookups.
|
|
1407
|
-
// We intentionally do NOT cache this handle — the resolver contract owns
|
|
1408
|
-
// its own lifecycle and we close after the batch.
|
|
1409
|
-
await ensureGlobalSignaldockDb();
|
|
1410
|
-
const dbPath = getGlobalSignaldockDbPath();
|
|
1411
|
-
const db = new _DatabaseSyncCtor(dbPath);
|
|
1412
|
-
db.exec('PRAGMA foreign_keys = ON');
|
|
1413
|
-
const warnings = [];
|
|
1414
|
-
const preferTier = input.preferTier === undefined ? undefined : numericToAgentTier(input.preferTier);
|
|
1415
|
-
const plannedWaves = [];
|
|
1416
|
-
try {
|
|
1417
|
-
for (const wave of enriched.waves) {
|
|
1418
|
-
const workers = [];
|
|
1419
|
-
for (const taskRef of wave.tasks) {
|
|
1420
|
-
const task = children.find((c) => c.id === taskRef.id);
|
|
1421
|
-
if (!task)
|
|
1422
|
-
continue;
|
|
1423
|
-
const classifiedAgentId = classifyTaskToAgent(task);
|
|
1424
|
-
const resolved = resolveAgentGraceful(db, classifiedAgentId, preferTier);
|
|
1425
|
-
let persona = classifiedAgentId;
|
|
1426
|
-
let orchLevel = 2; // default to worker
|
|
1427
|
-
if (resolved) {
|
|
1428
|
-
persona = resolved.agentId;
|
|
1429
|
-
orchLevel = resolved.orchLevel;
|
|
1430
|
-
if (resolved.resolverWarning) {
|
|
1431
|
-
warnings.push({
|
|
1432
|
-
taskId: task.id,
|
|
1433
|
-
code: 'agent_fallback_universal_base',
|
|
1434
|
-
message: resolved.resolverWarning,
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
else {
|
|
1439
|
-
persona = 'cleo-subagent';
|
|
1440
|
-
// Try to resolve the fallback too so we pick up its orchLevel
|
|
1441
|
-
// (packaged seed agents ship with orchLevel 2). If even the
|
|
1442
|
-
// fallback misses, keep orchLevel at the worker default.
|
|
1443
|
-
const fallback = resolveAgentGraceful(db, 'cleo-subagent', preferTier);
|
|
1444
|
-
if (fallback)
|
|
1445
|
-
orchLevel = fallback.orchLevel;
|
|
1446
|
-
warnings.push({
|
|
1447
|
-
taskId: task.id,
|
|
1448
|
-
code: 'E_AGENT_NOT_FOUND',
|
|
1449
|
-
message: `Classifier produced '${classifiedAgentId}' for ${task.id}; agent not registered. Falling back to 'cleo-subagent'.`,
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
const role = orchLevelToRole(orchLevel);
|
|
1453
|
-
const tier = roleToTier(role);
|
|
1454
|
-
const files = task.files ?? [];
|
|
1455
|
-
if (role === 'worker' && files.length === 0) {
|
|
1456
|
-
warnings.push({
|
|
1457
|
-
taskId: task.id,
|
|
1458
|
-
code: 'W_NO_ATOMIC_SCOPE',
|
|
1459
|
-
message: `Worker task ${task.id} has no AC.files declared; atomicScope will be empty and may be rejected by checkAtomicity.`,
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
const dependsOn = (task.depends ?? []).slice().sort();
|
|
1463
|
-
workers.push({
|
|
1464
|
-
taskId: task.id,
|
|
1465
|
-
title: task.title ?? task.id,
|
|
1466
|
-
persona,
|
|
1467
|
-
tier,
|
|
1468
|
-
role,
|
|
1469
|
-
atomicScope: { files: [...files] },
|
|
1470
|
-
orchLevel,
|
|
1471
|
-
status: task.status,
|
|
1472
|
-
dependsOn,
|
|
1473
|
-
});
|
|
1474
|
-
}
|
|
1475
|
-
// Lead selection: first lead; else first orchestrator; else null.
|
|
1476
|
-
const leadWorker = workers.find((w) => w.role === 'lead') ??
|
|
1477
|
-
workers.find((w) => w.role === 'orchestrator') ??
|
|
1478
|
-
null;
|
|
1479
|
-
plannedWaves.push({
|
|
1480
|
-
wave: wave.waveNumber,
|
|
1481
|
-
leadTaskId: leadWorker ? leadWorker.taskId : null,
|
|
1482
|
-
workers,
|
|
1483
|
-
});
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
finally {
|
|
1487
|
-
db.close();
|
|
1488
|
-
}
|
|
1489
|
-
const inputHash = computePlanInputHash(input.epicId, children);
|
|
1490
|
-
return {
|
|
1491
|
-
success: true,
|
|
1492
|
-
data: {
|
|
1493
|
-
epicId: input.epicId,
|
|
1494
|
-
epicTitle: epic.title ?? input.epicId,
|
|
1495
|
-
totalTasks: children.length,
|
|
1496
|
-
waves: plannedWaves,
|
|
1497
|
-
generatedAt: new Date().toISOString(),
|
|
1498
|
-
deterministic: true,
|
|
1499
|
-
inputHash,
|
|
1500
|
-
warnings,
|
|
1501
|
-
},
|
|
1502
|
-
};
|
|
1503
|
-
}
|
|
1504
|
-
catch (err) {
|
|
1505
|
-
const code = err.code ?? 'E_GENERAL';
|
|
1506
|
-
return engineError(code, err.message);
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
/**
|
|
1510
|
-
* Map a numeric tier (0|1|2) used by the CLI/domain boundary to the
|
|
1511
|
-
* string-typed {@link AgentTier} understood by the resolver.
|
|
1512
|
-
*
|
|
1513
|
-
* @param tier - Numeric tier from input.
|
|
1514
|
-
* @returns Resolver-compatible tier or `undefined` when out of range.
|
|
1515
|
-
* @task T889 / W3-6
|
|
1516
|
-
*/
|
|
1517
|
-
function numericToAgentTier(tier) {
|
|
1518
|
-
if (tier === 0)
|
|
1519
|
-
return 'project';
|
|
1520
|
-
if (tier === 1)
|
|
1521
|
-
return 'global';
|
|
1522
|
-
if (tier === 2)
|
|
1523
|
-
return 'packaged';
|
|
1524
|
-
return undefined;
|
|
1525
|
-
}
|
|
1526
|
-
//# sourceMappingURL=orchestrate-engine.js.map
|