@fitlab-ai/agent-infra 0.9.10 → 0.9.12
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 +19 -9
- package/README.zh-CN.md +19 -9
- package/bin/cli.ts +17 -4
- package/dist/bin/cli.js +19 -4
- package/dist/bin/internal-cli.js +55 -4
- package/dist/lib/agent-client.js +0 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
- package/dist/lib/agent-clients/adapters/opencode-sandbox.js +0 -4
- package/dist/lib/agent-clients/adapters/traecli.js +7 -8
- package/dist/lib/agent-clients/config.js +14 -99
- package/dist/lib/agent-clients/reconcile.js +1 -11
- package/dist/lib/agent-clients/schema.js +5 -4
- package/dist/lib/agent-clients/tokens.js +5 -15
- package/dist/lib/decide.js +14 -30
- package/dist/lib/defaults.json +8 -0
- package/dist/lib/git/workflow.js +43 -1
- package/dist/lib/init.js +3 -2
- package/dist/lib/internal/git-workflow.js +8 -1
- package/dist/lib/internal/platform-pr.js +8 -2
- package/dist/lib/internal/release-workflow.js +0 -1
- package/dist/lib/internal/task-delivery.js +59 -0
- package/dist/lib/internal/task-finalization.js +19 -9
- package/dist/lib/internal/task-ledger.js +8 -2
- package/dist/lib/internal/task-lifecycle.js +17 -93
- package/dist/lib/internal/task-orchestration.js +30 -216
- package/dist/lib/internal/task-validate.js +2 -1
- package/dist/lib/merge.js +205 -103
- package/dist/lib/platform/github-client.js +7 -1
- package/dist/lib/platform/pr-checks.js +8 -5
- package/dist/lib/platform/pr-summary.js +12 -8
- package/dist/lib/platform/pull-requests.js +393 -91
- package/dist/lib/platform/verification-required.js +13 -2
- package/dist/lib/platform/verification-sync.js +9 -4
- package/dist/lib/pr-review/evidence-grading.js +12 -4
- package/dist/lib/process-data/normalize.js +2 -9
- package/dist/lib/run/host.js +46 -16
- package/dist/lib/sandbox/agent-client-reconciler.js +4 -12
- package/dist/lib/sandbox/commands/create.js +3 -3
- package/dist/lib/sandbox/commands/enter.js +18 -4
- package/dist/lib/sandbox/config.js +8 -12
- package/dist/lib/sandbox/control/executor.js +131 -39
- package/dist/lib/sandbox/control/lifecycle.js +55 -24
- package/dist/lib/sandbox/control/server.js +18 -16
- package/dist/lib/sandbox/mounts.js +3 -2
- package/dist/lib/sandbox/recovery.js +123 -22
- package/dist/lib/sandbox/workspace-identity.js +14 -0
- package/dist/lib/sandbox/workspace-view.js +8 -9
- package/dist/lib/self-update.js +278 -0
- package/dist/lib/server/process-state.js +2 -2
- package/dist/lib/server/protocol.js +5 -5
- package/dist/lib/task/activity-log.js +4 -1
- package/dist/lib/task/artifact-lifecycle.js +6 -4
- package/dist/lib/task/codex-orchestration.js +1 -1
- package/dist/lib/task/command-options.js +1 -3
- package/dist/lib/task/commands/cat.js +0 -5
- package/dist/lib/task/commands/decisions.js +76 -92
- package/dist/lib/task/commands/files.js +6 -6
- package/dist/lib/task/commands/grep.js +25 -61
- package/dist/lib/task/commands/issue-body.js +6 -6
- package/dist/lib/task/commands/log.js +25 -10
- package/dist/lib/task/commands/show.js +5 -6
- package/dist/lib/task/commands/status.js +8 -8
- package/dist/lib/task/commit-intent.js +100 -0
- package/dist/lib/task/commit-operation.js +181 -91
- package/dist/lib/task/commit-policy.js +1 -1
- package/dist/lib/task/control-authority.js +431 -0
- package/dist/lib/task/create.js +39 -8
- package/dist/lib/task/current-contract.js +35 -0
- package/dist/lib/task/decision-details.js +218 -0
- package/dist/lib/task/decision-intents.js +5 -2
- package/dist/lib/task/delivery-target.js +97 -0
- package/dist/lib/task/delivery.js +153 -0
- package/dist/lib/task/events.js +11 -5
- package/dist/lib/task/human-override.js +5 -2
- package/dist/lib/task/index.js +19 -20
- package/dist/lib/task/ledger-intents.js +8 -9
- package/dist/lib/task/ledger.js +13 -6
- package/dist/lib/task/lifecycle.js +122 -9
- package/dist/lib/task/orchestration.js +105 -75
- package/dist/lib/task/pr-delivery-fact.js +182 -0
- package/dist/lib/task/review-artifacts.js +31 -12
- package/dist/lib/task/review-finalization.js +13 -4
- package/dist/lib/task/review-fingerprint.js +8 -0
- package/dist/lib/task/verification-engine.js +86 -39
- package/dist/lib/task/verification-review.js +2 -2
- package/dist/lib/task/workspace-snapshot.js +5 -11
- package/dist/lib/task/write.js +11 -1
- package/dist/lib/update.js +13 -35
- package/dist/lib/version.js +5 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-client.ts +0 -1
- package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
- package/lib/agent-clients/adapters/opencode-sandbox.ts +0 -5
- package/lib/agent-clients/adapters/traecli.ts +7 -8
- package/lib/agent-clients/config.ts +14 -144
- package/lib/agent-clients/reconcile.ts +1 -12
- package/lib/agent-clients/schema.ts +5 -4
- package/lib/agent-clients/tokens.ts +5 -18
- package/lib/decide.ts +12 -22
- package/lib/defaults.json +8 -0
- package/lib/git/workflow.ts +38 -1
- package/lib/init.ts +5 -2
- package/lib/internal/git-workflow.ts +7 -1
- package/lib/internal/platform-pr.ts +8 -1
- package/lib/internal/release-workflow.ts +0 -1
- package/lib/internal/task-delivery.ts +53 -0
- package/lib/internal/task-finalization.ts +27 -13
- package/lib/internal/task-ledger.ts +8 -2
- package/lib/internal/task-lifecycle.ts +33 -76
- package/lib/internal/task-orchestration.ts +33 -190
- package/lib/internal/task-validate.ts +3 -2
- package/lib/merge.ts +236 -120
- package/lib/platform/github-client.ts +8 -1
- package/lib/platform/pr-checks.ts +7 -5
- package/lib/platform/pr-summary.ts +10 -7
- package/lib/platform/pull-requests.ts +425 -87
- package/lib/platform/verification-required.ts +12 -2
- package/lib/platform/verification-sync.ts +9 -4
- package/lib/pr-review/evidence-grading.ts +7 -4
- package/lib/process-data/normalize.ts +2 -8
- package/lib/run/host.ts +63 -14
- package/lib/sandbox/agent-client-reconciler.ts +5 -15
- package/lib/sandbox/commands/create.ts +4 -4
- package/lib/sandbox/commands/enter.ts +24 -4
- package/lib/sandbox/config.ts +9 -14
- package/lib/sandbox/control/container-identity.ts +2 -2
- package/lib/sandbox/control/executor.ts +148 -51
- package/lib/sandbox/control/lifecycle.ts +59 -31
- package/lib/sandbox/control/protocol.ts +1 -3
- package/lib/sandbox/control/server.ts +15 -12
- package/lib/sandbox/control/state.ts +7 -7
- package/lib/sandbox/mounts.ts +4 -3
- package/lib/sandbox/recovery.ts +162 -34
- package/lib/sandbox/tools.ts +1 -1
- package/lib/sandbox/workspace-identity.ts +28 -0
- package/lib/sandbox/workspace-view.ts +14 -10
- package/lib/self-update.ts +341 -0
- package/lib/server/process-state.ts +2 -2
- package/lib/server/protocol.ts +5 -5
- package/lib/task/activity-log.ts +6 -1
- package/lib/task/artifact-lifecycle.ts +7 -5
- package/lib/task/codex-orchestration.ts +2 -1
- package/lib/task/command-options.ts +1 -2
- package/lib/task/commands/cat.ts +0 -4
- package/lib/task/commands/decisions.ts +80 -75
- package/lib/task/commands/files.ts +6 -6
- package/lib/task/commands/grep.ts +23 -51
- package/lib/task/commands/issue-body.ts +6 -6
- package/lib/task/commands/log.ts +22 -10
- package/lib/task/commands/show.ts +5 -6
- package/lib/task/commands/status.ts +8 -8
- package/lib/task/commit-intent.ts +137 -0
- package/lib/task/commit-operation.ts +161 -79
- package/lib/task/commit-policy.ts +1 -2
- package/lib/task/control-authority.ts +563 -0
- package/lib/task/create.ts +40 -10
- package/lib/task/current-contract.ts +49 -0
- package/lib/task/decision-details.ts +280 -0
- package/lib/task/decision-intents.ts +7 -2
- package/lib/task/delivery-target.ts +130 -0
- package/lib/task/delivery.ts +160 -0
- package/lib/task/events.ts +10 -5
- package/lib/task/human-override.ts +5 -2
- package/lib/task/index.ts +19 -20
- package/lib/task/ledger-intents.ts +6 -8
- package/lib/task/ledger.ts +17 -7
- package/lib/task/lifecycle.ts +113 -4
- package/lib/task/orchestration.ts +102 -80
- package/lib/task/pr-delivery-fact.ts +254 -0
- package/lib/task/review-artifacts.ts +53 -15
- package/lib/task/review-finalization.ts +21 -5
- package/lib/task/review-fingerprint.ts +10 -0
- package/lib/task/verification-engine.ts +78 -46
- package/lib/task/verification-review.ts +3 -1
- package/lib/task/workspace-snapshot.ts +4 -13
- package/lib/task/write.ts +20 -1
- package/lib/update.ts +14 -38
- package/lib/version.ts +6 -1
- package/package.json +1 -1
- package/templates/.agents/README.en.md +5 -3
- package/templates/.agents/README.zh-CN.md +5 -3
- package/templates/.agents/rules/README.en.md +4 -2
- package/templates/.agents/rules/README.zh-CN.md +4 -2
- package/templates/.agents/rules/compatibility-policy.en.md +5 -4
- package/templates/.agents/rules/compatibility-policy.zh-CN.md +5 -4
- package/templates/.agents/rules/create-issue.en.md +11 -2
- package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
- package/templates/.agents/rules/human-decision-context.en.md +9 -7
- package/templates/.agents/rules/human-decision-context.zh-CN.md +9 -7
- package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +1 -1
- package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +1 -1
- package/templates/.agents/rules/issue-pr-commands.en.md +5 -18
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +26 -5
- package/templates/.agents/rules/issue-sync.zh-CN.md +62 -5
- package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
- package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
- package/templates/.agents/rules/local-artifact-repair.en.md +46 -0
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +46 -0
- package/templates/.agents/rules/milestone-inference.en.md +12 -2
- package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
- package/templates/.agents/rules/next-step-output.en.md +3 -3
- package/templates/.agents/rules/next-step-output.zh-CN.md +3 -3
- package/templates/.agents/rules/no-mid-flow-questions.en.md +1 -1
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +1 -1
- package/templates/.agents/rules/pr-sync.en.md +23 -14
- package/templates/.agents/rules/pr-sync.zh-CN.md +23 -2
- package/templates/.agents/rules/release-commands.en.md +42 -3
- package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
- package/templates/.agents/rules/review-handshake.en.md +1 -1
- package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
- package/templates/.agents/rules/security-alerts.en.md +17 -2
- package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
- package/templates/.agents/rules/sync-content-generation.en.md +8 -0
- package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
- package/templates/.agents/rules/task-management.en.md +2 -3
- package/templates/.agents/rules/task-management.zh-CN.md +2 -3
- package/templates/.agents/scripts/security-alerts.github.sh +151 -0
- package/templates/.agents/scripts/security-alerts.sh +31 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +4 -3
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +4 -3
- package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/check-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -3
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -3
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/code-task/SKILL.en.md +8 -5
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +9 -6
- package/templates/.agents/skills/commit/SKILL.en.md +30 -10
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +6 -7
- package/templates/.agents/skills/commit/config/verify.json +1 -1
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
- 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 +2 -2
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -6
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -6
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- 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 +13 -13
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +13 -13
- package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
- package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
- package/templates/.agents/skills/create-pr/SKILL.en.md +9 -11
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +9 -11
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -4
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -4
- package/templates/.agents/skills/create-pr/scripts/change-report.mjs +203 -0
- package/templates/.agents/skills/create-release-note/SKILL.en.md +5 -6
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +5 -6
- package/templates/.agents/skills/create-task/SKILL.en.md +2 -1
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +2 -1
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/init-labels/SKILL.en.md +9 -10
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
- package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
- package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
- package/templates/.agents/skills/plan-task/SKILL.en.md +4 -3
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +4 -3
- package/templates/.agents/skills/restore-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +8 -5
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +8 -5
- package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
- 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/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.en.md +2 -1
- package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +2 -1
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
- package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
- package/templates/.agents/skills/review-plan/SKILL.en.md +8 -5
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +8 -5
- package/templates/.agents/skills/review-plan/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
- package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
- package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -0
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -0
- package/templates/.agents/skills/run-task/SKILL.en.md +5 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -2
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +144 -109
- package/templates/.agents/skills/watch-pr/SKILL.en.md +5 -5
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +5 -5
- package/templates/.agents/templates/task.en.md +6 -2
- package/templates/.agents/templates/task.zh-CN.md +6 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/feature-development.en.yaml +9 -8
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/refactoring.en.yaml +9 -8
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
- package/templates/.claude/commands/analyze-task.en.md +1 -1
- package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
- package/templates/.claude/commands/block-task.en.md +1 -1
- package/templates/.claude/commands/block-task.zh-CN.md +1 -1
- package/templates/.claude/commands/cancel-task.en.md +1 -1
- package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
- package/templates/.claude/commands/check-task.en.md +1 -1
- package/templates/.claude/commands/check-task.zh-CN.md +1 -1
- package/templates/.claude/commands/code-task.en.md +1 -1
- package/templates/.claude/commands/code-task.zh-CN.md +1 -1
- package/templates/.claude/commands/commit.en.md +1 -1
- package/templates/.claude/commands/commit.zh-CN.md +1 -1
- package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
- package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
- package/templates/.claude/commands/complete-task.en.md +1 -1
- package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
- package/templates/.claude/commands/create-pr.en.md +1 -1
- package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
- package/templates/.claude/commands/plan-task.en.md +1 -1
- package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
- package/templates/.claude/commands/review-analysis.en.md +1 -1
- package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
- package/templates/.claude/commands/review-code.en.md +1 -1
- package/templates/.claude/commands/review-code.zh-CN.md +1 -1
- package/templates/.claude/commands/review-plan.en.md +1 -1
- package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
- package/templates/.claude/commands/run-manual-validation.en.md +1 -1
- package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
- package/templates/.claude/commands/run-task.en.md +1 -1
- package/templates/.claude/commands/run-task.zh-CN.md +1 -1
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.en.md +0 -1
- package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.zh-CN.md +0 -1
- package/dist/lib/builtin-tuis.js +0 -40
- package/lib/builtin-tuis.ts +0 -56
- package/templates/.agents/rules/create-issue.github.en.md +0 -14
- package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
- package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
- package/templates/.agents/rules/issue-sync.github.en.md +0 -40
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
- package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
- package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
- package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
- package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
- package/templates/.agents/rules/pr-sync.github.en.md +0 -43
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
- package/templates/.agents/rules/release-commands.github.en.md +0 -38
- package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -38
- package/templates/.agents/rules/security-alerts.github.en.md +0 -43
- package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
package/lib/sandbox/recovery.ts
CHANGED
|
@@ -28,11 +28,12 @@ import {
|
|
|
28
28
|
sandboxControlPaths,
|
|
29
29
|
sandboxWorkspaceViewPaths
|
|
30
30
|
} from './workspace-view.ts';
|
|
31
|
+
import { resolveTaskWorkspace } from './task-resolver.ts';
|
|
31
32
|
import {
|
|
32
33
|
parseSandboxWorkspaceIdentity,
|
|
33
34
|
sameSandboxWorkspaceIdentity,
|
|
34
35
|
type SandboxContainerWorkspaceIdentity,
|
|
35
|
-
type
|
|
36
|
+
type SandboxWorkspaceReference
|
|
36
37
|
} from './workspace-identity.ts';
|
|
37
38
|
import { inspectWorktree, type WorktreeSnapshot } from './worktree-safety.ts';
|
|
38
39
|
import { commandForEngine, runEngine, runOkEngine, runProbe, runVerboseEngine } from './shell.ts';
|
|
@@ -91,7 +92,7 @@ export type SandboxRecoverySnapshot = {
|
|
|
91
92
|
containerIdValid: boolean;
|
|
92
93
|
expectedBranch: string;
|
|
93
94
|
actualBranch: string | null;
|
|
94
|
-
expectedWorkspace:
|
|
95
|
+
expectedWorkspace: SandboxWorkspaceReference;
|
|
95
96
|
actualWorkspace: SandboxContainerWorkspaceIdentity;
|
|
96
97
|
workspaceTopology?: 'legacy-parent' | 'per-state' | 'unknown';
|
|
97
98
|
taskView?: { path: string; readable: boolean };
|
|
@@ -174,7 +175,8 @@ type EnsureSandboxReadyParams = {
|
|
|
174
175
|
config: SandboxConfig;
|
|
175
176
|
engine: string;
|
|
176
177
|
branch: string;
|
|
177
|
-
workspace?:
|
|
178
|
+
workspace?: SandboxWorkspaceReference;
|
|
179
|
+
reentry?: 'standard' | 'completed';
|
|
178
180
|
row: SandboxRow;
|
|
179
181
|
allowRecreate?: boolean;
|
|
180
182
|
forceRecreate?: boolean;
|
|
@@ -187,6 +189,7 @@ type ExpectedMount = {
|
|
|
187
189
|
path: string;
|
|
188
190
|
expectedType: 'bind' | 'tmpfs';
|
|
189
191
|
hostPaths: string[];
|
|
192
|
+
sourceAccessiblePaths?: string[];
|
|
190
193
|
expectedRW: boolean;
|
|
191
194
|
};
|
|
192
195
|
|
|
@@ -324,7 +327,7 @@ export async function startSandboxControlBroker(repoRoot: string, manifestPath:
|
|
|
324
327
|
async function ensureSandboxControlBroker(params: {
|
|
325
328
|
config: SandboxConfig;
|
|
326
329
|
container: string;
|
|
327
|
-
workspace:
|
|
330
|
+
workspace: SandboxWorkspaceReference;
|
|
328
331
|
}): Promise<void> {
|
|
329
332
|
const control = sandboxControlPaths({
|
|
330
333
|
base: params.config.controlBase ?? path.join(params.config.home, '.agent-infra', 'sandbox-control'),
|
|
@@ -603,6 +606,93 @@ function sourceCandidates(engine: string, hostPath: string): string[] {
|
|
|
603
606
|
return [...new Set(candidates.map((candidate) => normalizeMountSource(engine, candidate)))];
|
|
604
607
|
}
|
|
605
608
|
|
|
609
|
+
function recoveryTaskSources(repoRoot: string, taskId: string): {
|
|
610
|
+
mountPaths: string[];
|
|
611
|
+
accessiblePaths: string[];
|
|
612
|
+
} {
|
|
613
|
+
const activePath = path.join(repoRoot, '.agents', 'workspace', 'active', taskId);
|
|
614
|
+
const completedPath = path.join(repoRoot, '.agents', 'workspace', 'completed', taskId);
|
|
615
|
+
if (fs.existsSync(activePath) && !fs.existsSync(completedPath)) {
|
|
616
|
+
const source = assertSandboxTaskSource(repoRoot, taskId);
|
|
617
|
+
return { mountPaths: [source], accessiblePaths: [source] };
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
const task = resolveTaskWorkspace(taskId, repoRoot);
|
|
621
|
+
if (task.state === 'active') {
|
|
622
|
+
const source = assertSandboxTaskSource(repoRoot, taskId);
|
|
623
|
+
return { mountPaths: [source], accessiblePaths: [source] };
|
|
624
|
+
}
|
|
625
|
+
if (task.state !== 'completed') {
|
|
626
|
+
throw new Error(`SANDBOX_TASK_SOURCE_STATE_UNSUPPORTED: task ${taskId} is ${task.state}`);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const completedRoot = fs.realpathSync.native(
|
|
630
|
+
path.join(repoRoot, '.agents', 'workspace', 'completed')
|
|
631
|
+
);
|
|
632
|
+
const completedSource = fs.realpathSync.native(path.dirname(task.taskMd));
|
|
633
|
+
if (path.dirname(completedSource) !== completedRoot) {
|
|
634
|
+
throw new Error(`SANDBOX_TASK_SOURCE_INVALID: ${completedSource} is not under completed workspace`);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const historicalActivePath = path.join(
|
|
638
|
+
repoRoot,
|
|
639
|
+
'.agents',
|
|
640
|
+
'workspace',
|
|
641
|
+
'active',
|
|
642
|
+
taskId
|
|
643
|
+
);
|
|
644
|
+
const mountPaths = [completedSource, historicalActivePath];
|
|
645
|
+
if (fs.existsSync(historicalActivePath)) {
|
|
646
|
+
try {
|
|
647
|
+
mountPaths[1] = fs.realpathSync.native(historicalActivePath);
|
|
648
|
+
} catch {
|
|
649
|
+
// Keep the exact historical path as a candidate; the current completed
|
|
650
|
+
// source remains the only source that must still be accessible.
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return { mountPaths, accessiblePaths: [completedSource] };
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
function startCompletedSandboxContainer(params: {
|
|
657
|
+
config: SandboxConfig;
|
|
658
|
+
engine: string;
|
|
659
|
+
container: string;
|
|
660
|
+
taskId: string;
|
|
661
|
+
start: typeof startSandboxContainer;
|
|
662
|
+
}): void {
|
|
663
|
+
const taskSources = recoveryTaskSources(params.config.repoRoot, params.taskId);
|
|
664
|
+
const completedSource = taskSources.accessiblePaths[0]!;
|
|
665
|
+
const activeRoot = path.join(params.config.repoRoot, '.agents', 'workspace', 'active');
|
|
666
|
+
const historicalSource = path.join(activeRoot, params.taskId);
|
|
667
|
+
fs.mkdirSync(activeRoot, { recursive: true });
|
|
668
|
+
try {
|
|
669
|
+
fs.lstatSync(historicalSource);
|
|
670
|
+
throw new Error(
|
|
671
|
+
`SANDBOX_COMPLETED_SOURCE_CONFLICT: historical task source already exists at ${historicalSource}`
|
|
672
|
+
);
|
|
673
|
+
} catch (error) {
|
|
674
|
+
if (!(error instanceof Error && 'code' in error && error.code === 'ENOENT')) throw error;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
fs.symlinkSync(
|
|
678
|
+
completedSource,
|
|
679
|
+
historicalSource,
|
|
680
|
+
process.platform === 'win32' ? 'junction' : 'dir'
|
|
681
|
+
);
|
|
682
|
+
try {
|
|
683
|
+
params.start(params.engine, params.container);
|
|
684
|
+
} finally {
|
|
685
|
+
const temporarySource = fs.lstatSync(historicalSource);
|
|
686
|
+
const resolvedSource = fs.realpathSync.native(historicalSource);
|
|
687
|
+
if (!temporarySource.isSymbolicLink() || resolvedSource !== completedSource) {
|
|
688
|
+
throw new Error(
|
|
689
|
+
`SANDBOX_COMPLETED_SOURCE_CHANGED: refusing to remove unexpected path at ${historicalSource}`
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
fs.unlinkSync(historicalSource);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
606
696
|
function sameHostSource(left: string, right: string): boolean {
|
|
607
697
|
try {
|
|
608
698
|
const leftStat = fs.statSync(left, { bigint: true });
|
|
@@ -629,7 +719,7 @@ function expectedMounts(params: {
|
|
|
629
719
|
config: SandboxConfig;
|
|
630
720
|
branch: string;
|
|
631
721
|
container: string;
|
|
632
|
-
workspace:
|
|
722
|
+
workspace: SandboxWorkspaceReference;
|
|
633
723
|
tools: readonly SandboxTool[];
|
|
634
724
|
actualMounts: Map<string, DockerMount>;
|
|
635
725
|
}): ExpectedMount[] {
|
|
@@ -646,21 +736,29 @@ function expectedMounts(params: {
|
|
|
646
736
|
container: params.container,
|
|
647
737
|
identity: params.workspace
|
|
648
738
|
});
|
|
739
|
+
const taskSources = params.workspace.mode === 'task-bound'
|
|
740
|
+
? recoveryTaskSources(config.repoRoot, params.workspace.taskId)
|
|
741
|
+
: null;
|
|
742
|
+
const taskId = params.workspace.mode === 'task-bound' ? params.workspace.taskId : null;
|
|
649
743
|
const core = sandboxCoreBindMounts(config, branch, {
|
|
650
744
|
workspaceViewRoot: view.root,
|
|
651
745
|
controlDir: control.channelDir,
|
|
652
746
|
controlStatusDir: control.statusDir,
|
|
653
|
-
...(
|
|
654
|
-
? {
|
|
747
|
+
...(taskSources === null
|
|
748
|
+
? {}
|
|
749
|
+
: {
|
|
655
750
|
runtimeDir: control.runtimeDir,
|
|
656
|
-
|
|
657
|
-
taskId:
|
|
658
|
-
}
|
|
659
|
-
: {})
|
|
751
|
+
taskSources: taskSources.mountPaths,
|
|
752
|
+
taskId: taskId!
|
|
753
|
+
})
|
|
660
754
|
}).map((mount) => ({
|
|
661
755
|
path: mount.containerPath,
|
|
662
756
|
expectedType: 'bind' as const,
|
|
663
757
|
hostPaths: mount.hostPaths,
|
|
758
|
+
...(taskSources !== null && taskId !== null
|
|
759
|
+
&& mount.containerPath === `/workspace/.agents/workspace/active/${taskId}`
|
|
760
|
+
? { sourceAccessiblePaths: taskSources.accessiblePaths }
|
|
761
|
+
: {}),
|
|
664
762
|
expectedRW: !mount.readOnly
|
|
665
763
|
}));
|
|
666
764
|
const live = tools.flatMap((tool) =>
|
|
@@ -676,13 +774,7 @@ function expectedMounts(params: {
|
|
|
676
774
|
})
|
|
677
775
|
);
|
|
678
776
|
const persistentTools = tools
|
|
679
|
-
.filter((tool) =>
|
|
680
|
-
!tool.tmpfs
|
|
681
|
-
&& (
|
|
682
|
-
config.agentClientSource === 'canonical'
|
|
683
|
-
|| actualMounts.has(tool.containerMount)
|
|
684
|
-
)
|
|
685
|
-
)
|
|
777
|
+
.filter((tool) => !tool.tmpfs)
|
|
686
778
|
.map((tool) => ({
|
|
687
779
|
path: tool.containerMount,
|
|
688
780
|
expectedType: 'bind' as const,
|
|
@@ -755,7 +847,7 @@ export function collectSandboxRecoverySnapshot(params: {
|
|
|
755
847
|
config: SandboxConfig;
|
|
756
848
|
engine: string;
|
|
757
849
|
branch: string;
|
|
758
|
-
workspace?:
|
|
850
|
+
workspace?: SandboxWorkspaceReference;
|
|
759
851
|
container: string;
|
|
760
852
|
deps?: RecoveryCommandDeps;
|
|
761
853
|
}): SandboxRecoverySnapshot {
|
|
@@ -836,13 +928,10 @@ export function collectSandboxRecoverySnapshot(params: {
|
|
|
836
928
|
taskId: sandboxTaskIdLabel(params.config)
|
|
837
929
|
});
|
|
838
930
|
const selectedToolIds = new Set(tools.map((tool) => tool.id));
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
.map((tool) => tool.containerMount)
|
|
844
|
-
.filter((mountPath) => mountsByDestination.has(mountPath))
|
|
845
|
-
: [];
|
|
931
|
+
const unexpectedCapabilityMounts = capabilityPlan.cleanupInventory
|
|
932
|
+
.filter((tool) => isAgentClientId(tool.id) && !selectedToolIds.has(tool.id))
|
|
933
|
+
.map((tool) => tool.containerMount)
|
|
934
|
+
.filter((mountPath) => mountsByDestination.has(mountPath));
|
|
846
935
|
const mountSnapshots = expectedMounts({
|
|
847
936
|
config: params.config,
|
|
848
937
|
branch: params.branch,
|
|
@@ -880,7 +969,9 @@ export function collectSandboxRecoverySnapshot(params: {
|
|
|
880
969
|
sourceAccessible: expected.expectedType === 'tmpfs'
|
|
881
970
|
? true
|
|
882
971
|
: matchedHostPath !== undefined
|
|
883
|
-
&&
|
|
972
|
+
&& (expected.sourceAccessiblePaths ?? [matchedHostPath]).some((hostPath) =>
|
|
973
|
+
hostSourceAccessible(hostPath, expected.expectedRW)
|
|
974
|
+
)
|
|
884
975
|
};
|
|
885
976
|
});
|
|
886
977
|
|
|
@@ -907,9 +998,7 @@ export function collectSandboxRecoverySnapshot(params: {
|
|
|
907
998
|
identityOk: typeof inspection.Id === 'string' && inspection.Id.length > 0
|
|
908
999
|
&& branchLabel === params.branch
|
|
909
1000
|
&& sameSandboxWorkspaceIdentity(containerWorkspace, workspace),
|
|
910
|
-
runtimeCapabilityOk:
|
|
911
|
-
? labels[sandboxRuntimeCapabilityLabel(params.config)] === capabilityPlan.runtimeSignature
|
|
912
|
-
: undefined,
|
|
1001
|
+
runtimeCapabilityOk: labels[sandboxRuntimeCapabilityLabel(params.config)] === capabilityPlan.runtimeSignature,
|
|
913
1002
|
unexpectedCapabilityMounts,
|
|
914
1003
|
mounts: mountSnapshots,
|
|
915
1004
|
tmpfs,
|
|
@@ -1069,7 +1158,7 @@ function assess(params: {
|
|
|
1069
1158
|
config: SandboxConfig;
|
|
1070
1159
|
engine: string;
|
|
1071
1160
|
branch: string;
|
|
1072
|
-
workspace?:
|
|
1161
|
+
workspace?: SandboxWorkspaceReference;
|
|
1073
1162
|
container: string;
|
|
1074
1163
|
deps?: RecoveryCommandDeps;
|
|
1075
1164
|
}): { snapshot: SandboxRecoverySnapshot; findings: SandboxRecoveryFinding[] } {
|
|
@@ -1095,7 +1184,7 @@ export async function assertFreshSandboxReady(params: {
|
|
|
1095
1184
|
config: SandboxConfig;
|
|
1096
1185
|
engine: string;
|
|
1097
1186
|
branch: string;
|
|
1098
|
-
workspace?:
|
|
1187
|
+
workspace?: SandboxWorkspaceReference;
|
|
1099
1188
|
container: string;
|
|
1100
1189
|
copiedEntries: TmpfsSeedEntry[];
|
|
1101
1190
|
deps?: RecoveryCommandDeps;
|
|
@@ -1157,11 +1246,21 @@ export async function ensureSandboxReady(params: EnsureSandboxReadyParams): Prom
|
|
|
1157
1246
|
workspace: params.workspace ?? { mode: 'branch-only' }
|
|
1158
1247
|
});
|
|
1159
1248
|
}
|
|
1160
|
-
if (params.forceRecreate) {
|
|
1249
|
+
if (params.forceRecreate || (params.reentry === 'completed' && params.allowRecreate)) {
|
|
1161
1250
|
throw new Error('Explicit container recreation requested.');
|
|
1162
1251
|
}
|
|
1163
1252
|
if (!params.row.running) {
|
|
1164
|
-
|
|
1253
|
+
if (params.reentry === 'completed' && params.workspace?.mode === 'task-bound') {
|
|
1254
|
+
startCompletedSandboxContainer({
|
|
1255
|
+
config: params.config,
|
|
1256
|
+
engine: params.engine,
|
|
1257
|
+
container: params.row.name,
|
|
1258
|
+
taskId: params.workspace.taskId,
|
|
1259
|
+
start: startFn
|
|
1260
|
+
});
|
|
1261
|
+
} else {
|
|
1262
|
+
startFn(params.engine, params.row.name);
|
|
1263
|
+
}
|
|
1165
1264
|
const initial = assess({
|
|
1166
1265
|
config: params.config,
|
|
1167
1266
|
engine: params.engine,
|
|
@@ -1281,6 +1380,35 @@ export async function ensureSandboxReady(params: EnsureSandboxReadyParams): Prom
|
|
|
1281
1380
|
failure = error instanceof Error ? error : new Error(String(error));
|
|
1282
1381
|
}
|
|
1283
1382
|
|
|
1383
|
+
if (params.reentry === 'completed') {
|
|
1384
|
+
if (params.workspace?.mode !== 'task-bound') {
|
|
1385
|
+
throw new Error('SANDBOX_COMPLETED_REENTRY_INVALID: completed re-entry requires a task-bound workspace');
|
|
1386
|
+
}
|
|
1387
|
+
const taskId = params.workspace.taskId;
|
|
1388
|
+
const commandChain = [
|
|
1389
|
+
`docker exec -it ${params.row.name} bash /usr/local/bin/sandbox-tmux-entry`,
|
|
1390
|
+
`ai sandbox rm ${taskId}`,
|
|
1391
|
+
`ai sandbox create ${params.branch}`
|
|
1392
|
+
];
|
|
1393
|
+
const code = params.allowRecreate || params.forceRecreate
|
|
1394
|
+
? 'SANDBOX_COMPLETED_RECREATE_UNSUPPORTED'
|
|
1395
|
+
: 'SANDBOX_COMPLETED_REENTRY_FAILED';
|
|
1396
|
+
const lead = code === 'SANDBOX_COMPLETED_RECREATE_UNSUPPORTED'
|
|
1397
|
+
? 'Completed sandbox replacement is unsupported; the existing container was not replaced.'
|
|
1398
|
+
: 'Completed sandbox recovery failed; the existing container was not replaced.';
|
|
1399
|
+
throw new Error([
|
|
1400
|
+
`${code}: ${lead}`,
|
|
1401
|
+
`Task: ${taskId}; container: ${params.row.name}; branch: ${params.branch}.`,
|
|
1402
|
+
'To preserve the current container state, enter it manually with:',
|
|
1403
|
+
` ${commandChain[0]}`,
|
|
1404
|
+
'If you intentionally want a replacement, the following is the full interactive sandbox cleanup, not a container-only delete.',
|
|
1405
|
+
'It may remove the worktree, local branch, tool/shell state, and branch share:',
|
|
1406
|
+
` ${commandChain[1]}`,
|
|
1407
|
+
` ${commandChain[2]}`,
|
|
1408
|
+
`Details: ${failure.message}`
|
|
1409
|
+
].join('\n'));
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1284
1412
|
const dataBoundary =
|
|
1285
1413
|
'The existing container writable layer, ordinary /tmp data, processes, tmux sessions, and RAM state may be lost by replacement; worktree and host-managed sandbox data are preserved.';
|
|
1286
1414
|
const recoveryTarget = params.workspace?.mode === 'task-bound'
|
package/lib/sandbox/tools.ts
CHANGED
|
@@ -41,7 +41,7 @@ type ToolsConfig = {
|
|
|
41
41
|
project: string;
|
|
42
42
|
tools: string[];
|
|
43
43
|
customTools?: SandboxTool[];
|
|
44
|
-
agentClientState
|
|
44
|
+
agentClientState: import('../agent-clients/types.ts').AgentClientState;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
const TOOL_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
@@ -17,6 +17,8 @@ export type SandboxWorkspaceKey =
|
|
|
17
17
|
| Readonly<{ mode: 'task-bound'; taskId: string }>
|
|
18
18
|
| Readonly<{ mode: 'branch-only' }>;
|
|
19
19
|
|
|
20
|
+
export type SandboxWorkspaceReference = SandboxWorkspaceIdentity | SandboxWorkspaceKey;
|
|
21
|
+
|
|
20
22
|
export type SandboxCleanupTarget = Readonly<{
|
|
21
23
|
requestedRef: string;
|
|
22
24
|
branch: string;
|
|
@@ -35,6 +37,11 @@ export type SandboxTarget = Readonly<{
|
|
|
35
37
|
workspace: SandboxWorkspaceIdentity;
|
|
36
38
|
}>;
|
|
37
39
|
|
|
40
|
+
export type SandboxReentryContext = Readonly<{
|
|
41
|
+
workspace: SandboxWorkspaceReference;
|
|
42
|
+
reentry: 'standard' | 'completed';
|
|
43
|
+
}>;
|
|
44
|
+
|
|
38
45
|
function stripQuotes(value: string): string {
|
|
39
46
|
return value.replace(/^(?:"([^"]*)"|'([^']*)')$/, '$1$2');
|
|
40
47
|
}
|
|
@@ -116,6 +123,27 @@ export function resolveSandboxTarget(requestedRef: string, repoRoot: string): Sa
|
|
|
116
123
|
return { requestedRef, branch: requestedRef, workspace: { mode: 'branch-only' } };
|
|
117
124
|
}
|
|
118
125
|
|
|
126
|
+
export function resolveSandboxReentryContext(params: Readonly<{
|
|
127
|
+
target: SandboxTarget;
|
|
128
|
+
containerWorkspace: SandboxContainerWorkspaceIdentity;
|
|
129
|
+
repoRoot: string;
|
|
130
|
+
}>): SandboxReentryContext {
|
|
131
|
+
if (params.target.workspace.mode !== 'branch-only'
|
|
132
|
+
|| params.containerWorkspace.mode !== 'task-bound') {
|
|
133
|
+
return { workspace: params.target.workspace, reentry: 'standard' };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const task = resolveTaskWorkspace(params.containerWorkspace.taskId, params.repoRoot);
|
|
137
|
+
if (task.state !== 'completed' || task.branch !== params.target.branch) {
|
|
138
|
+
return { workspace: params.target.workspace, reentry: 'standard' };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
workspace: { mode: 'task-bound', taskId: task.taskId },
|
|
143
|
+
reentry: 'completed'
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
119
147
|
export function resolveSandboxCleanupTarget(
|
|
120
148
|
requestedRef: string,
|
|
121
149
|
repoRoot: string,
|
|
@@ -52,10 +52,15 @@ export type SandboxControlSetup = Readonly<{
|
|
|
52
52
|
statusDir: string;
|
|
53
53
|
runtimeDir: string;
|
|
54
54
|
manifestPath: string;
|
|
55
|
+
manifestDraft: SandboxControlManifestDraft;
|
|
55
56
|
token: string;
|
|
56
57
|
generation: string;
|
|
57
58
|
}>;
|
|
58
59
|
|
|
60
|
+
export type SandboxControlManifestDraft = Readonly<Omit<SandboxControlManifest, 'containerIdentity' | 'engine'> & {
|
|
61
|
+
engine: string;
|
|
62
|
+
}>;
|
|
63
|
+
|
|
59
64
|
export function sandboxControlPaths(params: Readonly<{
|
|
60
65
|
base: string;
|
|
61
66
|
project: string;
|
|
@@ -230,14 +235,12 @@ export function materializeSandboxControl(params: Readonly<{
|
|
|
230
235
|
const token = randomBytes(32).toString('hex');
|
|
231
236
|
const generation = randomBytes(16).toString('hex');
|
|
232
237
|
const repoRoot = fs.realpathSync.native(params.repoRoot);
|
|
233
|
-
const
|
|
234
|
-
version: 5,
|
|
238
|
+
const manifestDraft: SandboxControlManifestDraft = {
|
|
235
239
|
engine: params.engine ?? 'docker',
|
|
236
240
|
repoRoot,
|
|
237
241
|
worktreeRoot: fs.realpathSync.native(params.worktreeRoot),
|
|
238
242
|
project: params.project,
|
|
239
243
|
container: params.container,
|
|
240
|
-
containerIdentity: { id: '', labels: {} },
|
|
241
244
|
branch: params.branch,
|
|
242
245
|
mode: params.identity.mode,
|
|
243
246
|
taskId: params.identity.mode === 'task-bound' ? params.identity.taskId : null,
|
|
@@ -248,19 +251,19 @@ export function materializeSandboxControl(params: Readonly<{
|
|
|
248
251
|
processingDir,
|
|
249
252
|
runtimeDir
|
|
250
253
|
};
|
|
251
|
-
|
|
252
|
-
return { root, channelDir, statusDir, runtimeDir, manifestPath, token, generation };
|
|
254
|
+
return { root, channelDir, statusDir, runtimeDir, manifestPath, manifestDraft, token, generation };
|
|
253
255
|
}
|
|
254
256
|
|
|
255
257
|
export function finalizeSandboxControlManifest(
|
|
256
258
|
setup: SandboxControlSetup,
|
|
257
259
|
identity: Readonly<{ engine: string; id: string; labels: Readonly<Record<string, string>> }>
|
|
258
|
-
):
|
|
260
|
+
): SandboxControlManifest {
|
|
259
261
|
if (!identity.engine || !identity.id) throw new Error('SANDBOX_CONTROL_CONTAINER_ID_INVALID');
|
|
260
|
-
const manifest =
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
const manifest: SandboxControlManifest = {
|
|
263
|
+
...setup.manifestDraft,
|
|
264
|
+
engine: identity.engine,
|
|
265
|
+
containerIdentity: { id: identity.id, labels: { ...identity.labels } }
|
|
266
|
+
};
|
|
264
267
|
const temporary = `${setup.manifestPath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
265
268
|
try {
|
|
266
269
|
fs.writeFileSync(temporary, `${JSON.stringify(manifest)}\n`, { mode: 0o600, flag: 'wx' });
|
|
@@ -268,4 +271,5 @@ export function finalizeSandboxControlManifest(
|
|
|
268
271
|
} finally {
|
|
269
272
|
fs.rmSync(temporary, { force: true });
|
|
270
273
|
}
|
|
274
|
+
return manifest;
|
|
271
275
|
}
|