@fitlab-ai/agent-infra 0.9.12 → 0.9.14
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 +11 -11
- package/README.zh-CN.md +11 -11
- package/bin/cli.ts +26 -9
- package/dist/bin/cli.js +173 -157
- package/dist/bin/internal-cli.js +66 -40
- package/dist/lib/agent-client.js +5 -0
- package/dist/lib/agent-clients/next-steps.js +6 -1
- package/dist/lib/decide.js +3 -3
- package/dist/lib/internal/agent-client.js +5 -2
- package/dist/lib/internal/cli-route-inventory.js +152 -0
- package/dist/lib/internal/codex-lifecycle.js +9 -6
- package/dist/lib/internal/codex-sandbox-controller.js +8 -2
- package/dist/lib/internal/git-workflow.js +10 -6
- package/dist/lib/internal/platform-checks.js +19 -7
- package/dist/lib/internal/platform-comment.js +25 -13
- package/dist/lib/internal/platform-context.js +6 -3
- package/dist/lib/internal/platform-issue.js +20 -13
- package/dist/lib/internal/platform-metadata.js +88 -0
- package/dist/lib/internal/platform-pr-review.js +26 -13
- package/dist/lib/internal/platform-pr.js +84 -31
- package/dist/lib/internal/platform-release-notes.js +9 -6
- package/dist/lib/internal/platform-security.js +93 -0
- package/dist/lib/internal/pr-review-grade.js +25 -12
- package/dist/lib/internal/release-workflow.js +23 -9
- package/dist/lib/internal/sandbox-control.js +50 -7
- package/dist/lib/internal/task-activity.js +16 -7
- package/dist/lib/internal/task-artifact.js +235 -24
- package/dist/lib/internal/task-context.js +4 -1
- package/dist/lib/internal/task-create.js +50 -17
- package/dist/lib/internal/task-delivery.js +4 -1
- package/dist/lib/internal/task-event.js +10 -4
- package/dist/lib/internal/task-finalization.js +6 -3
- package/dist/lib/internal/task-invalidation.js +63 -0
- package/dist/lib/internal/task-ledger.js +20 -6
- package/dist/lib/internal/task-lifecycle.js +6 -3
- package/dist/lib/internal/task-operation-registry.js +421 -0
- package/dist/lib/internal/task-orchestration.js +12 -0
- package/dist/lib/internal/task-override.js +14 -7
- package/dist/lib/internal/task-qualification.js +90 -0
- package/dist/lib/internal/task-review.js +7 -4
- package/dist/lib/internal/task-short-id.js +11 -1
- package/dist/lib/internal/task-snapshot.js +4 -1
- package/dist/lib/internal/task-validate.js +7 -2
- package/dist/lib/internal/task-verify.js +11 -7
- package/dist/lib/internal/task-warning.js +11 -4
- package/dist/lib/platform/adapters.js +1 -3
- package/dist/lib/platform/change-request-git-evidence.js +27 -7
- package/dist/lib/platform/comment-safety.js +226 -0
- package/dist/lib/platform/completion-backfill.js +6 -5
- package/dist/lib/platform/context.js +70 -130
- package/dist/lib/platform/github-client.js +1 -1
- package/dist/lib/platform/github-provider.js +1130 -0
- package/dist/lib/platform/in-label-sync.js +143 -0
- package/dist/lib/platform/issue-comments.js +237 -72
- package/dist/lib/platform/issues.js +335 -189
- package/dist/lib/platform/metadata-labels.js +6 -2
- package/dist/lib/platform/none-provider.js +28 -0
- package/dist/lib/platform/pr-change-report.js +545 -0
- package/dist/lib/platform/pr-checks.js +119 -104
- package/dist/lib/platform/pr-review.js +88 -72
- package/dist/lib/platform/pr-summary.js +541 -50
- package/dist/lib/platform/provider-bridge.js +45 -0
- package/dist/lib/platform/provider-contract.d.ts +553 -0
- package/dist/lib/platform/provider-contract.js +99 -0
- package/dist/lib/platform/provider-loader.js +251 -0
- package/dist/lib/platform/provider-validation.js +577 -0
- package/dist/lib/platform/pull-request-metadata.js +8 -6
- package/dist/lib/platform/pull-requests.js +734 -543
- package/dist/lib/platform/release-notes.js +78 -55
- package/dist/lib/platform/releases.js +79 -50
- package/dist/lib/platform/repository-metadata.js +377 -0
- package/dist/lib/platform/resource-identity.d.ts +26 -0
- package/dist/lib/platform/resource-identity.js +92 -0
- package/dist/lib/platform/security-alerts.js +155 -0
- package/dist/lib/platform/task-identities.js +31 -0
- package/dist/lib/platform/verification-required.js +11 -12
- package/dist/lib/platform/verification-sync.js +129 -248
- package/dist/lib/pr-review/evidence-grading.js +19 -6
- package/dist/lib/process-data/index.js +7 -0
- package/dist/lib/run/index.js +68 -23
- package/dist/lib/sandbox/commands/control-status.js +22 -0
- package/dist/lib/sandbox/commands/create.js +32 -6
- package/dist/lib/sandbox/commands/ls.js +5 -0
- package/dist/lib/sandbox/commands/rm.js +827 -120
- package/dist/lib/sandbox/commands/show.js +16 -0
- package/dist/lib/sandbox/control/client.js +174 -19
- package/dist/lib/sandbox/control/completed-reentry.js +85 -0
- package/dist/lib/sandbox/control/container-identity.js +28 -31
- package/dist/lib/sandbox/control/executor.js +151 -16
- package/dist/lib/sandbox/control/lifecycle.js +621 -127
- package/dist/lib/sandbox/control/native-file-lock.js +177 -0
- package/dist/lib/sandbox/control/protocol.js +77 -0
- package/dist/lib/sandbox/control/server.js +677 -34
- package/dist/lib/sandbox/control/state.js +209 -4
- package/dist/lib/sandbox/control/task-view.js +183 -0
- package/dist/lib/sandbox/engines/authority.js +289 -0
- package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
- package/dist/lib/sandbox/index.js +5 -0
- package/dist/lib/sandbox/recovery.js +21 -1
- package/dist/lib/sandbox/workspace-view.js +2 -1
- package/dist/lib/sandbox/worktree-safety.js +4 -1
- package/dist/lib/server/index.js +8 -0
- package/dist/lib/server/protocol.js +38 -1
- package/dist/lib/task/activity-log.js +8 -1
- package/dist/lib/task/artifact-lifecycle.js +75 -18
- package/dist/lib/task/artifact-operations.js +520 -0
- package/dist/lib/task/artifact-repair-intent.js +59 -0
- package/dist/lib/task/artifact-schema.js +135 -0
- package/dist/lib/task/capabilities.js +310 -0
- package/dist/lib/task/commands/status.js +32 -0
- package/dist/lib/task/commit-operation.js +12 -1
- package/dist/lib/task/control-authority.js +12 -5
- package/dist/lib/task/create-service.js +111 -12
- package/dist/lib/task/create.js +25 -0
- package/dist/lib/task/current-contract.js +5 -1
- package/dist/lib/task/decision-details.js +1 -1
- package/dist/lib/task/events.js +416 -17
- package/dist/lib/task/finalization.js +37 -13
- package/dist/lib/task/human-override.js +58 -36
- package/dist/lib/task/index.js +11 -3
- package/dist/lib/task/invalidation-command.js +86 -0
- package/dist/lib/task/invalidation.js +260 -0
- package/dist/lib/task/ledger-intents.js +37 -0
- package/dist/lib/task/local-artifact-finalization.js +299 -0
- package/dist/lib/task/orchestration.js +240 -144
- package/dist/lib/task/pr-delivery-fact.js +102 -101
- package/dist/lib/task/qualification-audit.js +490 -0
- package/dist/lib/task/qualification-confirmation.js +109 -0
- package/dist/lib/task/qualification-intents.js +148 -0
- package/dist/lib/task/review-artifacts.js +22 -23
- package/dist/lib/task/review-finalization.js +121 -4
- package/dist/lib/task/review-fingerprint.js +24 -2
- package/dist/lib/task/rework-intent.js +138 -0
- package/dist/lib/task/sections.js +6 -4
- package/dist/lib/task/skill-scope.js +23 -0
- package/dist/lib/task/task-execution-lock.js +27 -17
- package/dist/lib/task/verification-config.js +11 -0
- package/dist/lib/task/verification-engine.js +93 -16
- package/dist/lib/task/verification.js +3 -3
- package/dist/lib/task/workflow-warning-intents.js +1 -1
- package/dist/lib/task/write.js +11 -0
- package/dist/lib/version.js +11 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-client.ts +9 -0
- package/lib/agent-clients/next-steps.ts +6 -1
- package/lib/decide.ts +3 -3
- package/lib/init.ts +1 -1
- package/lib/internal/agent-client.ts +4 -2
- package/lib/internal/cli-route-inventory.ts +140 -0
- package/lib/internal/codex-lifecycle.ts +8 -6
- package/lib/internal/codex-sandbox-controller.ts +7 -2
- package/lib/internal/git-workflow.ts +9 -6
- package/lib/internal/platform-checks.ts +14 -6
- package/lib/internal/platform-comment.ts +20 -12
- package/lib/internal/platform-context.ts +5 -3
- package/lib/internal/platform-issue.ts +17 -11
- package/lib/internal/platform-metadata.ts +70 -0
- package/lib/internal/platform-pr-review.ts +23 -12
- package/lib/internal/platform-pr.ts +65 -27
- package/lib/internal/platform-release-notes.ts +8 -6
- package/lib/internal/platform-security.ts +83 -0
- package/lib/internal/pr-review-grade.ts +20 -11
- package/lib/internal/release-workflow.ts +21 -9
- package/lib/internal/sandbox-control.ts +44 -6
- package/lib/internal/task-activity.ts +15 -7
- package/lib/internal/task-artifact.ts +204 -22
- package/lib/internal/task-context.ts +3 -1
- package/lib/internal/task-create.ts +78 -17
- package/lib/internal/task-delivery.ts +3 -1
- package/lib/internal/task-event.ts +9 -4
- package/lib/internal/task-finalization.ts +6 -4
- package/lib/internal/task-invalidation.ts +41 -0
- package/lib/internal/task-ledger.ts +21 -8
- package/lib/internal/task-lifecycle.ts +5 -3
- package/lib/internal/task-operation-registry.ts +482 -0
- package/lib/internal/task-orchestration.ts +12 -0
- package/lib/internal/task-override.ts +15 -9
- package/lib/internal/task-qualification.ts +61 -0
- package/lib/internal/task-review.ts +6 -4
- package/lib/internal/task-short-id.ts +10 -1
- package/lib/internal/task-snapshot.ts +3 -1
- package/lib/internal/task-validate.ts +6 -2
- package/lib/internal/task-verify.ts +10 -7
- package/lib/internal/task-warning.ts +10 -4
- package/lib/platform/adapters.ts +3 -2
- package/lib/platform/change-request-git-evidence.ts +36 -9
- package/lib/platform/comment-safety.ts +250 -0
- package/lib/platform/completion-backfill.ts +9 -8
- package/lib/platform/context.ts +97 -134
- package/lib/platform/github-client.ts +2 -2
- package/lib/platform/github-provider.ts +1132 -0
- package/lib/platform/in-label-sync.ts +208 -0
- package/lib/platform/issue-comments.ts +255 -80
- package/lib/platform/issues.ts +344 -174
- package/lib/platform/metadata-labels.ts +5 -2
- package/lib/platform/none-provider.ts +35 -0
- package/lib/platform/pr-change-report.ts +639 -0
- package/lib/platform/pr-checks.ts +126 -106
- package/lib/platform/pr-review.ts +88 -85
- package/lib/platform/pr-summary.ts +581 -53
- package/lib/platform/provider-bridge.ts +82 -0
- package/lib/platform/provider-contract.ts +611 -0
- package/lib/platform/provider-loader.ts +307 -0
- package/lib/platform/provider-validation.ts +611 -0
- package/lib/platform/pull-request-metadata.ts +10 -7
- package/lib/platform/pull-requests.ts +781 -550
- package/lib/platform/release-notes.ts +76 -59
- package/lib/platform/releases.ts +77 -43
- package/lib/platform/repository-metadata.ts +453 -0
- package/lib/platform/resource-identity.ts +121 -0
- package/lib/platform/security-alerts.ts +191 -0
- package/lib/platform/task-identities.ts +40 -0
- package/lib/platform/types.ts +4 -2
- package/lib/platform/verification-required.ts +11 -13
- package/lib/platform/verification-sync.ts +128 -304
- package/lib/pr-review/evidence-grading.ts +25 -8
- package/lib/process-data/index.ts +7 -0
- package/lib/run/index.ts +62 -22
- package/lib/sandbox/commands/control-status.ts +26 -0
- package/lib/sandbox/commands/create.ts +46 -6
- package/lib/sandbox/commands/ls.ts +7 -0
- package/lib/sandbox/commands/rm.ts +1000 -87
- package/lib/sandbox/commands/show.ts +16 -0
- package/lib/sandbox/control/client.ts +203 -19
- package/lib/sandbox/control/completed-reentry.ts +98 -0
- package/lib/sandbox/control/container-identity.ts +27 -43
- package/lib/sandbox/control/executor.ts +180 -15
- package/lib/sandbox/control/lifecycle.ts +629 -17
- package/lib/sandbox/control/native-file-lock.ts +209 -0
- package/lib/sandbox/control/protocol.ts +118 -2
- package/lib/sandbox/control/server.ts +724 -34
- package/lib/sandbox/control/state.ts +257 -4
- package/lib/sandbox/control/task-view.ts +240 -0
- package/lib/sandbox/engines/authority.ts +365 -0
- package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
- package/lib/sandbox/index.ts +7 -0
- package/lib/sandbox/recovery.ts +21 -1
- package/lib/sandbox/workspace-view.ts +9 -3
- package/lib/sandbox/worktree-safety.ts +4 -1
- package/lib/server/index.ts +10 -0
- package/lib/server/protocol.ts +36 -1
- package/lib/task/activity-log.ts +8 -0
- package/lib/task/artifact-lifecycle.ts +70 -22
- package/lib/task/artifact-operations.ts +626 -0
- package/lib/task/artifact-repair-intent.ts +71 -0
- package/lib/task/artifact-schema.ts +192 -0
- package/lib/task/capabilities.ts +331 -0
- package/lib/task/commands/status.ts +38 -0
- package/lib/task/commit-operation.ts +12 -1
- package/lib/task/control-authority.ts +22 -9
- package/lib/task/create-service.ts +139 -14
- package/lib/task/create.ts +27 -0
- package/lib/task/current-contract.ts +6 -1
- package/lib/task/decision-details.ts +6 -2
- package/lib/task/events.ts +392 -16
- package/lib/task/finalization.ts +50 -14
- package/lib/task/human-override.ts +70 -46
- package/lib/task/index.ts +16 -3
- package/lib/task/invalidation-command.ts +86 -0
- package/lib/task/invalidation.ts +332 -0
- package/lib/task/ledger-intents.ts +35 -1
- package/lib/task/local-artifact-finalization.ts +432 -0
- package/lib/task/orchestration.ts +223 -133
- package/lib/task/pr-delivery-fact.ts +131 -148
- package/lib/task/qualification-audit.ts +599 -0
- package/lib/task/qualification-confirmation.ts +117 -0
- package/lib/task/qualification-intents.ts +150 -0
- package/lib/task/review-artifacts.ts +21 -22
- package/lib/task/review-finalization.ts +133 -4
- package/lib/task/review-fingerprint.ts +23 -2
- package/lib/task/rework-intent.ts +165 -0
- package/lib/task/sections.ts +6 -4
- package/lib/task/skill-scope.ts +24 -0
- package/lib/task/task-execution-lock.ts +23 -14
- package/lib/task/verification-config.ts +12 -0
- package/lib/task/verification-engine.ts +103 -17
- package/lib/task/verification.ts +4 -4
- package/lib/task/workflow-warning-intents.ts +1 -1
- package/lib/task/write.ts +19 -0
- package/lib/update.ts +1 -1
- package/lib/version.ts +15 -1
- package/package.json +12 -1
- package/templates/.agents/rules/README.en.md +3 -1
- package/templates/.agents/rules/README.zh-CN.md +3 -1
- package/templates/.agents/rules/decision-qualification.en.md +22 -0
- package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
- package/templates/.agents/rules/evidence-reporting.en.md +28 -0
- package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
- package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +2 -0
- package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
- package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
- package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
- package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
- package/templates/.agents/rules/pr-sync.en.md +10 -4
- package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
- package/templates/.agents/rules/security-alerts.en.md +8 -8
- package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
- package/templates/.agents/rules/task-short-id.en.md +1 -4
- package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
- package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
- package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
- package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
- package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
- package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
- package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
- package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
- package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
- package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
- package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
- package/templates/.agents/skills/create-pr/config/verify.json +1 -0
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
- package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
- package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
- package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
- package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
- package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
- package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
- package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
- package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
- package/templates/.agents/skills/test/SKILL.en.md +13 -2
- package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
- package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
- package/templates/.agents/templates/task.en.md +24 -1
- package/templates/.agents/templates/task.zh-CN.md +24 -1
- package/templates/.github/workflows/pr-label.yml +7 -26
- package/templates/.agents/scripts/security-alerts.github.sh +0 -151
- package/templates/.agents/scripts/security-alerts.sh +0 -31
- package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
- package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
- package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { runProbe } from '../shell.js';
|
|
3
|
+
import { getAdapter } from './index.js';
|
|
4
|
+
function digest(value) {
|
|
5
|
+
return createHash('sha256').update(value).digest('hex');
|
|
6
|
+
}
|
|
7
|
+
function canonical(value) {
|
|
8
|
+
if (Array.isArray(value))
|
|
9
|
+
return `[${value.map(canonical).join(',')}]`;
|
|
10
|
+
if (!value || typeof value !== 'object')
|
|
11
|
+
return JSON.stringify(value) ?? 'null';
|
|
12
|
+
return `{${Object.entries(value)
|
|
13
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
14
|
+
.map(([key, entry]) => `${JSON.stringify(key)}:${canonical(entry)}`)
|
|
15
|
+
.join(',')}}`;
|
|
16
|
+
}
|
|
17
|
+
function text(value) {
|
|
18
|
+
return typeof value === 'string' ? value : value?.toString('utf8') ?? '';
|
|
19
|
+
}
|
|
20
|
+
function safeEndpoint(value) {
|
|
21
|
+
if (!value)
|
|
22
|
+
return 'docker-default';
|
|
23
|
+
try {
|
|
24
|
+
const parsed = new URL(value);
|
|
25
|
+
const hasUnreplayableParts = Boolean(parsed.username || parsed.password || parsed.search || parsed.hash);
|
|
26
|
+
parsed.username = '';
|
|
27
|
+
parsed.password = '';
|
|
28
|
+
parsed.search = '';
|
|
29
|
+
parsed.hash = '';
|
|
30
|
+
const normalized = parsed.toString().replace(/\/$/u, '');
|
|
31
|
+
return hasUnreplayableParts
|
|
32
|
+
? `${normalized}#<redacted>`
|
|
33
|
+
: normalized;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
const normalized = value
|
|
37
|
+
.replace(/\/\/[^/@]+@/u, '//<redacted>@')
|
|
38
|
+
.replace(/[?&](?:token|password|secret|key)=[^&]*/giu, '');
|
|
39
|
+
return /[@?#]/u.test(value) ? `${normalized.replace(/[?#].*$/u, '')}#<redacted>` : normalized;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function lockDomainFor(engine, endpoint) {
|
|
43
|
+
return digest(`${process.platform}\0${process.arch}\0${engine}\0${endpoint}`);
|
|
44
|
+
}
|
|
45
|
+
function contextRoute(context) {
|
|
46
|
+
return {
|
|
47
|
+
kind: 'context',
|
|
48
|
+
selector: { context },
|
|
49
|
+
endpoint: `docker-context://${context}`,
|
|
50
|
+
command: (args) => ({ cmd: 'docker', args: ['--context', context, ...args] })
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function endpointRoute(endpoint, rawEndpoint, unreplayable) {
|
|
54
|
+
return {
|
|
55
|
+
kind: 'endpoint',
|
|
56
|
+
selector: {
|
|
57
|
+
source: 'DOCKER_HOST',
|
|
58
|
+
endpoint,
|
|
59
|
+
...(unreplayable ? { unreplayable } : {})
|
|
60
|
+
},
|
|
61
|
+
endpoint,
|
|
62
|
+
command: (args) => ({ cmd: 'docker', args: ['--host', rawEndpoint, ...args] })
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function tlsEnvironmentReason(env) {
|
|
66
|
+
return env.DOCKER_TLS_VERIFY || env.DOCKER_CERT_PATH || env.DOCKER_TLS
|
|
67
|
+
? 'tls-environment'
|
|
68
|
+
: undefined;
|
|
69
|
+
}
|
|
70
|
+
function routeFor(engine, env) {
|
|
71
|
+
const context = getAdapter(engine).dockerContext;
|
|
72
|
+
if (context) {
|
|
73
|
+
return contextRoute(context);
|
|
74
|
+
}
|
|
75
|
+
if (env.DOCKER_CONTEXT) {
|
|
76
|
+
return contextRoute(env.DOCKER_CONTEXT);
|
|
77
|
+
}
|
|
78
|
+
if (env.DOCKER_HOST) {
|
|
79
|
+
return endpointRoute(safeEndpoint(env.DOCKER_HOST), env.DOCKER_HOST, tlsEnvironmentReason(env));
|
|
80
|
+
}
|
|
81
|
+
return contextRoute('default');
|
|
82
|
+
}
|
|
83
|
+
function validRouteName(value) {
|
|
84
|
+
return /^[A-Za-z0-9][A-Za-z0-9_.@/-]*$/u.test(value);
|
|
85
|
+
}
|
|
86
|
+
function resolveWslDistro(probe, timeoutMs, explicit) {
|
|
87
|
+
if (explicit) {
|
|
88
|
+
if (!validRouteName(explicit))
|
|
89
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
|
|
90
|
+
return explicit;
|
|
91
|
+
}
|
|
92
|
+
const result = probe('wsl.exe', ['--list', '--verbose'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
|
|
93
|
+
if (result.status !== 0)
|
|
94
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
|
|
95
|
+
const output = text(result.stdout).replace(/\0/gu, '').replace(/\r/gu, '');
|
|
96
|
+
const defaultLine = output.split('\n').find((line) => /^\s*\*\s+/u.test(line));
|
|
97
|
+
const distro = defaultLine?.replace(/^\s*\*\s+/u, '').replace(/\s+(?:Running|Stopped)\s+\d+\s*$/iu, '').trim();
|
|
98
|
+
if (!distro || !validRouteName(distro))
|
|
99
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
|
|
100
|
+
return distro;
|
|
101
|
+
}
|
|
102
|
+
function wslRoute(distro, context, env) {
|
|
103
|
+
const endpoint = env.DOCKER_HOST
|
|
104
|
+
? safeEndpoint(env.DOCKER_HOST)
|
|
105
|
+
: `wsl://${distro}/${context ?? 'default'}`;
|
|
106
|
+
const unreplayable = tlsEnvironmentReason(env)
|
|
107
|
+
?? (endpoint.includes('<redacted>') ? 'ambient-endpoint-secret' : undefined);
|
|
108
|
+
return {
|
|
109
|
+
kind: 'wsl2',
|
|
110
|
+
selector: {
|
|
111
|
+
distro,
|
|
112
|
+
...(context ? { context } : {}),
|
|
113
|
+
...(unreplayable ? { unreplayable } : {}),
|
|
114
|
+
...(env.DOCKER_HOST ? { endpoint } : {})
|
|
115
|
+
},
|
|
116
|
+
endpoint,
|
|
117
|
+
command: (args) => ({
|
|
118
|
+
cmd: 'wsl.exe',
|
|
119
|
+
args: [
|
|
120
|
+
'--distribution', distro,
|
|
121
|
+
'--exec', 'docker',
|
|
122
|
+
...(context ? ['--context', context] : []),
|
|
123
|
+
...(env.DOCKER_HOST ? ['--host', env.DOCKER_HOST] : []),
|
|
124
|
+
...args
|
|
125
|
+
]
|
|
126
|
+
})
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function currentWslRoute(env, probe, timeoutMs) {
|
|
130
|
+
const distro = resolveWslDistro(probe, timeoutMs, env.WSL_DISTRO_NAME);
|
|
131
|
+
let context = env.DOCKER_CONTEXT;
|
|
132
|
+
if (!context && !env.DOCKER_HOST) {
|
|
133
|
+
const result = probe('wsl.exe', ['--distribution', distro, '--exec', 'docker', 'context', 'show'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
|
|
134
|
+
context = text(result.stdout).trim();
|
|
135
|
+
if (result.status !== 0 || !validRouteName(context)) {
|
|
136
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return wslRoute(distro, context, env);
|
|
140
|
+
}
|
|
141
|
+
function routeFromEvidence(evidence) {
|
|
142
|
+
return {
|
|
143
|
+
kind: evidence.routeKind,
|
|
144
|
+
selector: evidence.routeSelector,
|
|
145
|
+
endpoint: evidence.normalizedEndpoint,
|
|
146
|
+
command: (args) => commandForSandboxAuthority(evidence, 'docker', args)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function currentContextRoute(engine, env, probe, timeoutMs) {
|
|
150
|
+
const configured = routeFor(engine, env);
|
|
151
|
+
if (configured.kind !== 'context' || configured.selector.context !== 'default')
|
|
152
|
+
return configured;
|
|
153
|
+
if (env.DOCKER_CONTEXT || env.DOCKER_HOST || getAdapter(engine).dockerContext)
|
|
154
|
+
return configured;
|
|
155
|
+
const result = probe('docker', ['context', 'show'], timeoutMs === undefined ? {} : { timeout: timeoutMs });
|
|
156
|
+
const context = text(result.stdout).trim();
|
|
157
|
+
if (result.status !== 0 || !/^[A-Za-z0-9][A-Za-z0-9_.@/-]*$/u.test(context)) {
|
|
158
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_CAPTURE_FAILED');
|
|
159
|
+
}
|
|
160
|
+
return contextRoute(context);
|
|
161
|
+
}
|
|
162
|
+
/** Build a command using only the route persisted with the sandbox authority. */
|
|
163
|
+
export function commandForSandboxAuthority(evidence, cmd, args = []) {
|
|
164
|
+
if (cmd !== 'docker') {
|
|
165
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_UNSUPPORTED');
|
|
166
|
+
}
|
|
167
|
+
if (evidence.routeKind === 'context') {
|
|
168
|
+
const context = evidence.routeSelector.context;
|
|
169
|
+
if (!context)
|
|
170
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_INVALID');
|
|
171
|
+
return { cmd, args: ['--context', context, ...args] };
|
|
172
|
+
}
|
|
173
|
+
if (evidence.routeKind === 'endpoint') {
|
|
174
|
+
const endpoint = evidence.routeSelector.endpoint;
|
|
175
|
+
if (!endpoint || endpoint.includes('<redacted>') || evidence.routeSelector.unreplayable) {
|
|
176
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_UNREPLAYABLE');
|
|
177
|
+
}
|
|
178
|
+
return { cmd, args: ['--host', endpoint, ...args] };
|
|
179
|
+
}
|
|
180
|
+
if (evidence.routeKind === 'wsl2') {
|
|
181
|
+
const distro = evidence.routeSelector.distro;
|
|
182
|
+
const context = evidence.routeSelector.context;
|
|
183
|
+
const endpoint = evidence.routeSelector.endpoint;
|
|
184
|
+
if (!distro || evidence.routeSelector.unreplayable || endpoint?.includes('<redacted>')) {
|
|
185
|
+
throw new Error('SANDBOX_AUTHORITY_ROUTE_UNREPLAYABLE');
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
cmd: 'wsl.exe',
|
|
189
|
+
args: [
|
|
190
|
+
'--distribution', distro,
|
|
191
|
+
'--exec', cmd,
|
|
192
|
+
...(context ? ['--context', context] : []),
|
|
193
|
+
...(endpoint && !endpoint.startsWith('wsl://') ? ['--host', endpoint] : []),
|
|
194
|
+
...args
|
|
195
|
+
]
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return { cmd, args: ['--context', 'default', ...args] };
|
|
199
|
+
}
|
|
200
|
+
export function authorityVersionArgs() {
|
|
201
|
+
return ['version', '--format', '{{json .Server}}'];
|
|
202
|
+
}
|
|
203
|
+
export function captureSandboxAuthority(engine, options = {}) {
|
|
204
|
+
const env = options.env ?? process.env;
|
|
205
|
+
const probe = options.probe ?? runProbe;
|
|
206
|
+
const route = options.route
|
|
207
|
+
? routeFromEvidence(options.route)
|
|
208
|
+
: engine === 'wsl2'
|
|
209
|
+
? currentWslRoute(env, probe, options.timeoutMs)
|
|
210
|
+
: currentContextRoute(engine, env, probe, options.timeoutMs);
|
|
211
|
+
function probeJson(args) {
|
|
212
|
+
const command = options.route
|
|
213
|
+
? commandForSandboxAuthority(options.route, 'docker', args)
|
|
214
|
+
: route.command(args);
|
|
215
|
+
try {
|
|
216
|
+
const response = probe(command.cmd, command.args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
|
|
217
|
+
if (response.status !== 0)
|
|
218
|
+
throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
|
|
219
|
+
return JSON.parse(text(response.stdout).trim());
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const server = probeJson(authorityVersionArgs());
|
|
226
|
+
if (!server || typeof server !== 'object' || Array.isArray(server)) {
|
|
227
|
+
throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
|
|
228
|
+
}
|
|
229
|
+
const record = server;
|
|
230
|
+
const api = typeof record.ApiVersion === 'string' ? /^(\d+)\.(\d+)$/u.exec(record.ApiVersion) : null;
|
|
231
|
+
if (!api)
|
|
232
|
+
throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
|
|
233
|
+
// Docker version exposes API metadata; the daemon ID belongs to Docker info.
|
|
234
|
+
const serverId = probeJson(['info', '--format', '{{json .ID}}']);
|
|
235
|
+
if (typeof serverId !== 'string' || !serverId.trim())
|
|
236
|
+
throw new Error('SANDBOX_AUTHORITY_CAPTURE_FAILED');
|
|
237
|
+
const normalizedEndpoint = route.endpoint;
|
|
238
|
+
const evidenceWithoutFingerprint = {
|
|
239
|
+
version: 1,
|
|
240
|
+
provider: engine,
|
|
241
|
+
lockDomain: options.lockDomain ?? options.route?.lockDomain ?? lockDomainFor(engine, normalizedEndpoint),
|
|
242
|
+
routeKind: route.kind,
|
|
243
|
+
routeSelector: route.selector,
|
|
244
|
+
normalizedEndpoint,
|
|
245
|
+
endpointFingerprint: digest(normalizedEndpoint),
|
|
246
|
+
daemonIdentity: { kind: 'docker-server-id', fingerprint: digest(serverId) },
|
|
247
|
+
apiVersion: { major: Number(api[1]), minor: Number(api[2]) }
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
...evidenceWithoutFingerprint,
|
|
251
|
+
authorityFingerprint: digest(canonical(evidenceWithoutFingerprint))
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export function verifySandboxAuthority(expected, actual) {
|
|
255
|
+
if (!expected)
|
|
256
|
+
return { state: 'unknown', reason: 'SANDBOX_AUTHORITY_EVIDENCE_MISSING' };
|
|
257
|
+
if (!actual)
|
|
258
|
+
return { state: 'unknown', reason: 'SANDBOX_AUTHORITY_UNAVAILABLE' };
|
|
259
|
+
if (expected.authorityFingerprint !== actual.authorityFingerprint
|
|
260
|
+
|| expected.lockDomain !== actual.lockDomain
|
|
261
|
+
|| expected.routeKind !== actual.routeKind
|
|
262
|
+
|| expected.endpointFingerprint !== actual.endpointFingerprint
|
|
263
|
+
|| expected.daemonIdentity.fingerprint !== actual.daemonIdentity.fingerprint) {
|
|
264
|
+
return { state: 'conflict', reason: 'SANDBOX_AUTHORITY_DRIFT' };
|
|
265
|
+
}
|
|
266
|
+
return { state: 'verified' };
|
|
267
|
+
}
|
|
268
|
+
export function isSandboxAuthorityEvidence(value) {
|
|
269
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
270
|
+
return false;
|
|
271
|
+
const evidence = value;
|
|
272
|
+
const selector = evidence.routeSelector;
|
|
273
|
+
const daemon = evidence.daemonIdentity;
|
|
274
|
+
const api = evidence.apiVersion;
|
|
275
|
+
return evidence.version === 1
|
|
276
|
+
&& typeof evidence.provider === 'string'
|
|
277
|
+
&& /^[a-f0-9]{64}$/u.test(evidence.lockDomain)
|
|
278
|
+
&& ['default', 'context', 'endpoint', 'wsl2'].includes(evidence.routeKind)
|
|
279
|
+
&& !!selector && typeof selector === 'object' && !Array.isArray(selector)
|
|
280
|
+
&& Object.values(selector).every((entry) => typeof entry === 'string')
|
|
281
|
+
&& typeof evidence.normalizedEndpoint === 'string'
|
|
282
|
+
&& /^[a-f0-9]{64}$/u.test(evidence.endpointFingerprint)
|
|
283
|
+
&& !!daemon && daemon.kind === 'docker-server-id'
|
|
284
|
+
&& /^[a-f0-9]{64}$/u.test(daemon.fingerprint)
|
|
285
|
+
&& !!api && Number.isSafeInteger(api.major) && api.major >= 0
|
|
286
|
+
&& Number.isSafeInteger(api.minor) && api.minor >= 0
|
|
287
|
+
&& /^[a-f0-9]{64}$/u.test(evidence.authorityFingerprint);
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=authority.js.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { commandForEngine, runProbe } from '../shell.js';
|
|
2
|
+
import { commandForSandboxAuthority } from './authority.js';
|
|
3
|
+
const FULL_CONTAINER_ID = /^[a-f0-9]{64}$/u;
|
|
4
|
+
function outputText(value) {
|
|
5
|
+
return typeof value === 'string' ? value : value?.toString('utf8') ?? '';
|
|
6
|
+
}
|
|
7
|
+
function unknown(reason) {
|
|
8
|
+
return { state: 'unknown', reason };
|
|
9
|
+
}
|
|
10
|
+
export function buildExactContainerListArgs(id) {
|
|
11
|
+
if (!FULL_CONTAINER_ID.test(id))
|
|
12
|
+
throw new Error('SANDBOX_CONTAINER_ID_NOT_FULL');
|
|
13
|
+
return ['container', 'ls', '--all', '--no-trunc', '--filter', `id=${id}`, '--format', '{{.ID}}'];
|
|
14
|
+
}
|
|
15
|
+
function buildExactContainerInspectArgs(id) {
|
|
16
|
+
return ['container', 'inspect', '--format', '{{json .}}', id];
|
|
17
|
+
}
|
|
18
|
+
function runDockerProbe(engine, args, options) {
|
|
19
|
+
const command = options.authority
|
|
20
|
+
? commandForSandboxAuthority(options.authority, 'docker', args)
|
|
21
|
+
: commandForEngine(engine, 'docker', args);
|
|
22
|
+
return (options.probe ?? runProbe)(command.cmd, command.args, options.timeoutMs === undefined ? {} : { timeout: options.timeoutMs });
|
|
23
|
+
}
|
|
24
|
+
function parseExactList(stdout, expectedId) {
|
|
25
|
+
const rows = stdout.split(/\r?\n/u).map((row) => row.trim()).filter(Boolean);
|
|
26
|
+
if (rows.length === 0)
|
|
27
|
+
return 'empty';
|
|
28
|
+
if (rows.length !== 1)
|
|
29
|
+
return 'exact container query returned multiple rows';
|
|
30
|
+
if (!FULL_CONTAINER_ID.test(rows[0]))
|
|
31
|
+
return 'exact container query returned a malformed ID';
|
|
32
|
+
if (rows[0] !== expectedId)
|
|
33
|
+
return 'conflict';
|
|
34
|
+
return 'present';
|
|
35
|
+
}
|
|
36
|
+
function parseExactInspect(stdout, expectedId) {
|
|
37
|
+
let value;
|
|
38
|
+
try {
|
|
39
|
+
value = JSON.parse(stdout);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return unknown('exact container inspection returned malformed JSON');
|
|
43
|
+
}
|
|
44
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
45
|
+
return unknown('exact container inspection returned an incomplete object');
|
|
46
|
+
}
|
|
47
|
+
const inspected = value;
|
|
48
|
+
if (inspected.Id !== expectedId || typeof inspected.State?.Running !== 'boolean'
|
|
49
|
+
|| !inspected.Config?.Labels || typeof inspected.Config.Labels !== 'object'
|
|
50
|
+
|| Array.isArray(inspected.Config.Labels)) {
|
|
51
|
+
return unknown('exact container inspection identity is incomplete');
|
|
52
|
+
}
|
|
53
|
+
const rawLabels = inspected.Config.Labels;
|
|
54
|
+
if (Object.values(rawLabels).some((value) => typeof value !== 'string')) {
|
|
55
|
+
return unknown('exact container inspection labels are malformed');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
state: 'found',
|
|
59
|
+
id: expectedId,
|
|
60
|
+
running: inspected.State.Running,
|
|
61
|
+
labels: { ...rawLabels },
|
|
62
|
+
evidence: 'exact-present'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function discoverExactContainer(engine, id, options = {}) {
|
|
66
|
+
if (!FULL_CONTAINER_ID.test(id))
|
|
67
|
+
return unknown('container identity is not a full 64-character ID');
|
|
68
|
+
let listed;
|
|
69
|
+
try {
|
|
70
|
+
listed = runDockerProbe(engine, buildExactContainerListArgs(id), options);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return unknown('exact container query failed before producing a result');
|
|
74
|
+
}
|
|
75
|
+
if (listed.status !== 0) {
|
|
76
|
+
return unknown(`exact container query exited with ${listed.status ?? 'unknown status'}`);
|
|
77
|
+
}
|
|
78
|
+
const listState = parseExactList(outputText(listed.stdout), id);
|
|
79
|
+
if (listState === 'empty')
|
|
80
|
+
return { state: 'absent', id, evidence: 'exact-empty' };
|
|
81
|
+
if (listState === 'conflict')
|
|
82
|
+
return { state: 'conflict', reason: 'exact container query returned a different ID' };
|
|
83
|
+
if (listState !== 'present')
|
|
84
|
+
return unknown(listState);
|
|
85
|
+
let inspected;
|
|
86
|
+
try {
|
|
87
|
+
inspected = runDockerProbe(engine, buildExactContainerInspectArgs(id), options);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return unknown('exact container inspection failed before producing a result');
|
|
91
|
+
}
|
|
92
|
+
if (inspected.status !== 0) {
|
|
93
|
+
return unknown(`exact container inspection exited with ${inspected.status ?? 'unknown status'}`);
|
|
94
|
+
}
|
|
95
|
+
return parseExactInspect(outputText(inspected.stdout).trim(), id);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=docker-exact-discovery.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PUBLIC_CLI_ROUTE_SELECTORS } from '../internal/cli-route-inventory.js';
|
|
1
2
|
const USAGE = `Usage: ai sandbox <command> [options]
|
|
2
3
|
|
|
3
4
|
Commands:
|
|
@@ -26,6 +27,7 @@ Commands:
|
|
|
26
27
|
vm status|start|stop Manage the sandbox VM (macOS) or check the backend (Windows)
|
|
27
28
|
|
|
28
29
|
Run 'ai sandbox <command> --help' for details.`;
|
|
30
|
+
const SANDBOX_OPERATIONS = PUBLIC_CLI_ROUTE_SELECTORS.sandbox;
|
|
29
31
|
export async function runSandbox(args) {
|
|
30
32
|
const [subcommand, ...rest] = args;
|
|
31
33
|
if (!subcommand) {
|
|
@@ -37,6 +39,9 @@ export async function runSandbox(args) {
|
|
|
37
39
|
process.stdout.write(`${USAGE}\n`);
|
|
38
40
|
return;
|
|
39
41
|
}
|
|
42
|
+
if (!SANDBOX_OPERATIONS.includes(subcommand)) {
|
|
43
|
+
throw new Error(`Unknown sandbox command: ${subcommand}`);
|
|
44
|
+
}
|
|
40
45
|
switch (subcommand) {
|
|
41
46
|
case 'create': {
|
|
42
47
|
const { create } = await import('./commands/create.js');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { prepareCompletedReentry, publishCompletedReentry, waitForCompletedReentry } from './control/completed-reentry.js';
|
|
1
2
|
import fs from 'node:fs';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { spawn } from 'node:child_process';
|
|
@@ -441,7 +442,7 @@ function recoveryTaskSources(repoRoot, taskId) {
|
|
|
441
442
|
}
|
|
442
443
|
return { mountPaths, accessiblePaths: [completedSource] };
|
|
443
444
|
}
|
|
444
|
-
function startCompletedSandboxContainer(params) {
|
|
445
|
+
export function startCompletedSandboxContainer(params) {
|
|
445
446
|
const taskSources = recoveryTaskSources(params.config.repoRoot, params.taskId);
|
|
446
447
|
const completedSource = taskSources.accessiblePaths[0];
|
|
447
448
|
const activeRoot = path.join(params.config.repoRoot, '.agents', 'workspace', 'active');
|
|
@@ -879,7 +880,17 @@ export async function ensureSandboxReady(params) {
|
|
|
879
880
|
throw new Error('Explicit container recreation requested.');
|
|
880
881
|
}
|
|
881
882
|
if (!params.row.running) {
|
|
883
|
+
let completedReentry = null;
|
|
882
884
|
if (params.reentry === 'completed' && params.workspace?.mode === 'task-bound') {
|
|
885
|
+
const control = sandboxControlPaths({
|
|
886
|
+
base: params.config.controlBase, project: params.config.project,
|
|
887
|
+
container: params.row.name, identity: params.workspace
|
|
888
|
+
});
|
|
889
|
+
const manifest = readSandboxControlManifest(control.manifestPath);
|
|
890
|
+
if (manifest.taskId !== params.workspace.taskId || manifest.branch !== params.branch) {
|
|
891
|
+
throw new Error('SANDBOX_COMPLETED_REENTRY_EVIDENCE_INVALID');
|
|
892
|
+
}
|
|
893
|
+
completedReentry = { manifest, evidence: await prepareCompletedReentry(manifest) };
|
|
883
894
|
startCompletedSandboxContainer({
|
|
884
895
|
config: params.config,
|
|
885
896
|
engine: params.engine,
|
|
@@ -943,6 +954,15 @@ export async function ensureSandboxReady(params) {
|
|
|
943
954
|
if (final.findings.length > 0) {
|
|
944
955
|
throw new Error(describeFindings(final.findings));
|
|
945
956
|
}
|
|
957
|
+
if (completedReentry) {
|
|
958
|
+
const { manifest, evidence } = completedReentry;
|
|
959
|
+
const current = await prepareCompletedReentry(manifest);
|
|
960
|
+
if (JSON.stringify(current) !== JSON.stringify(evidence)) {
|
|
961
|
+
throw new Error('SANDBOX_COMPLETED_REENTRY_EVIDENCE_INVALID');
|
|
962
|
+
}
|
|
963
|
+
publishCompletedReentry(manifest, evidence);
|
|
964
|
+
await waitForCompletedReentry(manifest, evidence);
|
|
965
|
+
}
|
|
946
966
|
return { container: params.row.name, path: 'recovered', warnings };
|
|
947
967
|
}
|
|
948
968
|
const initial = assess({
|
|
@@ -195,7 +195,8 @@ export function finalizeSandboxControlManifest(setup, identity) {
|
|
|
195
195
|
const manifest = {
|
|
196
196
|
...setup.manifestDraft,
|
|
197
197
|
engine: identity.engine,
|
|
198
|
-
containerIdentity: { id: identity.id, labels: { ...identity.labels } }
|
|
198
|
+
containerIdentity: { id: identity.id, labels: { ...identity.labels } },
|
|
199
|
+
authorityEvidence: identity.authorityEvidence
|
|
199
200
|
};
|
|
200
201
|
const temporary = `${setup.manifestPath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
201
202
|
try {
|
|
@@ -387,7 +387,10 @@ function verifyWorktreePermit(permit, options = {}) {
|
|
|
387
387
|
: inspectWorktree(permit.snapshot.worktree, options);
|
|
388
388
|
if (current.status === 'failed')
|
|
389
389
|
throw new Error(`Unable to verify worktree permit: ${current.message}`);
|
|
390
|
-
|
|
390
|
+
const sameTarget = current.snapshot.worktree === permit.snapshot.worktree
|
|
391
|
+
&& current.snapshot.branch === permit.snapshot.branch;
|
|
392
|
+
if (!sameTarget || (permit.mode === 'clean'
|
|
393
|
+
&& (current.snapshot.identity !== permit.snapshot.identity || current.status !== 'clean'))) {
|
|
391
394
|
throw new Error(`Worktree changed after authorization: ${permit.snapshot.worktree}`);
|
|
392
395
|
}
|
|
393
396
|
return current.snapshot;
|
package/dist/lib/server/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { runDaemon } from './daemon.js';
|
|
2
2
|
import { start, stop, status, logs } from './process-control.js';
|
|
3
|
+
import { PUBLIC_CLI_ROUTE_SELECTORS } from '../internal/cli-route-inventory.js';
|
|
4
|
+
const SERVER_OPERATIONS = PUBLIC_CLI_ROUTE_SELECTORS.server;
|
|
3
5
|
const USAGE = `Usage: ai server <command> [options]
|
|
4
6
|
|
|
5
7
|
Commands:
|
|
@@ -21,6 +23,12 @@ export async function runServer(args) {
|
|
|
21
23
|
process.stdout.write(`${USAGE}\n`);
|
|
22
24
|
return;
|
|
23
25
|
}
|
|
26
|
+
if (!SERVER_OPERATIONS.includes(subcommand)) {
|
|
27
|
+
process.stderr.write(`Unknown server command: ${subcommand}\n`);
|
|
28
|
+
process.stdout.write(`${USAGE}\n`);
|
|
29
|
+
process.exitCode = 1;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
24
32
|
switch (subcommand) {
|
|
25
33
|
case 'start':
|
|
26
34
|
await start({ foreground: rest.includes('--foreground') });
|
|
@@ -9,6 +9,28 @@ function splitWords(text) {
|
|
|
9
9
|
function taskSubcommand(subcommand) {
|
|
10
10
|
return subcommand === 'list' ? 'ls' : subcommand;
|
|
11
11
|
}
|
|
12
|
+
function splitRunArguments(args) {
|
|
13
|
+
const hostArgs = [];
|
|
14
|
+
const skillArgs = [];
|
|
15
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
if (arg === '--tui') {
|
|
18
|
+
hostArgs.push(arg);
|
|
19
|
+
const value = args[i + 1];
|
|
20
|
+
if (value !== undefined) {
|
|
21
|
+
hostArgs.push(value);
|
|
22
|
+
i += 1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (arg === '--recreate') {
|
|
26
|
+
hostArgs.push(arg);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
skillArgs.push(arg);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { hostArgs, skillArgs };
|
|
33
|
+
}
|
|
12
34
|
export function commandHelp() {
|
|
13
35
|
return [
|
|
14
36
|
`agent-infra ${VERSION}`,
|
|
@@ -78,7 +100,22 @@ export function parseCommand(text) {
|
|
|
78
100
|
const spec = getSkillRunSpec(subcommand);
|
|
79
101
|
if (!spec)
|
|
80
102
|
return { kind: 'error', message: `Unknown skill: ${subcommand}` };
|
|
81
|
-
|
|
103
|
+
if (spec.kind === 'create') {
|
|
104
|
+
return { kind: 'ai', role: spec.role, argv: ['run', '--skill', subcommand, ...rest] };
|
|
105
|
+
}
|
|
106
|
+
const [taskRef, ...skillArgs] = rest;
|
|
107
|
+
if (!taskRef)
|
|
108
|
+
return { kind: 'error', message: '/run task skills require a task-ref' };
|
|
109
|
+
const { hostArgs, skillArgs: forwardedSkillArgs } = splitRunArguments(skillArgs);
|
|
110
|
+
return {
|
|
111
|
+
kind: 'ai',
|
|
112
|
+
role: spec.role,
|
|
113
|
+
argv: [
|
|
114
|
+
'run', '--skill', subcommand, '--task', taskRef,
|
|
115
|
+
...hostArgs,
|
|
116
|
+
...(forwardedSkillArgs.length > 0 ? ['--', ...forwardedSkillArgs] : [])
|
|
117
|
+
]
|
|
118
|
+
};
|
|
82
119
|
}
|
|
83
120
|
return { kind: 'error', message: `Unknown command: ${command}` };
|
|
84
121
|
}
|
|
@@ -5,6 +5,7 @@ const STARTED_SUFFIX_RE = /\s*\[started\]\s*$/;
|
|
|
5
5
|
const ABORTED_SUFFIX_RE = /\s*\[aborted\]\s*$/;
|
|
6
6
|
const ATTEMPT_RE = /(?:^|;\s*)attempt=([A-Za-z0-9-]{8,64})(?:;|$)/;
|
|
7
7
|
const COMMIT_STARTED_RE = /^started; attempt=([A-Za-z0-9-]{8,64}); baseline=([a-f0-9]{40,64}); agent=([a-z-]+)$/;
|
|
8
|
+
const LIFECYCLE_STEP_RE = /^(?:Complete Manual Validation|(?:Analyze Task|Review Analysis|Plan Task|Review Plan|Code Task|Review Code|Run Manual Validation) \(Round [1-9]\d*(?:(?:, fix for review-code(?:-r[2-9]|-r[1-9]\d+)?\.md)|(?:, decision II-[1-9]\d*))?\))$/;
|
|
8
9
|
function parseActivityLog(content) {
|
|
9
10
|
const section = locateActivityLog(content);
|
|
10
11
|
return section ? { sectionFound: true, entries: section.entries } : { sectionFound: false, entries: [] };
|
|
@@ -87,5 +88,11 @@ function pairEntries(entries) {
|
|
|
87
88
|
function startedBackedRows(rows) {
|
|
88
89
|
return rows.filter((row) => row.started !== '');
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
+
function hasOpenLifecycleExecution(content) {
|
|
92
|
+
const section = locateActivityLog(content);
|
|
93
|
+
if (!section)
|
|
94
|
+
return false;
|
|
95
|
+
return pairEntries(section.entries).some((row) => row.done === '' && LIFECYCLE_STEP_RE.test(row.step));
|
|
96
|
+
}
|
|
97
|
+
export { activityAttempt, appendActivityEntry, hasOpenLifecycleExecution, commitAttemptStartedNote, locateActivityLog, pairEntries, parseActivityLog, parseCommitAttemptStarted, startedBackedRows };
|
|
91
98
|
//# sourceMappingURL=activity-log.js.map
|