@fitlab-ai/agent-infra 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/README.zh-CN.md +12 -9
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +134 -108
- package/dist/lib/agent-clients/adapter.js +137 -4
- package/dist/lib/agent-clients/adapters/antigravity-cli.js +64 -0
- package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js} +4 -14
- package/dist/lib/agent-clients/adapters/claude-code-refresh.js +85 -0
- package/dist/lib/agent-clients/adapters/claude-code-sandbox.js +247 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +27 -4
- package/dist/lib/agent-clients/adapters/codex.js +9 -0
- package/dist/lib/agent-clients/adapters/index.js +2 -2
- package/dist/lib/agent-clients/adapters/opencode-sandbox.js +108 -0
- package/dist/lib/agent-clients/adapters/opencode.js +24 -3
- package/dist/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/dist/lib/agent-clients/config.js +42 -4
- package/dist/lib/agent-clients/next-steps.js +11 -2
- package/dist/lib/agent-clients/reconcile.js +2 -1
- package/dist/lib/agent-clients/registry.js +16 -2
- package/dist/lib/agent-clients/schema.js +18 -0
- package/dist/lib/agent-clients/tokens.js +49 -0
- package/dist/lib/agent-clients/types.js +1 -1
- package/dist/lib/defaults.json +1 -1
- package/dist/lib/git/workflow.js +54 -1
- package/dist/lib/internal/agent-client.js +61 -4
- package/dist/lib/internal/git-workflow.js +6 -1
- package/dist/lib/internal/platform-checks.js +3 -3
- package/dist/lib/internal/platform-comment.js +29 -2
- package/dist/lib/internal/platform-issue.js +7 -0
- package/dist/lib/internal/platform-pr-review.js +132 -0
- package/dist/lib/internal/platform-pr.js +20 -2
- package/dist/lib/internal/platform-release-notes.js +52 -16
- package/dist/lib/internal/pr-review-grade.js +140 -0
- package/dist/lib/internal/release-workflow.js +13 -6
- package/dist/lib/internal/sandbox-control.js +24 -0
- package/dist/lib/internal/task-activity.js +105 -0
- package/dist/lib/internal/task-event.js +17 -1
- package/dist/lib/internal/task-ledger.js +12 -3
- package/dist/lib/internal/task-lifecycle.js +26 -1
- package/dist/lib/internal/task-orchestration.js +167 -18
- package/dist/lib/internal/task-review.js +8 -3
- package/dist/lib/platform/adapters.js +8 -1
- package/dist/lib/platform/completion-backfill.js +122 -0
- package/dist/lib/platform/github-client.js +19 -2
- package/dist/lib/platform/issue-comments.js +3 -2
- package/dist/lib/platform/merged-pr-equivalence.js +115 -5
- package/dist/lib/platform/pr-checks.js +65 -42
- package/dist/lib/platform/pr-review.js +166 -0
- package/dist/lib/platform/pull-requests.js +371 -4
- package/dist/lib/platform/release-notes.js +85 -3
- package/dist/lib/platform/releases.js +13 -5
- package/dist/lib/pr-review/evidence-grading.js +229 -0
- package/dist/lib/process-data/index.js +239 -0
- package/dist/lib/process-data/normalize.js +198 -0
- package/dist/lib/process-data/privacy.js +33 -0
- package/dist/lib/process-data/reconcile.js +95 -0
- package/dist/lib/process-data/repair.js +58 -0
- package/dist/lib/process-data/sources.js +345 -0
- package/dist/lib/process-data/store.js +282 -0
- package/dist/lib/process-data/types.js +2 -0
- package/dist/lib/run/index.js +4 -3
- package/dist/lib/run/tui.js +10 -13
- package/dist/lib/sandbox/agent-client-reconciler.js +26 -2
- package/dist/lib/sandbox/capture.js +7 -2
- package/dist/lib/sandbox/commands/create.js +109 -248
- package/dist/lib/sandbox/commands/enter.js +15 -47
- package/dist/lib/sandbox/commands/list-running.js +16 -6
- package/dist/lib/sandbox/commands/ls.js +10 -6
- package/dist/lib/sandbox/commands/rebuild.js +4 -3
- package/dist/lib/sandbox/commands/refresh.js +4 -84
- package/dist/lib/sandbox/commands/rm.js +24 -3
- package/dist/lib/sandbox/commands/show.js +13 -4
- package/dist/lib/sandbox/commands/start.js +7 -4
- package/dist/lib/sandbox/config.js +2 -0
- package/dist/lib/sandbox/constants.js +6 -0
- package/dist/lib/sandbox/control/client.js +44 -0
- package/dist/lib/sandbox/control/protocol.js +35 -0
- package/dist/lib/sandbox/control/server.js +109 -0
- package/dist/lib/sandbox/dockerfile.js +36 -13
- package/dist/lib/sandbox/mounts.js +17 -4
- package/dist/lib/sandbox/recovery.js +128 -5
- package/dist/lib/sandbox/redaction.js +12 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/dist/lib/sandbox/workspace-identity.js +95 -0
- package/dist/lib/sandbox/workspace-view.js +103 -0
- package/dist/lib/task/activity-intent.js +307 -0
- package/dist/lib/task/artifact-lifecycle.js +2 -1
- package/dist/lib/task/commands/log.js +15 -14
- package/dist/lib/task/commit-finalization.js +267 -0
- package/dist/lib/task/commit-intent.js +165 -0
- package/dist/lib/task/decision-intents.js +31 -17
- package/dist/lib/task/delegation-receipts.js +25 -4
- package/dist/lib/task/events.js +67 -28
- package/dist/lib/task/finalization-artifacts.js +35 -0
- package/dist/lib/task/implementation-inputs.js +54 -7
- package/dist/lib/task/ledger-intents.js +35 -1
- package/dist/lib/task/lifecycle-execution.js +46 -0
- package/dist/lib/task/orchestration.js +753 -54
- package/dist/lib/task/resolve-ref.js +41 -1
- package/dist/lib/task/review-finalization.js +29 -9
- package/dist/lib/task/task-execution-lock.js +231 -0
- package/dist/lib/task/verification-checks.js +1 -1
- package/dist/lib/task/verification-engine.js +218 -2
- package/dist/lib/task/verification.js +4 -3
- package/dist/lib/task/workspace-snapshot.js +17 -5
- package/lib/agent-clients/adapter.ts +201 -4
- package/lib/agent-clients/adapters/antigravity-cli.ts +65 -0
- package/lib/{sandbox/credentials.ts → agent-clients/adapters/claude-code-credentials.ts} +3 -18
- package/lib/agent-clients/adapters/claude-code-refresh.ts +128 -0
- package/lib/agent-clients/adapters/claude-code-sandbox.ts +295 -0
- package/lib/agent-clients/adapters/claude-code.ts +31 -4
- package/lib/agent-clients/adapters/codex.ts +9 -0
- package/lib/agent-clients/adapters/index.ts +2 -2
- package/lib/agent-clients/adapters/opencode-sandbox.ts +136 -0
- package/lib/agent-clients/adapters/opencode.ts +27 -3
- package/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/lib/agent-clients/config.ts +49 -4
- package/lib/agent-clients/next-steps.ts +15 -2
- package/lib/agent-clients/reconcile.ts +2 -1
- package/lib/agent-clients/registry.ts +19 -1
- package/lib/agent-clients/schema.ts +18 -0
- package/lib/agent-clients/tokens.ts +53 -0
- package/lib/agent-clients/types.ts +15 -1
- package/lib/defaults.json +1 -1
- package/lib/git/workflow.ts +66 -2
- package/lib/internal/agent-client.ts +59 -4
- package/lib/internal/git-workflow.ts +5 -1
- package/lib/internal/platform-checks.ts +4 -4
- package/lib/internal/platform-comment.ts +17 -2
- package/lib/internal/platform-issue.ts +4 -0
- package/lib/internal/platform-pr-review.ts +104 -0
- package/lib/internal/platform-pr.ts +14 -1
- package/lib/internal/platform-release-notes.ts +59 -16
- package/lib/internal/pr-review-grade.ts +130 -0
- package/lib/internal/release-workflow.ts +13 -6
- package/lib/internal/sandbox-control.ts +24 -0
- package/lib/internal/task-activity.ts +91 -0
- package/lib/internal/task-event.ts +9 -1
- package/lib/internal/task-ledger.ts +12 -3
- package/lib/internal/task-lifecycle.ts +26 -1
- package/lib/internal/task-orchestration.ts +123 -14
- package/lib/internal/task-review.ts +8 -3
- package/lib/platform/adapters.ts +29 -2
- package/lib/platform/completion-backfill.ts +134 -0
- package/lib/platform/github-client.ts +20 -2
- package/lib/platform/issue-comments.ts +3 -2
- package/lib/platform/merged-pr-equivalence.ts +127 -5
- package/lib/platform/pr-checks.ts +73 -46
- package/lib/platform/pr-review.ts +201 -0
- package/lib/platform/pull-requests.ts +444 -3
- package/lib/platform/release-notes.ts +100 -4
- package/lib/platform/releases.ts +16 -4
- package/lib/pr-review/evidence-grading.ts +318 -0
- package/lib/process-data/index.ts +224 -0
- package/lib/process-data/normalize.ts +202 -0
- package/lib/process-data/privacy.ts +41 -0
- package/lib/process-data/reconcile.ts +110 -0
- package/lib/process-data/repair.ts +64 -0
- package/lib/process-data/sources.ts +354 -0
- package/lib/process-data/store.ts +315 -0
- package/lib/process-data/types.ts +135 -0
- package/lib/run/index.ts +5 -3
- package/lib/run/tui.ts +14 -12
- package/lib/sandbox/agent-client-reconciler.ts +44 -2
- package/lib/sandbox/capture.ts +9 -2
- package/lib/sandbox/commands/create.ts +126 -280
- package/lib/sandbox/commands/enter.ts +13 -59
- package/lib/sandbox/commands/list-running.ts +23 -6
- package/lib/sandbox/commands/ls.ts +22 -6
- package/lib/sandbox/commands/rebuild.ts +4 -3
- package/lib/sandbox/commands/refresh.ts +4 -126
- package/lib/sandbox/commands/rm.ts +24 -3
- package/lib/sandbox/commands/show.ts +30 -4
- package/lib/sandbox/commands/start.ts +6 -4
- package/lib/sandbox/config.ts +4 -0
- package/lib/sandbox/constants.ts +8 -0
- package/lib/sandbox/control/client.ts +55 -0
- package/lib/sandbox/control/protocol.ts +75 -0
- package/lib/sandbox/control/server.ts +117 -0
- package/lib/sandbox/dockerfile.ts +66 -13
- package/lib/sandbox/mounts.ts +24 -4
- package/lib/sandbox/recovery.ts +163 -6
- package/lib/sandbox/redaction.ts +14 -0
- package/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/lib/sandbox/tool-types.ts +16 -0
- package/lib/sandbox/workspace-identity.ts +123 -0
- package/lib/sandbox/workspace-view.ts +143 -0
- package/lib/server/server.schema.json +2 -2
- package/lib/task/activity-intent.ts +417 -0
- package/lib/task/artifact-lifecycle.ts +2 -1
- package/lib/task/commands/log.ts +15 -14
- package/lib/task/commit-finalization.ts +356 -0
- package/lib/task/commit-intent.ts +230 -0
- package/lib/task/decision-intents.ts +32 -12
- package/lib/task/delegation-receipts.ts +34 -5
- package/lib/task/events.ts +75 -30
- package/lib/task/finalization-artifacts.ts +58 -0
- package/lib/task/implementation-inputs.ts +62 -8
- package/lib/task/ledger-intents.ts +43 -3
- package/lib/task/lifecycle-execution.ts +106 -0
- package/lib/task/orchestration.ts +1019 -72
- package/lib/task/resolve-ref.ts +46 -1
- package/lib/task/review-finalization.ts +40 -9
- package/lib/task/task-execution-lock.ts +296 -0
- package/lib/task/verification-checks.ts +1 -1
- package/lib/task/verification-engine.ts +249 -2
- package/lib/task/verification.ts +5 -3
- package/lib/task/workspace-snapshot.ts +26 -5
- package/package.json +3 -3
- package/templates/.agents/QUICKSTART.en.md +25 -8
- package/templates/.agents/QUICKSTART.zh-CN.md +25 -8
- package/templates/.agents/README.en.md +10 -7
- package/templates/.agents/README.zh-CN.md +10 -7
- package/templates/.agents/hooks/lifecycle-delegation.js +15 -4
- package/templates/.agents/rules/README.en.md +1 -1
- package/templates/.agents/rules/README.zh-CN.md +1 -1
- package/templates/.agents/rules/create-issue.github.en.md +4 -2
- package/templates/.agents/rules/create-issue.github.zh-CN.md +4 -2
- package/templates/.agents/rules/human-decision-context.en.md +11 -2
- package/templates/.agents/rules/human-decision-context.zh-CN.md +11 -2
- package/templates/.agents/rules/issue-fields.github.en.md +3 -1
- package/templates/.agents/rules/issue-fields.github.zh-CN.md +3 -1
- package/templates/.agents/rules/issue-pr-commands.en.md +5 -3
- package/templates/.agents/rules/issue-pr-commands.github.en.md +5 -3
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +5 -3
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +5 -3
- package/templates/.agents/rules/issue-sync.github.en.md +7 -3
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +8 -4
- package/templates/.agents/rules/lifecycle-orchestration.en.md +5 -2
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +5 -2
- package/templates/.agents/rules/milestone-inference.github.en.md +4 -2
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +4 -2
- package/templates/.agents/rules/next-step-output.en.md +3 -1
- package/templates/.agents/rules/next-step-output.zh-CN.md +3 -1
- package/templates/.agents/rules/no-mid-flow-questions.en.md +17 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +17 -0
- package/templates/.agents/rules/pr-checks-commands.en.md +3 -3
- package/templates/.agents/rules/pr-checks-commands.github.en.md +2 -2
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +3 -3
- package/templates/.agents/rules/pr-checks-commands.zh-CN.md +3 -3
- package/templates/.agents/rules/pr-sync.en.md +3 -1
- package/templates/.agents/rules/pr-sync.github.en.md +11 -1
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +11 -1
- package/templates/.agents/rules/pr-sync.zh-CN.md +3 -1
- package/templates/.agents/rules/release-commands.en.md +1 -1
- package/templates/.agents/rules/release-commands.github.en.md +12 -2
- package/templates/.agents/rules/release-commands.github.zh-CN.md +12 -2
- package/templates/.agents/rules/release-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
- package/templates/.agents/rules/task-management.en.md +13 -0
- package/templates/.agents/rules/task-management.zh-CN.md +13 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +10 -7
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +10 -7
- package/templates/.agents/skills/block-task/SKILL.en.md +7 -5
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +7 -5
- package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -4
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -4
- package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -1
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -1
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -1
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +10 -7
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +12 -9
- package/templates/.agents/skills/commit/SKILL.en.md +23 -11
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +29 -11
- package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
- package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +49 -0
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +55 -0
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +4 -4
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +4 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +6 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +6 -4
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.en.md +22 -7
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +22 -7
- package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +17 -0
- package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +17 -0
- package/templates/.agents/skills/create-pr/SKILL.en.md +7 -5
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -5
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
- package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -16
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +17 -16
- package/templates/.agents/skills/create-task/SKILL.en.md +5 -3
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +34 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +34 -0
- package/templates/.agents/skills/import-issue/SKILL.en.md +5 -3
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/plan-task/SKILL.en.md +8 -5
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +8 -5
- package/templates/.agents/skills/post-release/SKILL.en.md +2 -0
- package/templates/.agents/skills/post-release/SKILL.zh-CN.md +2 -0
- package/templates/.agents/skills/release/SKILL.en.md +16 -10
- package/templates/.agents/skills/release/SKILL.zh-CN.md +16 -10
- package/templates/.agents/skills/restore-task/SKILL.en.md +4 -1
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +4 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +7 -4
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/review-code/SKILL.en.md +11 -8
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +11 -8
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +1 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.en.md +7 -4
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/review-pr/SKILL.en.md +186 -0
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +186 -0
- package/templates/.agents/skills/review-pr/config/verify.en.json +37 -0
- package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +37 -0
- package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +65 -0
- package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +65 -0
- package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +18 -0
- package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +18 -0
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +85 -0
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +85 -0
- package/templates/.agents/skills/run-task/SKILL.en.md +8 -8
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/run-task/config/verify.en.json +2 -1
- package/templates/.agents/skills/run-task/config/verify.zh-CN.json +2 -1
- package/templates/.agents/skills/run-task/reference/host-validation.en.md +20 -0
- package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +20 -0
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +98 -107
- package/templates/.agents/skills/watch-pr/SKILL.en.md +13 -13
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +13 -13
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +27 -6
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +26 -5
- package/templates/.agents/templates/task.en.md +2 -2
- package/templates/.agents/templates/task.zh-CN.md +2 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +3 -3
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +3 -3
- package/templates/.agents/workflows/code-review.en.yaml +1 -1
- package/templates/.agents/workflows/code-review.zh-CN.yaml +1 -1
- package/templates/.agents/workflows/feature-development.en.yaml +4 -4
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +4 -4
- package/templates/.agents/workflows/refactoring.en.yaml +3 -3
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +3 -3
- package/templates/.claude/commands/post-release.en.md +1 -0
- package/templates/.claude/commands/post-release.zh-CN.md +1 -0
- package/templates/.claude/commands/review-pr.en.md +8 -0
- package/templates/.claude/commands/review-pr.zh-CN.md +8 -0
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.claude/rules/tool-preferences.en.md +20 -0
- package/templates/.claude/rules/tool-preferences.zh-CN.md +20 -0
- package/templates/.opencode/commands/post-release.en.md +2 -0
- package/templates/.opencode/commands/post-release.zh-CN.md +2 -0
- package/templates/.opencode/commands/review-pr.en.md +11 -0
- package/templates/.opencode/commands/review-pr.zh-CN.md +11 -0
- package/templates/.opencode/commands/watch-pr.en.md +1 -1
- package/templates/.opencode/commands/watch-pr.zh-CN.md +1 -1
- package/dist/lib/agent-clients/adapters/gemini-cli.js +0 -64
- package/lib/agent-clients/adapters/gemini-cli.ts +0 -65
- package/templates/.gemini/commands/_project_/analyze-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/archive-tasks.en.toml +0 -10
- package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/block-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/cancel-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/check-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/close-codescan.en.toml +0 -8
- package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/close-dependabot.en.toml +0 -8
- package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/code-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/commit.en.toml +0 -10
- package/templates/.gemini/commands/_project_/commit.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +0 -10
- package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/complete-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/create-pr.en.toml +0 -10
- package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/create-release-note.en.toml +0 -8
- package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/create-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/import-codescan.en.toml +0 -8
- package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/import-dependabot.en.toml +0 -8
- package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/import-issue.en.toml +0 -8
- package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/init-labels.en.toml +0 -8
- package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/init-milestones.en.toml +0 -10
- package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/plan-task.en.toml +0 -10
- package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/post-release.en.toml +0 -6
- package/templates/.gemini/commands/_project_/post-release.zh-CN.toml +0 -6
- package/templates/.gemini/commands/_project_/refine-title.en.toml +0 -8
- package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/release.en.toml +0 -8
- package/templates/.gemini/commands/_project_/release.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/restore-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/review-analysis.en.toml +0 -10
- package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/review-code.en.toml +0 -10
- package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/review-plan.en.toml +0 -10
- package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +0 -10
- package/templates/.gemini/commands/_project_/run-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/test-integration.en.toml +0 -6
- package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +0 -6
- package/templates/.gemini/commands/_project_/test.en.toml +0 -6
- package/templates/.gemini/commands/_project_/test.zh-CN.toml +0 -6
- package/templates/.gemini/commands/_project_/update-agent-infra.en.toml +0 -6
- package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +0 -6
- package/templates/.gemini/commands/_project_/upgrade-dependency.en.toml +0 -8
- package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/watch-pr.en.toml +0 -10
- package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +0 -10
- package/templates/.gemini/settings.json +0 -3
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
4
5
|
import { parseTypedTaskFrontmatter } from './frontmatter.js';
|
|
5
6
|
import { parseReviewSummary } from './review-artifacts.js';
|
|
6
7
|
import { inspectArtifactDirectory } from './artifact-lifecycle.js';
|
|
7
8
|
import { parseLedger, summarizeLedgerStage, validateLedgerRows } from './ledger.js';
|
|
8
9
|
import { resolveTaskRef } from './resolve-ref.js';
|
|
9
10
|
import { activateDelegation, completeDelegationStage, consumeDelegation, managedDelegationRole, prepareDelegation, sealDelegation } from './delegation-receipts.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { normalizeAgentClients } from '../agent-clients/config.js';
|
|
12
|
+
import { inspectPlatformPullRequest } from '../platform/pull-requests.js';
|
|
13
|
+
import { getAgentClientCapability, getAgentClientDelegationEvidence, getAgentClientModelSelection } from '../agent-clients/registry.js';
|
|
14
|
+
import { isAgentClientId } from '../agent-clients/types.js';
|
|
15
|
+
import { captureRepositorySnapshot, captureWorkspaceSnapshot, diffWorkspaceSnapshots } from './workspace-snapshot.js';
|
|
16
|
+
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
|
|
17
|
+
import { CommitIntentError, commitIntentPath, createCommitIntent, digest, readCommitIntent, removeCommitIntent, removeCommitIntentByDigest, serialize, updateCommitIntent } from './commit-intent.js';
|
|
18
|
+
import { inspectCommitFinalization, planCommitTaskFinalization } from './commit-finalization.js';
|
|
19
|
+
import { captureTaskWriteMetadata, writeTask } from './write.js';
|
|
20
|
+
function supportsLifecycleDelegation(client) {
|
|
21
|
+
return getAgentClientCapability(client, 'subagents').level !== 'unsupported'
|
|
22
|
+
&& getAgentClientCapability(client, 'orchestration').level !== 'unsupported'
|
|
23
|
+
&& getAgentClientDelegationEvidence(client).actualModel !== 'unavailable'
|
|
24
|
+
&& getAgentClientDelegationEvidence(client).actualReasoningEffort !== 'unavailable';
|
|
25
|
+
}
|
|
12
26
|
function orchestrationPath(taskDir) {
|
|
13
27
|
return path.join(taskDir, 'orchestration.json');
|
|
14
28
|
}
|
|
@@ -16,7 +30,22 @@ function readRun(taskDir) {
|
|
|
16
30
|
const file = orchestrationPath(taskDir);
|
|
17
31
|
if (!fs.existsSync(file))
|
|
18
32
|
return null;
|
|
19
|
-
|
|
33
|
+
const run = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
34
|
+
if (run.schemaVersion !== 2 || !isV2Policy(run.modelPolicy))
|
|
35
|
+
return run;
|
|
36
|
+
return {
|
|
37
|
+
...run,
|
|
38
|
+
modelPolicy: {
|
|
39
|
+
executor: {
|
|
40
|
+
model: run.modelPolicy.executor.model,
|
|
41
|
+
reasoningEffort: run.modelPolicy.executor.reasoningEffort
|
|
42
|
+
},
|
|
43
|
+
reviewer: {
|
|
44
|
+
model: run.modelPolicy.reviewer.model,
|
|
45
|
+
reasoningEffort: run.modelPolicy.reviewer.reasoningEffort
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
20
49
|
}
|
|
21
50
|
function atomicWrite(file, value) {
|
|
22
51
|
const temp = `${file}.${process.pid}.${randomUUID()}.tmp`;
|
|
@@ -26,39 +55,270 @@ function atomicWrite(file, value) {
|
|
|
26
55
|
function saveRun(taskDir, run) {
|
|
27
56
|
atomicWrite(orchestrationPath(taskDir), run);
|
|
28
57
|
}
|
|
29
|
-
function withUpdatedRun(run, updates) {
|
|
30
|
-
return Object.freeze({ ...run, ...updates, updatedAt: new Date().toISOString() });
|
|
58
|
+
function withUpdatedRun(run, updates, now) {
|
|
59
|
+
return Object.freeze({ ...run, ...updates, updatedAt: (now ?? (() => new Date().toISOString()))() });
|
|
60
|
+
}
|
|
61
|
+
function failed(code, message, taskId = null, details = {}) {
|
|
62
|
+
return { status: 'failed', changed: false, taskId, run: null, next: null, error: { code, message, ...details } };
|
|
63
|
+
}
|
|
64
|
+
function commitIntentFailed(code, message, taskId = null) {
|
|
65
|
+
return { status: 'failed', changed: false, taskId, intent: null, error: { code, message } };
|
|
66
|
+
}
|
|
67
|
+
function repositoryHead(repoRoot) {
|
|
68
|
+
return execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
69
|
+
cwd: repoRoot,
|
|
70
|
+
encoding: 'utf8',
|
|
71
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
72
|
+
}).trim();
|
|
73
|
+
}
|
|
74
|
+
function isAncestor(repoRoot, ancestor, descendant) {
|
|
75
|
+
return spawnSync('git', ['merge-base', '--is-ancestor', ancestor, descendant], {
|
|
76
|
+
cwd: repoRoot,
|
|
77
|
+
stdio: 'ignore'
|
|
78
|
+
}).status === 0;
|
|
79
|
+
}
|
|
80
|
+
function commitIntentView(intent, currentHead) {
|
|
81
|
+
return {
|
|
82
|
+
mode: intent.mode,
|
|
83
|
+
phase: intent.phase,
|
|
84
|
+
baselineHead: intent.baselineHead,
|
|
85
|
+
currentHead,
|
|
86
|
+
committedHead: intent.committedHead,
|
|
87
|
+
pushEvidence: intent.pushEvidence,
|
|
88
|
+
runId: intent.orchestration?.runId ?? null,
|
|
89
|
+
receiptId: intent.orchestration?.receiptId ?? null
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function commitFinalizationView(inspection) {
|
|
93
|
+
return {
|
|
94
|
+
disposition: inspection.disposition,
|
|
95
|
+
code: inspection.code,
|
|
96
|
+
message: inspection.message,
|
|
97
|
+
currentHead: inspection.currentHead,
|
|
98
|
+
committedHead: inspection.committedHead,
|
|
99
|
+
needsAnchor: inspection.needsAnchor,
|
|
100
|
+
needsLog: inspection.needsLog
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function validCommitRun(run, taskId) {
|
|
104
|
+
return run !== null
|
|
105
|
+
&& [1, 2].includes(run.schemaVersion)
|
|
106
|
+
&& run.taskId === taskId
|
|
107
|
+
&& ['running', 'paused', 'completed'].includes(run.status)
|
|
108
|
+
&& Array.isArray(run.receipts)
|
|
109
|
+
&& Object.prototype.hasOwnProperty.call(run, 'pendingDelegation')
|
|
110
|
+
&& typeof run.commitAuthorization === 'object'
|
|
111
|
+
&& run.commitAuthorization !== null
|
|
112
|
+
&& Object.prototype.hasOwnProperty.call(run.commitAuthorization, 'issuedAt')
|
|
113
|
+
&& Object.prototype.hasOwnProperty.call(run.commitAuthorization, 'consumedAt');
|
|
114
|
+
}
|
|
115
|
+
function mapCommitIntentError(error, taskId) {
|
|
116
|
+
if (error instanceof CommitIntentError)
|
|
117
|
+
return commitIntentFailed(error.code, error.message, taskId);
|
|
118
|
+
if (error instanceof TaskExecutionLockError)
|
|
119
|
+
return commitIntentFailed(error.code, error.message, taskId);
|
|
120
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_INTENT_INVALID', error instanceof Error ? error.message : String(error), taskId);
|
|
121
|
+
}
|
|
122
|
+
function validModel(value) {
|
|
123
|
+
return typeof value === 'string' && value.length > 0 && value.trim() === value;
|
|
124
|
+
}
|
|
125
|
+
function validateModelPolicy(policy) {
|
|
126
|
+
if (!policy
|
|
127
|
+
|| !validModel(policy.executor?.model)
|
|
128
|
+
|| !validModel(policy.executor?.reasoningEffort)
|
|
129
|
+
|| !validModel(policy.reviewer?.model)
|
|
130
|
+
|| !validModel(policy.reviewer?.reasoningEffort)) {
|
|
131
|
+
return { code: 'ORCHESTRATION_MODEL_POLICY_REQUIRED', message: 'executor and reviewer model and reasoning effort are required' };
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
function sameModelPolicy(left, right) {
|
|
136
|
+
return left.executor.model === right.executor.model
|
|
137
|
+
&& left.executor.reasoningEffort === right.executor.reasoningEffort
|
|
138
|
+
&& left.reviewer.model === right.reviewer.model
|
|
139
|
+
&& left.reviewer.reasoningEffort === right.reviewer.reasoningEffort;
|
|
140
|
+
}
|
|
141
|
+
function isV2Policy(policy) {
|
|
142
|
+
return typeof policy?.executor === 'object' && typeof policy?.reviewer === 'object';
|
|
31
143
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
144
|
+
function rolePolicy(run, role) {
|
|
145
|
+
return isV2Policy(run.modelPolicy) ? run.modelPolicy[role] : null;
|
|
146
|
+
}
|
|
147
|
+
function resolveProjectPolicy(repoRoot, client) {
|
|
148
|
+
const configPath = path.join(repoRoot, '.agents', '.airc.json');
|
|
149
|
+
if (!fs.existsSync(configPath))
|
|
150
|
+
return undefined;
|
|
151
|
+
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
152
|
+
return normalizeAgentClients(raw).state[client].orchestration;
|
|
34
153
|
}
|
|
35
154
|
function beginOrResumeOrchestration(taskRef, options = {}) {
|
|
36
155
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
37
156
|
if (!resolved.ok)
|
|
38
157
|
return failed(resolved.code, resolved.message, resolved.taskId);
|
|
39
|
-
|
|
158
|
+
if (!isAgentClientId(options.client)) {
|
|
159
|
+
return failed('ORCHESTRATION_PAYLOAD_INVALID', 'begin-or-resume requires a known client', resolved.taskId);
|
|
160
|
+
}
|
|
161
|
+
let existing;
|
|
162
|
+
try {
|
|
163
|
+
existing = readRun(resolved.taskDir);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
return failed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
167
|
+
}
|
|
40
168
|
if (existing) {
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return
|
|
169
|
+
if (![1, 2].includes(existing.schemaVersion)
|
|
170
|
+
|| !Array.isArray(existing.receipts)
|
|
171
|
+
|| !Object.prototype.hasOwnProperty.call(existing, 'pendingDelegation')) {
|
|
172
|
+
return failed('ORCHESTRATION_STATE_INVALID', 'orchestration state has an invalid schema', resolved.taskId);
|
|
173
|
+
}
|
|
174
|
+
if (existing.status === 'completed' && existing.schemaVersion === 1) {
|
|
175
|
+
return { status: 'completed', changed: false, taskId: resolved.taskId, run: existing, next: null, error: null };
|
|
176
|
+
}
|
|
177
|
+
if (existing.schemaVersion === 2) {
|
|
178
|
+
const policyError = validateModelPolicy(isV2Policy(existing.modelPolicy) ? existing.modelPolicy : undefined);
|
|
179
|
+
if (policyError
|
|
180
|
+
|| !existing.modelPolicySource
|
|
181
|
+
|| !isAgentClientId(existing.modelPolicySource.client)
|
|
182
|
+
|| !Array.isArray(existing.recoveryHistory)) {
|
|
183
|
+
return failed('ORCHESTRATION_STATE_INVALID', 'schemaVersion 2 orchestration state is incomplete', resolved.taskId);
|
|
184
|
+
}
|
|
185
|
+
if (existing.status === 'completed') {
|
|
186
|
+
return { status: 'completed', changed: false, taskId: resolved.taskId, run: existing, next: null, error: null };
|
|
187
|
+
}
|
|
188
|
+
if (existing.modelPolicySource.client !== options.client) {
|
|
189
|
+
return failed('ORCHESTRATION_CLIENT_MISMATCH', 'provided client does not match the persisted run policy source', resolved.taskId);
|
|
190
|
+
}
|
|
191
|
+
if (options.modelPolicy) {
|
|
192
|
+
const suppliedError = validateModelPolicy(options.modelPolicy);
|
|
193
|
+
if (suppliedError)
|
|
194
|
+
return failed(suppliedError.code, suppliedError.message, resolved.taskId);
|
|
195
|
+
if (!sameModelPolicy(existing.modelPolicy, options.modelPolicy)) {
|
|
196
|
+
return failed('ORCHESTRATION_MODEL_POLICY_MISMATCH', 'provided model policy does not match the persisted run policy', resolved.taskId);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (existing.status === 'paused' && existing.pause?.recoverable && existing.pendingDelegation === null) {
|
|
200
|
+
const resumed = withUpdatedRun(existing, { status: 'running', pause: null });
|
|
201
|
+
saveRun(resolved.taskDir, resumed);
|
|
202
|
+
return { status: 'running', changed: true, taskId: resolved.taskId, run: resumed, next: null, error: null };
|
|
203
|
+
}
|
|
204
|
+
return { status: existing.status, changed: false, taskId: resolved.taskId, run: existing, next: null, error: null };
|
|
205
|
+
}
|
|
206
|
+
let policy = options.modelPolicy;
|
|
207
|
+
let sourceKind = 'explicit';
|
|
208
|
+
if (!policy) {
|
|
209
|
+
try {
|
|
210
|
+
policy = resolveProjectPolicy(resolved.repoRoot, options.client);
|
|
211
|
+
sourceKind = 'project-config';
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
return failed('ORCHESTRATION_CONFIG_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const policyError = validateModelPolicy(policy);
|
|
218
|
+
if (policyError) {
|
|
219
|
+
return failed(policyError.code, policyError.message, resolved.taskId, {
|
|
220
|
+
client: options.client,
|
|
221
|
+
missingFields: ['executor.model', 'executor.reasoningEffort', 'reviewer.model', 'reviewer.reasoningEffort'],
|
|
222
|
+
modelSelectionContext: getAgentClientModelSelection(options.client)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (existing.pendingDelegation !== null) {
|
|
226
|
+
const alreadyPaused = existing.status === 'paused' && existing.pause?.code === 'ORCHESTRATION_DELEGATION_BUSY';
|
|
227
|
+
if (alreadyPaused)
|
|
228
|
+
return { status: 'paused', changed: false, taskId: resolved.taskId, run: existing, next: null, error: null };
|
|
229
|
+
const paused = withUpdatedRun(existing, {
|
|
230
|
+
status: 'paused',
|
|
231
|
+
pause: { code: 'ORCHESTRATION_DELEGATION_BUSY', message: 'legacy run has a pending delegation', recoverable: false }
|
|
232
|
+
});
|
|
233
|
+
saveRun(resolved.taskDir, paused);
|
|
234
|
+
return { status: 'paused', changed: true, taskId: resolved.taskId, run: paused, next: null, error: null };
|
|
235
|
+
}
|
|
236
|
+
if (existing.receipts.length > 0) {
|
|
237
|
+
const alreadyPaused = existing.status === 'paused' && existing.pause?.code === 'ORCHESTRATION_HISTORICAL_EFFORT_UNVERIFIED';
|
|
238
|
+
if (alreadyPaused)
|
|
239
|
+
return { status: 'paused', changed: false, taskId: resolved.taskId, run: existing, next: null, error: null };
|
|
240
|
+
const paused = withUpdatedRun(existing, {
|
|
241
|
+
status: 'paused',
|
|
242
|
+
pause: {
|
|
243
|
+
code: 'ORCHESTRATION_HISTORICAL_EFFORT_UNVERIFIED',
|
|
244
|
+
message: 'legacy receipts do not contain actual reasoning-effort evidence',
|
|
245
|
+
recoverable: false
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
saveRun(resolved.taskDir, paused);
|
|
249
|
+
return { status: 'paused', changed: true, taskId: resolved.taskId, run: paused, next: null, error: null };
|
|
45
250
|
}
|
|
46
|
-
|
|
251
|
+
if (existing.modelPolicy
|
|
252
|
+
&& typeof existing.modelPolicy.executor === 'string'
|
|
253
|
+
&& (existing.modelPolicy.executor !== policy.executor.model
|
|
254
|
+
|| existing.modelPolicy.reviewer !== policy.reviewer.model)) {
|
|
255
|
+
return failed('ORCHESTRATION_MODEL_POLICY_MISMATCH', 'provided model policy does not match the persisted run policy', resolved.taskId);
|
|
256
|
+
}
|
|
257
|
+
const now = (options.now ?? (() => new Date().toISOString()))();
|
|
258
|
+
const source = { kind: sourceKind, client: options.client, resolvedAt: now };
|
|
259
|
+
const clearsModelPause = existing.pause?.code === 'ORCHESTRATION_MODEL_EVIDENCE_MISSING';
|
|
260
|
+
const resultingStatus = clearsModelPause ? 'running' : existing.status;
|
|
261
|
+
const recovery = {
|
|
262
|
+
code: 'MODEL_POLICY_SUPPLEMENTED',
|
|
263
|
+
recoveredAt: now,
|
|
264
|
+
previousSchemaVersion: 1,
|
|
265
|
+
previousStatus: existing.status,
|
|
266
|
+
previousPause: existing.pause,
|
|
267
|
+
policySource: source,
|
|
268
|
+
receiptCount: 0,
|
|
269
|
+
pendingDelegation: false,
|
|
270
|
+
resultingStatus
|
|
271
|
+
};
|
|
272
|
+
const recovered = Object.freeze({
|
|
273
|
+
...existing,
|
|
274
|
+
schemaVersion: 2,
|
|
275
|
+
status: resultingStatus,
|
|
276
|
+
modelPolicy: policy,
|
|
277
|
+
modelPolicySource: source,
|
|
278
|
+
recoveryHistory: Object.freeze([recovery]),
|
|
279
|
+
pause: clearsModelPause ? null : existing.pause,
|
|
280
|
+
updatedAt: now
|
|
281
|
+
});
|
|
282
|
+
saveRun(resolved.taskDir, recovered);
|
|
283
|
+
return { status: resultingStatus, changed: true, taskId: resolved.taskId, run: recovered, next: null, error: null };
|
|
47
284
|
}
|
|
285
|
+
let policy = options.modelPolicy;
|
|
286
|
+
let sourceKind = 'explicit';
|
|
287
|
+
if (!policy) {
|
|
288
|
+
try {
|
|
289
|
+
policy = resolveProjectPolicy(resolved.repoRoot, options.client);
|
|
290
|
+
sourceKind = 'project-config';
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
return failed('ORCHESTRATION_CONFIG_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const policyError = validateModelPolicy(policy);
|
|
297
|
+
if (policyError)
|
|
298
|
+
return failed(policyError.code, policyError.message, resolved.taskId, {
|
|
299
|
+
client: options.client,
|
|
300
|
+
missingFields: ['executor.model', 'executor.reasoningEffort', 'reviewer.model', 'reviewer.reasoningEffort'],
|
|
301
|
+
modelSelectionContext: getAgentClientModelSelection(options.client)
|
|
302
|
+
});
|
|
48
303
|
const now = (options.now ?? (() => new Date().toISOString()))();
|
|
304
|
+
const source = { kind: sourceKind, client: options.client, resolvedAt: now };
|
|
49
305
|
const run = {
|
|
50
|
-
schemaVersion:
|
|
306
|
+
schemaVersion: 2,
|
|
51
307
|
taskId: resolved.taskId,
|
|
52
308
|
runId: (options.id ?? randomUUID)(),
|
|
53
309
|
status: 'running',
|
|
54
310
|
nextStage: null,
|
|
55
311
|
stepCount: 0,
|
|
56
312
|
maxSteps: options.maxSteps ?? 24,
|
|
313
|
+
modelPolicy: policy,
|
|
314
|
+
modelPolicySource: source,
|
|
315
|
+
recoveryHistory: [],
|
|
57
316
|
baseline: '',
|
|
58
317
|
pendingDelegation: null,
|
|
59
318
|
receipts: [],
|
|
60
319
|
pause: null,
|
|
61
320
|
commitAuthorization: { issuedAt: null, consumedAt: null },
|
|
321
|
+
completionEvidence: null,
|
|
62
322
|
createdAt: now,
|
|
63
323
|
updatedAt: now
|
|
64
324
|
};
|
|
@@ -146,24 +406,29 @@ function routeOrchestration(taskRef, options = {}) {
|
|
|
146
406
|
catch (error) {
|
|
147
407
|
return failed('ORCHESTRATION_TASK_READ_FAILED', String(error), resolved.taskId);
|
|
148
408
|
}
|
|
409
|
+
let metadata;
|
|
149
410
|
try {
|
|
150
|
-
parseTypedTaskFrontmatter(content);
|
|
411
|
+
metadata = parseTypedTaskFrontmatter(content);
|
|
151
412
|
}
|
|
152
413
|
catch (error) {
|
|
153
414
|
return failed('ORCHESTRATION_TASK_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
154
415
|
}
|
|
155
|
-
const
|
|
156
|
-
if (!
|
|
416
|
+
const routed = routeFromFacts(resolved.taskDir);
|
|
417
|
+
if (!routed)
|
|
157
418
|
return failed('ORCHESTRATION_ROUTE_UNKNOWN', 'cannot determine a unique lifecycle action', resolved.taskId);
|
|
419
|
+
const run = readRun(resolved.taskDir);
|
|
420
|
+
const policy = run ? rolePolicy(run, routed.role) : null;
|
|
421
|
+
const next = {
|
|
422
|
+
...routed,
|
|
423
|
+
requestedModel: policy?.model ?? null,
|
|
424
|
+
requestedReasoningEffort: policy?.reasoningEffort ?? null
|
|
425
|
+
};
|
|
158
426
|
if (next.stage === 'commit') {
|
|
159
427
|
const reviewRound = highestRound(resolved.taskDir, 'review-code');
|
|
160
428
|
const review = parseReviewSummary(fs.readFileSync(path.join(resolved.taskDir, artifactName('review-code', reviewRound)), 'utf8'));
|
|
161
429
|
if (!review.ok || review.summary.manualValidation === null) {
|
|
162
430
|
return failed('ORCHESTRATION_REVIEW_INVALID', 'latest code review has no numeric manual-validation count', resolved.taskId);
|
|
163
431
|
}
|
|
164
|
-
if (review.summary.manualValidation > 0) {
|
|
165
|
-
return failed('ORCHESTRATION_MANUAL_VALIDATION_PENDING', 'manual validation must be completed before commit', resolved.taskId);
|
|
166
|
-
}
|
|
167
432
|
const rows = parseLedger(content);
|
|
168
433
|
const ledgerError = validateLedgerRows(rows);
|
|
169
434
|
if (ledgerError)
|
|
@@ -171,8 +436,390 @@ function routeOrchestration(taskRef, options = {}) {
|
|
|
171
436
|
if (!summarizeLedgerStage(rows, 'code').canAdvance) {
|
|
172
437
|
return failed('ORCHESTRATION_LEDGER_BLOCKED', 'code review ledger has unresolved findings or human decisions', resolved.taskId);
|
|
173
438
|
}
|
|
439
|
+
if (run?.status === 'completed') {
|
|
440
|
+
return { status: 'completed', changed: false, taskId: resolved.taskId, run, next: null, error: null };
|
|
441
|
+
}
|
|
442
|
+
let config;
|
|
443
|
+
try {
|
|
444
|
+
config = JSON.parse(fs.readFileSync(path.join(resolved.repoRoot, '.agents', '.airc.json'), 'utf8'));
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
return failed('ORCHESTRATION_CONFIG_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
448
|
+
}
|
|
449
|
+
if (!config || typeof config !== 'object' || Array.isArray(config)) {
|
|
450
|
+
return failed('ORCHESTRATION_CONFIG_INVALID', 'project configuration must be an object', resolved.taskId);
|
|
451
|
+
}
|
|
452
|
+
const projectConfig = config;
|
|
453
|
+
if (!Object.hasOwn(projectConfig, 'prFlow') || projectConfig.prFlow === 'disabled') {
|
|
454
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
455
|
+
}
|
|
456
|
+
if (projectConfig.prFlow !== 'required') {
|
|
457
|
+
return failed('ORCHESTRATION_CONFIG_INVALID', "project configuration 'prFlow' must be 'required' or 'disabled'", resolved.taskId);
|
|
458
|
+
}
|
|
459
|
+
const prNumber = Number(metadata.pr_number);
|
|
460
|
+
if (!Number.isInteger(prNumber) || prNumber <= 0) {
|
|
461
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
462
|
+
}
|
|
463
|
+
if (!run) {
|
|
464
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
465
|
+
}
|
|
466
|
+
if (run.status !== 'running' || run.pendingDelegation !== null) {
|
|
467
|
+
return failed('ORCHESTRATION_RUN_NOT_RUNNING', 'clean completion requires an idle running orchestration', resolved.taskId);
|
|
468
|
+
}
|
|
469
|
+
const capture = options.captureRepository ?? captureRepositorySnapshot;
|
|
470
|
+
let before;
|
|
471
|
+
try {
|
|
472
|
+
before = capture(resolved.repoRoot);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
return failed('ORCHESTRATION_SNAPSHOT_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
476
|
+
}
|
|
477
|
+
if (before.headTree !== before.worktreeTree) {
|
|
478
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
479
|
+
}
|
|
480
|
+
const lastReviewedCommit = String(metadata.last_reviewed_commit ?? '');
|
|
481
|
+
if (before.head !== lastReviewedCommit) {
|
|
482
|
+
return failed('ORCHESTRATION_REVIEWED_HEAD_MISMATCH', 'local HEAD does not match last_reviewed_commit', resolved.taskId);
|
|
483
|
+
}
|
|
484
|
+
const inspect = options.inspectPullRequest ?? inspectPlatformPullRequest;
|
|
485
|
+
let inspection;
|
|
486
|
+
try {
|
|
487
|
+
inspection = inspect(resolved.taskId, { cwd: resolved.repoRoot });
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
return failed('ORCHESTRATION_PR_INSPECTION_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
491
|
+
}
|
|
492
|
+
if (inspection.status === 'blocked') {
|
|
493
|
+
return failed('ORCHESTRATION_PR_INSPECTION_BLOCKED', inspection.error?.message ?? 'pull request inspection is blocked', resolved.taskId);
|
|
494
|
+
}
|
|
495
|
+
if (inspection.status === 'failed') {
|
|
496
|
+
return failed('ORCHESTRATION_PR_INSPECTION_FAILED', inspection.error?.message ?? 'pull request inspection failed', resolved.taskId);
|
|
497
|
+
}
|
|
498
|
+
const inspectedPrNumber = inspection.task?.prNumber ?? inspection.prNumber;
|
|
499
|
+
const prHead = inspection.pullRequest?.head?.sha;
|
|
500
|
+
if (typeof prHead !== 'string') {
|
|
501
|
+
return failed('ORCHESTRATION_PR_INSPECTION_INVALID', 'pull request inspection returned incomplete identity evidence', resolved.taskId);
|
|
502
|
+
}
|
|
503
|
+
if (inspectedPrNumber !== prNumber || prHead !== before.head) {
|
|
504
|
+
return failed('ORCHESTRATION_PR_HEAD_MISMATCH', 'pull request identity does not match the reviewed local HEAD', resolved.taskId);
|
|
505
|
+
}
|
|
506
|
+
let after;
|
|
507
|
+
try {
|
|
508
|
+
after = capture(resolved.repoRoot);
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
return failed('ORCHESTRATION_SNAPSHOT_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
512
|
+
}
|
|
513
|
+
if (after.headTree !== after.worktreeTree) {
|
|
514
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
515
|
+
}
|
|
516
|
+
if (after.head !== before.head || after.headTree !== before.headTree) {
|
|
517
|
+
return failed('ORCHESTRATION_REPOSITORY_CHANGED', 'repository changed while clean completion evidence was collected', resolved.taskId);
|
|
518
|
+
}
|
|
519
|
+
const observedAt = (options.now ?? (() => new Date().toISOString()))();
|
|
520
|
+
const completionEvidence = {
|
|
521
|
+
kind: 'reviewed-head-clean',
|
|
522
|
+
observedAt,
|
|
523
|
+
head: after.head,
|
|
524
|
+
headTree: after.headTree,
|
|
525
|
+
worktreeTree: after.worktreeTree,
|
|
526
|
+
lastReviewedCommit,
|
|
527
|
+
prNumber,
|
|
528
|
+
prHead
|
|
529
|
+
};
|
|
530
|
+
const completed = withUpdatedRun(run, {
|
|
531
|
+
status: 'completed',
|
|
532
|
+
nextStage: null,
|
|
533
|
+
pause: null,
|
|
534
|
+
completionEvidence
|
|
535
|
+
});
|
|
536
|
+
saveRun(resolved.taskDir, completed);
|
|
537
|
+
return { status: 'completed', changed: true, taskId: resolved.taskId, run: completed, next: null, error: null };
|
|
174
538
|
}
|
|
175
|
-
return { status: 'running', changed: false, taskId: resolved.taskId, run
|
|
539
|
+
return { status: 'running', changed: false, taskId: resolved.taskId, run, next, error: null };
|
|
540
|
+
}
|
|
541
|
+
function beginCommitIntent(taskRef, input, options = {}) {
|
|
542
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
543
|
+
if (!resolved.ok)
|
|
544
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
545
|
+
try {
|
|
546
|
+
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'commit-intent.begin', () => {
|
|
547
|
+
const currentHead = repositoryHead(resolved.repoRoot);
|
|
548
|
+
if (currentHead !== input.baselineHead) {
|
|
549
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_BASELINE_MISMATCH', 'baseline HEAD does not match the repository HEAD', resolved.taskId);
|
|
550
|
+
}
|
|
551
|
+
if (fs.existsSync(commitIntentPath(resolved.taskDir))) {
|
|
552
|
+
try {
|
|
553
|
+
readCommitIntent(resolved.taskDir, resolved.taskId);
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
557
|
+
}
|
|
558
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_INTENT_BUSY', 'an active commit intent already exists', resolved.taskId);
|
|
559
|
+
}
|
|
560
|
+
const runFile = orchestrationPath(resolved.taskDir);
|
|
561
|
+
let run = null;
|
|
562
|
+
let sourceRunBytes = null;
|
|
563
|
+
if (fs.existsSync(runFile)) {
|
|
564
|
+
sourceRunBytes = fs.readFileSync(runFile, 'utf8');
|
|
565
|
+
try {
|
|
566
|
+
run = readRun(resolved.taskDir);
|
|
567
|
+
}
|
|
568
|
+
catch (error) {
|
|
569
|
+
return commitIntentFailed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
570
|
+
}
|
|
571
|
+
if (!validCommitRun(run, resolved.taskId)) {
|
|
572
|
+
return commitIntentFailed('ORCHESTRATION_STATE_INVALID', 'orchestration state has an invalid schema', resolved.taskId);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
const now = (options.now ?? (() => new Date().toISOString()))();
|
|
576
|
+
const failAndPause = (code, message) => {
|
|
577
|
+
if (run?.status === 'running') {
|
|
578
|
+
saveRun(resolved.taskDir, withUpdatedRun(run, {
|
|
579
|
+
status: 'paused', pause: { code, message, recoverable: true }
|
|
580
|
+
}, () => now));
|
|
581
|
+
}
|
|
582
|
+
return commitIntentFailed(code, message, resolved.taskId);
|
|
583
|
+
};
|
|
584
|
+
let orchestration = null;
|
|
585
|
+
if (!input.orchestrated) {
|
|
586
|
+
if (run?.pendingDelegation) {
|
|
587
|
+
return commitIntentFailed('ORCHESTRATION_STANDALONE_BUSY', 'standalone commit is blocked by a pending orchestration delegation', resolved.taskId);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
if (!run || run.status !== 'running') {
|
|
592
|
+
return commitIntentFailed('ORCHESTRATION_RUN_NOT_RUNNING', 'orchestrated commit requires a running orchestration', resolved.taskId);
|
|
593
|
+
}
|
|
594
|
+
const receipt = run.pendingDelegation;
|
|
595
|
+
if (!receipt
|
|
596
|
+
|| receipt.status !== 'activated'
|
|
597
|
+
|| receipt.stage !== 'commit'
|
|
598
|
+
|| receipt.round !== 1
|
|
599
|
+
|| receipt.artifact !== 'commit'
|
|
600
|
+
|| receipt.role !== 'executor') {
|
|
601
|
+
return failAndPause('ORCHESTRATION_PROVENANCE_MISMATCH', 'orchestrated commit requires one matching activated commit delegation');
|
|
602
|
+
}
|
|
603
|
+
if (!run.commitAuthorization.issuedAt || run.commitAuthorization.consumedAt) {
|
|
604
|
+
return failAndPause('ORCHESTRATION_COMMIT_AUTHORIZATION_INVALID', 'orchestrated commit requires an unconsumed one-use authorization');
|
|
605
|
+
}
|
|
606
|
+
const planned = planOrchestrationStageCompletion(taskRef, {
|
|
607
|
+
stage: 'commit', round: 1, artifact: 'commit', role: 'executor', agent: input.agent
|
|
608
|
+
}, { ...options, now: () => now });
|
|
609
|
+
if (planned.result.status === 'failed' || !planned.plan?.updatedRun.pendingDelegation) {
|
|
610
|
+
return failAndPause(planned.result.error?.code ?? 'ORCHESTRATION_PROVENANCE_MISMATCH', planned.result.error?.message ?? 'commit delegation could not be completed');
|
|
611
|
+
}
|
|
612
|
+
const plannedRunBytes = serialize(planned.plan.updatedRun);
|
|
613
|
+
orchestration = {
|
|
614
|
+
runId: run.runId,
|
|
615
|
+
receiptId: receipt.id,
|
|
616
|
+
authorizationIssuedAt: run.commitAuthorization.issuedAt,
|
|
617
|
+
sourceRunDigest: digest(sourceRunBytes),
|
|
618
|
+
plannedRunDigest: digest(plannedRunBytes),
|
|
619
|
+
completionUpdatedAt: planned.plan.updatedRun.updatedAt,
|
|
620
|
+
plannedReceipt: planned.plan.updatedRun.pendingDelegation
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
const created = createCommitIntent(resolved.taskDir, {
|
|
624
|
+
taskId: resolved.taskId,
|
|
625
|
+
mode: input.orchestrated ? 'orchestrated' : 'standalone',
|
|
626
|
+
phase: 'prepared',
|
|
627
|
+
baselineHead: input.baselineHead,
|
|
628
|
+
committedHead: null,
|
|
629
|
+
pushEvidence: null,
|
|
630
|
+
orchestration,
|
|
631
|
+
createdAt: now,
|
|
632
|
+
updatedAt: now
|
|
633
|
+
}, { token: options.token });
|
|
634
|
+
return {
|
|
635
|
+
status: 'ready', changed: true, taskId: resolved.taskId,
|
|
636
|
+
intent: commitIntentView(created.intent, currentHead), token: created.token, error: null
|
|
637
|
+
};
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function checkpointCommitIntent(taskRef, input, options = {}) {
|
|
645
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
646
|
+
if (!resolved.ok)
|
|
647
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
648
|
+
try {
|
|
649
|
+
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'commit-intent.checkpoint', () => {
|
|
650
|
+
const intent = readCommitIntent(resolved.taskDir, resolved.taskId, input.token);
|
|
651
|
+
const currentHead = repositoryHead(resolved.repoRoot);
|
|
652
|
+
if (currentHead !== input.head) {
|
|
653
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_RECOVERY_REQUIRED', 'checkpoint HEAD does not match the repository HEAD', resolved.taskId);
|
|
654
|
+
}
|
|
655
|
+
if (input.kind === 'committed' && !isAncestor(resolved.repoRoot, intent.baselineHead, input.head)) {
|
|
656
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_RECOVERY_REQUIRED', 'committed HEAD does not descend from the baseline', resolved.taskId);
|
|
657
|
+
}
|
|
658
|
+
if (input.kind === 'pushed') {
|
|
659
|
+
const expectedHead = intent.committedHead ?? intent.baselineHead;
|
|
660
|
+
if (input.head !== expectedHead || !input.remote || !input.ref) {
|
|
661
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_INTENT_STATE_INVALID', 'pushed checkpoint requires matching remote, ref and HEAD', resolved.taskId);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const now = (options.now ?? (() => new Date().toISOString()))();
|
|
665
|
+
const updated = updateCommitIntent(resolved.taskDir, resolved.taskId, input.token, input.kind === 'committed'
|
|
666
|
+
? { phase: 'committed', committedHead: input.head, updatedAt: now }
|
|
667
|
+
: {
|
|
668
|
+
phase: 'pushed', committedHead: intent.committedHead ?? intent.baselineHead, updatedAt: now,
|
|
669
|
+
pushEvidence: { remote: input.remote, ref: input.ref, head: input.head }
|
|
670
|
+
});
|
|
671
|
+
return {
|
|
672
|
+
status: 'ready', changed: true, taskId: resolved.taskId,
|
|
673
|
+
intent: commitIntentView(updated, currentHead), error: null
|
|
674
|
+
};
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
function completeCommitOrchestration(resolved, intent, agent) {
|
|
682
|
+
if (intent.orchestration === null)
|
|
683
|
+
return null;
|
|
684
|
+
if (intent.orchestration.plannedReceipt.agent !== agent) {
|
|
685
|
+
return { code: 'ORCHESTRATION_PROVENANCE_MISMATCH', message: 'completion agent does not match the planned receipt' };
|
|
686
|
+
}
|
|
687
|
+
const runFile = orchestrationPath(resolved.taskDir);
|
|
688
|
+
if (!fs.existsSync(runFile)) {
|
|
689
|
+
return { code: 'ORCHESTRATION_RUN_MISSING', message: 'orchestration run disappeared' };
|
|
690
|
+
}
|
|
691
|
+
const currentBytes = fs.readFileSync(runFile, 'utf8');
|
|
692
|
+
const currentDigest = digest(currentBytes);
|
|
693
|
+
if (currentDigest === intent.orchestration.sourceRunDigest) {
|
|
694
|
+
const run = readRun(resolved.taskDir);
|
|
695
|
+
if (!run)
|
|
696
|
+
return { code: 'ORCHESTRATION_RUN_MISSING', message: 'orchestration run disappeared' };
|
|
697
|
+
const plannedRun = Object.freeze({
|
|
698
|
+
...run,
|
|
699
|
+
pendingDelegation: intent.orchestration.plannedReceipt,
|
|
700
|
+
updatedAt: intent.orchestration.completionUpdatedAt
|
|
701
|
+
});
|
|
702
|
+
if (digest(serialize(plannedRun)) !== intent.orchestration.plannedRunDigest) {
|
|
703
|
+
return { code: 'ORCHESTRATION_COMMIT_RECOVERY_REQUIRED', message: 'planned orchestration bytes no longer match the intent' };
|
|
704
|
+
}
|
|
705
|
+
atomicWrite(runFile, plannedRun);
|
|
706
|
+
if (digest(fs.readFileSync(runFile)) !== intent.orchestration.plannedRunDigest) {
|
|
707
|
+
return { code: 'ORCHESTRATION_COMMIT_COMPLETE_PARTIAL', message: 'orchestration completion could not be verified' };
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
else if (currentDigest !== intent.orchestration.plannedRunDigest) {
|
|
711
|
+
return { code: 'ORCHESTRATION_COMMIT_RECOVERY_REQUIRED', message: 'orchestration state changed after commit begin' };
|
|
712
|
+
}
|
|
713
|
+
return null;
|
|
714
|
+
}
|
|
715
|
+
function finalizeCommitIntentUnlocked(resolved, inspection, agent, remove) {
|
|
716
|
+
if (inspection.disposition !== 'recoverable' || !inspection.intent) {
|
|
717
|
+
return commitIntentFailed(inspection.code ?? 'COMMIT_FINALIZATION_PENDING', inspection.message, resolved.taskId);
|
|
718
|
+
}
|
|
719
|
+
if (inspection.intent.orchestration !== null
|
|
720
|
+
&& inspection.intent.orchestration.plannedReceipt.agent !== agent) {
|
|
721
|
+
return commitIntentFailed('ORCHESTRATION_PROVENANCE_MISMATCH', 'completion agent does not match the planned receipt', resolved.taskId);
|
|
722
|
+
}
|
|
723
|
+
const metadata = captureTaskWriteMetadata();
|
|
724
|
+
const taskPlan = planCommitTaskFinalization(resolved.taskDir, inspection, agent, metadata.timestamp);
|
|
725
|
+
const written = writeTask({
|
|
726
|
+
taskRef: resolved.taskId,
|
|
727
|
+
expectedState: 'active',
|
|
728
|
+
mutations: taskPlan.mutations
|
|
729
|
+
}, {
|
|
730
|
+
repoRoot: resolved.repoRoot,
|
|
731
|
+
metadataProvider: () => metadata
|
|
732
|
+
});
|
|
733
|
+
if (written.status === 'failed') {
|
|
734
|
+
return commitIntentFailed(written.error.code, written.error.message, resolved.taskId);
|
|
735
|
+
}
|
|
736
|
+
const orchestrationError = completeCommitOrchestration(resolved, inspection.intent, agent);
|
|
737
|
+
if (orchestrationError) {
|
|
738
|
+
return commitIntentFailed(orchestrationError.code, orchestrationError.message, resolved.taskId);
|
|
739
|
+
}
|
|
740
|
+
try {
|
|
741
|
+
remove();
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_COMPLETE_PARTIAL', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
745
|
+
}
|
|
746
|
+
return { status: 'ready', changed: true, taskId: resolved.taskId, intent: null, error: null };
|
|
747
|
+
}
|
|
748
|
+
function completeCommitIntent(taskRef, input, options = {}) {
|
|
749
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
750
|
+
if (!resolved.ok)
|
|
751
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
752
|
+
try {
|
|
753
|
+
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'commit-intent.complete', () => {
|
|
754
|
+
readCommitIntent(resolved.taskDir, resolved.taskId, input.token);
|
|
755
|
+
const inspection = inspectCommitFinalization(resolved.taskDir, resolved.repoRoot, resolved.taskId);
|
|
756
|
+
return finalizeCommitIntentUnlocked(resolved, inspection, input.agent, () => {
|
|
757
|
+
removeCommitIntent(resolved.taskDir, resolved.taskId, input.token);
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function recoverCommitIntent(taskRef, input, options = {}) {
|
|
766
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
767
|
+
if (!resolved.ok)
|
|
768
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
769
|
+
try {
|
|
770
|
+
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'commit-intent.recover', () => {
|
|
771
|
+
const inspection = inspectCommitFinalization(resolved.taskDir, resolved.repoRoot, resolved.taskId);
|
|
772
|
+
if (inspection.disposition === 'prepared' && inspection.intentDigest) {
|
|
773
|
+
removeCommitIntentByDigest(resolved.taskDir, resolved.taskId, inspection.intentDigest);
|
|
774
|
+
return { status: 'ready', changed: true, taskId: resolved.taskId, intent: null, error: null };
|
|
775
|
+
}
|
|
776
|
+
if (!inspection.intentDigest) {
|
|
777
|
+
return commitIntentFailed(inspection.code ?? 'COMMIT_FINALIZATION_EVIDENCE_MISSING', inspection.message, resolved.taskId);
|
|
778
|
+
}
|
|
779
|
+
return finalizeCommitIntentUnlocked(resolved, inspection, input.agent, () => {
|
|
780
|
+
removeCommitIntentByDigest(resolved.taskDir, resolved.taskId, inspection.intentDigest);
|
|
781
|
+
});
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
catch (error) {
|
|
785
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
function abortCommitIntent(taskRef, input, options = {}) {
|
|
789
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
790
|
+
if (!resolved.ok)
|
|
791
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
792
|
+
try {
|
|
793
|
+
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'commit-intent.abort', () => {
|
|
794
|
+
const intent = readCommitIntent(resolved.taskDir, resolved.taskId, input.token);
|
|
795
|
+
const currentHead = repositoryHead(resolved.repoRoot);
|
|
796
|
+
if (intent.phase !== 'prepared'
|
|
797
|
+
|| intent.pushEvidence !== null
|
|
798
|
+
|| input.expectedHead !== intent.baselineHead
|
|
799
|
+
|| currentHead !== intent.baselineHead) {
|
|
800
|
+
return commitIntentFailed('ORCHESTRATION_COMMIT_RECOVERY_REQUIRED', 'commit intent has side effects or repository drift', resolved.taskId);
|
|
801
|
+
}
|
|
802
|
+
removeCommitIntent(resolved.taskDir, resolved.taskId, input.token);
|
|
803
|
+
return { status: 'ready', changed: true, taskId: resolved.taskId, intent: null, error: null };
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
catch (error) {
|
|
807
|
+
return mapCommitIntentError(error, resolved.taskId);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function statusCommitIntent(taskRef, options = {}) {
|
|
811
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
812
|
+
if (!resolved.ok)
|
|
813
|
+
return commitIntentFailed(resolved.code, resolved.message, resolved.taskId);
|
|
814
|
+
const inspection = inspectCommitFinalization(resolved.taskDir, resolved.repoRoot, resolved.taskId);
|
|
815
|
+
return {
|
|
816
|
+
status: 'ready',
|
|
817
|
+
changed: false,
|
|
818
|
+
taskId: resolved.taskId,
|
|
819
|
+
intent: inspection.intent ? commitIntentView(inspection.intent, inspection.currentHead) : null,
|
|
820
|
+
finalization: commitFinalizationView(inspection),
|
|
821
|
+
error: null
|
|
822
|
+
};
|
|
176
823
|
}
|
|
177
824
|
function statusOrchestration(taskRef, options = {}) {
|
|
178
825
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
@@ -183,21 +830,30 @@ function statusOrchestration(taskRef, options = {}) {
|
|
|
183
830
|
return failed('ORCHESTRATION_RUN_MISSING', 'no orchestration run exists', resolved.taskId);
|
|
184
831
|
return { status: run.status, changed: false, taskId: resolved.taskId, run, next: null, error: null };
|
|
185
832
|
}
|
|
186
|
-
function
|
|
833
|
+
function prepareOrchestrationDelegationUnlocked(taskRef, input, options = {}) {
|
|
187
834
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
188
835
|
if (!resolved.ok)
|
|
189
836
|
return failed(resolved.code, resolved.message, resolved.taskId);
|
|
190
|
-
if (
|
|
191
|
-
|
|
837
|
+
if (fs.existsSync(commitIntentPath(resolved.taskDir))) {
|
|
838
|
+
try {
|
|
839
|
+
readCommitIntent(resolved.taskDir, resolved.taskId);
|
|
840
|
+
}
|
|
841
|
+
catch (error) {
|
|
842
|
+
return failed('ORCHESTRATION_COMMIT_INTENT_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
843
|
+
}
|
|
844
|
+
return failed('ORCHESTRATION_COMMIT_INTENT_BUSY', 'an active commit intent blocks delegation preparation', resolved.taskId);
|
|
845
|
+
}
|
|
846
|
+
if (!(options.supportsLifecycleDelegation ?? supportsLifecycleDelegation)(input.client)) {
|
|
192
847
|
return failed('ORCHESTRATION_CLIENT_UNSUPPORTED', `client '${input.client}' does not support lifecycle orchestration`, resolved.taskId);
|
|
193
848
|
}
|
|
194
849
|
const run = readRun(resolved.taskDir);
|
|
195
850
|
if (!run || run.status !== 'running')
|
|
196
851
|
return failed('ORCHESTRATION_RUN_NOT_RUNNING', 'a running orchestration is required', resolved.taskId);
|
|
852
|
+
if (!isV2Policy(run.modelPolicy))
|
|
853
|
+
return failed('ORCHESTRATION_MODEL_EVIDENCE_MISSING', 'running orchestration has no persisted model policy', resolved.taskId);
|
|
197
854
|
if (run.pendingDelegation)
|
|
198
855
|
return failed('ORCHESTRATION_DELEGATION_BUSY', 'the run already has a pending delegation', resolved.taskId);
|
|
199
|
-
const repositoryPending =
|
|
200
|
-
.flatMap((client) => matchingDelegations(client, () => true, options));
|
|
856
|
+
const repositoryPending = matchingDelegations(() => true, options);
|
|
201
857
|
if (repositoryPending.length > 0) {
|
|
202
858
|
return failed('ORCHESTRATION_DELEGATION_BUSY', 'the repository already has a pending lifecycle delegation', resolved.taskId);
|
|
203
859
|
}
|
|
@@ -207,9 +863,22 @@ function prepareOrchestrationDelegation(taskRef, input, options = {}) {
|
|
|
207
863
|
if (!routed.next)
|
|
208
864
|
return routed;
|
|
209
865
|
const next = routed.next;
|
|
866
|
+
if (!validModel(input.requestedModel)) {
|
|
867
|
+
return failed('ORCHESTRATION_REQUESTED_MODEL_REQUIRED', 'prepare requires the exact requested model identity', resolved.taskId);
|
|
868
|
+
}
|
|
869
|
+
if (!validModel(input.requestedReasoningEffort)) {
|
|
870
|
+
return failed('ORCHESTRATION_REQUESTED_REASONING_EFFORT_REQUIRED', 'prepare requires the exact requested reasoning effort', resolved.taskId);
|
|
871
|
+
}
|
|
872
|
+
const expectedPolicy = run.modelPolicy[next.role];
|
|
873
|
+
if (input.requestedModel !== expectedPolicy.model) {
|
|
874
|
+
return failed('ORCHESTRATION_REQUESTED_MODEL_MISMATCH', `requested model does not match the persisted ${next.role} model`, resolved.taskId);
|
|
875
|
+
}
|
|
876
|
+
if (input.requestedReasoningEffort !== expectedPolicy.reasoningEffort) {
|
|
877
|
+
return failed('ORCHESTRATION_REQUESTED_REASONING_EFFORT_MISMATCH', `requested reasoning effort does not match the persisted ${next.role} policy`, resolved.taskId);
|
|
878
|
+
}
|
|
210
879
|
let beforeFingerprint;
|
|
211
880
|
try {
|
|
212
|
-
beforeFingerprint = (options.captureWorkspace ?? captureWorkspaceSnapshot)(resolved.repoRoot);
|
|
881
|
+
beforeFingerprint = (options.captureWorkspace ?? captureWorkspaceSnapshot)(resolved.repoRoot, resolved.taskId);
|
|
213
882
|
}
|
|
214
883
|
catch (error) {
|
|
215
884
|
return failed('ORCHESTRATION_SNAPSHOT_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
@@ -222,7 +891,9 @@ function prepareOrchestrationDelegation(taskRef, input, options = {}) {
|
|
|
222
891
|
round: next.round,
|
|
223
892
|
artifact: next.artifact,
|
|
224
893
|
client: input.client,
|
|
225
|
-
requestedModel: input.requestedModel
|
|
894
|
+
requestedModel: input.requestedModel,
|
|
895
|
+
requestedReasoningEffort: input.requestedReasoningEffort,
|
|
896
|
+
workspaceSnapshotScope: 'task',
|
|
226
897
|
beforeFingerprint
|
|
227
898
|
}, { id: options.id, now: options.now });
|
|
228
899
|
const updated = withUpdatedRun(run, {
|
|
@@ -235,7 +906,20 @@ function prepareOrchestrationDelegation(taskRef, input, options = {}) {
|
|
|
235
906
|
saveRun(resolved.taskDir, updated);
|
|
236
907
|
return { status: 'running', changed: true, taskId: resolved.taskId, run: updated, next, error: null };
|
|
237
908
|
}
|
|
238
|
-
function
|
|
909
|
+
function prepareOrchestrationDelegation(taskRef, input, options = {}) {
|
|
910
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
911
|
+
if (!resolved.ok)
|
|
912
|
+
return failed(resolved.code, resolved.message, resolved.taskId);
|
|
913
|
+
try {
|
|
914
|
+
return withTaskExecutionLock(resolved.repoRoot, '__repository__', 'task-orchestration.prepare.repository', () => withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-orchestration.prepare.task', () => prepareOrchestrationDelegationUnlocked(taskRef, input, options)));
|
|
915
|
+
}
|
|
916
|
+
catch (error) {
|
|
917
|
+
if (error instanceof TaskExecutionLockError)
|
|
918
|
+
return failed(error.code, error.message, resolved.taskId);
|
|
919
|
+
throw error;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
function matchingDelegations(predicate, options) {
|
|
239
923
|
const repoRoot = options.repoRoot ?? process.cwd();
|
|
240
924
|
const activeRoot = path.join(repoRoot, '.agents', 'workspace', 'active');
|
|
241
925
|
if (!fs.existsSync(activeRoot))
|
|
@@ -247,13 +931,13 @@ function matchingDelegations(client, predicate, options) {
|
|
|
247
931
|
if (!run?.pendingDelegation)
|
|
248
932
|
return [];
|
|
249
933
|
const receipt = run.pendingDelegation;
|
|
250
|
-
return
|
|
934
|
+
return predicate(receipt)
|
|
251
935
|
? [{ taskId: entry.name, run }]
|
|
252
936
|
: [];
|
|
253
937
|
});
|
|
254
938
|
}
|
|
255
939
|
function uniqueMatchingDelegation(client, predicate, options) {
|
|
256
|
-
const matches = matchingDelegations(client
|
|
940
|
+
const matches = matchingDelegations((receipt) => receipt.client === client && predicate(receipt), options);
|
|
257
941
|
if (matches.length === 0)
|
|
258
942
|
return failed('ORCHESTRATION_DELEGATION_MISSING', 'no matching lifecycle delegation exists');
|
|
259
943
|
if (matches.length > 1)
|
|
@@ -285,7 +969,8 @@ function sealMatchingOrchestrationDelegation(client, event, options = {}) {
|
|
|
285
969
|
}
|
|
286
970
|
const repoRoot = options.repoRoot ?? process.cwd();
|
|
287
971
|
try {
|
|
288
|
-
const
|
|
972
|
+
const snapshotTaskId = receipt.workspaceSnapshotScope === 'task' ? receipt.taskId : null;
|
|
973
|
+
const afterFingerprint = (options.captureWorkspace ?? captureWorkspaceSnapshot)(repoRoot, snapshotTaskId);
|
|
289
974
|
const changedPaths = (options.diffWorkspace ?? diffWorkspaceSnapshots)(repoRoot, receipt.beforeFingerprint, afterFingerprint);
|
|
290
975
|
return sealOrchestrationDelegation(matched.taskId, {
|
|
291
976
|
childId: event.childId,
|
|
@@ -331,31 +1016,19 @@ function completeOrchestrationStage(taskRef, event, options = {}) {
|
|
|
331
1016
|
saveRun(resolved.taskDir, updated);
|
|
332
1017
|
return { status: 'running', changed: true, taskId: resolved.taskId, run: updated, next: null, error: null };
|
|
333
1018
|
}
|
|
334
|
-
function
|
|
1019
|
+
function inspectOrchestrationStage(taskRef, event, options = {}) {
|
|
335
1020
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
336
1021
|
if (!resolved.ok)
|
|
337
1022
|
return failed(resolved.code, resolved.message, resolved.taskId);
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
return failed('
|
|
1023
|
+
let run;
|
|
1024
|
+
try {
|
|
1025
|
+
run = readRun(resolved.taskDir);
|
|
1026
|
+
}
|
|
1027
|
+
catch (error) {
|
|
1028
|
+
return failed('ORCHESTRATION_STATE_INVALID', error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
344
1029
|
}
|
|
345
|
-
return completeOrchestrationStage(taskRef, {
|
|
346
|
-
stage: receipt.stage,
|
|
347
|
-
round: receipt.round,
|
|
348
|
-
artifact: receipt.artifact,
|
|
349
|
-
agent
|
|
350
|
-
}, options);
|
|
351
|
-
}
|
|
352
|
-
function validateOrchestrationStage(taskRef, event, options = {}) {
|
|
353
|
-
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
354
|
-
if (!resolved.ok)
|
|
355
|
-
return failed(resolved.code, resolved.message, resolved.taskId);
|
|
356
|
-
const run = readRun(resolved.taskDir);
|
|
357
1030
|
if (!run)
|
|
358
|
-
return
|
|
1031
|
+
return failed('ORCHESTRATION_RUN_MISSING', 'no orchestration run exists', resolved.taskId);
|
|
359
1032
|
const receipt = run.pendingDelegation;
|
|
360
1033
|
if (!receipt
|
|
361
1034
|
|| receipt.status !== 'activated'
|
|
@@ -363,10 +1036,36 @@ function validateOrchestrationStage(taskRef, event, options = {}) {
|
|
|
363
1036
|
|| receipt.round !== event.round
|
|
364
1037
|
|| receipt.artifact !== event.artifact
|
|
365
1038
|
|| receipt.role !== event.role) {
|
|
366
|
-
return
|
|
1039
|
+
return failed('ORCHESTRATION_PROVENANCE_MISMATCH', 'active run does not have one matching activated delegation', resolved.taskId);
|
|
367
1040
|
}
|
|
368
1041
|
return { status: 'running', changed: false, taskId: resolved.taskId, run, next: null, error: null };
|
|
369
1042
|
}
|
|
1043
|
+
function planOrchestrationStageCompletion(taskRef, event, options = {}) {
|
|
1044
|
+
const inspected = inspectOrchestrationStage(taskRef, event, options);
|
|
1045
|
+
if (inspected.status === 'failed' || !inspected.run?.pendingDelegation) {
|
|
1046
|
+
return { result: inspected, plan: null };
|
|
1047
|
+
}
|
|
1048
|
+
const receipt = inspected.run.pendingDelegation;
|
|
1049
|
+
const completed = completeDelegationStage(receipt, event);
|
|
1050
|
+
if (!completed.ok) {
|
|
1051
|
+
return { result: failed(completed.code, completed.message, inspected.taskId), plan: null };
|
|
1052
|
+
}
|
|
1053
|
+
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
1054
|
+
if (!resolved.ok)
|
|
1055
|
+
return { result: failed(resolved.code, resolved.message, resolved.taskId), plan: null };
|
|
1056
|
+
const updatedRun = withUpdatedRun(inspected.run, { pendingDelegation: completed.receipt }, options.now);
|
|
1057
|
+
return {
|
|
1058
|
+
result: { status: 'running', changed: true, taskId: resolved.taskId, run: updatedRun, next: null, error: null },
|
|
1059
|
+
plan: {
|
|
1060
|
+
taskId: resolved.taskId,
|
|
1061
|
+
taskDir: resolved.taskDir,
|
|
1062
|
+
updatedRun
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
function commitOrchestrationStageCompletion(plan) {
|
|
1067
|
+
saveRun(plan.taskDir, plan.updatedRun);
|
|
1068
|
+
}
|
|
370
1069
|
function sealOrchestrationDelegation(taskRef, event, options = {}) {
|
|
371
1070
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
372
1071
|
if (!resolved.ok)
|
|
@@ -416,5 +1115,5 @@ function pauseOrchestration(taskRef, code, message, recoverable, options = {}) {
|
|
|
416
1115
|
saveRun(resolved.taskDir, updated);
|
|
417
1116
|
return { status: 'paused', changed: true, taskId: resolved.taskId, run: updated, next: null, error: null };
|
|
418
1117
|
}
|
|
419
|
-
export { activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, beginOrResumeOrchestration,
|
|
1118
|
+
export { activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, abortCommitIntent, beginCommitIntent, beginOrResumeOrchestration, checkpointCommitIntent, commitOrchestrationStageCompletion, completeCommitIntent, completeOrchestrationStage, inspectOrchestrationStage, orchestrationPath, pauseOrchestration, planOrchestrationStageCompletion, prepareOrchestrationDelegation, readRun, recoverCommitIntent, routeOrchestration, sealMatchingOrchestrationDelegation, sealOrchestrationDelegation, statusCommitIntent, statusOrchestration };
|
|
420
1119
|
//# sourceMappingURL=orchestration.js.map
|