@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,10 +1,10 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
2
|
import pc from 'picocolors';
|
|
3
3
|
import { loadConfig } from '../config.js';
|
|
4
|
-
import { sandboxBranchLabel, sandboxLabel } from '../constants.js';
|
|
4
|
+
import { sandboxBranchLabel, sandboxLabel, sandboxTaskIdLabel, sandboxWorkspaceModeLabel } from '../constants.js';
|
|
5
5
|
import { detectEngine } from '../engine.js';
|
|
6
6
|
import { formatTable } from '../../table.js';
|
|
7
|
-
import {
|
|
7
|
+
import { loadShortIdByTaskId } from '../../task/short-id.js';
|
|
8
8
|
import { fetchSandboxRows } from './list-running.js';
|
|
9
9
|
export { containerListFormat, parseLabels } from './list-running.js';
|
|
10
10
|
const USAGE = `Usage: ai sandbox ls
|
|
@@ -19,9 +19,9 @@ to remove with "ai sandbox rm <branch>".
|
|
|
19
19
|
|
|
20
20
|
Use "ai sandbox show <ref>" for a single sandbox's worktree and per-tool
|
|
21
21
|
state paths.`;
|
|
22
|
-
const CONTAINER_TABLE_HEADERS = ['#', 'SHORT', 'NAMES', 'STATUS', 'BRANCH'];
|
|
22
|
+
const CONTAINER_TABLE_HEADERS = ['#', 'SHORT', 'NAMES', 'STATUS', 'WORKSPACE', 'TASK', 'BRANCH'];
|
|
23
23
|
export function formatContainerTable(rows, zebra = false) {
|
|
24
|
-
return formatTable(CONTAINER_TABLE_HEADERS, rows.map((r) => [r.row, r.shortId, r.name, r.status, r.branch]), { zebra });
|
|
24
|
+
return formatTable(CONTAINER_TABLE_HEADERS, rows.map((r) => [r.row, r.shortId, r.name, r.status, r.workspace, r.taskId, r.branch]), { zebra });
|
|
25
25
|
}
|
|
26
26
|
export function ls(args = []) {
|
|
27
27
|
if (args.length > 0 && (args[0] === '--help' || args[0] === '-h')) {
|
|
@@ -31,7 +31,7 @@ export function ls(args = []) {
|
|
|
31
31
|
const config = loadConfig();
|
|
32
32
|
const engine = detectEngine(config);
|
|
33
33
|
const label = sandboxLabel(config);
|
|
34
|
-
const { running, nonRunning } = fetchSandboxRows(engine, label, sandboxBranchLabel(config));
|
|
34
|
+
const { running, nonRunning } = fetchSandboxRows(engine, label, sandboxBranchLabel(config), { mode: sandboxWorkspaceModeLabel(config), taskId: sandboxTaskIdLabel(config) });
|
|
35
35
|
p.intro(pc.cyan(`Sandbox status for ${config.project}`));
|
|
36
36
|
p.log.step('Containers');
|
|
37
37
|
const ordered = [...running, ...nonRunning];
|
|
@@ -40,12 +40,16 @@ export function ls(args = []) {
|
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
42
|
const tableRows = ordered.map((container, i) => {
|
|
43
|
-
const shortId = container.
|
|
43
|
+
const shortId = container.taskId
|
|
44
|
+
? loadShortIdByTaskId(config.repoRoot).get(container.taskId) ?? null
|
|
45
|
+
: null;
|
|
44
46
|
return {
|
|
45
47
|
row: String(i + 1),
|
|
46
48
|
shortId: shortId ?? '-',
|
|
47
49
|
name: container.name,
|
|
48
50
|
status: container.status,
|
|
51
|
+
workspace: container.workspaceMode ?? 'legacy-invalid',
|
|
52
|
+
taskId: container.taskId ?? '-',
|
|
49
53
|
branch: container.branch
|
|
50
54
|
};
|
|
51
55
|
});
|
|
@@ -7,7 +7,7 @@ import { sandboxImageRefreshLabel } from '../constants.js';
|
|
|
7
7
|
import { detectEngine, ensureDocker } from '../engine.js';
|
|
8
8
|
import { runEngine, runOkEngine, runSafeEngine, runVerboseEngine } from '../shell.js';
|
|
9
9
|
import { pruneSandboxDanglingImages } from '../image-prune.js';
|
|
10
|
-
import {
|
|
10
|
+
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.js';
|
|
11
11
|
import { buildImageSignature, buildSandboxImageArgs, parseImageLabels, parseRefreshTimestamp } from '../image-build.js';
|
|
12
12
|
import { assertBuildProxyCompatibility, buildProxyFailureHint, prepareBuildProxy, redactBuildProxyValues } from '../build-proxy.js';
|
|
13
13
|
const USAGE = `Usage: ai sandbox rebuild [--quiet] [--refresh] [--inherit-build-proxy|-B]`;
|
|
@@ -52,8 +52,9 @@ export async function rebuild(args) {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
const config = loadConfig();
|
|
55
|
-
const
|
|
56
|
-
const
|
|
55
|
+
const capabilityPlan = createSandboxCapabilityPlan(config);
|
|
56
|
+
const tools = [...capabilityPlan.tools];
|
|
57
|
+
const preparedDockerfile = prepareDockerfile(config, capabilityPlan.image);
|
|
57
58
|
const imageSignature = buildImageSignature(preparedDockerfile, tools);
|
|
58
59
|
const quiet = values.quiet ?? false;
|
|
59
60
|
const refresh = values.refresh ?? false;
|
|
@@ -1,85 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const USAGE = 'Usage: ai sandbox refresh';
|
|
6
|
-
export function probeClaudeStatus(spawnFn = runProbe) {
|
|
7
|
-
const result = spawnFn('claude', ['/status'], {
|
|
8
|
-
encoding: 'utf8',
|
|
9
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
10
|
-
timeout: 30_000
|
|
11
|
-
});
|
|
12
|
-
return {
|
|
13
|
-
ok: result.status === 0,
|
|
14
|
-
stderr: result.stderr?.toString() ?? '',
|
|
15
|
-
error: result.error?.message ?? null
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export async function refresh(args, deps = {}) {
|
|
19
|
-
const { spawnFn = runProbe, execFn, readFn, existsFn, writeFn, writeHostFn, discoverFn = discoverProjects, writeStdout = (chunk) => process.stdout.write(chunk), writeStderr = (chunk) => process.stderr.write(chunk) } = deps;
|
|
20
|
-
if (args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
21
|
-
writeStdout(`${USAGE}\n`);
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
const { positionals } = parseArgs({ args, allowPositionals: true, strict: true });
|
|
25
|
-
if (positionals.length > 0) {
|
|
26
|
-
throw new Error(USAGE);
|
|
27
|
-
}
|
|
28
|
-
validateClaudeCredentialsEnvOverride();
|
|
29
|
-
const home = homedir();
|
|
30
|
-
if (!home) {
|
|
31
|
-
throw new Error('sandbox: home directory is required');
|
|
32
|
-
}
|
|
33
|
-
const projects = discoverFn(home);
|
|
34
|
-
if (projects.length === 0) {
|
|
35
|
-
writeStdout('No project credentials to refresh.\n');
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
const reconcileOptions = { execFn, readFn, existsFn, writeFn, writeHostFn, projects };
|
|
39
|
-
let result = reconcileClaudeCredentials(home, reconcileOptions);
|
|
40
|
-
if (result.status === 'STALE_ACCESS' && result.authoritative === null) {
|
|
41
|
-
writeStdout('Host credentials appear stale; probing claude /status to trigger refresh...\n');
|
|
42
|
-
const probe = probeClaudeStatus(spawnFn);
|
|
43
|
-
if (!probe.ok) {
|
|
44
|
-
writeStderr(`Probe failed: ${redactCommandError(probe.stderr || probe.error || 'unknown error')}\n`);
|
|
45
|
-
writeStderr('Run "claude /login" on the host to renew credentials.\n');
|
|
46
|
-
return 1;
|
|
47
|
-
}
|
|
48
|
-
writeStdout('Probe succeeded; re-inspecting host credentials.\n');
|
|
49
|
-
result = reconcileClaudeCredentials(home, reconcileOptions);
|
|
50
|
-
}
|
|
51
|
-
if (result.status === 'MISSING') {
|
|
52
|
-
writeStderr('No Claude Code credentials found on host.\n');
|
|
53
|
-
writeStderr('Run "claude /login" on the host to authenticate.\n');
|
|
54
|
-
return 1;
|
|
55
|
-
}
|
|
56
|
-
if (result.status === 'KEYCHAIN_LOCKED') {
|
|
57
|
-
writeStderr(`${buildLockedGuidance()}\n`);
|
|
58
|
-
return 1;
|
|
59
|
-
}
|
|
60
|
-
if (result.status === 'KEYCHAIN_ERROR') {
|
|
61
|
-
writeStderr(`Host keychain error: ${redactCommandError(result.detail || 'unknown error')}\n`);
|
|
62
|
-
writeStderr(`${buildLockedGuidance()}\n`);
|
|
63
|
-
return 1;
|
|
64
|
-
}
|
|
65
|
-
if (result.status === 'KEYCHAIN_WRITE_FAILED') {
|
|
66
|
-
writeStderr(`[host] keychain write failed: ${formatCredentialWarnings(result.warnings) || 'unknown error'}\n`);
|
|
67
|
-
return 1;
|
|
68
|
-
}
|
|
69
|
-
if (result.status !== 'OK') {
|
|
70
|
-
writeStderr('Host credentials still invalid after probe; run "claude /login".\n');
|
|
71
|
-
return 1;
|
|
72
|
-
}
|
|
73
|
-
if (result.authoritative && result.authoritative !== 'host' && result.hostWritten) {
|
|
74
|
-
writeStdout(`[host] reconciled from ${result.authoritative}\n`);
|
|
75
|
-
}
|
|
76
|
-
for (const project of projects) {
|
|
77
|
-
const action = result.filesWritten.includes(project) ? 'updated' : 'unchanged';
|
|
78
|
-
writeStdout(`[${project}] ${action}; expires in ${formatRemaining(result.expiresAt)}\n`);
|
|
79
|
-
}
|
|
80
|
-
for (const failure of result.fileErrors) {
|
|
81
|
-
writeStderr(`[${failure.project}] sync failed: ${failure.error}\n`);
|
|
82
|
-
}
|
|
83
|
-
return result.fileErrors.length > 0 ? 1 : 0;
|
|
84
|
-
}
|
|
1
|
+
import { runClaudeCodeRefresh } from '../../agent-clients/adapters/claude-code-refresh.js';
|
|
2
|
+
const refresh = runClaudeCodeRefresh;
|
|
3
|
+
export { probeClaudeStatus, runClaudeCodeRefresh } from '../../agent-clients/adapters/claude-code-refresh.js';
|
|
4
|
+
export { refresh };
|
|
85
5
|
//# sourceMappingURL=refresh.js.map
|
|
@@ -9,7 +9,7 @@ import { ENGINES, detectEngine, engineDisplayName, isManagedEngine, stopManagedV
|
|
|
9
9
|
import { pruneSandboxDanglingImages } from '../image-prune.js';
|
|
10
10
|
import { removeManagedDir, removeWorktreeDir } from '../managed-fs.js';
|
|
11
11
|
import { runOk, runSafe, runSafeEngine } from '../shell.js';
|
|
12
|
-
import {
|
|
12
|
+
import { resolveSandboxTarget } from '../workspace-identity.js';
|
|
13
13
|
import { toolConfigDirCandidates, toolProjectDirCandidates } from '../tools.js';
|
|
14
14
|
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.js';
|
|
15
15
|
import { fetchSandboxRows } from './list-running.js';
|
|
@@ -57,6 +57,17 @@ async function rmOne(config, tools, branch, options = {}) {
|
|
|
57
57
|
for (const name of matchedContainers) {
|
|
58
58
|
runSafeEngine(engine, 'docker', ['stop', name]);
|
|
59
59
|
runSafeEngine(engine, 'docker', ['rm', name]);
|
|
60
|
+
for (const [base, label] of [
|
|
61
|
+
[path.join(config.workspaceViewBase, config.project), 'Workspace view'],
|
|
62
|
+
[path.join(config.controlBase, config.project), 'Control channel']
|
|
63
|
+
]) {
|
|
64
|
+
const directory = path.join(base, name);
|
|
65
|
+
if (fs.existsSync(directory)) {
|
|
66
|
+
removeManagedDir(base, directory);
|
|
67
|
+
if (!options.quiet)
|
|
68
|
+
p.log.success(`${label} removed: ${directory}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
60
71
|
}
|
|
61
72
|
spinner.stop(pc.green(`Removed container(s): ${matchedContainers.join(', ')}`));
|
|
62
73
|
}
|
|
@@ -184,6 +195,16 @@ async function rmPurge(config, tools) {
|
|
|
184
195
|
p.log.success(`Project share dirs removed: ${config.shareBase}`);
|
|
185
196
|
}
|
|
186
197
|
}
|
|
198
|
+
for (const [base, label] of [
|
|
199
|
+
[config.workspaceViewBase, 'workspace views'],
|
|
200
|
+
[config.controlBase, 'control channels']
|
|
201
|
+
]) {
|
|
202
|
+
const projectDir = path.join(base, config.project);
|
|
203
|
+
if (fs.existsSync(projectDir)) {
|
|
204
|
+
removeManagedDir(base, projectDir);
|
|
205
|
+
p.log.success(`Removed project ${label}: ${projectDir}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
187
208
|
const shouldRemoveImage = await p.confirm({
|
|
188
209
|
message: `Remove image ${config.imageName}?`,
|
|
189
210
|
initialValue: false
|
|
@@ -297,7 +318,7 @@ export async function rm(args) {
|
|
|
297
318
|
});
|
|
298
319
|
return;
|
|
299
320
|
}
|
|
300
|
-
const
|
|
301
|
-
await rmOne(config, tools, branch);
|
|
321
|
+
const target = resolveSandboxTarget(positionals[0] ?? '', config.repoRoot);
|
|
322
|
+
await rmOne(config, tools, target.branch);
|
|
302
323
|
}
|
|
303
324
|
//# sourceMappingURL=rm.js.map
|
|
@@ -2,13 +2,15 @@ import fs from 'node:fs';
|
|
|
2
2
|
import * as p from '@clack/prompts';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import { loadConfig } from '../config.js';
|
|
5
|
-
import { assertValidBranchName, worktreeDirCandidates } from '../constants.js';
|
|
6
|
-
import {
|
|
5
|
+
import { assertValidBranchName, containerNameCandidates, sandboxBranchLabel, sandboxLabel, sandboxTaskIdLabel, sandboxWorkspaceModeLabel, worktreeDirCandidates } from '../constants.js';
|
|
6
|
+
import { fetchSandboxRows, selectSandboxContainer } from './list-running.js';
|
|
7
7
|
import { resolveTools, toolConfigDirCandidates } from '../tools.js';
|
|
8
|
+
import { detectEngine } from '../engine.js';
|
|
9
|
+
import { resolveSandboxTarget } from '../workspace-identity.js';
|
|
8
10
|
const USAGE = `Usage: ai sandbox show <branch | TASK-id | N>
|
|
9
11
|
|
|
10
12
|
Shows one sandbox's worktree path and per-tool state paths (Claude Code,
|
|
11
|
-
Codex,
|
|
13
|
+
Codex, Antigravity CLI, OpenCode). The argument follows the same contract as
|
|
12
14
|
'ai sandbox exec' and 'ai sandbox start': N (bare) is the recommended form
|
|
13
15
|
for task short ids (e.g. 'ai sandbox show 11'); a TASK-id or a plain
|
|
14
16
|
branch name are also accepted. Use 'ai sandbox ls' for the container list.`;
|
|
@@ -40,9 +42,13 @@ export function show(args = []) {
|
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
44
|
const config = loadConfig();
|
|
43
|
-
const
|
|
45
|
+
const target = resolveSandboxTarget(args[0], config.repoRoot);
|
|
46
|
+
const branch = target.branch;
|
|
44
47
|
assertValidBranchName(branch);
|
|
45
48
|
const detail = collectSandboxDetail(config, branch);
|
|
49
|
+
const engine = detectEngine(config);
|
|
50
|
+
const rows = fetchSandboxRows(engine, sandboxLabel(config), sandboxBranchLabel(config), { mode: sandboxWorkspaceModeLabel(config), taskId: sandboxTaskIdLabel(config) });
|
|
51
|
+
const container = selectSandboxContainer([...rows.running, ...rows.nonRunning], containerNameCandidates(config, branch));
|
|
46
52
|
p.intro(pc.cyan(`Sandbox detail for ${config.project} · ${branch}`));
|
|
47
53
|
p.log.step('Worktree');
|
|
48
54
|
if (detail.worktrees.length === 0) {
|
|
@@ -53,6 +59,9 @@ export function show(args = []) {
|
|
|
53
59
|
process.stdout.write(` ${worktree}\n`);
|
|
54
60
|
}
|
|
55
61
|
}
|
|
62
|
+
p.log.step('Workspace identity');
|
|
63
|
+
process.stdout.write(` Mode: ${container?.workspaceMode ?? 'legacy-invalid'}\n`);
|
|
64
|
+
process.stdout.write(` Task: ${container?.taskId ?? '-'}\n`);
|
|
56
65
|
for (const tool of detail.toolStates) {
|
|
57
66
|
p.log.step(`${tool.name} state`);
|
|
58
67
|
if (tool.entries.length === 0) {
|
|
@@ -2,7 +2,8 @@ import { loadConfig } from '../config.js';
|
|
|
2
2
|
import { assertValidBranchName, containerNameCandidates, sandboxBranchLabel, sandboxLabel } from '../constants.js';
|
|
3
3
|
import { detectEngine } from '../engine.js';
|
|
4
4
|
import { ensureSandboxReady } from '../recovery.js';
|
|
5
|
-
import { fetchSandboxRows,
|
|
5
|
+
import { fetchSandboxRows, selectSandboxContainer, } from './list-running.js';
|
|
6
|
+
import { resolveSandboxTarget } from '../workspace-identity.js';
|
|
6
7
|
const USAGE = `Usage: ai sandbox start [--recreate] <branch | TASK-id | N>
|
|
7
8
|
|
|
8
9
|
Start an existing sandbox container that has stopped (for example after the
|
|
@@ -46,7 +47,8 @@ export async function start(args) {
|
|
|
46
47
|
}
|
|
47
48
|
const config = loadConfig();
|
|
48
49
|
const engine = detectEngine(config);
|
|
49
|
-
const
|
|
50
|
+
const target = resolveSandboxTarget(parsed.target, config.repoRoot);
|
|
51
|
+
const branch = target.branch;
|
|
50
52
|
assertValidBranchName(branch);
|
|
51
53
|
const { running, nonRunning } = fetchSandboxRows(engine, sandboxLabel(config), sandboxBranchLabel(config));
|
|
52
54
|
const found = selectSandboxContainer([...running, ...nonRunning], containerNameCandidates(config, branch));
|
|
@@ -57,11 +59,12 @@ export async function start(args) {
|
|
|
57
59
|
config,
|
|
58
60
|
engine,
|
|
59
61
|
branch,
|
|
62
|
+
workspace: target.workspace,
|
|
60
63
|
row: found,
|
|
61
64
|
allowRecreate: parsed.recreate,
|
|
62
|
-
recreate: async (
|
|
65
|
+
recreate: async () => {
|
|
63
66
|
const { create } = await import('./create.js');
|
|
64
|
-
await create([
|
|
67
|
+
await create([target.requestedRef, '--no-refresh']);
|
|
65
68
|
}
|
|
66
69
|
});
|
|
67
70
|
const message = ready.path === 'healthy'
|
|
@@ -111,6 +111,8 @@ export function loadConfig({ platformFn = platform, writeStderr = (chunk) => pro
|
|
|
111
111
|
worktreeBase: hostJoin(home, '.agent-infra', 'worktrees', project),
|
|
112
112
|
shareBase: hostJoin(home, '.agent-infra', 'share', project),
|
|
113
113
|
shellConfigBase: hostJoin(home, '.agent-infra', 'config', project),
|
|
114
|
+
workspaceViewBase: hostJoin(home, '.agent-infra', 'workspace-views'),
|
|
115
|
+
controlBase: hostJoin(home, '.agent-infra', 'sandbox-control'),
|
|
114
116
|
dotfilesDir: hostJoin(home, '.agent-infra', 'dotfiles'),
|
|
115
117
|
engine,
|
|
116
118
|
runtimes,
|
|
@@ -69,6 +69,12 @@ export function sandboxLabel(config) {
|
|
|
69
69
|
export function sandboxBranchLabel(config) {
|
|
70
70
|
return `${sandboxLabel(config)}.branch`;
|
|
71
71
|
}
|
|
72
|
+
export function sandboxWorkspaceModeLabel(config) {
|
|
73
|
+
return `${sandboxLabel(config)}.workspace-mode`;
|
|
74
|
+
}
|
|
75
|
+
export function sandboxTaskIdLabel(config) {
|
|
76
|
+
return `${sandboxLabel(config)}.task-id`;
|
|
77
|
+
}
|
|
72
78
|
export function sandboxImageConfigLabel(config) {
|
|
73
79
|
return `${sandboxLabel(config)}.image-config`;
|
|
74
80
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { SANDBOX_CONTROL_MAX_BYTES, isSandboxControlFamily } from './protocol.js';
|
|
5
|
+
function sleep(milliseconds) {
|
|
6
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
7
|
+
}
|
|
8
|
+
export function requestSandboxControl(params) {
|
|
9
|
+
if (!isSandboxControlFamily(params.family)) {
|
|
10
|
+
throw new Error(`SANDBOX_CONTROL_COMMAND_DENIED: '${params.family}' is not allowed`);
|
|
11
|
+
}
|
|
12
|
+
const channelDir = params.channelDir ?? process.env.AGENT_INFRA_CONTROL_DIR ?? '/run/agent-infra/control';
|
|
13
|
+
const token = params.token ?? process.env.AGENT_INFRA_CONTROL_TOKEN;
|
|
14
|
+
if (!token)
|
|
15
|
+
throw new Error('SANDBOX_CONTROL_UNAVAILABLE: control token is missing');
|
|
16
|
+
const requestsDir = path.join(channelDir, 'requests');
|
|
17
|
+
const responsesDir = path.join(channelDir, 'responses');
|
|
18
|
+
const id = randomUUID();
|
|
19
|
+
const request = { version: 1, id, token, family: params.family, args: params.args };
|
|
20
|
+
const encoded = `${JSON.stringify(request)}\n`;
|
|
21
|
+
if (Buffer.byteLength(encoded, 'utf8') > SANDBOX_CONTROL_MAX_BYTES) {
|
|
22
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_TOO_LARGE: request exceeds the control limit');
|
|
23
|
+
}
|
|
24
|
+
const temporary = path.join(requestsDir, `.${id}.tmp`);
|
|
25
|
+
const requestPath = path.join(requestsDir, `${id}.json`);
|
|
26
|
+
const responsePath = path.join(responsesDir, `${id}.json`);
|
|
27
|
+
fs.writeFileSync(temporary, encoded, { mode: 0o600, flag: 'wx' });
|
|
28
|
+
fs.renameSync(temporary, requestPath);
|
|
29
|
+
const deadline = Date.now() + (params.timeoutMs ?? 30_000);
|
|
30
|
+
while (Date.now() < deadline) {
|
|
31
|
+
if (fs.existsSync(responsePath)) {
|
|
32
|
+
const raw = fs.readFileSync(responsePath, 'utf8');
|
|
33
|
+
fs.unlinkSync(responsePath);
|
|
34
|
+
const response = JSON.parse(raw);
|
|
35
|
+
if (response.version !== 1 || response.id !== id || !Number.isInteger(response.exitCode)) {
|
|
36
|
+
throw new Error('SANDBOX_CONTROL_RESPONSE_INVALID: broker response is invalid');
|
|
37
|
+
}
|
|
38
|
+
return response;
|
|
39
|
+
}
|
|
40
|
+
sleep(25);
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`SANDBOX_CONTROL_TIMEOUT: broker did not respond within ${params.timeoutMs ?? 30_000}ms`);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const SANDBOX_CONTROL_MAX_BYTES = 64 * 1024;
|
|
2
|
+
export const SANDBOX_CONTROL_FAMILIES = ['task-lifecycle', 'task-orchestration'];
|
|
3
|
+
export function isSandboxControlFamily(value) {
|
|
4
|
+
return SANDBOX_CONTROL_FAMILIES.includes(value);
|
|
5
|
+
}
|
|
6
|
+
export function validateSandboxControlRequest(value, manifest) {
|
|
7
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
8
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_INVALID: request must be an object');
|
|
9
|
+
}
|
|
10
|
+
const request = value;
|
|
11
|
+
if (request.version !== 1
|
|
12
|
+
|| typeof request.id !== 'string'
|
|
13
|
+
|| !/^[a-f0-9-]{16,64}$/.test(request.id)
|
|
14
|
+
|| request.token !== manifest.token
|
|
15
|
+
|| typeof request.family !== 'string'
|
|
16
|
+
|| !isSandboxControlFamily(request.family)
|
|
17
|
+
|| !Array.isArray(request.args)
|
|
18
|
+
|| !request.args.every((arg) => typeof arg === 'string')) {
|
|
19
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_INVALID: request schema or authorization is invalid');
|
|
20
|
+
}
|
|
21
|
+
if (manifest.mode !== 'task-bound' || !manifest.taskId) {
|
|
22
|
+
throw new Error('SANDBOX_CONTROL_BRANCH_ONLY: branch-only sandboxes cannot coordinate tasks');
|
|
23
|
+
}
|
|
24
|
+
if (Buffer.byteLength(JSON.stringify(request), 'utf8') > SANDBOX_CONTROL_MAX_BYTES) {
|
|
25
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_TOO_LARGE: request exceeds the control limit');
|
|
26
|
+
}
|
|
27
|
+
return request;
|
|
28
|
+
}
|
|
29
|
+
export function bindSandboxControlTask(request, taskId) {
|
|
30
|
+
if (request.args.length === 0) {
|
|
31
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_INVALID: command arguments are required');
|
|
32
|
+
}
|
|
33
|
+
return [taskId, ...request.args.slice(1)];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { getProcessStartTime } from '../../server/process-state.js';
|
|
5
|
+
import { bindSandboxControlTask, validateSandboxControlRequest } from './protocol.js';
|
|
6
|
+
function readManifest(manifestPath) {
|
|
7
|
+
const stat = fs.lstatSync(manifestPath);
|
|
8
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
9
|
+
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
10
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
11
|
+
if (manifest.version !== 1
|
|
12
|
+
|| typeof manifest.repoRoot !== 'string'
|
|
13
|
+
|| typeof manifest.channelDir !== 'string'
|
|
14
|
+
|| typeof manifest.token !== 'string')
|
|
15
|
+
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
16
|
+
if (path.resolve(manifest.channelDir) !== path.join(path.dirname(path.resolve(manifestPath)), 'channel')) {
|
|
17
|
+
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
18
|
+
}
|
|
19
|
+
return manifest;
|
|
20
|
+
}
|
|
21
|
+
function assertRealDirectory(directory, parent) {
|
|
22
|
+
const stat = fs.lstatSync(directory);
|
|
23
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
24
|
+
throw new Error('SANDBOX_CONTROL_CHANNEL_INVALID');
|
|
25
|
+
if (parent && path.dirname(fs.realpathSync.native(directory)) !== fs.realpathSync.native(parent)) {
|
|
26
|
+
throw new Error('SANDBOX_CONTROL_CHANNEL_INVALID');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function writeResponse(directory, response) {
|
|
30
|
+
const temporary = path.join(directory, `.${response.id}.tmp`);
|
|
31
|
+
fs.writeFileSync(temporary, `${JSON.stringify(response)}\n`, { mode: 0o600, flag: 'wx' });
|
|
32
|
+
fs.renameSync(temporary, path.join(directory, `${response.id}.json`));
|
|
33
|
+
}
|
|
34
|
+
export function serveSandboxControl(manifestPath, signal = new AbortController().signal) {
|
|
35
|
+
const manifest = readManifest(manifestPath);
|
|
36
|
+
const brokerPath = path.join(path.dirname(manifestPath), 'broker.json');
|
|
37
|
+
const startTime = getProcessStartTime(process.pid);
|
|
38
|
+
if (!startTime)
|
|
39
|
+
throw new Error('SANDBOX_CONTROL_BROKER_IDENTITY_UNAVAILABLE');
|
|
40
|
+
fs.writeFileSync(brokerPath, `${JSON.stringify({
|
|
41
|
+
version: 1,
|
|
42
|
+
pid: process.pid,
|
|
43
|
+
startTime,
|
|
44
|
+
token: manifest.token
|
|
45
|
+
})}\n`, { mode: 0o600, flag: 'wx' });
|
|
46
|
+
const requestsDir = path.join(manifest.channelDir, 'requests');
|
|
47
|
+
const responsesDir = path.join(manifest.channelDir, 'responses');
|
|
48
|
+
assertRealDirectory(manifest.channelDir);
|
|
49
|
+
fs.mkdirSync(requestsDir, { recursive: true, mode: 0o700 });
|
|
50
|
+
fs.mkdirSync(responsesDir, { recursive: true, mode: 0o700 });
|
|
51
|
+
assertRealDirectory(requestsDir, manifest.channelDir);
|
|
52
|
+
assertRealDirectory(responsesDir, manifest.channelDir);
|
|
53
|
+
const consumed = new Set();
|
|
54
|
+
while (!signal.aborted) {
|
|
55
|
+
const current = readManifest(manifestPath);
|
|
56
|
+
if (current.token !== manifest.token)
|
|
57
|
+
return;
|
|
58
|
+
assertRealDirectory(requestsDir, manifest.channelDir);
|
|
59
|
+
assertRealDirectory(responsesDir, manifest.channelDir);
|
|
60
|
+
for (const name of fs.readdirSync(requestsDir).sort()) {
|
|
61
|
+
if (!/^[a-f0-9-]{16,64}\.json$/.test(name))
|
|
62
|
+
continue;
|
|
63
|
+
const requestPath = path.join(requestsDir, name);
|
|
64
|
+
let id = name.slice(0, -5);
|
|
65
|
+
let response;
|
|
66
|
+
try {
|
|
67
|
+
const stat = fs.lstatSync(requestPath);
|
|
68
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
69
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_INVALID');
|
|
70
|
+
const request = validateSandboxControlRequest(JSON.parse(fs.readFileSync(requestPath, 'utf8')), manifest);
|
|
71
|
+
id = request.id;
|
|
72
|
+
if (consumed.has(id))
|
|
73
|
+
throw new Error('SANDBOX_CONTROL_REQUEST_REPLAYED');
|
|
74
|
+
consumed.add(id);
|
|
75
|
+
const result = spawnSync(process.execPath, ['--experimental-strip-types', '--no-warnings', process.argv[1], request.family, ...bindSandboxControlTask(request, manifest.taskId)], {
|
|
76
|
+
cwd: manifest.repoRoot,
|
|
77
|
+
encoding: 'utf8',
|
|
78
|
+
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith('AGENT_INFRA_CONTROL_')))
|
|
79
|
+
});
|
|
80
|
+
response = {
|
|
81
|
+
version: 1,
|
|
82
|
+
id,
|
|
83
|
+
exitCode: result.status ?? 1,
|
|
84
|
+
stdout: result.stdout ?? '',
|
|
85
|
+
stderr: result.stderr ?? ''
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
response = {
|
|
90
|
+
version: 1,
|
|
91
|
+
id,
|
|
92
|
+
exitCode: 1,
|
|
93
|
+
stdout: '',
|
|
94
|
+
stderr: `${error instanceof Error ? error.message : String(error)}\n`
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
fs.unlinkSync(requestPath);
|
|
99
|
+
writeResponse(responsesDir, response);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (error.code !== 'ENOENT')
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 25);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -5,6 +5,11 @@ import { createHash } from 'node:crypto';
|
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { removeDirRecursive } from '../remove-dir.js';
|
|
7
7
|
const RUNTIMES_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), 'runtimes');
|
|
8
|
+
const AGENT_CLIENT_RUNTIMES_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'agent-clients', 'adapters', 'runtimes');
|
|
9
|
+
const EMPTY_IMAGE_CONTRIBUTION = Object.freeze({
|
|
10
|
+
dockerfileFragments: Object.freeze([]),
|
|
11
|
+
dotfilesExclusions: Object.freeze([])
|
|
12
|
+
});
|
|
8
13
|
function listRuntimeFragments() {
|
|
9
14
|
return fs.readdirSync(RUNTIMES_DIR)
|
|
10
15
|
.filter((file) => file.endsWith('.dockerfile'))
|
|
@@ -15,7 +20,24 @@ export function availableRuntimes() {
|
|
|
15
20
|
.filter((name) => name !== 'base' && name !== 'ai-tools')
|
|
16
21
|
.sort();
|
|
17
22
|
}
|
|
18
|
-
function
|
|
23
|
+
function exclusionsFragment(exclusions) {
|
|
24
|
+
return [
|
|
25
|
+
"RUN mkdir -p /etc/agent-infra && cat > /etc/agent-infra/dotfiles-exclusions <<'EXCLUSIONS'",
|
|
26
|
+
...exclusions,
|
|
27
|
+
'EXCLUSIONS'
|
|
28
|
+
].join('\n');
|
|
29
|
+
}
|
|
30
|
+
function adapterFragmentPath(fragment) {
|
|
31
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(fragment)) {
|
|
32
|
+
throw new Error(`Invalid Agent Client Dockerfile fragment: ${fragment}`);
|
|
33
|
+
}
|
|
34
|
+
const fragmentPath = path.join(AGENT_CLIENT_RUNTIMES_DIR, `${fragment}.dockerfile`);
|
|
35
|
+
if (!fs.existsSync(fragmentPath)) {
|
|
36
|
+
throw new Error(`Unknown Agent Client Dockerfile fragment: ${fragment}`);
|
|
37
|
+
}
|
|
38
|
+
return fragmentPath;
|
|
39
|
+
}
|
|
40
|
+
function dockerfileContent(config, image = EMPTY_IMAGE_CONTRIBUTION) {
|
|
19
41
|
if (config.dockerfile) {
|
|
20
42
|
const customPath = path.resolve(config.repoRoot, config.dockerfile);
|
|
21
43
|
if (!fs.existsSync(customPath)) {
|
|
@@ -30,22 +52,23 @@ function dockerfileContent(config) {
|
|
|
30
52
|
}
|
|
31
53
|
}
|
|
32
54
|
const fragments = [
|
|
33
|
-
'base.dockerfile',
|
|
34
|
-
|
|
35
|
-
'
|
|
55
|
+
fs.readFileSync(path.join(RUNTIMES_DIR, 'base.dockerfile'), 'utf8').trimEnd(),
|
|
56
|
+
exclusionsFragment(image.dotfilesExclusions),
|
|
57
|
+
...image.dockerfileFragments.map((fragment) => fs.readFileSync(adapterFragmentPath(fragment), 'utf8').trimEnd()),
|
|
58
|
+
...config.runtimes.map((runtime) => fs.readFileSync(path.join(RUNTIMES_DIR, `${runtime}.dockerfile`), 'utf8').trimEnd()),
|
|
59
|
+
fs.readFileSync(path.join(RUNTIMES_DIR, 'ai-tools.dockerfile'), 'utf8').trimEnd()
|
|
36
60
|
];
|
|
37
61
|
const content = fragments
|
|
38
|
-
.map((fragment) => fs.readFileSync(path.join(RUNTIMES_DIR, fragment), 'utf8').trimEnd())
|
|
39
62
|
.join('\n\n');
|
|
40
63
|
return `${content}\n`;
|
|
41
64
|
}
|
|
42
|
-
export function dockerfileSignature(config) {
|
|
65
|
+
export function dockerfileSignature(config, image = EMPTY_IMAGE_CONTRIBUTION) {
|
|
43
66
|
return createHash('sha256')
|
|
44
|
-
.update(dockerfileContent(config))
|
|
67
|
+
.update(dockerfileContent(config, image))
|
|
45
68
|
.digest('hex')
|
|
46
69
|
.slice(0, 12);
|
|
47
70
|
}
|
|
48
|
-
export function prepareDockerfile(config) {
|
|
71
|
+
export function prepareDockerfile(config, image = EMPTY_IMAGE_CONTRIBUTION) {
|
|
49
72
|
if (config.dockerfile) {
|
|
50
73
|
const customPath = path.resolve(config.repoRoot, config.dockerfile);
|
|
51
74
|
if (!fs.existsSync(customPath)) {
|
|
@@ -53,23 +76,23 @@ export function prepareDockerfile(config) {
|
|
|
53
76
|
}
|
|
54
77
|
return {
|
|
55
78
|
path: customPath,
|
|
56
|
-
signature: dockerfileSignature(config),
|
|
79
|
+
signature: dockerfileSignature(config, image),
|
|
57
80
|
cleanup() { }
|
|
58
81
|
};
|
|
59
82
|
}
|
|
60
83
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), `${config.project}-sandbox-`));
|
|
61
84
|
const tempPath = path.join(tempDir, 'Dockerfile');
|
|
62
|
-
fs.writeFileSync(tempPath, dockerfileContent(config), 'utf8');
|
|
85
|
+
fs.writeFileSync(tempPath, dockerfileContent(config, image), 'utf8');
|
|
63
86
|
return {
|
|
64
87
|
path: tempPath,
|
|
65
|
-
signature: dockerfileSignature(config),
|
|
88
|
+
signature: dockerfileSignature(config, image),
|
|
66
89
|
cleanup() {
|
|
67
90
|
removeDirRecursive(tempDir);
|
|
68
91
|
}
|
|
69
92
|
};
|
|
70
93
|
}
|
|
71
|
-
export function composeDockerfile(config) {
|
|
72
|
-
const content = dockerfileContent(config);
|
|
94
|
+
export function composeDockerfile(config, image = EMPTY_IMAGE_CONTRIBUTION) {
|
|
95
|
+
const content = dockerfileContent(config, image);
|
|
73
96
|
const tempPath = path.join(os.tmpdir(), `${config.project}-sandbox.Dockerfile`);
|
|
74
97
|
fs.writeFileSync(tempPath, content, 'utf8');
|
|
75
98
|
return tempPath;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { shareBranchDir, shareCommonDir, shellConfigDirCandidates, worktreeDirCandidates } from './constants.js';
|
|
3
|
-
export function sandboxCoreBindMounts(config, branch, overrides
|
|
4
|
-
|
|
3
|
+
export function sandboxCoreBindMounts(config, branch, overrides) {
|
|
4
|
+
const mounts = [
|
|
5
5
|
{
|
|
6
6
|
hostPaths: overrides.worktree
|
|
7
7
|
? [overrides.worktree]
|
|
@@ -10,9 +10,9 @@ export function sandboxCoreBindMounts(config, branch, overrides = {}) {
|
|
|
10
10
|
readOnly: false
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
|
-
hostPaths: [
|
|
13
|
+
hostPaths: [overrides.workspaceViewRoot],
|
|
14
14
|
containerPath: '/workspace/.agents/workspace',
|
|
15
|
-
readOnly:
|
|
15
|
+
readOnly: true
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
hostPaths: [shareCommonDir(config)],
|
|
@@ -32,5 +32,18 @@ export function sandboxCoreBindMounts(config, branch, overrides = {}) {
|
|
|
32
32
|
readOnly: true
|
|
33
33
|
}
|
|
34
34
|
];
|
|
35
|
+
if (overrides.taskSource && overrides.taskId) {
|
|
36
|
+
mounts.splice(2, 0, {
|
|
37
|
+
hostPaths: [overrides.taskSource],
|
|
38
|
+
containerPath: path.posix.join('/workspace/.agents/workspace/active', overrides.taskId),
|
|
39
|
+
readOnly: false
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
mounts.push({
|
|
43
|
+
hostPaths: [overrides.controlDir],
|
|
44
|
+
containerPath: '/run/agent-infra/control',
|
|
45
|
+
readOnly: false
|
|
46
|
+
});
|
|
47
|
+
return mounts;
|
|
35
48
|
}
|
|
36
49
|
//# sourceMappingURL=mounts.js.map
|