@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
|
@@ -5,10 +5,11 @@ import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.ts
|
|
|
5
5
|
import { listPrReviews, publishPrReview } from '../platform/pr-review.ts';
|
|
6
6
|
import type { PrReviewEvent } from '../platform/pr-review.ts';
|
|
7
7
|
import type { PlatformResult } from '../platform/types.ts';
|
|
8
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
8
9
|
|
|
9
|
-
const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <
|
|
10
|
-
agent-infra-internal platform-pr-review list --pr <
|
|
11
|
-
agent-infra-internal platform-pr-review publish --pr <
|
|
10
|
+
const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <token> [--cwd <path>]
|
|
11
|
+
agent-infra-internal platform-pr-review list --pr <token> [--cwd <path>]
|
|
12
|
+
agent-infra-internal platform-pr-review publish --pr <token> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--dry-run] [--cwd <path>]
|
|
12
13
|
`;
|
|
13
14
|
|
|
14
15
|
const BOOLEAN_FLAGS = new Set(['--dry-run']);
|
|
@@ -50,10 +51,15 @@ function readBodyFile(value: string, cwd: string): string {
|
|
|
50
51
|
return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
function platformPrReview(args: string[] = []): void {
|
|
54
|
+
async function platformPrReview(args: string[] = []): Promise<void> {
|
|
55
|
+
if (!ensureInternalHandlerRoute('platform-pr-review', args)) return;
|
|
54
56
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
55
57
|
const operation = args[0];
|
|
56
|
-
if (!operation || ![
|
|
58
|
+
if (!operation || ![
|
|
59
|
+
internalHandlerRoute('platform-pr-review', 'inspect', operation),
|
|
60
|
+
internalHandlerRoute('platform-pr-review', 'list', operation),
|
|
61
|
+
operation === 'publish'
|
|
62
|
+
].some(Boolean)) { fail('a valid operation is required'); return; }
|
|
57
63
|
const parsed = parse(args, 1);
|
|
58
64
|
if (parsed.error) { fail(parsed.error); return; }
|
|
59
65
|
const values = parsed.values;
|
|
@@ -65,21 +71,26 @@ function platformPrReview(args: string[] = []): void {
|
|
|
65
71
|
};
|
|
66
72
|
const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
|
|
67
73
|
if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
|
|
68
|
-
const pr =
|
|
69
|
-
if (
|
|
70
|
-
if (
|
|
71
|
-
finish(inspectPlatformPullRequestByNumber(pr, { cwd }));
|
|
74
|
+
const pr = values.pr;
|
|
75
|
+
if (typeof pr !== 'string' || !pr) { fail(`${operation} requires --pr <token>`); return; }
|
|
76
|
+
if (internalHandlerRoute('platform-pr-review', 'inspect', operation)) {
|
|
77
|
+
finish(await inspectPlatformPullRequestByNumber(pr, { cwd }));
|
|
72
78
|
return;
|
|
73
79
|
}
|
|
74
|
-
if (
|
|
75
|
-
finish(listPrReviews(pr, { cwd }));
|
|
80
|
+
if (internalHandlerRoute('platform-pr-review', 'list', operation)) {
|
|
81
|
+
finish(await listPrReviews(pr, { cwd }));
|
|
76
82
|
return;
|
|
77
83
|
}
|
|
78
84
|
const scope = typeof values.scope === 'string' ? values.scope : '';
|
|
85
|
+
const publishSelector = /^TASK-\d{8}-\d{6}$/u.test(scope) ? 'publish-task' : /^pr\d+$/u.test(scope) ? 'publish-pr' : '';
|
|
79
86
|
const round = Number(values.round);
|
|
80
87
|
const commit = typeof values.commit === 'string' ? values.commit : '';
|
|
81
88
|
const event = values.event as string;
|
|
82
89
|
if (!scope || !/^(?:pr\d+|TASK-\d{8}-\d{6})$/.test(scope)) { fail('publish requires --scope <taskId|pr{N}>'); return; }
|
|
90
|
+
if (!internalHandlerRoute('platform-pr-review', 'publish-task', publishSelector)
|
|
91
|
+
&& !internalHandlerRoute('platform-pr-review', 'publish-pr', publishSelector)) {
|
|
92
|
+
fail('publish scope is not registered'); return;
|
|
93
|
+
}
|
|
83
94
|
if (!Number.isInteger(round) || round <= 0) { fail('publish requires a positive --round'); return; }
|
|
84
95
|
if (!/^[0-9a-f]{7,40}$/i.test(commit)) { fail('publish requires --commit <sha>'); return; }
|
|
85
96
|
if (!['COMMENT', 'APPROVE', 'REQUEST_CHANGES'].includes(event)) { fail('publish requires --event <COMMENT|APPROVE|REQUEST_CHANGES>'); return; }
|
|
@@ -91,7 +102,7 @@ function platformPrReview(args: string[] = []): void {
|
|
|
91
102
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
92
103
|
return;
|
|
93
104
|
}
|
|
94
|
-
finish(publishPrReview({
|
|
105
|
+
finish(await publishPrReview({
|
|
95
106
|
cwd,
|
|
96
107
|
prNumber: pr,
|
|
97
108
|
identity: { scope, round, commitSha: commit },
|
|
@@ -8,24 +8,28 @@ import {
|
|
|
8
8
|
inspectPlatformPullRequest,
|
|
9
9
|
resolveExternalPullRequest,
|
|
10
10
|
skipPlatformPullRequestFact,
|
|
11
|
-
syncPlatformPullRequest
|
|
11
|
+
syncPlatformPullRequest,
|
|
12
|
+
syncPlatformPullRequestInLabels
|
|
12
13
|
} from '../platform/pull-requests.ts';
|
|
13
14
|
import type { PullRequestResult } from '../platform/pull-requests.ts';
|
|
14
|
-
import { summaryContext, syncPullRequestSummary } from '../platform/pr-summary.ts';
|
|
15
|
+
import { reportWrite, summaryContext, syncPullRequestSummary } from '../platform/pr-summary.ts';
|
|
15
16
|
import type { PlatformResult } from '../platform/types.ts';
|
|
17
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
16
18
|
|
|
17
19
|
const USAGE = `Usage: agent-infra-internal platform-pr inspect <task-ref> [--cwd <path>]
|
|
18
|
-
agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <
|
|
20
|
+
agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <token>] [--dry-run] [--cwd <path>]
|
|
19
21
|
agent-infra-internal platform-pr create <task-ref> --agent <agent> --base <branch> --head <branch> --title-file <path|-> --body-file <path|-> [--draft] [--dry-run] [--cwd <path>]
|
|
20
|
-
agent-infra-internal platform-pr bind <task-ref> --pr <
|
|
22
|
+
agent-infra-internal platform-pr bind <task-ref> --pr <token> --agent <agent> [--dry-run] [--cwd <path>]
|
|
21
23
|
agent-infra-internal platform-pr skip <task-ref> --agent <agent> [--dry-run] [--cwd <path>]
|
|
22
24
|
agent-infra-internal platform-pr sync <task-ref> --agent <agent> [--metadata] [--closing-issue] --result <pr_created|pr_reused|no_op> [--dry-run] [--cwd <path>]
|
|
25
|
+
agent-infra-internal platform-pr sync-in-labels --pr <N> [--dry-run] [--cwd <path>]
|
|
23
26
|
agent-infra-internal platform-pr summary-context <task-ref> [--cwd <path>]
|
|
24
|
-
agent-infra-internal platform-pr
|
|
27
|
+
agent-infra-internal platform-pr change-report <task-ref> --agent <agent> --mechanical-file <path> --precheck-file <path> [--dry-run] [--cwd <path>]
|
|
28
|
+
agent-infra-internal platform-pr summary-sync <task-ref> --agent <agent> --body-file <path|-> --change-report-file <path> --result <pr_created|pr_reused|no_op> [--strict] [--dry-run] [--cwd <path>]
|
|
25
29
|
`;
|
|
26
30
|
|
|
27
|
-
const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue']);
|
|
28
|
-
const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--pr', '--result']);
|
|
31
|
+
const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue', '--strict']);
|
|
32
|
+
const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--change-report-file', '--mechanical-file', '--precheck-file', '--pr', '--result']);
|
|
29
33
|
|
|
30
34
|
function key(flag: string): string {
|
|
31
35
|
return flag.slice(2).replace(/-([a-z])/g, (_, letter: string) => letter.toUpperCase());
|
|
@@ -63,10 +67,34 @@ function readFile(value: string, cwd: string): string {
|
|
|
63
67
|
return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
function platformPr(args: string[] = []): void {
|
|
70
|
+
async function platformPr(args: string[] = []): Promise<void> {
|
|
71
|
+
if (!ensureInternalHandlerRoute('platform-pr', args)) return;
|
|
67
72
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
68
73
|
const operation = args[0];
|
|
69
|
-
if (!operation || ![
|
|
74
|
+
if (!operation || ![
|
|
75
|
+
internalHandlerRoute('platform-pr', 'inspect', operation),
|
|
76
|
+
internalHandlerRoute('platform-pr', 'resolve-external', operation),
|
|
77
|
+
internalHandlerRoute('platform-pr', 'create', operation),
|
|
78
|
+
internalHandlerRoute('platform-pr', 'bind', operation),
|
|
79
|
+
internalHandlerRoute('platform-pr', 'skip', operation),
|
|
80
|
+
internalHandlerRoute('platform-pr', 'sync', operation),
|
|
81
|
+
internalHandlerRoute('platform-pr', 'sync-in-labels', operation),
|
|
82
|
+
internalHandlerRoute('platform-pr', 'summary-context', operation),
|
|
83
|
+
internalHandlerRoute('platform-pr', 'change-report', operation),
|
|
84
|
+
internalHandlerRoute('platform-pr', 'summary-sync', operation)
|
|
85
|
+
].some(Boolean)) { fail('a valid operation is required'); return; }
|
|
86
|
+
if (internalHandlerRoute('platform-pr', 'sync-in-labels', operation)) {
|
|
87
|
+
const parsed = parse(args, 1);
|
|
88
|
+
if (parsed.error) { fail(parsed.error); return; }
|
|
89
|
+
const values = parsed.values;
|
|
90
|
+
const unexpected = Object.keys(values).find((name) => !['cwd', 'pr', 'dryRun'].includes(name));
|
|
91
|
+
if (unexpected) { fail(`sync-in-labels does not accept --${unexpected}`); return; }
|
|
92
|
+
const pr = Number(values.pr);
|
|
93
|
+
if (!Number.isInteger(pr) || pr <= 0) { fail('sync-in-labels requires a positive --pr'); return; }
|
|
94
|
+
const cwd = path.resolve(typeof values.cwd === 'string' ? values.cwd : process.cwd());
|
|
95
|
+
finish(await syncPlatformPullRequestInLabels(pr, { cwd, dryRun: values.dryRun === true }));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
70
98
|
const taskRef = args[1];
|
|
71
99
|
if (!taskRef || taskRef.startsWith('--')) { fail(`${operation} requires a task ref`); return; }
|
|
72
100
|
const parsed = parse(args, 2);
|
|
@@ -80,19 +108,28 @@ function platformPr(args: string[] = []): void {
|
|
|
80
108
|
bind: ['cwd', 'agent', 'pr', 'dryRun'],
|
|
81
109
|
skip: ['cwd', 'agent', 'dryRun'],
|
|
82
110
|
sync: ['cwd', 'agent', 'metadata', 'closingIssue', 'result', 'dryRun'],
|
|
111
|
+
'sync-in-labels': ['cwd', 'pr', 'dryRun'],
|
|
83
112
|
'summary-context': ['cwd'],
|
|
84
|
-
'
|
|
113
|
+
'change-report': ['cwd', 'agent', 'mechanicalFile', 'precheckFile', 'dryRun'],
|
|
114
|
+
'summary-sync': ['cwd', 'agent', 'bodyFile', 'changeReportFile', 'result', 'dryRun', 'strict']
|
|
85
115
|
};
|
|
86
116
|
const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
|
|
87
117
|
if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
118
|
+
if (internalHandlerRoute('platform-pr', 'inspect', operation)) { finish(await inspectPlatformPullRequest(taskRef, { cwd })); return; }
|
|
119
|
+
if (internalHandlerRoute('platform-pr', 'summary-context', operation)) { finish(await summaryContext(taskRef, { cwd })); return; }
|
|
90
120
|
if (typeof values.agent !== 'string' || !values.agent) { fail(`${operation} requires --agent`); return; }
|
|
91
121
|
const agent = normalizeAgentToken(values.agent);
|
|
92
122
|
if (!agent) { fail(`invalid --agent '${values.agent}': ${AGENT_USAGE_HINT}`); return; }
|
|
93
123
|
values.agent = agent;
|
|
94
|
-
if (
|
|
95
|
-
|
|
124
|
+
if (internalHandlerRoute('platform-pr', 'change-report', operation)) {
|
|
125
|
+
if (typeof values.mechanicalFile !== 'string' || typeof values.precheckFile !== 'string') { fail('change-report requires --mechanical-file and --precheck-file'); return; }
|
|
126
|
+
finish(await reportWrite(taskRef, {
|
|
127
|
+
cwd, agent: values.agent, mechanicalFile: values.mechanicalFile, precheckFile: values.precheckFile, dryRun: values.dryRun === true
|
|
128
|
+
}));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (internalHandlerRoute('platform-pr', 'skip', operation)) {
|
|
132
|
+
finish(await skipPlatformPullRequestFact(taskRef, { cwd, agent, dryRun: values.dryRun === true }));
|
|
96
133
|
return;
|
|
97
134
|
}
|
|
98
135
|
const primaryResult = values.result === undefined ? undefined : values.result;
|
|
@@ -100,29 +137,30 @@ function platformPr(args: string[] = []): void {
|
|
|
100
137
|
fail('--result must be pr_created, pr_reused, or no_op');
|
|
101
138
|
return;
|
|
102
139
|
}
|
|
103
|
-
if (
|
|
104
|
-
const pr = values.pr === undefined ? undefined :
|
|
105
|
-
if (pr !== undefined && (
|
|
106
|
-
finish(resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
|
|
140
|
+
if (internalHandlerRoute('platform-pr', 'resolve-external', operation)) {
|
|
141
|
+
const pr = values.pr === undefined ? undefined : values.pr;
|
|
142
|
+
if (pr !== undefined && (typeof pr !== 'string' || !pr)) { fail('resolve-external requires --pr <token>'); return; }
|
|
143
|
+
finish(await resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
|
|
107
144
|
return;
|
|
108
145
|
}
|
|
109
|
-
if (
|
|
110
|
-
const pr =
|
|
111
|
-
if (
|
|
112
|
-
finish(bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
|
|
146
|
+
if (internalHandlerRoute('platform-pr', 'bind', operation)) {
|
|
147
|
+
const pr = values.pr;
|
|
148
|
+
if (typeof pr !== 'string' || !pr) { fail('bind requires --pr <token>'); return; }
|
|
149
|
+
finish(await bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
|
|
113
150
|
return;
|
|
114
151
|
}
|
|
115
|
-
if (
|
|
152
|
+
if (internalHandlerRoute('platform-pr', 'sync', operation)) {
|
|
116
153
|
if (values.metadata !== true && values.closingIssue !== true) { fail('sync requires --metadata or --closing-issue'); return; }
|
|
117
154
|
if (!primaryResult) { fail('sync requires --result pr_created, pr_reused, or no_op'); return; }
|
|
118
|
-
finish(syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
|
|
155
|
+
finish(await syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
|
|
119
156
|
return;
|
|
120
157
|
}
|
|
121
|
-
if (
|
|
158
|
+
if (internalHandlerRoute('platform-pr', 'summary-sync', operation)) {
|
|
122
159
|
if (typeof values.bodyFile !== 'string') { fail('summary-sync requires --body-file'); return; }
|
|
160
|
+
if (typeof values.changeReportFile !== 'string') { fail('summary-sync requires --change-report-file'); return; }
|
|
123
161
|
if (!primaryResult) { fail('summary-sync requires --result pr_created, pr_reused, or no_op'); return; }
|
|
124
162
|
try {
|
|
125
|
-
finish(syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true }));
|
|
163
|
+
finish(await syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), changeReportFile: values.changeReportFile, primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', dryRun: values.dryRun === true, strict: values.strict === true }));
|
|
126
164
|
} catch (error) {
|
|
127
165
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
128
166
|
}
|
|
@@ -133,7 +171,7 @@ function platformPr(args: string[] = []): void {
|
|
|
133
171
|
return;
|
|
134
172
|
}
|
|
135
173
|
try {
|
|
136
|
-
finish(createPlatformPullRequest(taskRef, {
|
|
174
|
+
finish(await createPlatformPullRequest(taskRef, {
|
|
137
175
|
cwd, agent: values.agent, base: values.base, head: values.head,
|
|
138
176
|
title: readFile(values.titleFile, cwd), body: readFile(values.bodyFile, cwd),
|
|
139
177
|
draft: values.draft === true, dryRun: values.dryRun === true
|
|
@@ -2,6 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { publishReleaseNotes, releaseNoteContext, stageReleaseNotes } from '../platform/release-notes.ts';
|
|
5
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
5
6
|
|
|
6
7
|
type ParsedOptions = Readonly<{ values: ReadonlyMap<string, string>; switches: ReadonlySet<string> }>;
|
|
7
8
|
|
|
@@ -36,14 +37,15 @@ function finish(result: { status: string; [key: string]: unknown }): void {
|
|
|
36
37
|
process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
function platformReleaseNotes(args: string[] = []): void {
|
|
40
|
+
async function platformReleaseNotes(args: string[] = []): Promise<void> {
|
|
41
|
+
if (!ensureInternalHandlerRoute('platform-release-notes', args)) return;
|
|
40
42
|
const [action, ...rest] = args;
|
|
41
|
-
if (action
|
|
43
|
+
if (internalHandlerRoute('platform-release-notes', 'context', action ?? '')) {
|
|
42
44
|
const parsed = parseOptions(rest, ['--cwd', '--history-limit', '--from-tag', '--to-tag', '--branch']);
|
|
43
45
|
if (!parsed) return finish(invalidInput('invalid context options'));
|
|
44
46
|
const cwd = path.resolve(parsed.values.get('--cwd') || process.cwd());
|
|
45
47
|
const historyRaw = parsed.values.get('--history-limit') ?? null;
|
|
46
|
-
finish(releaseNoteContext({
|
|
48
|
+
finish(await releaseNoteContext({
|
|
47
49
|
fromTag: parsed.values.get('--from-tag') || '',
|
|
48
50
|
toTag: parsed.values.get('--to-tag') || '',
|
|
49
51
|
branch: parsed.values.get('--branch') || '',
|
|
@@ -51,7 +53,7 @@ function platformReleaseNotes(args: string[] = []): void {
|
|
|
51
53
|
}, { cwd }));
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
|
-
if (action
|
|
56
|
+
if (internalHandlerRoute('platform-release-notes', 'stage', action ?? '')) {
|
|
55
57
|
const parsed = parseOptions(rest, ['--cwd', '--notes-file']);
|
|
56
58
|
if (!parsed) return finish(invalidInput('invalid stage options'));
|
|
57
59
|
const notesFile = parsed.values.get('--notes-file');
|
|
@@ -62,7 +64,7 @@ function platformReleaseNotes(args: string[] = []): void {
|
|
|
62
64
|
));
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
|
-
if (action
|
|
67
|
+
if (internalHandlerRoute('platform-release-notes', 'publish', action ?? '')) {
|
|
66
68
|
const parsed = parseOptions(
|
|
67
69
|
rest,
|
|
68
70
|
['--cwd', '--notes-file', '--tag', '--title', '--expected-sha256'],
|
|
@@ -80,7 +82,7 @@ function platformReleaseNotes(args: string[] = []): void {
|
|
|
80
82
|
fs.writeFileSync(resolvedNotesPath, fs.readFileSync(0));
|
|
81
83
|
}
|
|
82
84
|
try {
|
|
83
|
-
finish(publishReleaseNotes({
|
|
85
|
+
finish(await publishReleaseNotes({
|
|
84
86
|
tag: parsed.values.get('--tag') || '',
|
|
85
87
|
title: parsed.values.get('--title') || parsed.values.get('--tag') || '',
|
|
86
88
|
notesFile: resolvedNotesPath,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { dismissSecurityAlert, readCommentFile, readSecurityAlert } from '../platform/security-alerts.ts';
|
|
4
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
5
|
+
|
|
6
|
+
const USAGE = `Usage: agent-infra-internal platform-security read --kind <dependabot|code-scanning> --number <number> [--cwd <path>]
|
|
7
|
+
agent-infra-internal platform-security dismiss --kind <dependabot|code-scanning> --number <number> --reason <reason> --comment-file <path> [--cwd <path>]
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
function fail(message: string): void {
|
|
11
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SECURITY_INPUT_INVALID', message, retryable: false } })}\n`);
|
|
12
|
+
process.stderr.write(USAGE);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function finish(result: { status: string; [key: string]: unknown }): void {
|
|
17
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
18
|
+
process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function parseOptions(args: string[]): { values: Map<string, string>; switches: Set<string> } | null {
|
|
22
|
+
const values = new Map<string, string>();
|
|
23
|
+
const switches = new Set<string>();
|
|
24
|
+
const valueFlags = new Set(['--cwd', '--kind', '--number', '--reason', '--comment-file']);
|
|
25
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
26
|
+
const flag = args[index]!;
|
|
27
|
+
if (flag === '--help' || flag === '-h') return null;
|
|
28
|
+
if (!valueFlags.has(flag) || values.has(flag) || switches.has(flag)) return null;
|
|
29
|
+
const value = args[++index];
|
|
30
|
+
if (!value || value.startsWith('--')) return null;
|
|
31
|
+
values.set(flag, value);
|
|
32
|
+
}
|
|
33
|
+
return { values, switches };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function required(values: Map<string, string>, flag: string): string | null {
|
|
37
|
+
const value = values.get(flag);
|
|
38
|
+
return value && !value.startsWith('--') ? value : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function platformSecurity(args: string[] = []): Promise<void> {
|
|
42
|
+
if (!ensureInternalHandlerRoute('platform-security', args)) return;
|
|
43
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
44
|
+
const action = args[0];
|
|
45
|
+
if (!internalHandlerRoute('platform-security', 'read', action ?? '')
|
|
46
|
+
&& !internalHandlerRoute('platform-security', 'dismiss', action ?? '')) {
|
|
47
|
+
fail('a valid operation is required');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (action !== 'read' && action !== 'dismiss') { fail('a valid operation is required'); return; }
|
|
51
|
+
const parsed = parseOptions(args.slice(1));
|
|
52
|
+
if (!parsed) { fail('invalid security alert options'); return; }
|
|
53
|
+
const kind = required(parsed.values, '--kind');
|
|
54
|
+
const numberRaw = required(parsed.values, '--number');
|
|
55
|
+
const cwd = path.resolve(required(parsed.values, '--cwd') || process.cwd());
|
|
56
|
+
if (!kind || !numberRaw) { fail(`${action} requires --kind and --number`); return; }
|
|
57
|
+
const number = Number(numberRaw);
|
|
58
|
+
if (!Number.isSafeInteger(number) || number <= 0) { fail('--number must be a positive integer'); return; }
|
|
59
|
+
|
|
60
|
+
if (action === 'read') {
|
|
61
|
+
if ([...parsed.values.keys()].some((flag) => !['--kind', '--number', '--cwd'].includes(flag))) {
|
|
62
|
+
fail('read does not accept dismissal options');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
finish(await readSecurityAlert({ kind: kind as 'dependabot' | 'code-scanning', number }, { cwd }));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const reason = required(parsed.values, '--reason');
|
|
70
|
+
const commentFile = required(parsed.values, '--comment-file');
|
|
71
|
+
if (!reason || !commentFile) { fail('dismiss requires --reason and --comment-file'); return; }
|
|
72
|
+
const comment = readCommentFile(commentFile, cwd);
|
|
73
|
+
if (!comment.ok) {
|
|
74
|
+
finish({ status: 'failed', changed: false, error: comment.error });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
finish(await dismissSecurityAlert(
|
|
78
|
+
{ kind: kind as 'dependabot' | 'code-scanning', number, reason, comment: comment.value },
|
|
79
|
+
{ cwd }
|
|
80
|
+
));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { platformSecurity };
|
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
import type { DecisionRecord, HostResolution } from '../pr-review/evidence-grading.ts';
|
|
12
12
|
import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.ts';
|
|
13
13
|
import { verifyInProcess } from '../task/verification-engine.ts';
|
|
14
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
14
15
|
|
|
15
16
|
const USAGE = `Usage: agent-infra-internal pr-review-grade decide --input-file <path|-> [--cwd <path>]
|
|
16
|
-
agent-infra-internal pr-review-grade resolve-host --pr <
|
|
17
|
+
agent-infra-internal pr-review-grade resolve-host --pr <token> [--cwd <path>]
|
|
17
18
|
agent-infra-internal pr-review-grade verify-artifact --artifact-file <path> [--cwd <path>]
|
|
18
19
|
`;
|
|
19
20
|
|
|
@@ -49,10 +50,15 @@ function readInput(value: string, cwd: string): string {
|
|
|
49
50
|
return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
function prReviewGrade(args: string[] = []): void {
|
|
53
|
+
async function prReviewGrade(args: string[] = []): Promise<void> {
|
|
54
|
+
if (!ensureInternalHandlerRoute('pr-review-grade', args)) return;
|
|
53
55
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
54
56
|
const operation = args[0];
|
|
55
|
-
if (!operation || ![
|
|
57
|
+
if (!operation || ![
|
|
58
|
+
internalHandlerRoute('pr-review-grade', 'decide', operation),
|
|
59
|
+
internalHandlerRoute('pr-review-grade', 'resolve-host', operation),
|
|
60
|
+
internalHandlerRoute('pr-review-grade', 'verify-artifact', operation)
|
|
61
|
+
].some(Boolean)) { fail('a valid operation is required'); return; }
|
|
56
62
|
const parsed = parseFlags(args, 1);
|
|
57
63
|
if (parsed.error) { fail(parsed.error); return; }
|
|
58
64
|
const values = parsed.values;
|
|
@@ -65,7 +71,7 @@ function prReviewGrade(args: string[] = []): void {
|
|
|
65
71
|
const unexpected = Object.keys(values).find((key) => !allowed[operation]!.includes(key));
|
|
66
72
|
if (unexpected) { fail(`${operation} does not accept '--${unexpected}'`); return; }
|
|
67
73
|
|
|
68
|
-
if (
|
|
74
|
+
if (internalHandlerRoute('pr-review-grade', 'decide', operation)) {
|
|
69
75
|
if (typeof values.inputFile !== 'string') { fail('decide requires --input-file'); return; }
|
|
70
76
|
let input: unknown;
|
|
71
77
|
try {
|
|
@@ -84,10 +90,10 @@ function prReviewGrade(args: string[] = []): void {
|
|
|
84
90
|
return;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
if (
|
|
88
|
-
const pr =
|
|
89
|
-
if (!
|
|
90
|
-
const inspected = inspectPlatformPullRequestByNumber(pr, { cwd });
|
|
93
|
+
if (internalHandlerRoute('pr-review-grade', 'resolve-host', operation)) {
|
|
94
|
+
const pr = typeof values.pr === 'string' ? values.pr : '';
|
|
95
|
+
if (!pr) { fail('resolve-host requires --pr <token>'); return; }
|
|
96
|
+
const inspected = await inspectPlatformPullRequestByNumber(pr, { cwd });
|
|
91
97
|
if (!inspected.pullRequest) {
|
|
92
98
|
finish({
|
|
93
99
|
status: 'failed', changed: false, host: null, candidates: [], closingIssues: [],
|
|
@@ -95,23 +101,26 @@ function prReviewGrade(args: string[] = []): void {
|
|
|
95
101
|
}, inspected.status === 'blocked' ? 2 : 1);
|
|
96
102
|
return;
|
|
97
103
|
}
|
|
104
|
+
const prNumber = inspected.pullRequest.number;
|
|
105
|
+
const prIdentity = inspected.pullRequest.identity || { kind: 'number' as const, value: prNumber };
|
|
98
106
|
const closingIssues = extractClosingIssueNumbers(inspected.pullRequest.body);
|
|
99
|
-
const candidates = collectHostCandidates({ prNumber
|
|
107
|
+
const candidates = collectHostCandidates({ prNumber, prIdentity, closingIssues, workspaceRoot: cwd });
|
|
100
108
|
const host: HostResolution = resolveHostFromCandidates(candidates);
|
|
101
109
|
finish({
|
|
102
110
|
status: 'ok', changed: false,
|
|
103
|
-
pr: { number:
|
|
111
|
+
pr: { number: prNumber, identity: prIdentity, baseSha: inspected.pullRequest.base.sha, headSha: inspected.pullRequest.head.sha, state: inspected.pullRequest.state },
|
|
104
112
|
closingIssues, candidates, host,
|
|
105
113
|
taskIssueMatches: deriveTaskIssueMatches(host, closingIssues), error: null
|
|
106
114
|
});
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
if (!internalHandlerRoute('pr-review-grade', 'verify-artifact', operation)) { fail('operation is not registered'); return; }
|
|
110
119
|
if (typeof values.artifactFile !== 'string') { fail('verify-artifact requires --artifact-file'); return; }
|
|
111
120
|
const artifactPath = path.resolve(cwd, values.artifactFile);
|
|
112
121
|
let result: Record<string, unknown>;
|
|
113
122
|
try {
|
|
114
|
-
result = verifyInProcess({
|
|
123
|
+
result = await verifyInProcess({
|
|
115
124
|
mode: 'checks',
|
|
116
125
|
skillName: 'review-pr',
|
|
117
126
|
taskDir: path.dirname(artifactPath),
|
|
@@ -9,6 +9,7 @@ import { inspectPlatformRelease, reconcileReleaseMilestones } from '../platform/
|
|
|
9
9
|
import { inspectHomebrewChannel, inspectNpmChannel } from '../release/channels.ts';
|
|
10
10
|
import { releaseSnapshot } from '../release/workflow.ts';
|
|
11
11
|
import type { PostReleaseFacts, ReleaseFacts } from '../release/workflow.ts';
|
|
12
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
12
13
|
|
|
13
14
|
function command(cwd: string, executable: string, args: string[]) {
|
|
14
15
|
return spawnSync(executable, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
@@ -251,7 +252,7 @@ async function inspectFacts(cwd: string, version: string): Promise<ReleaseFacts>
|
|
|
251
252
|
const local = inspectLocalReleaseFacts(cwd, version);
|
|
252
253
|
const remoteBranch = branch ? git(cwd, ['ls-remote', '--heads', 'origin', branch]) : null;
|
|
253
254
|
const remoteTag = git(cwd, ['ls-remote', '--tags', 'origin', `refs/tags/${tag}`]);
|
|
254
|
-
const platform = inspectPlatformRelease(tag, { cwd });
|
|
255
|
+
const platform = await inspectPlatformRelease(tag, { cwd });
|
|
255
256
|
const npm = await inspectNpmChannel(pkg.name, version);
|
|
256
257
|
const formulaUrl = `https://raw.githubusercontent.com/${config.org}/homebrew-tap/main/Formula/${config.project}.rb`;
|
|
257
258
|
const homebrew = await inspectHomebrewChannel(formulaUrl, version);
|
|
@@ -262,7 +263,7 @@ async function inspectFacts(cwd: string, version: string): Promise<ReleaseFacts>
|
|
|
262
263
|
localTagAncestor: local.localTagAncestor,
|
|
263
264
|
localTagConflict: local.localTagConflict,
|
|
264
265
|
remoteBranch: Boolean(remoteBranch && remoteBranch.split(/\s+/)[0] === head), remoteTag: Boolean(remoteTag),
|
|
265
|
-
githubRelease: platform.
|
|
266
|
+
githubRelease: platform.error?.code === 'PLATFORM_CAPABILITY_UNSUPPORTED'
|
|
266
267
|
? true
|
|
267
268
|
: platform.status === 'blocked' ? null : Boolean(platform.release?.published),
|
|
268
269
|
npm: npm.published, homebrew: homebrew.published, smoke,
|
|
@@ -312,19 +313,26 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
|
|
|
312
313
|
const version = String(rawVersion || '').replace(/^v/, '');
|
|
313
314
|
const cwdIndex = rest.indexOf('--cwd');
|
|
314
315
|
const cwd = path.resolve(cwdIndex >= 0 && rest[cwdIndex + 1] ? rest[cwdIndex + 1]! : process.cwd());
|
|
315
|
-
if (![
|
|
316
|
+
if (![
|
|
317
|
+
internalHandlerRoute('release-workflow', 'inspect', action || ''),
|
|
318
|
+
internalHandlerRoute('release-workflow', 'prepare', action || ''),
|
|
319
|
+
internalHandlerRoute('release-workflow', 'publish', action || ''),
|
|
320
|
+
internalHandlerRoute('release-workflow', 'post-prepare', action || ''),
|
|
321
|
+
internalHandlerRoute('release-workflow', 'post-publish', action || '')
|
|
322
|
+
].some(Boolean) || !semver.valid(version)) {
|
|
316
323
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'RELEASE_INPUT_INVALID', message: 'Usage: release-workflow inspect|prepare|publish|post-prepare|post-publish <version>' } })}\n`);
|
|
317
324
|
process.exitCode = 1; return;
|
|
318
325
|
}
|
|
326
|
+
if (!ensureInternalHandlerRoute('release-workflow', args)) return;
|
|
319
327
|
const before = releaseSnapshot(version, await inspectFacts(cwd, version));
|
|
320
|
-
if (action
|
|
328
|
+
if (internalHandlerRoute('release-workflow', 'inspect', action || '')) { process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`); return; }
|
|
321
329
|
if (before.facts.localTagConflict) {
|
|
322
330
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'GIT_TAG_CONFLICT', message: `Tag v${version} is not reachable from HEAD` } })}\n`);
|
|
323
331
|
process.exitCode = 1; return;
|
|
324
332
|
}
|
|
325
|
-
if (action
|
|
333
|
+
if (internalHandlerRoute('release-workflow', 'prepare', action || '')) {
|
|
326
334
|
if (before.phase !== 'unprepared') {
|
|
327
|
-
const milestones = reconcileReleaseMilestones(version, { cwd });
|
|
335
|
+
const milestones = await reconcileReleaseMilestones(version, { cwd });
|
|
328
336
|
process.stdout.write(`${JSON.stringify({ ...milestones, snapshot: before })}\n`);
|
|
329
337
|
process.exitCode = milestones.status === 'failed' ? 1 : milestones.status === 'blocked' ? 2 : 0;
|
|
330
338
|
return;
|
|
@@ -344,7 +352,7 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
|
|
|
344
352
|
const committed = commitExplicitPaths({ cwd, paths: changedPaths(cwd), message: `chore: release v${version}` });
|
|
345
353
|
if (committed.status === 'failed') { process.stdout.write(`${JSON.stringify(committed)}\n`); process.exitCode = 1; return; }
|
|
346
354
|
const tagged = command(cwd, 'git', ['tag', '-a', `v${version}`, '-m', `Release v${version}`]);
|
|
347
|
-
const milestones = tagged.status === 0 ? reconcileReleaseMilestones(version, { cwd }) : null;
|
|
355
|
+
const milestones = tagged.status === 0 ? await reconcileReleaseMilestones(version, { cwd }) : null;
|
|
348
356
|
const snapshot = releaseSnapshot(version, await inspectFacts(cwd, version));
|
|
349
357
|
const failed = tagged.status !== 0 || milestones?.status === 'failed';
|
|
350
358
|
const blocked = milestones?.status === 'blocked';
|
|
@@ -352,14 +360,14 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
|
|
|
352
360
|
process.stdout.write(`${JSON.stringify({ status, changed: true, snapshot, operations: milestones?.operations ?? [], error: tagged.status !== 0 ? { code: 'GIT_TAG_FAILED', message: String(tagged.stderr) } : milestones?.error ?? null })}\n`);
|
|
353
361
|
process.exitCode = failed ? 1 : blocked ? 2 : 0; return;
|
|
354
362
|
}
|
|
355
|
-
if (action
|
|
363
|
+
if (internalHandlerRoute('release-workflow', 'publish', action || '')) {
|
|
356
364
|
if (!before.facts.localTag || !['prepared', 'partially-published'].includes(before.phase)) { process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_PHASE_INVALID', message: `Cannot publish from ${before.phase}` } })}\n`); process.exitCode = 1; return; }
|
|
357
365
|
const branch = git(cwd, ['branch', '--show-current']) || '';
|
|
358
366
|
const refs = [...(!before.facts.remoteBranch ? [branch] : []), ...(!before.facts.remoteTag ? [`refs/tags/v${version}`] : [])];
|
|
359
367
|
const result = pushGitRefs({ cwd, remote: 'origin', refs });
|
|
360
368
|
process.stdout.write(`${JSON.stringify({ ...result, snapshot: releaseSnapshot(version, await inspectFacts(cwd, version)) })}\n`); process.exitCode = result.status === 'failed' ? 1 : result.status === 'degraded' ? 2 : 0; return;
|
|
361
369
|
}
|
|
362
|
-
if (
|
|
370
|
+
if (internalHandlerRoute('release-workflow', 'post-publish', action || '')) {
|
|
363
371
|
const expectedValues = optionValues(rest, '--expected-sha256');
|
|
364
372
|
if (expectedValues.length !== 1 || !/^sha256:[0-9a-f]{64}$/.test(expectedValues[0]!)) {
|
|
365
373
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_INPUT_INVALID', message: 'post-publish requires one --expected-sha256 sha256:<64 hex>' } })}\n`);
|
|
@@ -394,6 +402,10 @@ async function releaseWorkflow(args: string[] = []): Promise<void> {
|
|
|
394
402
|
process.exitCode = blocked ? 2 : 1; return;
|
|
395
403
|
}
|
|
396
404
|
|
|
405
|
+
if (!internalHandlerRoute('release-workflow', 'post-prepare', action || '')) {
|
|
406
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, snapshot: before, error: { code: 'RELEASE_INPUT_INVALID', message: 'release-workflow action is not registered' } })}\n`);
|
|
407
|
+
process.exitCode = 1; return;
|
|
408
|
+
}
|
|
397
409
|
if (before.phase === 'complete') {
|
|
398
410
|
process.stdout.write(`${JSON.stringify({ status: 'no-op', changed: false, snapshot: before, error: null })}\n`);
|
|
399
411
|
return;
|