@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,90 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { applyQualificationConfirmation } from '../task/qualification-confirmation.js';
|
|
3
|
+
import { applyQualificationProposal } from '../task/qualification-intents.js';
|
|
4
|
+
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
5
|
+
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
|
|
6
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
7
|
+
const USAGE = `Usage: agent-infra-internal task-qualification <task-ref> <proposal|confirm|supersede|revoke> --input <json-file> [--dry-run]\n`;
|
|
8
|
+
function fail(message, code = 'QUALIFICATION_PROPOSAL_INVALID') {
|
|
9
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code, message } })}\n`);
|
|
10
|
+
process.stderr.write(USAGE);
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
}
|
|
13
|
+
async function taskQualification(args = []) {
|
|
14
|
+
const [taskRef, operation] = args;
|
|
15
|
+
const registered = [
|
|
16
|
+
internalHandlerRoute('task-qualification', 'proposal', operation ?? ''),
|
|
17
|
+
internalHandlerRoute('task-qualification', 'confirm', operation ?? ''),
|
|
18
|
+
internalHandlerRoute('task-qualification', 'supersede', operation ?? ''),
|
|
19
|
+
internalHandlerRoute('task-qualification', 'revoke', operation ?? '')
|
|
20
|
+
].some(Boolean);
|
|
21
|
+
if (!registered) {
|
|
22
|
+
fail('task ref and a valid qualification operation are required');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!ensureInternalHandlerRoute('task-qualification', args))
|
|
26
|
+
return;
|
|
27
|
+
if (!taskRef || !['proposal', 'confirm', 'supersede', 'revoke'].includes(operation ?? '')) {
|
|
28
|
+
fail('task ref and a valid qualification operation are required');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let inputPath = '';
|
|
32
|
+
let dryRun = false;
|
|
33
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
34
|
+
const arg = args[index];
|
|
35
|
+
if (arg === '--dry-run') {
|
|
36
|
+
if (dryRun) {
|
|
37
|
+
fail('duplicate option --dry-run');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
dryRun = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (arg !== '--input' || inputPath) {
|
|
44
|
+
fail(`unknown or duplicate option '${arg}'`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
inputPath = args[++index] ?? '';
|
|
48
|
+
if (!inputPath || inputPath.startsWith('--')) {
|
|
49
|
+
fail("option '--input' requires a value");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!inputPath) {
|
|
54
|
+
fail("option '--input' is required");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
let payload;
|
|
58
|
+
try {
|
|
59
|
+
payload = JSON.parse(fs.readFileSync(inputPath, 'utf8'));
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
fail(`cannot read qualification input: ${error instanceof Error ? error.message : String(error)}`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
66
|
+
fail('qualification input must be an object');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const resolved = resolveTaskRef(taskRef);
|
|
70
|
+
if (!resolved.ok) {
|
|
71
|
+
fail(resolved.message, resolved.code);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-qualification.${operation}`, () => operation === 'proposal'
|
|
76
|
+
? applyQualificationProposal({ ...payload, taskRef: resolved.taskId, dryRun }, { repoRoot: resolved.repoRoot })
|
|
77
|
+
: applyQualificationConfirmation({ ...payload, taskRef: resolved.taskId, operation, dryRun }, { repoRoot: resolved.repoRoot }));
|
|
78
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
79
|
+
if (result.status === 'failed')
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof TaskExecutionLockError)
|
|
84
|
+
fail(`${error.code}: ${error.message}`, error.code);
|
|
85
|
+
else
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export { taskQualification };
|
|
90
|
+
//# sourceMappingURL=task-qualification.js.map
|
|
@@ -2,6 +2,7 @@ import { finalizeReviewSummary } from '../task/review-finalization.js';
|
|
|
2
2
|
import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.js';
|
|
3
3
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
4
4
|
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
|
|
5
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
5
6
|
const USAGE = 'Usage: agent-infra-internal task-review <task-ref> finalize-summary --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run] [--override-ticket <ticket> --override-target <target> --override-scope <scope>]\n';
|
|
6
7
|
function failUsage(message) {
|
|
7
8
|
process.stdout.write(`${JSON.stringify({
|
|
@@ -13,7 +14,9 @@ function failUsage(message) {
|
|
|
13
14
|
process.stderr.write(USAGE);
|
|
14
15
|
process.exitCode = 2;
|
|
15
16
|
}
|
|
16
|
-
function taskReview(args = []) {
|
|
17
|
+
async function taskReview(args = []) {
|
|
18
|
+
if (!ensureInternalHandlerRoute('task-review', args))
|
|
19
|
+
return;
|
|
17
20
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
18
21
|
process.stdout.write(USAGE);
|
|
19
22
|
return;
|
|
@@ -22,7 +25,7 @@ function taskReview(args = []) {
|
|
|
22
25
|
failUsage('task ref and intent are required');
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
|
-
if (args[1]
|
|
28
|
+
if (!internalHandlerRoute('task-review', 'finalize-summary', args[1] ?? '')) {
|
|
26
29
|
failUsage(`unknown intent '${args[1]}'`);
|
|
27
30
|
return;
|
|
28
31
|
}
|
|
@@ -86,7 +89,7 @@ function taskReview(args = []) {
|
|
|
86
89
|
let result;
|
|
87
90
|
let humanOverride = null;
|
|
88
91
|
try {
|
|
89
|
-
result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-review.finalize-summary', () => {
|
|
92
|
+
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-review.finalize-summary', async () => {
|
|
90
93
|
let current = finalizeReviewSummary({ taskRef: args[0], stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true });
|
|
91
94
|
if (current.status !== 'failed' || !overrideTicket)
|
|
92
95
|
return current;
|
|
@@ -94,7 +97,7 @@ function taskReview(args = []) {
|
|
|
94
97
|
failUsage('override ticket requires target and scope');
|
|
95
98
|
return current;
|
|
96
99
|
}
|
|
97
|
-
const consumed = consumeHumanOverride({
|
|
100
|
+
const consumed = await consumeHumanOverride({
|
|
98
101
|
taskRef: args[0], ticketId: overrideTicket,
|
|
99
102
|
failureId: failureId('review-finalization', current.error?.code ?? 'TASK_STATE_MISMATCH'),
|
|
100
103
|
target: overrideTarget, scope: overrideScope
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { detectRepoRoot } from '../task/resolve-ref.js';
|
|
3
3
|
import { configuredShortIdLength, executeShortIdCommand } from '../task/short-id.js';
|
|
4
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
4
5
|
const USAGE = `Usage: agent-infra-internal task-short-id <alloc|release|resolve|list> [argument] [--active-dir <path>] [--short-id-length <N>] [--verify]\n`;
|
|
5
6
|
function failure(message) {
|
|
6
7
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, output: '', error: { code: 'SHORT_ID_PAYLOAD_INVALID', message } })}\n`);
|
|
@@ -8,12 +9,21 @@ function failure(message) {
|
|
|
8
9
|
process.exitCode = 1;
|
|
9
10
|
}
|
|
10
11
|
function taskShortId(args = []) {
|
|
12
|
+
if (!ensureInternalHandlerRoute('task-short-id', args))
|
|
13
|
+
return;
|
|
11
14
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
12
15
|
process.stdout.write(USAGE);
|
|
13
16
|
return;
|
|
14
17
|
}
|
|
15
18
|
const operation = args[0];
|
|
16
|
-
|
|
19
|
+
const route = operation === 'list' && args.includes('--verify') ? 'list-verify' : operation ?? '';
|
|
20
|
+
if (!operation || ![
|
|
21
|
+
internalHandlerRoute('task-short-id', 'alloc', route),
|
|
22
|
+
internalHandlerRoute('task-short-id', 'release', route),
|
|
23
|
+
internalHandlerRoute('task-short-id', 'resolve', route),
|
|
24
|
+
internalHandlerRoute('task-short-id', 'list', route),
|
|
25
|
+
internalHandlerRoute('task-short-id', 'list-verify', route)
|
|
26
|
+
].some(Boolean)) {
|
|
17
27
|
failure('a valid short-id operation is required');
|
|
18
28
|
return;
|
|
19
29
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { collectTaskSnapshot } from '../task/snapshot.js';
|
|
2
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
2
3
|
const USAGE = 'Usage: agent-infra-internal task-snapshot <N | TASK-id> [--format json|text]\n';
|
|
3
4
|
function fail(message) {
|
|
4
5
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SNAPSHOT_PAYLOAD_INVALID', message } })}\n`);
|
|
@@ -6,11 +7,13 @@ function fail(message) {
|
|
|
6
7
|
process.exitCode = 1;
|
|
7
8
|
}
|
|
8
9
|
function taskSnapshot(args = []) {
|
|
10
|
+
if (!ensureInternalHandlerRoute('task-snapshot', args))
|
|
11
|
+
return;
|
|
9
12
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
10
13
|
process.stdout.write(USAGE);
|
|
11
14
|
return;
|
|
12
15
|
}
|
|
13
|
-
if (!args[0] || args[0].startsWith('--')) {
|
|
16
|
+
if (!args[0] || args[0].startsWith('--') || !internalHandlerRoute('task-snapshot', 'snapshot', 'snapshot')) {
|
|
14
17
|
fail('task ref is required');
|
|
15
18
|
return;
|
|
16
19
|
}
|
|
@@ -16,6 +16,7 @@ import { readSandboxControlManifest } from '../sandbox/control/lifecycle.js';
|
|
|
16
16
|
import { SANDBOX_CONTROL_FUTURE_SKEW_MS, SANDBOX_CONTROL_STATUS_STALE_MS } from '../sandbox/control/protocol.js';
|
|
17
17
|
import { getProcessStartTime } from '../server/process-state.js';
|
|
18
18
|
import { assertGitWorktreeBinding } from '../git/worktree-identity.js';
|
|
19
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
19
20
|
const USAGE = `Usage: agent-infra-internal task-validate <branch | TASK-id | N> [--scope snapshot|inplace] [--timeout <ms>] [--format text|json] -- <command> [args...]`;
|
|
20
21
|
const MAX_TIMEOUT_MS = 60 * 60 * 1000;
|
|
21
22
|
const RECOVERY_GRACE_MS = 30_000;
|
|
@@ -273,6 +274,8 @@ function sniffFormat(args) {
|
|
|
273
274
|
return index >= 0 && args[index + 1] === 'json' ? 'json' : 'text';
|
|
274
275
|
}
|
|
275
276
|
function taskValidate(args) {
|
|
277
|
+
if (!ensureInternalHandlerRoute('task-validate', args))
|
|
278
|
+
return;
|
|
276
279
|
let options;
|
|
277
280
|
try {
|
|
278
281
|
options = parseValidateArgs(args);
|
|
@@ -290,9 +293,11 @@ function taskValidate(args) {
|
|
|
290
293
|
const target = resolveSandboxTarget(options.target, config.repoRoot);
|
|
291
294
|
const commit = git(config.repoRoot, ['rev-parse', target.branch]);
|
|
292
295
|
const startedAt = new Date().toISOString();
|
|
293
|
-
const result =
|
|
296
|
+
const result = internalHandlerRoute('task-validate', 'snapshot', options.scope)
|
|
294
297
|
? snapshotValidation(config.repoRoot, commit, options)
|
|
295
|
-
:
|
|
298
|
+
: internalHandlerRoute('task-validate', 'inplace', options.scope)
|
|
299
|
+
? inplaceValidation(config, target, options)
|
|
300
|
+
: (() => { throw new Error('TASK_VALIDATE_SCOPE_UNREGISTERED'); })();
|
|
296
301
|
const evidence = {
|
|
297
302
|
version: 1,
|
|
298
303
|
taskId: target.workspace.mode === 'task-bound' ? target.workspace.taskId : null,
|
|
@@ -2,18 +2,22 @@ import { renderTaskVerification, verifyTaskEvent } from '../task/verification.js
|
|
|
2
2
|
import { consumeHumanOverride, failureId } from '../task/human-override.js';
|
|
3
3
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
4
4
|
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
|
|
5
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
5
6
|
const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text] [--override-ticket <ticket> --override-target <target> --override-scope <scope>]\n';
|
|
6
7
|
function fail(message) {
|
|
7
8
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'VERIFY_PAYLOAD_INVALID', message } })}\n`);
|
|
8
9
|
process.stderr.write(USAGE);
|
|
9
10
|
process.exitCode = 1;
|
|
10
11
|
}
|
|
11
|
-
function taskVerify(args = []) {
|
|
12
|
+
async function taskVerify(args = []) {
|
|
13
|
+
if (!ensureInternalHandlerRoute('task-verify', args))
|
|
14
|
+
return;
|
|
12
15
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
13
16
|
process.stdout.write(USAGE);
|
|
14
17
|
return;
|
|
15
18
|
}
|
|
16
|
-
if (!args[0] || !args[1] || args[0].startsWith('--') || args[1].startsWith('--')
|
|
19
|
+
if (!args[0] || !args[1] || args[0].startsWith('--') || args[1].startsWith('--')
|
|
20
|
+
|| !internalHandlerRoute('task-verify', 'event', args[1] ? 'event' : '')) {
|
|
17
21
|
fail('task ref and verification event are required');
|
|
18
22
|
return;
|
|
19
23
|
}
|
|
@@ -64,8 +68,8 @@ function taskVerify(args = []) {
|
|
|
64
68
|
let result;
|
|
65
69
|
let humanOverride = null;
|
|
66
70
|
try {
|
|
67
|
-
result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, () => {
|
|
68
|
-
let current = verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) });
|
|
71
|
+
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, async () => {
|
|
72
|
+
let current = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) });
|
|
69
73
|
if (current.status === 'pass' || !overrideTicket)
|
|
70
74
|
return current;
|
|
71
75
|
if (!overrideTarget || !overrideScope) {
|
|
@@ -80,13 +84,13 @@ function taskVerify(args = []) {
|
|
|
80
84
|
: current.status === 'fail'
|
|
81
85
|
? 'CHECK_FAILED'
|
|
82
86
|
: current.error?.code ?? 'VERIFY_TASK_STATE_MISMATCH';
|
|
83
|
-
const consumed = consumeHumanOverride({
|
|
87
|
+
const consumed = await consumeHumanOverride({
|
|
84
88
|
taskRef, ticketId: overrideTicket,
|
|
85
89
|
failureId: failureId(failureProducer, failureCode),
|
|
86
90
|
target: overrideTarget, scope: overrideScope
|
|
87
91
|
}, {
|
|
88
|
-
effectExecutor: (capability) => {
|
|
89
|
-
const retried = verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }, { manualOverride: capability });
|
|
92
|
+
effectExecutor: async (capability) => {
|
|
93
|
+
const retried = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }, { manualOverride: capability });
|
|
90
94
|
current = retried;
|
|
91
95
|
return retried.status !== 'pass'
|
|
92
96
|
? { code: 'OVERRIDE_EFFECT_FAILED', message: `${retried.error?.code ?? 'VERIFY_FAILED'}: ${retried.error?.message ?? 'manual verification effect failed'}` }
|
|
@@ -2,6 +2,7 @@ import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.js'
|
|
|
2
2
|
import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.js';
|
|
3
3
|
import { resolveTaskRef } from '../task/resolve-ref.js';
|
|
4
4
|
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
|
|
5
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
|
|
5
6
|
const USAGE = `Usage: agent-infra-internal task-warning <task-ref> <add|set-status|list> [intent flags] [--dry-run]\n`;
|
|
6
7
|
const FLAGS = {
|
|
7
8
|
'--step': 'step', '--severity': 'severity', '--code': 'code', '--target': 'target',
|
|
@@ -13,13 +14,19 @@ function usageFailure(message) {
|
|
|
13
14
|
process.stderr.write(USAGE);
|
|
14
15
|
process.exitCode = 1;
|
|
15
16
|
}
|
|
16
|
-
function taskWarning(args = []) {
|
|
17
|
+
async function taskWarning(args = []) {
|
|
18
|
+
if (!ensureInternalHandlerRoute('task-warning', args))
|
|
19
|
+
return;
|
|
17
20
|
if (args[0] === '--help' || args[0] === '-h') {
|
|
18
21
|
process.stdout.write(USAGE);
|
|
19
22
|
return;
|
|
20
23
|
}
|
|
21
24
|
const [taskRef, kind] = args;
|
|
22
|
-
if (!taskRef || !kind || ![
|
|
25
|
+
if (!taskRef || !kind || ![
|
|
26
|
+
internalHandlerRoute('task-warning', 'add', kind ?? ''),
|
|
27
|
+
internalHandlerRoute('task-warning', 'set-status', kind ?? ''),
|
|
28
|
+
internalHandlerRoute('task-warning', 'list', kind ?? '')
|
|
29
|
+
].some(Boolean)) {
|
|
23
30
|
usageFailure('task ref and a valid intent are required');
|
|
24
31
|
return;
|
|
25
32
|
}
|
|
@@ -85,7 +92,7 @@ function taskWarning(args = []) {
|
|
|
85
92
|
let result;
|
|
86
93
|
let humanOverride = null;
|
|
87
94
|
try {
|
|
88
|
-
result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, () => {
|
|
95
|
+
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, async () => {
|
|
89
96
|
let current = applyWorkflowWarningIntent(values);
|
|
90
97
|
if (current.status !== 'failed' || !values.overrideTicket)
|
|
91
98
|
return current;
|
|
@@ -93,7 +100,7 @@ function taskWarning(args = []) {
|
|
|
93
100
|
usageFailure('override ticket requires target and scope');
|
|
94
101
|
return current;
|
|
95
102
|
}
|
|
96
|
-
const consumed = consumeHumanOverride({
|
|
103
|
+
const consumed = await consumeHumanOverride({
|
|
97
104
|
taskRef, ticketId: String(values.overrideTicket),
|
|
98
105
|
failureId: failureId('workflow-warning', current.error?.code ?? 'TASK_STATE_MISMATCH'),
|
|
99
106
|
target: String(values.overrideTarget), scope: String(values.overrideScope)
|
|
@@ -8,9 +8,7 @@ function getPlatformAdapter(type) {
|
|
|
8
8
|
return type ? adapters.get(type) ?? null : null;
|
|
9
9
|
}
|
|
10
10
|
function registerPlatformCapabilities(type, capabilities) {
|
|
11
|
-
const adapter = adapters.get(type);
|
|
12
|
-
if (!adapter)
|
|
13
|
-
throw new Error(`Platform adapter '${type}' must be registered before its capabilities`);
|
|
11
|
+
const adapter = adapters.get(type) ?? { type };
|
|
14
12
|
adapters.set(type, { ...adapter, ...capabilities });
|
|
15
13
|
}
|
|
16
14
|
function hasPlatformCapability(type, capability) {
|
|
@@ -2,7 +2,9 @@ import fs from "node:fs";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
5
|
-
import {
|
|
5
|
+
import { resolvePlatformProviderContext } from './context.js';
|
|
6
|
+
import { providerError, providerOperationContext, unsupportedProviderOperation } from './provider-bridge.js';
|
|
7
|
+
import { isResourceIdentity } from './resource-identity.js';
|
|
6
8
|
import { resolveReviewedHeadRelation } from "./merged-pr-equivalence.js";
|
|
7
9
|
const SHA_PATTERN = /^[0-9a-f]{40}$/i;
|
|
8
10
|
const REVIEWED_HEAD_REF = "refs/agent-infra/reviewed-head";
|
|
@@ -37,18 +39,36 @@ function validMergeIdentity(lastReviewedCommit, pullRequest) {
|
|
|
37
39
|
}
|
|
38
40
|
return null;
|
|
39
41
|
}
|
|
40
|
-
function resolveMaterializedReviewedHeadRelation(input) {
|
|
42
|
+
async function resolveMaterializedReviewedHeadRelation(input) {
|
|
41
43
|
const identityFailure = validMergeIdentity(input.lastReviewedCommit, input.pullRequest);
|
|
42
44
|
if (identityFailure)
|
|
43
45
|
return identityFailure;
|
|
44
|
-
const
|
|
46
|
+
const loaded = await resolvePlatformProviderContext({
|
|
45
47
|
cwd: input.cwd,
|
|
46
|
-
|
|
47
|
-
number: input.pullRequest.number,
|
|
48
|
-
pullRequest: input.pullRequest
|
|
48
|
+
platformType: input.platformType || undefined
|
|
49
49
|
});
|
|
50
|
+
if (!loaded.ok) {
|
|
51
|
+
return blocked(loaded.context.error?.code || 'PR_MERGE_EVIDENCE_SOURCE_UNAVAILABLE', loaded.context.error?.message || 'Unable to resolve the configured platform provider');
|
|
52
|
+
}
|
|
53
|
+
const target = isResourceIdentity(input.pullRequest.identity)
|
|
54
|
+
? input.pullRequest.identity
|
|
55
|
+
: { kind: 'number', value: input.pullRequest.number };
|
|
56
|
+
const operation = loaded.value.provider.changeRequests?.resolveGitEvidence
|
|
57
|
+
? await loaded.value.provider.changeRequests.resolveGitEvidence({
|
|
58
|
+
context: providerOperationContext(loaded.value),
|
|
59
|
+
target,
|
|
60
|
+
expected: {
|
|
61
|
+
baseSha: input.pullRequest.base.sha,
|
|
62
|
+
headSha: input.pullRequest.head.sha,
|
|
63
|
+
targetBranch: input.pullRequest.base.ref
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
: unsupportedProviderOperation(loaded.value.provider, 'changeRequests.resolveGitEvidence');
|
|
67
|
+
const source = operation.ok
|
|
68
|
+
? operation
|
|
69
|
+
: { ok: false, error: providerError(operation.error, 'PR_MERGE_EVIDENCE_SOURCE_UNAVAILABLE') };
|
|
50
70
|
if (!source.ok || !source.value) {
|
|
51
|
-
return blocked(source.error?.code || "PR_MERGE_EVIDENCE_SOURCE_UNAVAILABLE", source.error?.message || "Unable to resolve authoritative PR Git evidence");
|
|
71
|
+
return blocked(('error' in source && source.error?.code) || "PR_MERGE_EVIDENCE_SOURCE_UNAVAILABLE", ('error' in source && source.error?.message) || "Unable to resolve authoritative PR Git evidence");
|
|
52
72
|
}
|
|
53
73
|
if (!source.value.remoteUrl.trim() ||
|
|
54
74
|
source.value.remoteUrl.trimStart().startsWith("-") ||
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
const CONTROL_MARKER_PATTERN = /<!--\s*(?:sync-issue|sync-pr|last-commit)\b[\s\S]*?-->|<!--\s*canonical-pr-change-report\s*-->/gi;
|
|
2
|
+
function ok(value) {
|
|
3
|
+
return { ok: true, value };
|
|
4
|
+
}
|
|
5
|
+
function invalid(message, offset) {
|
|
6
|
+
return { ok: false, error: { code: 'COMMENT_DOCUMENT_INVALID', message, offset } };
|
|
7
|
+
}
|
|
8
|
+
function normalized(value) {
|
|
9
|
+
return value.replace(/\r\n?/g, '\n');
|
|
10
|
+
}
|
|
11
|
+
function linesOf(value) {
|
|
12
|
+
const lines = [];
|
|
13
|
+
let start = 0;
|
|
14
|
+
while (start < value.length) {
|
|
15
|
+
const newline = value.indexOf('\n', start);
|
|
16
|
+
const end = newline === -1 ? value.length : newline;
|
|
17
|
+
lines.push({ start, end: newline === -1 ? end : newline + 1, text: value.slice(start, end) });
|
|
18
|
+
start = newline === -1 ? value.length : newline + 1;
|
|
19
|
+
}
|
|
20
|
+
if (value.length === 0)
|
|
21
|
+
lines.push({ start: 0, end: 0, text: '' });
|
|
22
|
+
return lines;
|
|
23
|
+
}
|
|
24
|
+
function openingFence(line) {
|
|
25
|
+
const match = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
26
|
+
if (!match)
|
|
27
|
+
return null;
|
|
28
|
+
const character = match[1][0];
|
|
29
|
+
const info = match[2];
|
|
30
|
+
if (character === '`' && info.includes('`'))
|
|
31
|
+
return 'invalid';
|
|
32
|
+
return { character, length: match[1].length };
|
|
33
|
+
}
|
|
34
|
+
function closesFence(line, fence) {
|
|
35
|
+
const escaped = fence.character === '`' ? '`' : '~';
|
|
36
|
+
return new RegExp(`^ {0,3}${escaped}{${fence.length},}[ \\t]*$`).test(line);
|
|
37
|
+
}
|
|
38
|
+
function fenceRanges(value) {
|
|
39
|
+
const ranges = [];
|
|
40
|
+
let fence = null;
|
|
41
|
+
for (const line of linesOf(value)) {
|
|
42
|
+
if (!fence) {
|
|
43
|
+
const opening = openingFence(line.text);
|
|
44
|
+
if (opening === 'invalid')
|
|
45
|
+
return invalid('fenced code info string is invalid', line.start);
|
|
46
|
+
if (opening)
|
|
47
|
+
fence = { ...opening, start: line.start, openingEnd: line.end };
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (closesFence(line.text, fence)) {
|
|
51
|
+
ranges.push({
|
|
52
|
+
start: fence.start,
|
|
53
|
+
end: line.end,
|
|
54
|
+
openingEnd: fence.openingEnd,
|
|
55
|
+
closingStart: line.start,
|
|
56
|
+
character: fence.character,
|
|
57
|
+
opening: value.slice(fence.start, fence.openingEnd),
|
|
58
|
+
closing: value.slice(line.start, line.end)
|
|
59
|
+
});
|
|
60
|
+
fence = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (fence)
|
|
64
|
+
return invalid('fenced code block is not closed', fence.start);
|
|
65
|
+
return ok(ranges);
|
|
66
|
+
}
|
|
67
|
+
function escapeHtml(value) {
|
|
68
|
+
return value
|
|
69
|
+
.replace(/&/g, '&')
|
|
70
|
+
.replace(/</g, '<')
|
|
71
|
+
.replace(/>/g, '>')
|
|
72
|
+
.replace(/"/g, '"')
|
|
73
|
+
.replace(/'/g, ''');
|
|
74
|
+
}
|
|
75
|
+
function escapeHtmlText(value) {
|
|
76
|
+
return escapeHtml(value);
|
|
77
|
+
}
|
|
78
|
+
function escapeHtmlAttribute(value) {
|
|
79
|
+
return escapeHtml(value);
|
|
80
|
+
}
|
|
81
|
+
function escapeMarkdownLiteral(value) {
|
|
82
|
+
return value.replace(/[\\`*_{}\[\]()#+.!|<>-]/g, '\\$&');
|
|
83
|
+
}
|
|
84
|
+
function markerSafe(value, markers) {
|
|
85
|
+
let result = value;
|
|
86
|
+
for (const marker of markers) {
|
|
87
|
+
const flags = marker.flags.includes('g') ? marker.flags : `${marker.flags}g`;
|
|
88
|
+
const pattern = new RegExp(marker.source, flags);
|
|
89
|
+
result = result.replace(pattern, (match) => escapeHtmlText(match));
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
function tagEnd(value, start) {
|
|
94
|
+
let quote = null;
|
|
95
|
+
for (let index = start + 1; index < value.length; index += 1) {
|
|
96
|
+
const character = value[index];
|
|
97
|
+
if (quote) {
|
|
98
|
+
if (character === quote)
|
|
99
|
+
quote = null;
|
|
100
|
+
}
|
|
101
|
+
else if (character === '"' || character === "'") {
|
|
102
|
+
quote = character;
|
|
103
|
+
}
|
|
104
|
+
else if (character === '>') {
|
|
105
|
+
return index;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return -1;
|
|
109
|
+
}
|
|
110
|
+
function isMarkdownAutolink(value, start) {
|
|
111
|
+
const end = value.indexOf('>', start + 1);
|
|
112
|
+
if (end === -1)
|
|
113
|
+
return false;
|
|
114
|
+
const target = value.slice(start + 1, end);
|
|
115
|
+
return /^(?:https?:\/\/|mailto:)[^<>\s]+$/i.test(target)
|
|
116
|
+
|| /^[^<>\s@]+@[^<>\s@]+\.[^<>\s@]+$/.test(target);
|
|
117
|
+
}
|
|
118
|
+
function sanitizeOutside(value, baseOffset) {
|
|
119
|
+
let result = '';
|
|
120
|
+
let index = 0;
|
|
121
|
+
while (index < value.length) {
|
|
122
|
+
if (value.startsWith('<!--', index)) {
|
|
123
|
+
const end = value.indexOf('-->', index + 4);
|
|
124
|
+
if (end === -1)
|
|
125
|
+
return invalid('HTML comment is not closed', baseOffset + index);
|
|
126
|
+
const token = value.slice(index, end + 3);
|
|
127
|
+
result += escapeHtmlText(token);
|
|
128
|
+
index = end + 3;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (value[index] === '<' && isMarkdownAutolink(value, index)) {
|
|
132
|
+
const end = value.indexOf('>', index + 1);
|
|
133
|
+
result += value.slice(index, end + 1);
|
|
134
|
+
index = end + 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (value[index] === '<' && /[\\/!?A-Za-z]/.test(value[index + 1] || '')) {
|
|
138
|
+
const end = tagEnd(value, index);
|
|
139
|
+
if (end === -1)
|
|
140
|
+
return invalid('HTML-like tag is not closed', baseOffset + index);
|
|
141
|
+
result += escapeHtmlText(value.slice(index, end + 1));
|
|
142
|
+
index = end + 1;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
result += value[index];
|
|
146
|
+
index += 1;
|
|
147
|
+
}
|
|
148
|
+
return ok(result);
|
|
149
|
+
}
|
|
150
|
+
function sanitizeMarkdownDocument(value, options = {}) {
|
|
151
|
+
const source = normalized(value);
|
|
152
|
+
const ranges = fenceRanges(source);
|
|
153
|
+
if (!ranges.ok)
|
|
154
|
+
return ranges;
|
|
155
|
+
const markers = options.reservedMarkers || [];
|
|
156
|
+
let result = '';
|
|
157
|
+
let cursor = 0;
|
|
158
|
+
for (const range of ranges.value) {
|
|
159
|
+
const outside = sanitizeOutside(source.slice(cursor, range.start), cursor);
|
|
160
|
+
if (!outside.ok)
|
|
161
|
+
return outside;
|
|
162
|
+
result += outside.value;
|
|
163
|
+
result += markerSafe(source.slice(range.start, range.end), markers);
|
|
164
|
+
cursor = range.end;
|
|
165
|
+
}
|
|
166
|
+
const tail = sanitizeOutside(source.slice(cursor), cursor);
|
|
167
|
+
if (!tail.ok)
|
|
168
|
+
return tail;
|
|
169
|
+
return ok(result + tail.value);
|
|
170
|
+
}
|
|
171
|
+
function renderSafeCodeFence(value, language = '', reservedMarkers = [CONTROL_MARKER_PATTERN]) {
|
|
172
|
+
const content = markerSafe(normalized(value), reservedMarkers);
|
|
173
|
+
const longestRun = Math.max(0, ...(content.match(/`+/g) || []).map((run) => run.length));
|
|
174
|
+
const delimiter = '`'.repeat(Math.max(3, longestRun + 1));
|
|
175
|
+
const suffix = content.endsWith('\n') ? '' : '\n';
|
|
176
|
+
return `${delimiter}${language}\n${content}${suffix}${delimiter}`;
|
|
177
|
+
}
|
|
178
|
+
function commentRangesOutsideFences(source, ranges) {
|
|
179
|
+
const comments = [];
|
|
180
|
+
let cursor = 0;
|
|
181
|
+
for (const fence of [...ranges, { start: source.length, end: source.length }]) {
|
|
182
|
+
const segment = source.slice(cursor, fence.start);
|
|
183
|
+
let index = 0;
|
|
184
|
+
while (index < segment.length) {
|
|
185
|
+
const opening = segment.indexOf('<!--', index);
|
|
186
|
+
if (opening === -1)
|
|
187
|
+
break;
|
|
188
|
+
const absoluteStart = cursor + opening;
|
|
189
|
+
const closing = segment.indexOf('-->', opening + 4);
|
|
190
|
+
if (closing === -1)
|
|
191
|
+
return invalid('HTML comment is not closed', absoluteStart);
|
|
192
|
+
comments.push({ start: absoluteStart, end: cursor + closing + 3 });
|
|
193
|
+
index = closing + 3;
|
|
194
|
+
}
|
|
195
|
+
cursor = fence.end;
|
|
196
|
+
}
|
|
197
|
+
return ok(comments);
|
|
198
|
+
}
|
|
199
|
+
function splitDocumentPlaceholder(value, placeholder) {
|
|
200
|
+
const source = normalized(value);
|
|
201
|
+
const ranges = fenceRanges(source);
|
|
202
|
+
if (!ranges.ok)
|
|
203
|
+
return ranges;
|
|
204
|
+
const positions = [];
|
|
205
|
+
let cursor = source.indexOf(placeholder);
|
|
206
|
+
while (cursor !== -1) {
|
|
207
|
+
positions.push(cursor);
|
|
208
|
+
cursor = source.indexOf(placeholder, cursor + placeholder.length);
|
|
209
|
+
}
|
|
210
|
+
if (positions.length !== 1)
|
|
211
|
+
return invalid('document must contain exactly one placeholder', positions[1] ?? positions[0] ?? source.length);
|
|
212
|
+
const position = positions[0];
|
|
213
|
+
if (ranges.value.some((range) => position >= range.start && position < range.end)) {
|
|
214
|
+
return invalid('placeholder must be outside fenced code', position);
|
|
215
|
+
}
|
|
216
|
+
const comments = commentRangesOutsideFences(source, ranges.value);
|
|
217
|
+
if (!comments.ok)
|
|
218
|
+
return comments;
|
|
219
|
+
const containing = comments.value.find((comment) => position >= comment.start && position < comment.end);
|
|
220
|
+
if (containing && (containing.start !== position || containing.end !== position + placeholder.length)) {
|
|
221
|
+
return invalid('placeholder must not be nested in another HTML comment', position);
|
|
222
|
+
}
|
|
223
|
+
return ok({ prefix: source.slice(0, position), suffix: source.slice(position + placeholder.length) });
|
|
224
|
+
}
|
|
225
|
+
export { CONTROL_MARKER_PATTERN, escapeHtmlAttribute, escapeHtmlText, escapeMarkdownLiteral, fenceRanges, renderSafeCodeFence, sanitizeMarkdownDocument, splitDocumentPlaceholder };
|
|
226
|
+
//# sourceMappingURL=comment-safety.js.map
|
|
@@ -9,6 +9,7 @@ import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.js'
|
|
|
9
9
|
import { captureTaskWriteMetadata } from '../task/write.js';
|
|
10
10
|
import { syncPlatformComment } from './issue-comments.js';
|
|
11
11
|
import { platformResult } from './types.js';
|
|
12
|
+
import { taskIssueIdentity } from './task-identities.js';
|
|
12
13
|
function result(base, artifacts, warnings) {
|
|
13
14
|
return { ...base, artifacts, warnings };
|
|
14
15
|
}
|
|
@@ -29,7 +30,7 @@ function excludedPrReview(taskDir, message) {
|
|
|
29
30
|
return null;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
function backfillCompletionComments(taskRef, options) {
|
|
33
|
+
async function backfillCompletionComments(taskRef, options) {
|
|
33
34
|
const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
|
|
34
35
|
if (!resolved.ok)
|
|
35
36
|
return result(platformResult('failed', {
|
|
@@ -45,16 +46,16 @@ function backfillCompletionComments(taskRef, options) {
|
|
|
45
46
|
}
|
|
46
47
|
}), [], []);
|
|
47
48
|
const initialContent = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
48
|
-
const
|
|
49
|
-
if (!
|
|
49
|
+
const issueIdentity = taskIssueIdentity(parseTaskFrontmatter(initialContent));
|
|
50
|
+
if (!issueIdentity)
|
|
50
51
|
return result(platformResult('no-op', {
|
|
51
|
-
error: { code: 'ISSUE_NOT_LINKED', message: 'Task has no valid
|
|
52
|
+
error: { code: 'ISSUE_NOT_LINKED', message: 'Task has no valid platform issue identity', retryable: false }
|
|
52
53
|
}), [], []);
|
|
53
54
|
const artifacts = [];
|
|
54
55
|
const operations = [];
|
|
55
56
|
let latest = platformResult('no-op', { error: null });
|
|
56
57
|
for (const artifact of inventory.artifacts) {
|
|
57
|
-
latest = syncPlatformComment(resolved.taskId, {
|
|
58
|
+
latest = await syncPlatformComment(resolved.taskId, {
|
|
58
59
|
kind: 'artifact',
|
|
59
60
|
artifact: artifact.name,
|
|
60
61
|
agent: options.agent,
|