@fitlab-ai/agent-infra 0.9.1 → 0.9.3
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 +24 -11
- package/README.zh-CN.md +24 -11
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +30 -0
- package/dist/lib/agent-client.js +163 -0
- package/dist/lib/agent-clients/adapter.js +337 -0
- package/dist/lib/agent-clients/adapters/antigravity-cli.js +64 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +71 -0
- package/dist/lib/agent-clients/adapters/codex-sandbox.js +210 -0
- package/dist/lib/agent-clients/adapters/codex.js +63 -0
- package/dist/lib/agent-clients/adapters/index.js +20 -0
- package/dist/lib/agent-clients/adapters/opencode.js +73 -0
- package/dist/lib/agent-clients/config.js +215 -0
- package/dist/lib/agent-clients/custom-tuis.js +99 -0
- package/dist/lib/agent-clients/invocation.js +9 -0
- package/dist/lib/agent-clients/next-steps.js +47 -0
- package/dist/lib/agent-clients/project-assets.js +45 -0
- package/dist/lib/agent-clients/reconcile.js +236 -0
- package/dist/lib/agent-clients/registry.js +78 -0
- package/dist/lib/agent-clients/schema.js +75 -0
- package/dist/lib/agent-clients/tokens.js +49 -0
- package/dist/lib/agent-clients/types.js +29 -0
- package/dist/lib/builtin-tuis.js +9 -14
- package/dist/lib/defaults.json +85 -73
- package/dist/lib/git/review-snapshot.js +25 -10
- package/dist/lib/git/reviewed-commit-equivalence.js +110 -0
- package/dist/lib/git/workflow.js +54 -1
- package/dist/lib/init.js +47 -91
- package/dist/lib/internal/agent-client.js +174 -0
- package/dist/lib/internal/git-workflow.js +7 -2
- 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 +82 -20
- package/dist/lib/internal/task-activity.js +73 -0
- package/dist/lib/internal/task-event.js +17 -1
- package/dist/lib/internal/task-lifecycle.js +7 -0
- package/dist/lib/internal/task-orchestration.js +196 -0
- package/dist/lib/internal/task-review.js +70 -0
- package/dist/lib/merge.js +2 -1
- package/dist/lib/platform/adapters.js +45 -1
- package/dist/lib/platform/change-request-git-evidence.js +113 -0
- package/dist/lib/platform/completion-backfill.js +122 -0
- package/dist/lib/platform/issue-comments.js +3 -2
- package/dist/lib/platform/merged-pr-equivalence.js +156 -16
- package/dist/lib/platform/pr-checks.js +101 -50
- package/dist/lib/platform/pr-review.js +166 -0
- package/dist/lib/platform/pull-requests.js +432 -7
- package/dist/lib/platform/release-notes.js +85 -3
- package/dist/lib/platform/releases.js +1 -1
- package/dist/lib/platform/verification-required.js +8 -10
- package/dist/lib/pr-review/evidence-grading.js +229 -0
- package/dist/lib/prompt.js +15 -3
- package/dist/lib/release/channels.js +4 -1
- package/dist/lib/release/workflow.js +4 -2
- package/dist/lib/remove-dir.js +25 -0
- package/dist/lib/run/tui.js +11 -7
- package/dist/lib/sandbox/agent-client-reconciler.js +234 -0
- package/dist/lib/sandbox/clipboard/linux.js +2 -1
- package/dist/lib/sandbox/commands/create.js +76 -200
- package/dist/lib/sandbox/commands/enter.js +17 -1
- package/dist/lib/sandbox/commands/prune.js +2 -2
- package/dist/lib/sandbox/commands/rm.js +3 -2
- package/dist/lib/sandbox/commands/show.js +1 -1
- package/dist/lib/sandbox/config.js +21 -4
- package/dist/lib/sandbox/constants.js +3 -0
- package/dist/lib/sandbox/dockerfile.js +2 -1
- package/dist/lib/sandbox/managed-fs.js +10 -5
- package/dist/lib/sandbox/recovery.js +52 -36
- package/dist/lib/sandbox/shell.js +1 -1
- package/dist/lib/sandbox/tool-types.js +8 -0
- package/dist/lib/sandbox/tools.js +2 -126
- package/dist/lib/task/activity-intent.js +101 -0
- package/dist/lib/task/artifact-lifecycle.js +3 -50
- package/dist/lib/task/commands/decisions.js +50 -20
- package/dist/lib/task/commands/log.js +15 -14
- package/dist/lib/task/delegation-receipts.js +128 -0
- package/dist/lib/task/events.js +146 -8
- package/dist/lib/task/finalization-artifacts.js +35 -0
- package/dist/lib/task/lifecycle-execution.js +46 -0
- package/dist/lib/task/orchestration.js +784 -0
- package/dist/lib/task/review-artifacts.js +143 -59
- package/dist/lib/task/review-finalization.js +186 -0
- package/dist/lib/task/review-fingerprint.js +4 -0
- package/dist/lib/task/task-execution-lock.js +231 -0
- package/dist/lib/task/verification-checks.js +2 -1
- package/dist/lib/task/verification-engine.js +372 -28
- package/dist/lib/task/verification-review.js +1 -1
- package/dist/lib/task/verification.js +5 -2
- package/dist/lib/task/workspace-snapshot.js +46 -0
- package/dist/lib/update.js +42 -161
- package/lib/agent-client.ts +214 -0
- package/lib/agent-clients/adapter.ts +534 -0
- package/lib/agent-clients/adapters/antigravity-cli.ts +65 -0
- package/lib/agent-clients/adapters/claude-code.ts +79 -0
- package/lib/agent-clients/adapters/codex-sandbox.ts +245 -0
- package/lib/agent-clients/adapters/codex.ts +67 -0
- package/lib/agent-clients/adapters/index.ts +27 -0
- package/lib/agent-clients/adapters/opencode.ts +75 -0
- package/lib/agent-clients/config.ts +323 -0
- package/lib/agent-clients/custom-tuis.ts +149 -0
- package/lib/agent-clients/invocation.ts +19 -0
- package/lib/agent-clients/next-steps.ts +85 -0
- package/lib/agent-clients/project-assets.ts +96 -0
- package/lib/agent-clients/reconcile.ts +325 -0
- package/lib/agent-clients/registry.ts +154 -0
- package/lib/agent-clients/schema.ts +80 -0
- package/lib/agent-clients/tokens.ts +53 -0
- package/lib/agent-clients/types.ts +92 -0
- package/lib/benchmark/schemas/v1.0.0/case-manifest.schema.json +120 -0
- package/lib/benchmark/schemas/v1.0.0/common.schema.json +109 -0
- package/lib/benchmark/schemas/v1.0.0/grader-result.schema.json +160 -0
- package/lib/benchmark/schemas/v1.0.0/run-manifest.schema.json +122 -0
- package/lib/benchmark/schemas/v1.0.0/subject.schema.json +227 -0
- package/lib/builtin-tuis.ts +16 -15
- package/lib/defaults.json +24 -12
- package/lib/git/review-snapshot.ts +39 -9
- package/lib/git/reviewed-commit-equivalence.ts +135 -0
- package/lib/git/workflow.ts +66 -2
- package/lib/init.ts +53 -121
- package/lib/internal/agent-client.ts +186 -0
- package/lib/internal/git-workflow.ts +6 -2
- 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 +79 -20
- package/lib/internal/task-activity.ts +55 -0
- package/lib/internal/task-event.ts +9 -1
- package/lib/internal/task-lifecycle.ts +4 -0
- package/lib/internal/task-orchestration.ts +171 -0
- package/lib/internal/task-review.ts +70 -0
- package/lib/merge.ts +2 -1
- package/lib/platform/adapters.ts +169 -3
- package/lib/platform/change-request-git-evidence.ts +159 -0
- package/lib/platform/completion-backfill.ts +134 -0
- package/lib/platform/issue-comments.ts +3 -2
- package/lib/platform/merged-pr-equivalence.ts +178 -19
- package/lib/platform/pr-checks.ts +121 -66
- package/lib/platform/pr-review.ts +201 -0
- package/lib/platform/pull-requests.ts +529 -27
- package/lib/platform/release-notes.ts +100 -4
- package/lib/platform/releases.ts +1 -1
- package/lib/platform/verification-required.ts +12 -10
- package/lib/pr-review/evidence-grading.ts +318 -0
- package/lib/prompt.ts +16 -3
- package/lib/release/channels.ts +4 -1
- package/lib/release/workflow.ts +4 -3
- package/lib/remove-dir.ts +28 -0
- package/lib/run/tui.ts +12 -5
- package/lib/sandbox/agent-client-reconciler.ts +378 -0
- package/lib/sandbox/clipboard/linux.ts +2 -1
- package/lib/sandbox/commands/create.ts +111 -212
- package/lib/sandbox/commands/enter.ts +23 -1
- package/lib/sandbox/commands/prune.ts +2 -2
- package/lib/sandbox/commands/rm.ts +3 -2
- package/lib/sandbox/commands/show.ts +1 -1
- package/lib/sandbox/config.ts +31 -4
- package/lib/sandbox/constants.ts +6 -0
- package/lib/sandbox/dockerfile.ts +2 -1
- package/lib/sandbox/managed-fs.ts +18 -5
- package/lib/sandbox/recovery.ts +98 -67
- package/lib/sandbox/shell.ts +1 -1
- package/lib/sandbox/tool-types.ts +143 -0
- package/lib/sandbox/tools.ts +5 -157
- package/lib/server/server.schema.json +2 -2
- package/lib/task/activity-intent.ts +128 -0
- package/lib/task/artifact-lifecycle.ts +3 -39
- package/lib/task/commands/decisions.ts +53 -20
- package/lib/task/commands/log.ts +15 -14
- package/lib/task/delegation-receipts.ts +199 -0
- package/lib/task/events.ts +164 -11
- package/lib/task/finalization-artifacts.ts +58 -0
- package/lib/task/lifecycle-execution.ts +106 -0
- package/lib/task/orchestration.ts +1022 -0
- package/lib/task/review-artifacts.ts +201 -69
- package/lib/task/review-finalization.ts +306 -0
- package/lib/task/review-fingerprint.ts +5 -0
- package/lib/task/task-execution-lock.ts +296 -0
- package/lib/task/verification-checks.ts +2 -1
- package/lib/task/verification-engine.ts +424 -28
- package/lib/task/verification-review.ts +1 -0
- package/lib/task/verification.ts +8 -3
- package/lib/task/workspace-snapshot.ts +57 -0
- package/lib/update.ts +48 -184
- package/package.json +4 -4
- package/templates/.agents/QUICKSTART.en.md +25 -8
- package/templates/.agents/QUICKSTART.zh-CN.md +25 -8
- package/templates/.agents/README.en.md +29 -25
- package/templates/.agents/README.zh-CN.md +29 -25
- package/templates/.agents/hooks/lifecycle-delegation.js +75 -0
- package/templates/.agents/rules/README.en.md +2 -0
- package/templates/.agents/rules/README.zh-CN.md +2 -0
- package/templates/.agents/rules/commit-and-pr.en.md +1 -0
- package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -0
- 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 +14 -12
- package/templates/.agents/rules/human-decision-context.zh-CN.md +14 -12
- 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 +24 -0
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +24 -0
- 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 +18 -0
- package/templates/.agents/rules/next-step-output.zh-CN.md +18 -0
- package/templates/.agents/rules/no-mid-flow-questions.en.md +19 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +19 -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 +2 -2
- 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 +21 -5
- package/templates/.agents/rules/release-commands.github.zh-CN.md +21 -5
- package/templates/.agents/rules/release-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/review-handshake.en.md +4 -4
- package/templates/.agents/rules/review-handshake.zh-CN.md +4 -4
- package/templates/.agents/rules/review-method.en.md +113 -0
- package/templates/.agents/rules/review-method.zh-CN.md +98 -0
- package/templates/.agents/rules/task-management.en.md +11 -0
- package/templates/.agents/rules/task-management.zh-CN.md +11 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -12
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +15 -12
- package/templates/.agents/skills/block-task/SKILL.en.md +11 -9
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +11 -9
- package/templates/.agents/skills/cancel-task/SKILL.en.md +10 -8
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +11 -9
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -16
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -16
- package/templates/.agents/skills/close-codescan/SKILL.en.md +7 -5
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +7 -5
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +7 -5
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +7 -5
- package/templates/.agents/skills/code-task/SKILL.en.md +10 -7
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +13 -10
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +14 -16
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +14 -16
- package/templates/.agents/skills/code-task/reference/output-template.en.md +3 -3
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/SKILL.en.md +13 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +13 -1
- 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/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 +24 -28
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +24 -28
- 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 +23 -8
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +23 -8
- 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 +13 -11
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +13 -11
- 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-pr/reference/pr-body-template.en.md +3 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +3 -3
- 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 +16 -14
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +16 -14
- package/templates/.agents/skills/import-codescan/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.en.md +10 -8
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -8
- package/templates/.agents/skills/init-labels/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/plan-task/SKILL.en.md +13 -10
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +13 -10
- 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/refine-title/SKILL.en.md +1 -1
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
- 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 +18 -4
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +19 -5
- package/templates/.agents/skills/review-analysis/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +51 -5
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +52 -6
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +25 -22
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +25 -22
- package/templates/.agents/skills/review-code/SKILL.en.md +35 -12
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +35 -12
- package/templates/.agents/skills/review-code/config/verify.en.json +7 -0
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +7 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.en.md +27 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.zh-CN.md +27 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.en.md +13 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.zh-CN.md +13 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +22 -24
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +22 -24
- package/templates/.agents/skills/review-code/reference/report-template.en.md +54 -7
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +54 -7
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +29 -24
- package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +29 -24
- package/templates/.agents/skills/review-code/reference/security-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/security-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-plan/SKILL.en.md +18 -4
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +19 -5
- package/templates/.agents/skills/review-plan/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +61 -5
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +61 -5
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +21 -24
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +21 -24
- package/templates/.agents/skills/review-pr/SKILL.en.md +158 -0
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +158 -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 +22 -0
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +22 -0
- package/templates/.agents/skills/run-task/config/verify.en.json +10 -0
- package/templates/.agents/skills/run-task/config/verify.zh-CN.json +10 -0
- 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/test/SKILL.en.md +4 -4
- package/templates/.agents/skills/test/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.en.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +5 -5
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +664 -246
- package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +4 -4
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/watch-pr/SKILL.en.md +21 -21
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +21 -21
- 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 +1 -1
- package/templates/.agents/templates/task.zh-CN.md +1 -1
- 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/agents/agent-infra-lifecycle-executor.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +6 -0
- 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/run-task.en.md +8 -0
- package/templates/.claude/commands/run-task.zh-CN.md +8 -0
- package/templates/.claude/settings.json +24 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +3 -0
- package/templates/.gemini/commands/_project_/review-pr.en.toml +10 -0
- package/templates/.gemini/commands/_project_/review-pr.zh-CN.toml +10 -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/run-task.en.md +11 -0
- package/templates/.opencode/commands/run-task.zh-CN.md +11 -0
- 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_/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
|
@@ -6,14 +6,15 @@ import { execFileSync } from 'node:child_process';
|
|
|
6
6
|
import { parseArgs } from 'node:util';
|
|
7
7
|
import * as p from '@clack/prompts';
|
|
8
8
|
import pc from 'picocolors';
|
|
9
|
-
import
|
|
9
|
+
import { listAgentClientAdapters } from '../../agent-clients/registry.js';
|
|
10
10
|
import { loadConfig } from '../config.js';
|
|
11
|
-
import { assertValidBranchName, containerName, containerNameCandidates, parsePositiveIntegerOption, sandboxBranchLabel, sandboxImageConfigLabel, sandboxImageRefreshLabel, sandboxLabel, shareBranchDir, shareCommonDir, shellConfigDir, worktreeDirCandidates } from '../constants.js';
|
|
11
|
+
import { assertValidBranchName, containerName, containerNameCandidates, parsePositiveIntegerOption, sandboxBranchLabel, sandboxImageConfigLabel, sandboxImageRefreshLabel, sandboxLabel, sandboxRuntimeCapabilityLabel, shareBranchDir, shareCommonDir, shellConfigDir, worktreeDirCandidates } from '../constants.js';
|
|
12
12
|
import { prepareDockerfile } from '../dockerfile.js';
|
|
13
13
|
import { assertBuildProxyCompatibility, buildProxyFailureHint, prepareBuildProxy, redactBuildProxyValues } from '../build-proxy.js';
|
|
14
14
|
import { detectEngine, ensureDocker } from '../engine.js';
|
|
15
15
|
import { commandForEngine, execEngine, run, runEngine, runOk, runOkEngine, runSafe, runSafeEngine, runVerboseEngine } from '../shell.js';
|
|
16
16
|
import { resolveTaskBranch } from '../task-resolver.js';
|
|
17
|
+
import { createSandboxCapabilityPlan, runSandboxHooks, runBoundedSandboxHookCommand } from '../agent-client-reconciler.js';
|
|
17
18
|
import { resolveTools, tmpfsSeedStagingPath, tmpfsSeedTargetPath, toolConfigDirCandidates } from '../tools.js';
|
|
18
19
|
import { assertFreshSandboxReady, hydrateTmpfsSeedEntries, prepareTmpfsMounts } from '../recovery.js';
|
|
19
20
|
import { hostJoin, toEnginePath, volumeArg } from '../engines/wsl2-paths.js';
|
|
@@ -22,32 +23,13 @@ import { clipboardHostDir, CONTAINER_CLIPBOARD_MOUNT } from '../clipboard/paths.
|
|
|
22
23
|
import { validateSelinuxDisableEnv } from '../engines/selinux.js';
|
|
23
24
|
import { dotfilesCacheDir, materializeDotfiles } from '../dotfiles.js';
|
|
24
25
|
import { ensureSandboxDiscoveryReadmes } from '../readme-scaffold.js';
|
|
26
|
+
import { removeDirRecursive } from '../../remove-dir.js';
|
|
25
27
|
import { prepareClaudeCredentials, redactCommandError, validateClaudeCredentialsEnvOverride } from '../credentials.js';
|
|
26
28
|
import { detectHostTimezone } from '../host-timezone.js';
|
|
27
29
|
import { buildImageSignature, buildSandboxImageArgs, isRefreshDisabled, isRefreshDue, parseImageLabels, parseRefreshTimestamp } from '../image-build.js';
|
|
28
|
-
|
|
30
|
+
export { ensureCodexModelInheritance, ensureCodexWorkspaceTrust } from '../../agent-clients/adapters/codex-sandbox.js';
|
|
29
31
|
const SANDBOX_ALIAS_BLOCK_BEGIN = '# >>> agent-infra managed aliases >>>';
|
|
30
32
|
const SANDBOX_ALIAS_BLOCK_END = '# <<< agent-infra managed aliases <<<';
|
|
31
|
-
const SANDBOX_ALIAS_NAMES = [
|
|
32
|
-
'claude-yolo',
|
|
33
|
-
'opencode-yolo',
|
|
34
|
-
'codex-yolo',
|
|
35
|
-
'gemini-yolo',
|
|
36
|
-
'cy',
|
|
37
|
-
'oy',
|
|
38
|
-
'xy',
|
|
39
|
-
'gy'
|
|
40
|
-
];
|
|
41
|
-
const DEFAULT_SANDBOX_ALIASES = `alias claude-yolo='claude --dangerously-skip-permissions; tput ed'
|
|
42
|
-
alias opencode-yolo='OPENCODE_PERMISSION='\\''${OPENCODE_YOLO_PERMISSION}'\\'' opencode; tput ed'
|
|
43
|
-
alias codex-yolo='codex --yolo; tput ed'
|
|
44
|
-
alias gemini-yolo='gemini --yolo; tput ed'
|
|
45
|
-
|
|
46
|
-
alias cy='claude --dangerously-skip-permissions; tput ed'
|
|
47
|
-
alias oy='OPENCODE_PERMISSION='\\''${OPENCODE_YOLO_PERMISSION}'\\'' opencode; tput ed'
|
|
48
|
-
alias xy='codex --yolo; tput ed'
|
|
49
|
-
alias gy='gemini --yolo; tput ed'
|
|
50
|
-
`;
|
|
51
33
|
const CONTAINER_HOME = '/home/devuser';
|
|
52
34
|
const CONTAINER_SHELL_CONFIG_MOUNT = `${CONTAINER_HOME}/.host-shell-config`;
|
|
53
35
|
const USAGE = `Usage: ai sandbox create <branch> [base] [--cpu <n>] [--memory <n>] [--no-refresh] [--inherit-proxy|-P] [--inherit-build-proxy|-B]
|
|
@@ -268,7 +250,7 @@ export function ensureShellConfigSymlinks(engine, container, execFn = execEngine
|
|
|
268
250
|
}
|
|
269
251
|
export function prepareHostShellConfig({ home, project, branch, repoRoot }) {
|
|
270
252
|
const hostDir = hostShellConfigDir(home, project, branch);
|
|
271
|
-
|
|
253
|
+
removeDirRecursive(hostDir);
|
|
272
254
|
fs.mkdirSync(hostDir, { recursive: true });
|
|
273
255
|
writeSanitizedGitconfig({
|
|
274
256
|
home,
|
|
@@ -306,11 +288,19 @@ function normalizeWorktreePath(worktreePath) {
|
|
|
306
288
|
if (!worktreePath) {
|
|
307
289
|
return '';
|
|
308
290
|
}
|
|
291
|
+
const wslMount = process.platform === 'win32'
|
|
292
|
+
? worktreePath.match(/^\/mnt\/([A-Za-z])(?:\/(.*))?$/)
|
|
293
|
+
: null;
|
|
294
|
+
const hostPath = wslMount
|
|
295
|
+
? `${wslMount[1].toUpperCase()}:\\${(wslMount[2] ?? '').replace(/\//g, '\\')}`
|
|
296
|
+
: worktreePath;
|
|
309
297
|
try {
|
|
310
|
-
|
|
298
|
+
const normalized = fs.existsSync(hostPath) ? fs.realpathSync(hostPath) : path.resolve(hostPath);
|
|
299
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
311
300
|
}
|
|
312
301
|
catch {
|
|
313
|
-
|
|
302
|
+
const normalized = path.resolve(hostPath);
|
|
303
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
314
304
|
}
|
|
315
305
|
}
|
|
316
306
|
export function getGitSigningKey({ home, repoPath = null, execFn = execFileSync } = {}) {
|
|
@@ -481,7 +471,7 @@ export function collectHostProxyEntries(env) {
|
|
|
481
471
|
});
|
|
482
472
|
}
|
|
483
473
|
export function buildContainerEnvFile(resolvedTools, engine, runSafeEngineFn = runSafeEngine, options = {}) {
|
|
484
|
-
const { additionalEntries = [], mkdtempFn = fs.mkdtempSync, writeFileFn = fs.writeFileSync, chmodFn = fs.chmodSync, rmFn =
|
|
474
|
+
const { additionalEntries = [], mkdtempFn = fs.mkdtempSync, writeFileFn = fs.writeFileSync, chmodFn = fs.chmodSync, rmFn = removeDirRecursive, tmpDir = os.tmpdir(), runSafeFn = runSafe } = options;
|
|
485
475
|
const entries = resolvedTools.flatMap(({ tool }) => Object.entries(tool.envVars ?? {}));
|
|
486
476
|
entries.push(...additionalEntries);
|
|
487
477
|
let ghToken = runSafeEngineFn(engine, 'gh', ['auth', 'token']);
|
|
@@ -705,141 +695,6 @@ export function ensureClaudeSettings(toolDir, hostHomeDir) {
|
|
|
705
695
|
fs.writeFileSync(settingsPath, JSON.stringify(data, null, 4), 'utf8');
|
|
706
696
|
}
|
|
707
697
|
}
|
|
708
|
-
function resolveHostCatalogPath(value, hostHomeDir) {
|
|
709
|
-
if (typeof value !== 'string' || value === '') {
|
|
710
|
-
return null;
|
|
711
|
-
}
|
|
712
|
-
let resolved;
|
|
713
|
-
if (value === '~' || value.startsWith('~/') || value.startsWith('~\\')) {
|
|
714
|
-
resolved = path.join(hostHomeDir, value.slice(1).replace(/^[/\\]+/, ''));
|
|
715
|
-
}
|
|
716
|
-
else if (path.isAbsolute(value)) {
|
|
717
|
-
resolved = value;
|
|
718
|
-
}
|
|
719
|
-
else {
|
|
720
|
-
resolved = path.join(hostHomeDir, '.codex', value);
|
|
721
|
-
}
|
|
722
|
-
try {
|
|
723
|
-
if (!fs.statSync(resolved).isFile()) {
|
|
724
|
-
return null;
|
|
725
|
-
}
|
|
726
|
-
fs.accessSync(resolved, fs.constants.R_OK);
|
|
727
|
-
return resolved;
|
|
728
|
-
}
|
|
729
|
-
catch {
|
|
730
|
-
return null;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
const CODEX_DISABLED_FEATURE_FLAGS = ['apps', 'enable_mcp_apps'];
|
|
734
|
-
function removeCodexMcpServers(sandboxParsed) {
|
|
735
|
-
if (!Object.hasOwn(sandboxParsed, 'mcp_servers')) {
|
|
736
|
-
return false;
|
|
737
|
-
}
|
|
738
|
-
delete sandboxParsed.mcp_servers;
|
|
739
|
-
return true;
|
|
740
|
-
}
|
|
741
|
-
function inheritDisabledCodexFeatureFlags(sandboxParsed, hostParsed) {
|
|
742
|
-
if (!isJsonObjectRecord(hostParsed.features)) {
|
|
743
|
-
return false;
|
|
744
|
-
}
|
|
745
|
-
if (Object.hasOwn(sandboxParsed, 'features') && !isJsonObjectRecord(sandboxParsed.features)) {
|
|
746
|
-
return false;
|
|
747
|
-
}
|
|
748
|
-
let sandboxFeatures = sandboxParsed.features;
|
|
749
|
-
let changed = false;
|
|
750
|
-
for (const key of CODEX_DISABLED_FEATURE_FLAGS) {
|
|
751
|
-
if (hostParsed.features[key] !== false) {
|
|
752
|
-
continue;
|
|
753
|
-
}
|
|
754
|
-
if (!sandboxFeatures) {
|
|
755
|
-
sandboxFeatures = {};
|
|
756
|
-
sandboxParsed.features = sandboxFeatures;
|
|
757
|
-
}
|
|
758
|
-
if (sandboxFeatures[key] !== false) {
|
|
759
|
-
sandboxFeatures[key] = false;
|
|
760
|
-
changed = true;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
return changed;
|
|
764
|
-
}
|
|
765
|
-
export function ensureCodexModelInheritance(toolDir, hostHomeDir, containerCodexDir = '/home/devuser/.codex') {
|
|
766
|
-
if (!hostHomeDir) {
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
const hostConfigPath = path.join(hostHomeDir, '.codex', 'config.toml');
|
|
770
|
-
if (!fs.existsSync(hostConfigPath)) {
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
let hostParsed;
|
|
774
|
-
try {
|
|
775
|
-
hostParsed = toml.parse(fs.readFileSync(hostConfigPath, 'utf8'));
|
|
776
|
-
}
|
|
777
|
-
catch {
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
const sandboxConfigPath = path.join(toolDir, 'config.toml');
|
|
781
|
-
// This rewrites sandbox-side TOML and drops comments; the host config stays untouched.
|
|
782
|
-
let sandboxParsed = {};
|
|
783
|
-
if (fs.existsSync(sandboxConfigPath)) {
|
|
784
|
-
try {
|
|
785
|
-
sandboxParsed = toml.parse(fs.readFileSync(sandboxConfigPath, 'utf8'));
|
|
786
|
-
}
|
|
787
|
-
catch {
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
let changed = removeCodexMcpServers(sandboxParsed);
|
|
792
|
-
changed = inheritDisabledCodexFeatureFlags(sandboxParsed, hostParsed) || changed;
|
|
793
|
-
const inheritSpecs = [
|
|
794
|
-
['model', 'string'],
|
|
795
|
-
['model_reasoning_effort', 'string'],
|
|
796
|
-
['model_auto_compact_token_limit', 'number']
|
|
797
|
-
];
|
|
798
|
-
for (const [key, type] of inheritSpecs) {
|
|
799
|
-
if (Object.hasOwn(sandboxParsed, key)) {
|
|
800
|
-
continue;
|
|
801
|
-
}
|
|
802
|
-
const value = hostParsed[key];
|
|
803
|
-
if (type === 'string' && (typeof value !== 'string' || value === '')) {
|
|
804
|
-
continue;
|
|
805
|
-
}
|
|
806
|
-
if (type === 'number' && (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)) {
|
|
807
|
-
continue;
|
|
808
|
-
}
|
|
809
|
-
sandboxParsed[key] = value;
|
|
810
|
-
changed = true;
|
|
811
|
-
}
|
|
812
|
-
if (!Object.hasOwn(sandboxParsed, 'model_catalog_json')) {
|
|
813
|
-
const hostCatalogPath = resolveHostCatalogPath(hostParsed['model_catalog_json'], hostHomeDir);
|
|
814
|
-
if (hostCatalogPath) {
|
|
815
|
-
try {
|
|
816
|
-
const basename = path.basename(hostCatalogPath);
|
|
817
|
-
const destDir = path.join(toolDir, 'model-catalogs');
|
|
818
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
819
|
-
fs.copyFileSync(hostCatalogPath, path.join(destDir, basename));
|
|
820
|
-
sandboxParsed['model_catalog_json'] = path.posix.join(containerCodexDir, 'model-catalogs', basename);
|
|
821
|
-
changed = true;
|
|
822
|
-
}
|
|
823
|
-
catch {
|
|
824
|
-
// Copy failed (e.g. permissions): skip catalog, keep scalar inheritance intact.
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
if (changed) {
|
|
829
|
-
fs.writeFileSync(sandboxConfigPath, `${toml.stringify(sandboxParsed)}\n`, 'utf8');
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
export function ensureCodexWorkspaceTrust(toolDir) {
|
|
833
|
-
const configPath = path.join(toolDir, 'config.toml');
|
|
834
|
-
let content = '';
|
|
835
|
-
if (fs.existsSync(configPath)) {
|
|
836
|
-
content = fs.readFileSync(configPath, 'utf8');
|
|
837
|
-
}
|
|
838
|
-
if (!content.includes('[projects."/workspace"]')) {
|
|
839
|
-
const entry = '\n[projects."/workspace"]\ntrust_level = "trusted"\n';
|
|
840
|
-
fs.writeFileSync(configPath, content + entry, 'utf8');
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
698
|
export function ensureOpenCodeModelInheritance(toolDir, hostHomeDir) {
|
|
844
699
|
if (!hostHomeDir) {
|
|
845
700
|
return;
|
|
@@ -874,22 +729,6 @@ export function ensureOpenCodeModelInheritance(toolDir, hostHomeDir) {
|
|
|
874
729
|
fs.writeFileSync(sandboxConfigPath, JSON.stringify(sandboxJson, null, 2), 'utf8');
|
|
875
730
|
}
|
|
876
731
|
}
|
|
877
|
-
export function ensureGeminiWorkspaceTrust(toolDir) {
|
|
878
|
-
const trustPath = path.join(toolDir, 'trustedFolders.json');
|
|
879
|
-
let data = {};
|
|
880
|
-
if (fs.existsSync(trustPath)) {
|
|
881
|
-
try {
|
|
882
|
-
data = JSON.parse(fs.readFileSync(trustPath, 'utf8'));
|
|
883
|
-
}
|
|
884
|
-
catch {
|
|
885
|
-
// malformed JSON, start fresh
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
if (data['/workspace'] !== 'TRUST_FOLDER') {
|
|
889
|
-
data['/workspace'] = 'TRUST_FOLDER';
|
|
890
|
-
fs.writeFileSync(trustPath, JSON.stringify(data, null, 2), 'utf8');
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
732
|
export function sandboxAliasesPath(home) {
|
|
894
733
|
return hostJoin(home, '.agent-infra', 'aliases', 'sandbox.sh');
|
|
895
734
|
}
|
|
@@ -900,7 +739,7 @@ function stripManagedSandboxAliasBlocks(content) {
|
|
|
900
739
|
const blockPattern = new RegExp(`${escapeRegExp(SANDBOX_ALIAS_BLOCK_BEGIN)}[\\s\\S]*?${escapeRegExp(SANDBOX_ALIAS_BLOCK_END)}\\n?`, 'g');
|
|
901
740
|
return content.replace(blockPattern, '').trimEnd();
|
|
902
741
|
}
|
|
903
|
-
function isLegacyManagedSandboxAliasFile(content) {
|
|
742
|
+
function isLegacyManagedSandboxAliasFile(content, aliases) {
|
|
904
743
|
const lines = content
|
|
905
744
|
.split(/\r?\n/)
|
|
906
745
|
.map((line) => line.trim())
|
|
@@ -908,19 +747,25 @@ function isLegacyManagedSandboxAliasFile(content) {
|
|
|
908
747
|
if (lines.length === 0) {
|
|
909
748
|
return false;
|
|
910
749
|
}
|
|
911
|
-
const aliasPattern = new RegExp(`^alias (${
|
|
750
|
+
const aliasPattern = new RegExp(`^alias (${aliases.map((alias) => escapeRegExp(alias.name)).join('|')})=`);
|
|
912
751
|
return lines.every((line) => aliasPattern.test(line));
|
|
913
752
|
}
|
|
914
|
-
|
|
753
|
+
function registrySandboxAliases() {
|
|
754
|
+
return listAgentClientAdapters().flatMap((adapter) => adapter.sandbox.aliases);
|
|
755
|
+
}
|
|
756
|
+
function renderSandboxAliases(aliases) {
|
|
757
|
+
return `${aliases.map((alias) => `alias ${alias.name}='${alias.command.replaceAll("'", "'\\''")}'`).join('\n')}\n`;
|
|
758
|
+
}
|
|
759
|
+
export function ensureSandboxAliasesFile(home, aliases = registrySandboxAliases()) {
|
|
915
760
|
const aliasesPath = sandboxAliasesPath(home);
|
|
916
|
-
const managedBlock = `${SANDBOX_ALIAS_BLOCK_BEGIN}\n${
|
|
761
|
+
const managedBlock = `${SANDBOX_ALIAS_BLOCK_BEGIN}\n${renderSandboxAliases(aliases)}${SANDBOX_ALIAS_BLOCK_END}\n`;
|
|
917
762
|
fs.mkdirSync(path.dirname(aliasesPath), { recursive: true });
|
|
918
763
|
const created = !fs.existsSync(aliasesPath);
|
|
919
764
|
let existing = '';
|
|
920
765
|
if (!created) {
|
|
921
766
|
existing = fs.readFileSync(aliasesPath, 'utf8');
|
|
922
767
|
}
|
|
923
|
-
const userContent = isLegacyManagedSandboxAliasFile(existing)
|
|
768
|
+
const userContent = isLegacyManagedSandboxAliasFile(existing, aliases)
|
|
924
769
|
? ''
|
|
925
770
|
: stripManagedSandboxAliasBlocks(existing);
|
|
926
771
|
const nextContent = userContent
|
|
@@ -1018,15 +863,14 @@ export async function create(args) {
|
|
|
1018
863
|
};
|
|
1019
864
|
const worktreeCandidates = worktreeDirCandidates(effectiveConfig, branch);
|
|
1020
865
|
assertBranchAvailable(config.repoRoot, branch, { allowedWorktrees: worktreeCandidates });
|
|
1021
|
-
const
|
|
866
|
+
const capabilityPlan = createSandboxCapabilityPlan(effectiveConfig);
|
|
867
|
+
const tools = [...capabilityPlan.tools];
|
|
1022
868
|
const resolvedTools = resolveToolDirs(effectiveConfig, tools, branch);
|
|
1023
869
|
// Fatal credential states still fail before filesystem/docker side effects.
|
|
1024
|
-
//
|
|
1025
|
-
//
|
|
870
|
+
// Missing credentials leave the selected Claude Code capability installed
|
|
871
|
+
// and mounted; only the absent live credential file is omitted.
|
|
1026
872
|
const credentialOutcome = prepareClaudeCredentials(effectiveConfig.home, effectiveConfig.project, resolvedTools);
|
|
1027
|
-
const effectiveResolvedTools =
|
|
1028
|
-
? resolvedTools.filter(({ tool }) => tool.id !== 'claude-code')
|
|
1029
|
-
: resolvedTools;
|
|
873
|
+
const effectiveResolvedTools = resolvedTools;
|
|
1030
874
|
const container = containerName(effectiveConfig, branch);
|
|
1031
875
|
const worktree = worktreeCandidates.find((candidate) => fs.existsSync(candidate)) ?? worktreeCandidates[0] ?? '';
|
|
1032
876
|
const shareCommon = shareCommonDir(effectiveConfig);
|
|
@@ -1045,6 +889,16 @@ export async function create(args) {
|
|
|
1045
889
|
}
|
|
1046
890
|
try {
|
|
1047
891
|
p.log.step('Checking container engine...');
|
|
892
|
+
const prepareHookResults = await runSandboxHooks({
|
|
893
|
+
hooks: capabilityPlan.hooksByPhase.prepare,
|
|
894
|
+
phase: 'prepare',
|
|
895
|
+
context: { config: effectiveConfig, plan: capabilityPlan },
|
|
896
|
+
runCommand: runBoundedSandboxHookCommand
|
|
897
|
+
});
|
|
898
|
+
const prepareFailure = prepareHookResults.find((result) => result.status === 'fatal');
|
|
899
|
+
if (prepareFailure) {
|
|
900
|
+
throw new Error(prepareFailure.message ?? `Sandbox hook '${prepareFailure.hookId}' failed.`);
|
|
901
|
+
}
|
|
1048
902
|
await ensureDocker(effectiveConfig, (detail) => {
|
|
1049
903
|
p.log.info(` ${detail}`);
|
|
1050
904
|
});
|
|
@@ -1111,7 +965,7 @@ export async function create(args) {
|
|
|
1111
965
|
if (fs.readdirSync(worktree).length > 0) {
|
|
1112
966
|
return `Worktree exists at ${worktree}`;
|
|
1113
967
|
}
|
|
1114
|
-
|
|
968
|
+
removeDirRecursive(worktree);
|
|
1115
969
|
}
|
|
1116
970
|
const branchExists = runOk('git', [
|
|
1117
971
|
'-C',
|
|
@@ -1200,7 +1054,7 @@ export async function create(args) {
|
|
|
1200
1054
|
runSafeEngine(engine, 'docker', ['rm', name]);
|
|
1201
1055
|
}
|
|
1202
1056
|
}
|
|
1203
|
-
const aliasesFile = ensureSandboxAliasesFile(effectiveConfig.home);
|
|
1057
|
+
const aliasesFile = ensureSandboxAliasesFile(effectiveConfig.home, capabilityPlan.aliases);
|
|
1204
1058
|
if (aliasesFile.created) {
|
|
1205
1059
|
message(`Created default sandbox aliases at ${aliasesFile.path}`);
|
|
1206
1060
|
}
|
|
@@ -1229,6 +1083,24 @@ export async function create(args) {
|
|
|
1229
1083
|
let hostShellConfig;
|
|
1230
1084
|
let tmpfsSeedPlan = [];
|
|
1231
1085
|
try {
|
|
1086
|
+
const beforeCreateResults = await runSandboxHooks({
|
|
1087
|
+
hooks: capabilityPlan.hooksByPhase['before-container-create'],
|
|
1088
|
+
phase: 'before-container-create',
|
|
1089
|
+
context: {
|
|
1090
|
+
config: effectiveConfig,
|
|
1091
|
+
plan: capabilityPlan,
|
|
1092
|
+
create: {
|
|
1093
|
+
hostHome: effectiveConfig.home,
|
|
1094
|
+
resolvedTools: effectiveResolvedTools
|
|
1095
|
+
}
|
|
1096
|
+
},
|
|
1097
|
+
runCommand: runBoundedSandboxHookCommand
|
|
1098
|
+
});
|
|
1099
|
+
const beforeCreateFailure = beforeCreateResults.find((result) => result.status === 'fatal');
|
|
1100
|
+
if (beforeCreateFailure) {
|
|
1101
|
+
throw new Error(beforeCreateFailure.message
|
|
1102
|
+
?? `Sandbox hook '${beforeCreateFailure.hookId}' failed.`);
|
|
1103
|
+
}
|
|
1232
1104
|
const claudeCodeEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'claude-code');
|
|
1233
1105
|
if (claudeCodeEntry) {
|
|
1234
1106
|
ensureClaudeOnboarding(claudeCodeEntry.dir, effectiveConfig.home);
|
|
@@ -1237,15 +1109,6 @@ export async function create(args) {
|
|
|
1237
1109
|
// provider/API settings are enough for Claude Code. If no usable
|
|
1238
1110
|
// auth was present, the claude-code entry was removed above.
|
|
1239
1111
|
}
|
|
1240
|
-
const codexEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'codex');
|
|
1241
|
-
if (codexEntry) {
|
|
1242
|
-
ensureCodexModelInheritance(codexEntry.dir, effectiveConfig.home, codexEntry.tool.containerMount);
|
|
1243
|
-
ensureCodexWorkspaceTrust(codexEntry.dir);
|
|
1244
|
-
}
|
|
1245
|
-
const geminiEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'gemini-cli');
|
|
1246
|
-
if (geminiEntry) {
|
|
1247
|
-
ensureGeminiWorkspaceTrust(geminiEntry.dir);
|
|
1248
|
-
}
|
|
1249
1112
|
const opencodeEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'opencode');
|
|
1250
1113
|
if (opencodeEntry) {
|
|
1251
1114
|
// The TUI reads <toolDir>/opencode.json via OPENCODE_CONFIG pinned in tools.js.
|
|
@@ -1315,6 +1178,8 @@ export async function create(args) {
|
|
|
1315
1178
|
sandboxLabel(effectiveConfig),
|
|
1316
1179
|
'--label',
|
|
1317
1180
|
`${sandboxBranchLabel(effectiveConfig)}=${branch}`,
|
|
1181
|
+
'--label',
|
|
1182
|
+
`${sandboxRuntimeCapabilityLabel(effectiveConfig)}=${capabilityPlan.runtimeSignature}`,
|
|
1318
1183
|
...coreVolumes,
|
|
1319
1184
|
...buildClipboardVolumeArgs(engine, effectiveConfig.home),
|
|
1320
1185
|
'-v',
|
|
@@ -1392,6 +1257,17 @@ export async function create(args) {
|
|
|
1392
1257
|
runSafeEngine(engine, 'docker', ['exec', container, 'bash', '-lc', command]);
|
|
1393
1258
|
}
|
|
1394
1259
|
}
|
|
1260
|
+
const afterStartResults = await runSandboxHooks({
|
|
1261
|
+
hooks: capabilityPlan.hooksByPhase['after-container-start'],
|
|
1262
|
+
phase: 'after-container-start',
|
|
1263
|
+
context: { config: effectiveConfig, plan: capabilityPlan },
|
|
1264
|
+
runCommand: runBoundedSandboxHookCommand
|
|
1265
|
+
});
|
|
1266
|
+
const afterStartFailure = afterStartResults.find((result) => result.status === 'fatal');
|
|
1267
|
+
if (afterStartFailure) {
|
|
1268
|
+
throw new Error(afterStartFailure.message
|
|
1269
|
+
?? `Sandbox hook '${afterStartFailure.hookId}' failed.`);
|
|
1270
|
+
}
|
|
1395
1271
|
return 'Container started';
|
|
1396
1272
|
}
|
|
1397
1273
|
}
|
|
@@ -2,6 +2,7 @@ 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 { createSandboxCapabilityPlan, runBoundedSandboxHookCommand, runSandboxHooks } from '../agent-client-reconciler.js';
|
|
5
6
|
import { formatCredentialWarnings, formatRemaining, hasClaudeProviderAuth, reconcileClaudeCredentials, redactCommandError, validateClaudeCredentialsEnvOverride } from '../credentials.js';
|
|
6
7
|
import { runInteractiveEngine } from '../shell.js';
|
|
7
8
|
import { dotfilesCacheDir, materializeDotfiles } from '../dotfiles.js';
|
|
@@ -123,7 +124,22 @@ export async function enter(args) {
|
|
|
123
124
|
});
|
|
124
125
|
const container = ready.container;
|
|
125
126
|
const cmd = parsed.command;
|
|
126
|
-
|
|
127
|
+
const capabilityPlan = createSandboxCapabilityPlan(config);
|
|
128
|
+
const enterHookResults = await runSandboxHooks({
|
|
129
|
+
hooks: capabilityPlan.hooksByPhase['before-enter'],
|
|
130
|
+
phase: 'before-enter',
|
|
131
|
+
context: { config, plan: capabilityPlan },
|
|
132
|
+
runCommand: runBoundedSandboxHookCommand
|
|
133
|
+
});
|
|
134
|
+
for (const result of enterHookResults) {
|
|
135
|
+
if (result.status === 'fatal') {
|
|
136
|
+
throw new Error(result.message ?? `Sandbox hook '${result.hookId}' failed.`);
|
|
137
|
+
}
|
|
138
|
+
if (result.status === 'warning') {
|
|
139
|
+
process.stderr.write(`Warning: ${result.message ?? `Sandbox hook '${result.hookId}' did not complete.`}\n`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (capabilityPlan.selectedAgentClients.some((adapter) => adapter.id === 'claude-code')) {
|
|
127
143
|
try {
|
|
128
144
|
// Scan all projects so a refresh from a neighbouring sandbox can still flow back to the host.
|
|
129
145
|
const providerAuthAvailable = hasClaudeProviderAuth(config.home);
|
|
@@ -10,7 +10,7 @@ import { hostJoin } from '../engines/wsl2-paths.js';
|
|
|
10
10
|
import { removeManagedDir, removeWorktreeDir } from '../managed-fs.js';
|
|
11
11
|
import { parseLabels } from './ls.js';
|
|
12
12
|
import { runEngine, runSafe } from '../shell.js';
|
|
13
|
-
import {
|
|
13
|
+
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.js';
|
|
14
14
|
const USAGE = `Usage: ai sandbox prune [--dry-run]`;
|
|
15
15
|
function listChildDirs(base) {
|
|
16
16
|
if (!fs.existsSync(base)) {
|
|
@@ -129,7 +129,7 @@ export async function prune(args) {
|
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
const config = loadConfig();
|
|
132
|
-
const tools =
|
|
132
|
+
const tools = [...createSandboxCapabilityPlan(config).cleanupInventory];
|
|
133
133
|
const engine = detectEngine(config);
|
|
134
134
|
const psArgs = [
|
|
135
135
|
'ps',
|
|
@@ -10,7 +10,8 @@ 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
12
|
import { resolveTaskBranch } from '../task-resolver.js';
|
|
13
|
-
import {
|
|
13
|
+
import { toolConfigDirCandidates, toolProjectDirCandidates } from '../tools.js';
|
|
14
|
+
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.js';
|
|
14
15
|
import { fetchSandboxRows } from './list-running.js';
|
|
15
16
|
import { lookupShortIdByBranch } from '../../task/short-id.js';
|
|
16
17
|
const USAGE = `Usage:
|
|
@@ -284,7 +285,7 @@ export async function rm(args) {
|
|
|
284
285
|
throw new Error(USAGE);
|
|
285
286
|
}
|
|
286
287
|
const config = loadConfig();
|
|
287
|
-
const tools =
|
|
288
|
+
const tools = [...createSandboxCapabilityPlan(config).cleanupInventory];
|
|
288
289
|
if (values.purge) {
|
|
289
290
|
await rmPurge(config, tools);
|
|
290
291
|
return;
|
|
@@ -8,7 +8,7 @@ import { resolveTools, toolConfigDirCandidates } from '../tools.js';
|
|
|
8
8
|
const USAGE = `Usage: ai sandbox show <branch | TASK-id | N>
|
|
9
9
|
|
|
10
10
|
Shows one sandbox's worktree path and per-tool state paths (Claude Code,
|
|
11
|
-
Codex,
|
|
11
|
+
Codex, Antigravity CLI, OpenCode). The argument follows the same contract as
|
|
12
12
|
'ai sandbox exec' and 'ai sandbox start': N (bare) is the recommended form
|
|
13
13
|
for task short ids (e.g. 'ai sandbox show 11'); a TASK-id or a plain
|
|
14
14
|
branch name are also accepted. Use 'ai sandbox ls' for the container list.`;
|
|
@@ -3,6 +3,8 @@ import path from 'node:path';
|
|
|
3
3
|
import { homedir, platform } from 'node:os';
|
|
4
4
|
import { execFileSync } from 'node:child_process';
|
|
5
5
|
import pc from 'picocolors';
|
|
6
|
+
import { normalizeAgentClients } from '../agent-clients/config.js';
|
|
7
|
+
import { isAgentClientId } from '../agent-clients/types.js';
|
|
6
8
|
import { validateSandboxEngine } from './engine.js';
|
|
7
9
|
import { hostJoin } from './engines/wsl2-paths.js';
|
|
8
10
|
import { findRuntimeEngineMismatches } from './runtime-engines.js';
|
|
@@ -10,7 +12,7 @@ import { parseCustomTools } from './tools.js';
|
|
|
10
12
|
const DEFAULTS = Object.freeze({
|
|
11
13
|
engine: null,
|
|
12
14
|
runtimes: ['node22'],
|
|
13
|
-
tools: ['agent-infra'
|
|
15
|
+
tools: ['agent-infra'],
|
|
14
16
|
refreshIntervalDays: 7,
|
|
15
17
|
dockerfile: null,
|
|
16
18
|
vm: {
|
|
@@ -46,6 +48,18 @@ function cloneDefaults() {
|
|
|
46
48
|
vm: { ...DEFAULTS.vm }
|
|
47
49
|
};
|
|
48
50
|
}
|
|
51
|
+
function resolveSandboxToolIds(sandbox, agentClients, defaults) {
|
|
52
|
+
if (Array.isArray(sandbox.tools)) {
|
|
53
|
+
const tools = sandbox.tools.filter((tool) => typeof tool === 'string');
|
|
54
|
+
return agentClients.source === 'canonical'
|
|
55
|
+
? tools.filter((tool) => !isAgentClientId(tool))
|
|
56
|
+
: tools;
|
|
57
|
+
}
|
|
58
|
+
if (agentClients.remainingSandboxTools !== undefined) {
|
|
59
|
+
return [...agentClients.remainingSandboxTools];
|
|
60
|
+
}
|
|
61
|
+
return [...defaults];
|
|
62
|
+
}
|
|
49
63
|
export function loadConfig({ platformFn = platform, writeStderr = (chunk) => process.stderr.write(chunk) } = {}) {
|
|
50
64
|
const repoRoot = detectRepoRoot();
|
|
51
65
|
const home = homedir();
|
|
@@ -57,6 +71,8 @@ export function loadConfig({ platformFn = platform, writeStderr = (chunk) => pro
|
|
|
57
71
|
throw new Error('No .agents/.airc.json found. Run "ai init" first.');
|
|
58
72
|
}
|
|
59
73
|
const airc = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
74
|
+
const sandboxInput = airc.sandbox;
|
|
75
|
+
const agentClients = normalizeAgentClients(airc);
|
|
60
76
|
const defaults = cloneDefaults();
|
|
61
77
|
const sandbox = airc.sandbox ?? {};
|
|
62
78
|
const engine = validateSandboxEngine(sandbox.engine ?? defaults.engine, { platformFn });
|
|
@@ -83,6 +99,7 @@ export function loadConfig({ platformFn = platform, writeStderr = (chunk) => pro
|
|
|
83
99
|
}
|
|
84
100
|
}
|
|
85
101
|
const customTools = parseCustomTools(sandbox.customTools, { home });
|
|
102
|
+
const tools = resolveSandboxToolIds(sandbox, agentClients, defaults.tools);
|
|
86
103
|
return {
|
|
87
104
|
repoRoot,
|
|
88
105
|
configPath,
|
|
@@ -97,10 +114,10 @@ export function loadConfig({ platformFn = platform, writeStderr = (chunk) => pro
|
|
|
97
114
|
dotfilesDir: hostJoin(home, '.agent-infra', 'dotfiles'),
|
|
98
115
|
engine,
|
|
99
116
|
runtimes,
|
|
100
|
-
tools
|
|
101
|
-
? [...sandbox.tools]
|
|
102
|
-
: defaults.tools,
|
|
117
|
+
tools,
|
|
103
118
|
customTools,
|
|
119
|
+
agentClientState: agentClients.state,
|
|
120
|
+
agentClientSource: agentClients.source,
|
|
104
121
|
refreshIntervalDays: asNonNegativeIntegerOrDefault(sandbox.refreshIntervalDays, defaults.refreshIntervalDays),
|
|
105
122
|
dockerfile,
|
|
106
123
|
vm: {
|
|
@@ -75,6 +75,9 @@ export function sandboxImageConfigLabel(config) {
|
|
|
75
75
|
export function sandboxImageRefreshLabel(config) {
|
|
76
76
|
return `${sandboxLabel(config)}.last-refresh`;
|
|
77
77
|
}
|
|
78
|
+
export function sandboxRuntimeCapabilityLabel(config) {
|
|
79
|
+
return `agent-infra.sandbox.runtime-capability.${config.project}`;
|
|
80
|
+
}
|
|
78
81
|
export function parsePositiveIntegerOption(value, optionName) {
|
|
79
82
|
if (value === undefined || value === null) {
|
|
80
83
|
return undefined;
|
|
@@ -3,6 +3,7 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { createHash } from 'node:crypto';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { removeDirRecursive } from '../remove-dir.js';
|
|
6
7
|
const RUNTIMES_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), 'runtimes');
|
|
7
8
|
function listRuntimeFragments() {
|
|
8
9
|
return fs.readdirSync(RUNTIMES_DIR)
|
|
@@ -63,7 +64,7 @@ export function prepareDockerfile(config) {
|
|
|
63
64
|
path: tempPath,
|
|
64
65
|
signature: dockerfileSignature(config),
|
|
65
66
|
cleanup() {
|
|
66
|
-
|
|
67
|
+
removeDirRecursive(tempDir);
|
|
67
68
|
}
|
|
68
69
|
};
|
|
69
70
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
|
-
import { run } from './shell.js';
|
|
2
|
+
import { run, runSafe } from './shell.js';
|
|
3
|
+
import { removeDirRecursive } from '../remove-dir.js';
|
|
4
4
|
export function assertManagedPath(root, target) {
|
|
5
5
|
const resolvedRoot = path.resolve(root);
|
|
6
6
|
const resolvedTarget = path.resolve(target);
|
|
@@ -12,14 +12,19 @@ export function assertManagedPath(root, target) {
|
|
|
12
12
|
}
|
|
13
13
|
export function removeManagedDir(root, dir) {
|
|
14
14
|
assertManagedPath(root, dir);
|
|
15
|
-
|
|
15
|
+
removeDirRecursive(dir);
|
|
16
16
|
}
|
|
17
|
-
export function removeWorktreeDir(repoRoot, worktreeBase, dir) {
|
|
17
|
+
export function removeWorktreeDir(repoRoot, worktreeBase, dir, { runFn = run, runSafeFn = runSafe } = {}) {
|
|
18
18
|
try {
|
|
19
|
-
|
|
19
|
+
runFn('git', ['-C', repoRoot, 'worktree', 'remove', dir, '--force']);
|
|
20
20
|
}
|
|
21
21
|
catch {
|
|
22
|
+
// On WSL2 the worktree is registered under its `/mnt/<drive>/...` path, so
|
|
23
|
+
// `git worktree remove <windows-path>` cannot match it. Delete the managed
|
|
24
|
+
// directory directly, then prune the now-dangling worktree metadata so the
|
|
25
|
+
// branch is no longer reported as checked out.
|
|
22
26
|
removeManagedDir(worktreeBase, dir);
|
|
27
|
+
runSafeFn('git', ['-C', repoRoot, 'worktree', 'prune']);
|
|
23
28
|
}
|
|
24
29
|
}
|
|
25
30
|
//# sourceMappingURL=managed-fs.js.map
|