@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
|
@@ -7,7 +7,8 @@ import type { ExecFileSyncOptions, StdioOptions } from 'node:child_process';
|
|
|
7
7
|
import { parseArgs } from 'node:util';
|
|
8
8
|
import * as p from '@clack/prompts';
|
|
9
9
|
import pc from 'picocolors';
|
|
10
|
-
import
|
|
10
|
+
import { listAgentClientAdapters } from '../../agent-clients/registry.ts';
|
|
11
|
+
import type { SandboxAlias } from '../tool-types.ts';
|
|
11
12
|
import { loadConfig } from '../config.ts';
|
|
12
13
|
import {
|
|
13
14
|
assertValidBranchName,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
sandboxImageConfigLabel,
|
|
19
20
|
sandboxImageRefreshLabel,
|
|
20
21
|
sandboxLabel,
|
|
22
|
+
sandboxRuntimeCapabilityLabel,
|
|
21
23
|
shareBranchDir,
|
|
22
24
|
shareCommonDir,
|
|
23
25
|
shellConfigDir,
|
|
@@ -43,6 +45,11 @@ import {
|
|
|
43
45
|
runVerboseEngine
|
|
44
46
|
} from '../shell.ts';
|
|
45
47
|
import { resolveTaskBranch } from '../task-resolver.ts';
|
|
48
|
+
import {
|
|
49
|
+
createSandboxCapabilityPlan,
|
|
50
|
+
runSandboxHooks,
|
|
51
|
+
runBoundedSandboxHookCommand
|
|
52
|
+
} from '../agent-client-reconciler.ts';
|
|
46
53
|
import {
|
|
47
54
|
resolveTools,
|
|
48
55
|
tmpfsSeedStagingPath,
|
|
@@ -61,6 +68,7 @@ import { clipboardHostDir, CONTAINER_CLIPBOARD_MOUNT } from '../clipboard/paths.
|
|
|
61
68
|
import { validateSelinuxDisableEnv } from '../engines/selinux.ts';
|
|
62
69
|
import { dotfilesCacheDir, materializeDotfiles } from '../dotfiles.ts';
|
|
63
70
|
import { ensureSandboxDiscoveryReadmes } from '../readme-scaffold.ts';
|
|
71
|
+
import { removeDirRecursive } from '../../remove-dir.ts';
|
|
64
72
|
import {
|
|
65
73
|
prepareClaudeCredentials,
|
|
66
74
|
redactCommandError,
|
|
@@ -76,29 +84,13 @@ import {
|
|
|
76
84
|
parseRefreshTimestamp
|
|
77
85
|
} from '../image-build.ts';
|
|
78
86
|
|
|
79
|
-
|
|
87
|
+
export {
|
|
88
|
+
ensureCodexModelInheritance,
|
|
89
|
+
ensureCodexWorkspaceTrust
|
|
90
|
+
} from '../../agent-clients/adapters/codex-sandbox.ts';
|
|
91
|
+
|
|
80
92
|
const SANDBOX_ALIAS_BLOCK_BEGIN = '# >>> agent-infra managed aliases >>>';
|
|
81
93
|
const SANDBOX_ALIAS_BLOCK_END = '# <<< agent-infra managed aliases <<<';
|
|
82
|
-
const SANDBOX_ALIAS_NAMES = [
|
|
83
|
-
'claude-yolo',
|
|
84
|
-
'opencode-yolo',
|
|
85
|
-
'codex-yolo',
|
|
86
|
-
'gemini-yolo',
|
|
87
|
-
'cy',
|
|
88
|
-
'oy',
|
|
89
|
-
'xy',
|
|
90
|
-
'gy'
|
|
91
|
-
];
|
|
92
|
-
const DEFAULT_SANDBOX_ALIASES = `alias claude-yolo='claude --dangerously-skip-permissions; tput ed'
|
|
93
|
-
alias opencode-yolo='OPENCODE_PERMISSION='\\''${OPENCODE_YOLO_PERMISSION}'\\'' opencode; tput ed'
|
|
94
|
-
alias codex-yolo='codex --yolo; tput ed'
|
|
95
|
-
alias gemini-yolo='gemini --yolo; tput ed'
|
|
96
|
-
|
|
97
|
-
alias cy='claude --dangerously-skip-permissions; tput ed'
|
|
98
|
-
alias oy='OPENCODE_PERMISSION='\\''${OPENCODE_YOLO_PERMISSION}'\\'' opencode; tput ed'
|
|
99
|
-
alias xy='codex --yolo; tput ed'
|
|
100
|
-
alias gy='gemini --yolo; tput ed'
|
|
101
|
-
`;
|
|
102
94
|
const CONTAINER_HOME = '/home/devuser';
|
|
103
95
|
const CONTAINER_SHELL_CONFIG_MOUNT = `${CONTAINER_HOME}/.host-shell-config`;
|
|
104
96
|
const USAGE = `Usage: ai sandbox create <branch> [base] [--cpu <n>] [--memory <n>] [--no-refresh] [--inherit-proxy|-P] [--inherit-build-proxy|-B]
|
|
@@ -410,7 +402,7 @@ export function prepareHostShellConfig({
|
|
|
410
402
|
repoRoot: string;
|
|
411
403
|
}): HostShellConfig {
|
|
412
404
|
const hostDir = hostShellConfigDir(home, project, branch);
|
|
413
|
-
|
|
405
|
+
removeDirRecursive(hostDir);
|
|
414
406
|
fs.mkdirSync(hostDir, { recursive: true });
|
|
415
407
|
|
|
416
408
|
writeSanitizedGitconfig({
|
|
@@ -459,10 +451,19 @@ function normalizeWorktreePath(worktreePath: string): string {
|
|
|
459
451
|
return '';
|
|
460
452
|
}
|
|
461
453
|
|
|
454
|
+
const wslMount = process.platform === 'win32'
|
|
455
|
+
? worktreePath.match(/^\/mnt\/([A-Za-z])(?:\/(.*))?$/)
|
|
456
|
+
: null;
|
|
457
|
+
const hostPath = wslMount
|
|
458
|
+
? `${wslMount[1]!.toUpperCase()}:\\${(wslMount[2] ?? '').replace(/\//g, '\\')}`
|
|
459
|
+
: worktreePath;
|
|
460
|
+
|
|
462
461
|
try {
|
|
463
|
-
|
|
462
|
+
const normalized = fs.existsSync(hostPath) ? fs.realpathSync(hostPath) : path.resolve(hostPath);
|
|
463
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
464
464
|
} catch {
|
|
465
|
-
|
|
465
|
+
const normalized = path.resolve(hostPath);
|
|
466
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
466
467
|
}
|
|
467
468
|
}
|
|
468
469
|
|
|
@@ -714,7 +715,7 @@ export function buildContainerEnvFile(
|
|
|
714
715
|
mkdtempFn = fs.mkdtempSync,
|
|
715
716
|
writeFileFn = fs.writeFileSync,
|
|
716
717
|
chmodFn = fs.chmodSync,
|
|
717
|
-
rmFn = fs.rmSync,
|
|
718
|
+
rmFn = removeDirRecursive as typeof fs.rmSync,
|
|
718
719
|
tmpDir = os.tmpdir(),
|
|
719
720
|
runSafeFn = runSafe
|
|
720
721
|
} = options;
|
|
@@ -971,154 +972,6 @@ export function ensureClaudeSettings(toolDir: string, hostHomeDir?: string): voi
|
|
|
971
972
|
}
|
|
972
973
|
}
|
|
973
974
|
|
|
974
|
-
function resolveHostCatalogPath(value: unknown, hostHomeDir: string): string | null {
|
|
975
|
-
if (typeof value !== 'string' || value === '') {
|
|
976
|
-
return null;
|
|
977
|
-
}
|
|
978
|
-
let resolved: string;
|
|
979
|
-
if (value === '~' || value.startsWith('~/') || value.startsWith('~\\')) {
|
|
980
|
-
resolved = path.join(hostHomeDir, value.slice(1).replace(/^[/\\]+/, ''));
|
|
981
|
-
} else if (path.isAbsolute(value)) {
|
|
982
|
-
resolved = value;
|
|
983
|
-
} else {
|
|
984
|
-
resolved = path.join(hostHomeDir, '.codex', value);
|
|
985
|
-
}
|
|
986
|
-
try {
|
|
987
|
-
if (!fs.statSync(resolved).isFile()) {
|
|
988
|
-
return null;
|
|
989
|
-
}
|
|
990
|
-
fs.accessSync(resolved, fs.constants.R_OK);
|
|
991
|
-
return resolved;
|
|
992
|
-
} catch {
|
|
993
|
-
return null;
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
const CODEX_DISABLED_FEATURE_FLAGS = ['apps', 'enable_mcp_apps'] as const;
|
|
998
|
-
|
|
999
|
-
function removeCodexMcpServers(sandboxParsed: JsonObject): boolean {
|
|
1000
|
-
if (!Object.hasOwn(sandboxParsed, 'mcp_servers')) {
|
|
1001
|
-
return false;
|
|
1002
|
-
}
|
|
1003
|
-
delete sandboxParsed.mcp_servers;
|
|
1004
|
-
return true;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
function inheritDisabledCodexFeatureFlags(sandboxParsed: JsonObject, hostParsed: JsonObject): boolean {
|
|
1008
|
-
if (!isJsonObjectRecord(hostParsed.features)) {
|
|
1009
|
-
return false;
|
|
1010
|
-
}
|
|
1011
|
-
if (Object.hasOwn(sandboxParsed, 'features') && !isJsonObjectRecord(sandboxParsed.features)) {
|
|
1012
|
-
return false;
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
let sandboxFeatures = sandboxParsed.features as JsonObject | undefined;
|
|
1016
|
-
let changed = false;
|
|
1017
|
-
for (const key of CODEX_DISABLED_FEATURE_FLAGS) {
|
|
1018
|
-
if (hostParsed.features[key] !== false) {
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
if (!sandboxFeatures) {
|
|
1022
|
-
sandboxFeatures = {};
|
|
1023
|
-
sandboxParsed.features = sandboxFeatures;
|
|
1024
|
-
}
|
|
1025
|
-
if (sandboxFeatures[key] !== false) {
|
|
1026
|
-
sandboxFeatures[key] = false;
|
|
1027
|
-
changed = true;
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
return changed;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
export function ensureCodexModelInheritance(
|
|
1034
|
-
toolDir: string,
|
|
1035
|
-
hostHomeDir?: string,
|
|
1036
|
-
containerCodexDir: string = '/home/devuser/.codex'
|
|
1037
|
-
): void {
|
|
1038
|
-
if (!hostHomeDir) {
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
const hostConfigPath = path.join(hostHomeDir, '.codex', 'config.toml');
|
|
1043
|
-
if (!fs.existsSync(hostConfigPath)) {
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
let hostParsed: JsonObject;
|
|
1048
|
-
try {
|
|
1049
|
-
hostParsed = toml.parse(fs.readFileSync(hostConfigPath, 'utf8')) as JsonObject;
|
|
1050
|
-
} catch {
|
|
1051
|
-
return;
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
const sandboxConfigPath = path.join(toolDir, 'config.toml');
|
|
1055
|
-
// This rewrites sandbox-side TOML and drops comments; the host config stays untouched.
|
|
1056
|
-
let sandboxParsed: JsonObject = {};
|
|
1057
|
-
if (fs.existsSync(sandboxConfigPath)) {
|
|
1058
|
-
try {
|
|
1059
|
-
sandboxParsed = toml.parse(fs.readFileSync(sandboxConfigPath, 'utf8')) as JsonObject;
|
|
1060
|
-
} catch {
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
let changed = removeCodexMcpServers(sandboxParsed);
|
|
1066
|
-
changed = inheritDisabledCodexFeatureFlags(sandboxParsed, hostParsed) || changed;
|
|
1067
|
-
|
|
1068
|
-
const inheritSpecs: Array<readonly [string, 'string' | 'number']> = [
|
|
1069
|
-
['model', 'string'],
|
|
1070
|
-
['model_reasoning_effort', 'string'],
|
|
1071
|
-
['model_auto_compact_token_limit', 'number']
|
|
1072
|
-
];
|
|
1073
|
-
|
|
1074
|
-
for (const [key, type] of inheritSpecs) {
|
|
1075
|
-
if (Object.hasOwn(sandboxParsed, key)) {
|
|
1076
|
-
continue;
|
|
1077
|
-
}
|
|
1078
|
-
const value = hostParsed[key];
|
|
1079
|
-
if (type === 'string' && (typeof value !== 'string' || value === '')) {
|
|
1080
|
-
continue;
|
|
1081
|
-
}
|
|
1082
|
-
if (type === 'number' && (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)) {
|
|
1083
|
-
continue;
|
|
1084
|
-
}
|
|
1085
|
-
sandboxParsed[key] = value;
|
|
1086
|
-
changed = true;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
if (!Object.hasOwn(sandboxParsed, 'model_catalog_json')) {
|
|
1090
|
-
const hostCatalogPath = resolveHostCatalogPath(hostParsed['model_catalog_json'], hostHomeDir);
|
|
1091
|
-
if (hostCatalogPath) {
|
|
1092
|
-
try {
|
|
1093
|
-
const basename = path.basename(hostCatalogPath);
|
|
1094
|
-
const destDir = path.join(toolDir, 'model-catalogs');
|
|
1095
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
1096
|
-
fs.copyFileSync(hostCatalogPath, path.join(destDir, basename));
|
|
1097
|
-
sandboxParsed['model_catalog_json'] = path.posix.join(containerCodexDir, 'model-catalogs', basename);
|
|
1098
|
-
changed = true;
|
|
1099
|
-
} catch {
|
|
1100
|
-
// Copy failed (e.g. permissions): skip catalog, keep scalar inheritance intact.
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
if (changed) {
|
|
1106
|
-
fs.writeFileSync(sandboxConfigPath, `${toml.stringify(sandboxParsed)}\n`, 'utf8');
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
export function ensureCodexWorkspaceTrust(toolDir: string): void {
|
|
1111
|
-
const configPath = path.join(toolDir, 'config.toml');
|
|
1112
|
-
let content = '';
|
|
1113
|
-
if (fs.existsSync(configPath)) {
|
|
1114
|
-
content = fs.readFileSync(configPath, 'utf8');
|
|
1115
|
-
}
|
|
1116
|
-
if (!content.includes('[projects."/workspace"]')) {
|
|
1117
|
-
const entry = '\n[projects."/workspace"]\ntrust_level = "trusted"\n';
|
|
1118
|
-
fs.writeFileSync(configPath, content + entry, 'utf8');
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
975
|
export function ensureOpenCodeModelInheritance(toolDir: string, hostHomeDir?: string): void {
|
|
1123
976
|
if (!hostHomeDir) {
|
|
1124
977
|
return;
|
|
@@ -1157,22 +1010,6 @@ export function ensureOpenCodeModelInheritance(toolDir: string, hostHomeDir?: st
|
|
|
1157
1010
|
}
|
|
1158
1011
|
}
|
|
1159
1012
|
|
|
1160
|
-
export function ensureGeminiWorkspaceTrust(toolDir: string): void {
|
|
1161
|
-
const trustPath = path.join(toolDir, 'trustedFolders.json');
|
|
1162
|
-
let data: Record<string, string> = {};
|
|
1163
|
-
if (fs.existsSync(trustPath)) {
|
|
1164
|
-
try {
|
|
1165
|
-
data = JSON.parse(fs.readFileSync(trustPath, 'utf8')) as Record<string, string>;
|
|
1166
|
-
} catch {
|
|
1167
|
-
// malformed JSON, start fresh
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
if (data['/workspace'] !== 'TRUST_FOLDER') {
|
|
1171
|
-
data['/workspace'] = 'TRUST_FOLDER';
|
|
1172
|
-
fs.writeFileSync(trustPath, JSON.stringify(data, null, 2), 'utf8');
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
1013
|
export function sandboxAliasesPath(home: string): string {
|
|
1177
1014
|
return hostJoin(home, '.agent-infra', 'aliases', 'sandbox.sh');
|
|
1178
1015
|
}
|
|
@@ -1189,7 +1026,10 @@ function stripManagedSandboxAliasBlocks(content: string): string {
|
|
|
1189
1026
|
return content.replace(blockPattern, '').trimEnd();
|
|
1190
1027
|
}
|
|
1191
1028
|
|
|
1192
|
-
function isLegacyManagedSandboxAliasFile(
|
|
1029
|
+
function isLegacyManagedSandboxAliasFile(
|
|
1030
|
+
content: string,
|
|
1031
|
+
aliases: readonly SandboxAlias[]
|
|
1032
|
+
): boolean {
|
|
1193
1033
|
const lines = content
|
|
1194
1034
|
.split(/\r?\n/)
|
|
1195
1035
|
.map((line) => line.trim())
|
|
@@ -1199,13 +1039,29 @@ function isLegacyManagedSandboxAliasFile(content: string): boolean {
|
|
|
1199
1039
|
return false;
|
|
1200
1040
|
}
|
|
1201
1041
|
|
|
1202
|
-
const aliasPattern = new RegExp(
|
|
1042
|
+
const aliasPattern = new RegExp(
|
|
1043
|
+
`^alias (${aliases.map((alias) => escapeRegExp(alias.name)).join('|')})=`
|
|
1044
|
+
);
|
|
1203
1045
|
return lines.every((line) => aliasPattern.test(line));
|
|
1204
1046
|
}
|
|
1205
1047
|
|
|
1206
|
-
|
|
1048
|
+
function registrySandboxAliases(): readonly SandboxAlias[] {
|
|
1049
|
+
return listAgentClientAdapters().flatMap((adapter) => adapter.sandbox.aliases);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
function renderSandboxAliases(aliases: readonly SandboxAlias[]): string {
|
|
1053
|
+
return `${aliases.map((alias) =>
|
|
1054
|
+
`alias ${alias.name}='${alias.command.replaceAll("'", "'\\''")}'`
|
|
1055
|
+
).join('\n')}\n`;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
export function ensureSandboxAliasesFile(
|
|
1059
|
+
home: string,
|
|
1060
|
+
aliases: readonly SandboxAlias[] = registrySandboxAliases()
|
|
1061
|
+
): { created: boolean; path: string } {
|
|
1207
1062
|
const aliasesPath = sandboxAliasesPath(home);
|
|
1208
|
-
const managedBlock =
|
|
1063
|
+
const managedBlock =
|
|
1064
|
+
`${SANDBOX_ALIAS_BLOCK_BEGIN}\n${renderSandboxAliases(aliases)}${SANDBOX_ALIAS_BLOCK_END}\n`;
|
|
1209
1065
|
fs.mkdirSync(path.dirname(aliasesPath), { recursive: true });
|
|
1210
1066
|
const created = !fs.existsSync(aliasesPath);
|
|
1211
1067
|
let existing = '';
|
|
@@ -1214,7 +1070,7 @@ export function ensureSandboxAliasesFile(home: string): { created: boolean; path
|
|
|
1214
1070
|
existing = fs.readFileSync(aliasesPath, 'utf8');
|
|
1215
1071
|
}
|
|
1216
1072
|
|
|
1217
|
-
const userContent = isLegacyManagedSandboxAliasFile(existing)
|
|
1073
|
+
const userContent = isLegacyManagedSandboxAliasFile(existing, aliases)
|
|
1218
1074
|
? ''
|
|
1219
1075
|
: stripManagedSandboxAliasBlocks(existing);
|
|
1220
1076
|
const nextContent = userContent
|
|
@@ -1355,19 +1211,18 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1355
1211
|
};
|
|
1356
1212
|
const worktreeCandidates = worktreeDirCandidates(effectiveConfig, branch);
|
|
1357
1213
|
assertBranchAvailable(config.repoRoot, branch, { allowedWorktrees: worktreeCandidates });
|
|
1358
|
-
const
|
|
1214
|
+
const capabilityPlan = createSandboxCapabilityPlan(effectiveConfig);
|
|
1215
|
+
const tools = [...capabilityPlan.tools];
|
|
1359
1216
|
const resolvedTools = resolveToolDirs(effectiveConfig, tools, branch);
|
|
1360
1217
|
// Fatal credential states still fail before filesystem/docker side effects.
|
|
1361
|
-
//
|
|
1362
|
-
//
|
|
1218
|
+
// Missing credentials leave the selected Claude Code capability installed
|
|
1219
|
+
// and mounted; only the absent live credential file is omitted.
|
|
1363
1220
|
const credentialOutcome = prepareClaudeCredentials(
|
|
1364
1221
|
effectiveConfig.home,
|
|
1365
1222
|
effectiveConfig.project,
|
|
1366
1223
|
resolvedTools
|
|
1367
1224
|
);
|
|
1368
|
-
const effectiveResolvedTools =
|
|
1369
|
-
? resolvedTools.filter(({ tool }) => tool.id !== 'claude-code')
|
|
1370
|
-
: resolvedTools;
|
|
1225
|
+
const effectiveResolvedTools = resolvedTools;
|
|
1371
1226
|
const container = containerName(effectiveConfig, branch);
|
|
1372
1227
|
const worktree = worktreeCandidates.find((candidate) => fs.existsSync(candidate)) ?? worktreeCandidates[0] ?? '';
|
|
1373
1228
|
const shareCommon = shareCommonDir(effectiveConfig);
|
|
@@ -1392,6 +1247,16 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1392
1247
|
|
|
1393
1248
|
try {
|
|
1394
1249
|
p.log.step('Checking container engine...');
|
|
1250
|
+
const prepareHookResults = await runSandboxHooks({
|
|
1251
|
+
hooks: capabilityPlan.hooksByPhase.prepare,
|
|
1252
|
+
phase: 'prepare',
|
|
1253
|
+
context: { config: effectiveConfig, plan: capabilityPlan },
|
|
1254
|
+
runCommand: runBoundedSandboxHookCommand
|
|
1255
|
+
});
|
|
1256
|
+
const prepareFailure = prepareHookResults.find((result) => result.status === 'fatal');
|
|
1257
|
+
if (prepareFailure) {
|
|
1258
|
+
throw new Error(prepareFailure.message ?? `Sandbox hook '${prepareFailure.hookId}' failed.`);
|
|
1259
|
+
}
|
|
1395
1260
|
await ensureDocker(effectiveConfig, (detail: string) => {
|
|
1396
1261
|
p.log.info(` ${detail}`);
|
|
1397
1262
|
});
|
|
@@ -1476,7 +1341,7 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1476
1341
|
if (fs.readdirSync(worktree).length > 0) {
|
|
1477
1342
|
return `Worktree exists at ${worktree}`;
|
|
1478
1343
|
}
|
|
1479
|
-
|
|
1344
|
+
removeDirRecursive(worktree);
|
|
1480
1345
|
}
|
|
1481
1346
|
|
|
1482
1347
|
const branchExists = runOk('git', [
|
|
@@ -1573,7 +1438,10 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1573
1438
|
}
|
|
1574
1439
|
}
|
|
1575
1440
|
|
|
1576
|
-
const aliasesFile = ensureSandboxAliasesFile(
|
|
1441
|
+
const aliasesFile = ensureSandboxAliasesFile(
|
|
1442
|
+
effectiveConfig.home,
|
|
1443
|
+
capabilityPlan.aliases
|
|
1444
|
+
);
|
|
1577
1445
|
if (aliasesFile.created) {
|
|
1578
1446
|
message(`Created default sandbox aliases at ${aliasesFile.path}`);
|
|
1579
1447
|
}
|
|
@@ -1609,6 +1477,28 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1609
1477
|
let hostShellConfig: HostShellConfig;
|
|
1610
1478
|
let tmpfsSeedPlan: TmpfsSeedPlanEntry[] = [];
|
|
1611
1479
|
try {
|
|
1480
|
+
const beforeCreateResults = await runSandboxHooks({
|
|
1481
|
+
hooks: capabilityPlan.hooksByPhase['before-container-create'],
|
|
1482
|
+
phase: 'before-container-create',
|
|
1483
|
+
context: {
|
|
1484
|
+
config: effectiveConfig,
|
|
1485
|
+
plan: capabilityPlan,
|
|
1486
|
+
create: {
|
|
1487
|
+
hostHome: effectiveConfig.home,
|
|
1488
|
+
resolvedTools: effectiveResolvedTools
|
|
1489
|
+
}
|
|
1490
|
+
},
|
|
1491
|
+
runCommand: runBoundedSandboxHookCommand
|
|
1492
|
+
});
|
|
1493
|
+
const beforeCreateFailure = beforeCreateResults.find(
|
|
1494
|
+
(result) => result.status === 'fatal'
|
|
1495
|
+
);
|
|
1496
|
+
if (beforeCreateFailure) {
|
|
1497
|
+
throw new Error(
|
|
1498
|
+
beforeCreateFailure.message
|
|
1499
|
+
?? `Sandbox hook '${beforeCreateFailure.hookId}' failed.`
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1612
1502
|
const claudeCodeEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'claude-code');
|
|
1613
1503
|
if (claudeCodeEntry) {
|
|
1614
1504
|
ensureClaudeOnboarding(claudeCodeEntry.dir, effectiveConfig.home);
|
|
@@ -1617,15 +1507,6 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1617
1507
|
// provider/API settings are enough for Claude Code. If no usable
|
|
1618
1508
|
// auth was present, the claude-code entry was removed above.
|
|
1619
1509
|
}
|
|
1620
|
-
const codexEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'codex');
|
|
1621
|
-
if (codexEntry) {
|
|
1622
|
-
ensureCodexModelInheritance(codexEntry.dir, effectiveConfig.home, codexEntry.tool.containerMount);
|
|
1623
|
-
ensureCodexWorkspaceTrust(codexEntry.dir);
|
|
1624
|
-
}
|
|
1625
|
-
const geminiEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'gemini-cli');
|
|
1626
|
-
if (geminiEntry) {
|
|
1627
|
-
ensureGeminiWorkspaceTrust(geminiEntry.dir);
|
|
1628
|
-
}
|
|
1629
1510
|
const opencodeEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'opencode');
|
|
1630
1511
|
if (opencodeEntry) {
|
|
1631
1512
|
// The TUI reads <toolDir>/opencode.json via OPENCODE_CONFIG pinned in tools.js.
|
|
@@ -1709,6 +1590,8 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1709
1590
|
sandboxLabel(effectiveConfig),
|
|
1710
1591
|
'--label',
|
|
1711
1592
|
`${sandboxBranchLabel(effectiveConfig)}=${branch}`,
|
|
1593
|
+
'--label',
|
|
1594
|
+
`${sandboxRuntimeCapabilityLabel(effectiveConfig)}=${capabilityPlan.runtimeSignature}`,
|
|
1712
1595
|
...coreVolumes,
|
|
1713
1596
|
...buildClipboardVolumeArgs(engine, effectiveConfig.home),
|
|
1714
1597
|
'-v',
|
|
@@ -1805,6 +1688,22 @@ export async function create(args: string[]): Promise<void> {
|
|
|
1805
1688
|
}
|
|
1806
1689
|
}
|
|
1807
1690
|
|
|
1691
|
+
const afterStartResults = await runSandboxHooks({
|
|
1692
|
+
hooks: capabilityPlan.hooksByPhase['after-container-start'],
|
|
1693
|
+
phase: 'after-container-start',
|
|
1694
|
+
context: { config: effectiveConfig, plan: capabilityPlan },
|
|
1695
|
+
runCommand: runBoundedSandboxHookCommand
|
|
1696
|
+
});
|
|
1697
|
+
const afterStartFailure = afterStartResults.find(
|
|
1698
|
+
(result) => result.status === 'fatal'
|
|
1699
|
+
);
|
|
1700
|
+
if (afterStartFailure) {
|
|
1701
|
+
throw new Error(
|
|
1702
|
+
afterStartFailure.message
|
|
1703
|
+
?? `Sandbox hook '${afterStartFailure.hookId}' failed.`
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1808
1707
|
return 'Container started';
|
|
1809
1708
|
}
|
|
1810
1709
|
}
|
|
@@ -7,6 +7,11 @@ import {
|
|
|
7
7
|
} from '../constants.ts';
|
|
8
8
|
import { detectEngine } from '../engine.ts';
|
|
9
9
|
import { ensureSandboxReady } from '../recovery.ts';
|
|
10
|
+
import {
|
|
11
|
+
createSandboxCapabilityPlan,
|
|
12
|
+
runBoundedSandboxHookCommand,
|
|
13
|
+
runSandboxHooks
|
|
14
|
+
} from '../agent-client-reconciler.ts';
|
|
10
15
|
import {
|
|
11
16
|
formatCredentialWarnings,
|
|
12
17
|
formatRemaining,
|
|
@@ -186,8 +191,25 @@ export async function enter(args: string[]): Promise<number> {
|
|
|
186
191
|
});
|
|
187
192
|
const container = ready.container;
|
|
188
193
|
const cmd = parsed.command;
|
|
194
|
+
const capabilityPlan = createSandboxCapabilityPlan(config);
|
|
195
|
+
const enterHookResults = await runSandboxHooks({
|
|
196
|
+
hooks: capabilityPlan.hooksByPhase['before-enter'],
|
|
197
|
+
phase: 'before-enter',
|
|
198
|
+
context: { config, plan: capabilityPlan },
|
|
199
|
+
runCommand: runBoundedSandboxHookCommand
|
|
200
|
+
});
|
|
201
|
+
for (const result of enterHookResults) {
|
|
202
|
+
if (result.status === 'fatal') {
|
|
203
|
+
throw new Error(result.message ?? `Sandbox hook '${result.hookId}' failed.`);
|
|
204
|
+
}
|
|
205
|
+
if (result.status === 'warning') {
|
|
206
|
+
process.stderr.write(
|
|
207
|
+
`Warning: ${result.message ?? `Sandbox hook '${result.hookId}' did not complete.`}\n`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
189
211
|
|
|
190
|
-
if (
|
|
212
|
+
if (capabilityPlan.selectedAgentClients.some((adapter) => adapter.id === 'claude-code')) {
|
|
191
213
|
try {
|
|
192
214
|
// Scan all projects so a refresh from a neighbouring sandbox can still flow back to the host.
|
|
193
215
|
const providerAuthAvailable = hasClaudeProviderAuth(config.home);
|
|
@@ -11,7 +11,7 @@ import { hostJoin } from '../engines/wsl2-paths.ts';
|
|
|
11
11
|
import { removeManagedDir, removeWorktreeDir } from '../managed-fs.ts';
|
|
12
12
|
import { parseLabels } from './ls.ts';
|
|
13
13
|
import { runEngine, runSafe } from '../shell.ts';
|
|
14
|
-
import {
|
|
14
|
+
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.ts';
|
|
15
15
|
import type { SandboxTool } from '../tools.ts';
|
|
16
16
|
|
|
17
17
|
const USAGE = `Usage: ai sandbox prune [--dry-run]`;
|
|
@@ -158,7 +158,7 @@ export async function prune(args: string[]): Promise<void> {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
const config = loadConfig();
|
|
161
|
-
const tools =
|
|
161
|
+
const tools = [...createSandboxCapabilityPlan(config).cleanupInventory];
|
|
162
162
|
const engine = detectEngine(config);
|
|
163
163
|
const psArgs = [
|
|
164
164
|
'ps',
|
|
@@ -19,7 +19,8 @@ import { pruneSandboxDanglingImages } from '../image-prune.ts';
|
|
|
19
19
|
import { removeManagedDir, removeWorktreeDir } from '../managed-fs.ts';
|
|
20
20
|
import { runOk, runSafe, runSafeEngine } from '../shell.ts';
|
|
21
21
|
import { resolveTaskBranch } from '../task-resolver.ts';
|
|
22
|
-
import {
|
|
22
|
+
import { toolConfigDirCandidates, toolProjectDirCandidates } from '../tools.ts';
|
|
23
|
+
import { createSandboxCapabilityPlan } from '../agent-client-reconciler.ts';
|
|
23
24
|
import type { SandboxTool } from '../tools.ts';
|
|
24
25
|
import { fetchSandboxRows } from './list-running.ts';
|
|
25
26
|
import { lookupShortIdByBranch } from '../../task/short-id.ts';
|
|
@@ -353,7 +354,7 @@ export async function rm(args: string[]): Promise<void> {
|
|
|
353
354
|
}
|
|
354
355
|
|
|
355
356
|
const config = loadConfig();
|
|
356
|
-
const tools =
|
|
357
|
+
const tools = [...createSandboxCapabilityPlan(config).cleanupInventory];
|
|
357
358
|
|
|
358
359
|
if (values.purge) {
|
|
359
360
|
await rmPurge(config, tools);
|
|
@@ -10,7 +10,7 @@ import { resolveTools, toolConfigDirCandidates } from '../tools.ts';
|
|
|
10
10
|
const USAGE = `Usage: ai sandbox show <branch | TASK-id | N>
|
|
11
11
|
|
|
12
12
|
Shows one sandbox's worktree path and per-tool state paths (Claude Code,
|
|
13
|
-
Codex,
|
|
13
|
+
Codex, Antigravity CLI, OpenCode). The argument follows the same contract as
|
|
14
14
|
'ai sandbox exec' and 'ai sandbox start': N (bare) is the recommended form
|
|
15
15
|
for task short ids (e.g. 'ai sandbox show 11'); a TASK-id or a plain
|
|
16
16
|
branch name are also accepted. Use 'ai sandbox ls' for the container list.`;
|
package/lib/sandbox/config.ts
CHANGED
|
@@ -3,6 +3,9 @@ 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.ts';
|
|
7
|
+
import { isAgentClientId } from '../agent-clients/types.ts';
|
|
8
|
+
import type { AgentClientState } from '../agent-clients/types.ts';
|
|
6
9
|
import { validateSandboxEngine } from './engine.ts';
|
|
7
10
|
import { hostJoin } from './engines/wsl2-paths.ts';
|
|
8
11
|
import { findRuntimeEngineMismatches } from './runtime-engines.ts';
|
|
@@ -12,7 +15,7 @@ import type { SandboxTool } from './tools.ts';
|
|
|
12
15
|
const DEFAULTS = Object.freeze({
|
|
13
16
|
engine: null,
|
|
14
17
|
runtimes: ['node22'],
|
|
15
|
-
tools: ['agent-infra'
|
|
18
|
+
tools: ['agent-infra'],
|
|
16
19
|
refreshIntervalDays: 7,
|
|
17
20
|
dockerfile: null,
|
|
18
21
|
vm: {
|
|
@@ -57,6 +60,8 @@ export type SandboxConfig = {
|
|
|
57
60
|
runtimes: string[];
|
|
58
61
|
tools: string[];
|
|
59
62
|
customTools: SandboxTool[];
|
|
63
|
+
agentClientState: AgentClientState;
|
|
64
|
+
agentClientSource: 'canonical' | 'legacy';
|
|
60
65
|
refreshIntervalDays: number;
|
|
61
66
|
dockerfile: string | null;
|
|
62
67
|
vm: SandboxVmConfig;
|
|
@@ -65,6 +70,8 @@ export type SandboxConfig = {
|
|
|
65
70
|
type AircConfig = {
|
|
66
71
|
project?: unknown;
|
|
67
72
|
org?: unknown;
|
|
73
|
+
agentClients?: unknown;
|
|
74
|
+
tuis?: unknown;
|
|
68
75
|
sandbox?: SandboxConfigInput;
|
|
69
76
|
};
|
|
70
77
|
|
|
@@ -98,6 +105,23 @@ function cloneDefaults(): SandboxConfigInput & { vm: SandboxVmConfig; runtimes:
|
|
|
98
105
|
};
|
|
99
106
|
}
|
|
100
107
|
|
|
108
|
+
function resolveSandboxToolIds(
|
|
109
|
+
sandbox: SandboxConfigInput,
|
|
110
|
+
agentClients: ReturnType<typeof normalizeAgentClients>,
|
|
111
|
+
defaults: readonly string[]
|
|
112
|
+
): string[] {
|
|
113
|
+
if (Array.isArray(sandbox.tools)) {
|
|
114
|
+
const tools = sandbox.tools.filter((tool): tool is string => typeof tool === 'string');
|
|
115
|
+
return agentClients.source === 'canonical'
|
|
116
|
+
? tools.filter((tool) => !isAgentClientId(tool))
|
|
117
|
+
: tools;
|
|
118
|
+
}
|
|
119
|
+
if (agentClients.remainingSandboxTools !== undefined) {
|
|
120
|
+
return [...agentClients.remainingSandboxTools];
|
|
121
|
+
}
|
|
122
|
+
return [...defaults];
|
|
123
|
+
}
|
|
124
|
+
|
|
101
125
|
export function loadConfig({
|
|
102
126
|
platformFn = platform,
|
|
103
127
|
writeStderr = (chunk) => process.stderr.write(chunk)
|
|
@@ -115,6 +139,8 @@ export function loadConfig({
|
|
|
115
139
|
}
|
|
116
140
|
|
|
117
141
|
const airc = JSON.parse(fs.readFileSync(configPath, 'utf8')) as AircConfig;
|
|
142
|
+
const sandboxInput = airc.sandbox;
|
|
143
|
+
const agentClients = normalizeAgentClients(airc);
|
|
118
144
|
const defaults = cloneDefaults();
|
|
119
145
|
const sandbox = airc.sandbox ?? {};
|
|
120
146
|
const engine = validateSandboxEngine(sandbox.engine ?? defaults.engine, { platformFn });
|
|
@@ -149,6 +175,7 @@ export function loadConfig({
|
|
|
149
175
|
}
|
|
150
176
|
|
|
151
177
|
const customTools = parseCustomTools(sandbox.customTools, { home });
|
|
178
|
+
const tools = resolveSandboxToolIds(sandbox, agentClients, defaults.tools);
|
|
152
179
|
|
|
153
180
|
return {
|
|
154
181
|
repoRoot,
|
|
@@ -164,10 +191,10 @@ export function loadConfig({
|
|
|
164
191
|
dotfilesDir: hostJoin(home, '.agent-infra', 'dotfiles'),
|
|
165
192
|
engine,
|
|
166
193
|
runtimes,
|
|
167
|
-
tools
|
|
168
|
-
? [...sandbox.tools]
|
|
169
|
-
: defaults.tools,
|
|
194
|
+
tools,
|
|
170
195
|
customTools,
|
|
196
|
+
agentClientState: agentClients.state,
|
|
197
|
+
agentClientSource: agentClients.source,
|
|
171
198
|
refreshIntervalDays: asNonNegativeIntegerOrDefault(
|
|
172
199
|
sandbox.refreshIntervalDays,
|
|
173
200
|
defaults.refreshIntervalDays
|
package/lib/sandbox/constants.ts
CHANGED
|
@@ -111,6 +111,12 @@ export function sandboxImageRefreshLabel(config: Pick<SandboxPathConfig, 'projec
|
|
|
111
111
|
return `${sandboxLabel(config)}.last-refresh`;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
export function sandboxRuntimeCapabilityLabel(
|
|
115
|
+
config: Pick<SandboxPathConfig, 'project'>
|
|
116
|
+
): string {
|
|
117
|
+
return `agent-infra.sandbox.runtime-capability.${config.project}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
114
120
|
export function parsePositiveIntegerOption(value: unknown, optionName: string): number | undefined {
|
|
115
121
|
if (value === undefined || value === null) {
|
|
116
122
|
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.ts';
|
|
6
7
|
|
|
7
8
|
const RUNTIMES_DIR = path.join(
|
|
8
9
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
@@ -88,7 +89,7 @@ export function prepareDockerfile(config: DockerfileConfig): { path: string; sig
|
|
|
88
89
|
path: tempPath,
|
|
89
90
|
signature: dockerfileSignature(config),
|
|
90
91
|
cleanup() {
|
|
91
|
-
|
|
92
|
+
removeDirRecursive(tempDir);
|
|
92
93
|
}
|
|
93
94
|
};
|
|
94
95
|
}
|