@fitlab-ai/agent-infra 0.9.13 → 0.9.15
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 +10 -0
- package/README.zh-CN.md +10 -0
- package/bin/cli.ts +26 -9
- package/bin/internal-cli.sh +45 -0
- package/dist/bin/cli.js +173 -157
- package/dist/bin/internal-cli.js +126 -42
- package/dist/lib/agent-client.js +5 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
- package/dist/lib/defaults.json +103 -103
- package/dist/lib/fs/durable-write.js +37 -0
- package/dist/lib/fs/file-lock.js +111 -0
- package/dist/lib/host-control/audit.js +19 -0
- package/dist/lib/host-control/client.js +142 -0
- package/dist/lib/host-control/command.js +49 -0
- package/dist/lib/host-control/path.js +160 -0
- package/dist/lib/host-control/secure-fs.js +140 -0
- package/dist/lib/host-control/server.js +159 -0
- package/dist/lib/host-control/service.js +112 -0
- package/dist/lib/init.js +11 -2
- package/dist/lib/internal/agent-client.js +5 -2
- package/dist/lib/internal/cli-route-inventory.js +154 -0
- package/dist/lib/internal/codex-lifecycle.js +15 -12
- package/dist/lib/internal/codex-sandbox-controller.js +8 -2
- package/dist/lib/internal/demo-promotion.js +322 -0
- package/dist/lib/internal/demo-transcript.js +454 -0
- package/dist/lib/internal/git-workflow.js +10 -6
- package/dist/lib/internal/host-control.js +28 -0
- package/dist/lib/internal/manual-validation.js +322 -0
- package/dist/lib/internal/platform-checks.js +16 -4
- package/dist/lib/internal/platform-comment.js +16 -4
- package/dist/lib/internal/platform-context.js +4 -1
- package/dist/lib/internal/platform-issue.js +12 -4
- package/dist/lib/internal/platform-metadata.js +88 -0
- package/dist/lib/internal/platform-pr-review.js +16 -3
- package/dist/lib/internal/platform-pr.js +42 -14
- package/dist/lib/internal/platform-release-notes.js +6 -3
- package/dist/lib/internal/platform-security.js +93 -0
- package/dist/lib/internal/pr-review-grade.js +14 -3
- package/dist/lib/internal/release-workflow.js +82 -89
- package/dist/lib/internal/sandbox-control.js +171 -7
- package/dist/lib/internal/task-activity.js +13 -4
- package/dist/lib/internal/task-artifact.js +19 -107
- package/dist/lib/internal/task-context.js +4 -1
- package/dist/lib/internal/task-create.js +48 -14
- package/dist/lib/internal/task-delivery.js +4 -1
- package/dist/lib/internal/task-event.js +38 -35
- package/dist/lib/internal/task-finalization.js +4 -1
- package/dist/lib/internal/task-invalidation.js +4 -1
- package/dist/lib/internal/task-ledger.js +12 -1
- package/dist/lib/internal/task-lifecycle.js +4 -1
- package/dist/lib/internal/task-operation-registry.js +519 -0
- package/dist/lib/internal/task-orchestration.js +12 -0
- package/dist/lib/internal/task-override.js +10 -3
- package/dist/lib/internal/task-qualification.js +90 -0
- package/dist/lib/internal/task-review.js +10 -52
- 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 +37 -12
- package/dist/lib/internal/task-verify.js +5 -1
- package/dist/lib/internal/task-warning.js +8 -1
- package/dist/lib/owned-path.js +33 -0
- package/dist/lib/platform/check-status.js +11 -0
- package/dist/lib/platform/comment-safety.js +229 -0
- package/dist/lib/platform/completion-backfill.js +1 -1
- package/dist/lib/platform/github-data.js +241 -0
- package/dist/lib/platform/github-provider.js +248 -26
- package/dist/lib/platform/issue-comments.js +146 -34
- package/dist/lib/platform/issues.js +1 -179
- package/dist/lib/platform/pr-change-report.js +6 -12
- package/dist/lib/platform/pr-checks.js +12 -65
- package/dist/lib/platform/pr-summary.js +83 -10
- package/dist/lib/platform/provider-contract.d.ts +67 -1
- package/dist/lib/platform/provider-contract.js +6 -2
- package/dist/lib/platform/provider-validation.js +76 -3
- package/dist/lib/platform/pull-requests.js +117 -275
- package/dist/lib/platform/repository-metadata.js +377 -0
- package/dist/lib/platform/security-alerts.js +155 -0
- package/dist/lib/platform/snapshots.js +2 -0
- package/dist/lib/platform/verification-sync.js +154 -162
- package/dist/lib/process-data/index.js +7 -0
- package/dist/lib/release/workflow.js +1 -1
- package/dist/lib/run/index.js +5 -0
- package/dist/lib/sandbox/commands/control-status.js +22 -0
- package/dist/lib/sandbox/commands/create.js +39 -8
- package/dist/lib/sandbox/commands/ls.js +5 -0
- package/dist/lib/sandbox/commands/rm.js +3 -807
- package/dist/lib/sandbox/commands/show.js +16 -0
- package/dist/lib/sandbox/control/audit.js +203 -0
- package/dist/lib/sandbox/control/client.js +125 -12
- 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 +233 -34
- package/dist/lib/sandbox/control/finalization-response.js +27 -0
- package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
- package/dist/lib/sandbox/control/lifecycle.js +656 -128
- package/dist/lib/sandbox/control/native-file-lock.js +85 -0
- package/dist/lib/sandbox/control/protocol.js +55 -4
- package/dist/lib/sandbox/control/server.js +720 -79
- package/dist/lib/sandbox/control/state.js +63 -3
- package/dist/lib/sandbox/control/task-view.js +183 -0
- package/dist/lib/sandbox/control/task-workflow.js +74 -0
- package/dist/lib/sandbox/control/workflow-executor.js +99 -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 +7 -2
- package/dist/lib/sandbox/recovery.js +49 -5
- package/dist/lib/sandbox/removal.js +1717 -0
- package/dist/lib/sandbox/task-cleanup.js +217 -0
- package/dist/lib/sandbox/workspace-view.js +15 -15
- package/dist/lib/sandbox/worktree-safety.js +4 -1
- package/dist/lib/server/index.js +8 -0
- package/dist/lib/task/activity-intent.js +2 -1
- package/dist/lib/task/activity-log.js +30 -24
- package/dist/lib/task/artifact-command.js +101 -0
- package/dist/lib/task/artifact-lifecycle.js +71 -40
- package/dist/lib/task/artifact-name.js +36 -0
- package/dist/lib/task/artifact-operations.js +474 -0
- package/dist/lib/task/artifact-receipts.js +3 -15
- package/dist/lib/task/artifact-repair-intent.js +130 -0
- package/dist/lib/task/artifact-schema.js +127 -0
- package/dist/lib/task/capabilities.js +83 -19
- package/dist/lib/task/codex-orchestration.js +71 -25
- package/dist/lib/task/commit-identity.js +28 -0
- package/dist/lib/task/commit-operation.js +2 -16
- package/dist/lib/task/control-authority.js +375 -5
- package/dist/lib/task/control-recovery.js +128 -0
- package/dist/lib/task/create-service.js +103 -4
- package/dist/lib/task/create.js +80 -2
- package/dist/lib/task/decision-details.js +2 -46
- package/dist/lib/task/events.js +306 -76
- package/dist/lib/task/finalization-state.js +9 -0
- package/dist/lib/task/human-override.js +3 -6
- package/dist/lib/task/implementation-inputs.js +3 -3
- package/dist/lib/task/index.js +11 -3
- package/dist/lib/task/intermediate-cleanup.js +383 -0
- package/dist/lib/task/invalidation.js +18 -65
- package/dist/lib/task/ledger-intents.js +7 -22
- package/dist/lib/task/ledger.js +1 -3
- package/dist/lib/task/lifecycle.js +19 -1
- package/dist/lib/task/local-artifact-finalization.js +190 -290
- package/dist/lib/task/manual-validation-completion.js +26 -0
- package/dist/lib/task/manual-validation-evidence.js +130 -0
- package/dist/lib/task/manual-validation-receipt.js +101 -0
- package/dist/lib/task/manual-validation-shared.js +40 -0
- package/dist/lib/task/manual-validation-transaction.js +243 -0
- package/dist/lib/task/markdown.js +47 -0
- package/dist/lib/task/orchestration.js +206 -69
- package/dist/lib/task/qualification-audit.js +476 -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 +23 -40
- package/dist/lib/task/review-command.js +25 -0
- package/dist/lib/task/review-finalization.js +146 -97
- package/dist/lib/task/review-fingerprint.js +2 -2
- package/dist/lib/task/sections.js +34 -54
- package/dist/lib/task/verification-config.js +11 -0
- package/dist/lib/task/verification-engine.js +170 -327
- package/dist/lib/task/verification.js +1 -1
- package/dist/lib/task/workflow-command.js +17 -0
- package/dist/lib/task/workflow-warning-intents.js +0 -16
- package/dist/lib/task/workflow-warnings.js +28 -2
- package/dist/lib/update.js +2 -0
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-client.ts +9 -0
- package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
- package/lib/fs/durable-write.ts +29 -0
- package/lib/fs/file-lock.ts +113 -0
- package/lib/host-control/audit.ts +22 -0
- package/lib/host-control/client.ts +172 -0
- package/lib/host-control/command.ts +60 -0
- package/lib/host-control/path.ts +167 -0
- package/lib/host-control/secure-fs.ts +135 -0
- package/lib/host-control/server.ts +180 -0
- package/lib/host-control/service.ts +133 -0
- package/lib/init.ts +15 -2
- package/lib/internal/agent-client.ts +4 -2
- package/lib/internal/cli-route-inventory.ts +142 -0
- package/lib/internal/codex-lifecycle.ts +14 -12
- package/lib/internal/codex-sandbox-controller.ts +7 -2
- package/lib/internal/demo-promotion.ts +354 -0
- package/lib/internal/demo-transcript.ts +419 -0
- package/lib/internal/git-workflow.ts +9 -6
- package/lib/internal/host-control.ts +28 -0
- package/lib/internal/manual-validation.ts +306 -0
- package/lib/internal/platform-checks.ts +12 -4
- package/lib/internal/platform-comment.ts +12 -4
- package/lib/internal/platform-context.ts +3 -1
- package/lib/internal/platform-issue.ts +11 -4
- package/lib/internal/platform-metadata.ts +70 -0
- package/lib/internal/platform-pr-review.ts +14 -3
- package/lib/internal/platform-pr.ts +38 -14
- package/lib/internal/platform-release-notes.ts +5 -3
- package/lib/internal/platform-security.ts +83 -0
- package/lib/internal/pr-review-grade.ts +10 -3
- package/lib/internal/release-workflow.ts +91 -87
- package/lib/internal/sandbox-control.ts +181 -6
- package/lib/internal/task-activity.ts +12 -4
- package/lib/internal/task-artifact.ts +15 -79
- package/lib/internal/task-context.ts +3 -1
- package/lib/internal/task-create.ts +76 -15
- package/lib/internal/task-delivery.ts +3 -1
- package/lib/internal/task-event.ts +21 -10
- package/lib/internal/task-finalization.ts +3 -1
- package/lib/internal/task-invalidation.ts +3 -1
- package/lib/internal/task-ledger.ts +11 -1
- package/lib/internal/task-lifecycle.ts +3 -1
- package/lib/internal/task-operation-registry.ts +590 -0
- package/lib/internal/task-orchestration.ts +12 -0
- package/lib/internal/task-override.ts +9 -3
- package/lib/internal/task-qualification.ts +61 -0
- package/lib/internal/task-review.ts +7 -50
- package/lib/internal/task-short-id.ts +10 -1
- package/lib/internal/task-snapshot.ts +3 -1
- package/lib/internal/task-validate.ts +32 -12
- package/lib/internal/task-verify.ts +4 -1
- package/lib/internal/task-warning.ts +7 -1
- package/lib/owned-path.ts +26 -0
- package/lib/platform/check-status.ts +9 -0
- package/lib/platform/comment-safety.ts +255 -0
- package/lib/platform/completion-backfill.ts +1 -1
- package/lib/platform/github-data.ts +322 -0
- package/lib/platform/github-provider.ts +244 -27
- package/lib/platform/issue-comments.ts +159 -35
- package/lib/platform/issues.ts +4 -245
- package/lib/platform/pr-change-report.ts +6 -12
- package/lib/platform/pr-checks.ts +13 -77
- package/lib/platform/pr-summary.ts +88 -11
- package/lib/platform/provider-contract.ts +78 -3
- package/lib/platform/provider-validation.ts +85 -3
- package/lib/platform/pull-requests.ts +129 -348
- package/lib/platform/repository-metadata.ts +453 -0
- package/lib/platform/security-alerts.ts +191 -0
- package/lib/platform/snapshots.ts +53 -0
- package/lib/platform/verification-sync.ts +171 -177
- package/lib/process-data/index.ts +7 -0
- package/lib/release/workflow.ts +3 -3
- package/lib/run/index.ts +5 -0
- package/lib/sandbox/commands/control-status.ts +26 -0
- package/lib/sandbox/commands/create.ts +53 -12
- package/lib/sandbox/commands/ls.ts +7 -0
- package/lib/sandbox/commands/rm.ts +3 -996
- package/lib/sandbox/commands/show.ts +16 -0
- package/lib/sandbox/control/audit.ts +253 -0
- package/lib/sandbox/control/client.ts +150 -13
- package/lib/sandbox/control/completed-reentry.ts +98 -0
- package/lib/sandbox/control/container-identity.ts +27 -43
- package/lib/sandbox/control/executor.ts +262 -37
- package/lib/sandbox/control/finalization-response.ts +29 -0
- package/lib/sandbox/control/identity-sentinel.ts +137 -0
- package/lib/sandbox/control/lifecycle.ts +672 -18
- package/lib/sandbox/control/native-file-lock.ts +108 -0
- package/lib/sandbox/control/protocol.ts +80 -8
- package/lib/sandbox/control/server.ts +779 -82
- package/lib/sandbox/control/state.ts +84 -3
- package/lib/sandbox/control/task-view.ts +240 -0
- package/lib/sandbox/control/task-workflow.ts +95 -0
- package/lib/sandbox/control/workflow-executor.ts +102 -0
- package/lib/sandbox/engines/authority.ts +365 -0
- package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
- package/lib/sandbox/index.ts +9 -2
- package/lib/sandbox/recovery.ts +49 -6
- package/lib/sandbox/removal.ts +2144 -0
- package/lib/sandbox/task-cleanup.ts +209 -0
- package/lib/sandbox/workspace-view.ts +26 -18
- package/lib/sandbox/worktree-safety.ts +4 -1
- package/lib/server/index.ts +10 -0
- package/lib/task/activity-intent.ts +2 -2
- package/lib/task/activity-log.ts +27 -19
- package/lib/task/artifact-command.ts +104 -0
- package/lib/task/artifact-lifecycle.ts +66 -39
- package/lib/task/artifact-name.ts +55 -0
- package/lib/task/artifact-operations.ts +580 -0
- package/lib/task/artifact-receipts.ts +3 -14
- package/lib/task/artifact-repair-intent.ts +152 -0
- package/lib/task/artifact-schema.ts +163 -0
- package/lib/task/capabilities.ts +82 -22
- package/lib/task/codex-orchestration.ts +85 -24
- package/lib/task/commit-identity.ts +31 -0
- package/lib/task/commit-operation.ts +2 -16
- package/lib/task/control-authority.ts +513 -6
- package/lib/task/control-recovery.ts +174 -0
- package/lib/task/create-service.ts +131 -6
- package/lib/task/create.ts +83 -1
- package/lib/task/decision-details.ts +3 -71
- package/lib/task/events.ts +292 -75
- package/lib/task/finalization-state.ts +11 -0
- package/lib/task/human-override.ts +3 -8
- package/lib/task/implementation-inputs.ts +3 -3
- package/lib/task/index.ts +16 -3
- package/lib/task/intermediate-cleanup.ts +455 -0
- package/lib/task/invalidation.ts +18 -62
- package/lib/task/ledger-intents.ts +7 -24
- package/lib/task/ledger.ts +1 -3
- package/lib/task/lifecycle.ts +17 -1
- package/lib/task/local-artifact-finalization.ts +223 -388
- package/lib/task/manual-validation-completion.ts +40 -0
- package/lib/task/manual-validation-evidence.ts +209 -0
- package/lib/task/manual-validation-receipt.ts +152 -0
- package/lib/task/manual-validation-shared.ts +50 -0
- package/lib/task/manual-validation-transaction.ts +304 -0
- package/lib/task/markdown.ts +70 -0
- package/lib/task/orchestration.ts +191 -68
- package/lib/task/qualification-audit.ts +588 -0
- package/lib/task/qualification-confirmation.ts +117 -0
- package/lib/task/qualification-intents.ts +150 -0
- package/lib/task/review-artifacts.ts +21 -41
- package/lib/task/review-command.ts +23 -0
- package/lib/task/review-finalization.ts +154 -153
- package/lib/task/review-fingerprint.ts +2 -2
- package/lib/task/sections.ts +33 -52
- package/lib/task/verification-config.ts +12 -0
- package/lib/task/verification-engine.ts +165 -370
- package/lib/task/verification-types.ts +17 -0
- package/lib/task/verification.ts +1 -1
- package/lib/task/workflow-command.ts +18 -0
- package/lib/task/workflow-warning-intents.ts +0 -13
- package/lib/task/workflow-warnings.ts +21 -2
- package/lib/update.ts +6 -0
- package/package.json +7 -2
- package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
- package/templates/.agents/rules/README.en.md +2 -0
- package/templates/.agents/rules/README.zh-CN.md +2 -0
- 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/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 +5 -1
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
- 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/testing-discipline.en.md +2 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
- package/templates/.agents/scripts/package.json +3 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
- 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/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 +14 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
- package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -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/complete-manual-validation/SKILL.en.md +37 -21
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
- package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
- 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 +14 -1
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
- 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/release/SKILL.en.md +7 -3
- package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
- package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
- 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 +14 -1
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
- 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 +14 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
- 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 +25 -4
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/test/SKILL.en.md +29 -7
- package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
- package/templates/.agents/templates/task.en.md +6 -0
- package/templates/.agents/templates/task.zh-CN.md +6 -0
- package/templates/.claude/commands/run-manual-validation.en.md +1 -1
- package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
- package/dist/lib/platform/adapters.js +0 -56
- package/lib/platform/adapters.ts +0 -197
- 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
|
@@ -2,7 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
|
|
3
3
|
import { parseTypedTaskFrontmatter } from '../task/frontmatter.ts';
|
|
4
4
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
5
|
-
import type { PlatformCheckSnapshot } from './
|
|
5
|
+
import type { PlatformCheckSnapshot } from './snapshots.ts';
|
|
6
|
+
import { checkStatusBucket } from './check-status.ts';
|
|
6
7
|
import { resolvePlatformProviderContext } from './context.ts';
|
|
7
8
|
import type { PlatformClient } from './context.ts';
|
|
8
9
|
import { inspectPlatformPullRequest } from './pull-requests.ts';
|
|
@@ -33,7 +34,6 @@ type ChecksResult = PlatformResult & {
|
|
|
33
34
|
resolution?: { status: 'resolved' | 'missing' | 'ambiguous'; runId: number | null; jobId: number | null };
|
|
34
35
|
logs?: { runId: number; jobId?: number; text: string };
|
|
35
36
|
};
|
|
36
|
-
type GitHubClient = PlatformClient;
|
|
37
37
|
type InspectionOptions = { cwd?: string; client?: PlatformClient; runtimeVersion?: string };
|
|
38
38
|
type SharedOptions = { cwd?: string; client?: PlatformClient };
|
|
39
39
|
|
|
@@ -56,18 +56,6 @@ function classifyPullRequestReadiness(input: {
|
|
|
56
56
|
return { state: 'ready', headSha: input.headSha };
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function parseRunJobIdentity(detailsUrl: string): { runId: number; jobId: number | null } | null {
|
|
60
|
-
try {
|
|
61
|
-
const url = new URL(detailsUrl);
|
|
62
|
-
if (url.hostname !== 'github.com') return null;
|
|
63
|
-
const match = url.pathname.match(/\/actions\/runs\/(\d+)(?:\/job\/(\d+))?/);
|
|
64
|
-
if (!match) return null;
|
|
65
|
-
return { runId: Number(match[1]), jobId: match[2] ? Number(match[2]) : null };
|
|
66
|
-
} catch {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
59
|
function resolveRunCandidate(candidates: RunCandidate[], headSha: string, checkName: string):
|
|
72
60
|
| { status: 'resolved'; runId: number; jobId: number | null }
|
|
73
61
|
| { status: 'missing' | 'ambiguous'; runId: null; jobId: null } {
|
|
@@ -85,41 +73,6 @@ function checksResult(status: PlatformResult['status'], overrides: Partial<Check
|
|
|
85
73
|
};
|
|
86
74
|
}
|
|
87
75
|
|
|
88
|
-
function normalizeBucket(value: { bucket?: string; status?: string; state?: string; conclusion?: string }): CheckBucket {
|
|
89
|
-
const raw = String(value.bucket || value.status || value.conclusion || value.state || '').toLowerCase();
|
|
90
|
-
if (['pass', 'success', 'successful', 'neutral'].includes(raw)) return 'pass';
|
|
91
|
-
if (['fail', 'failure', 'failed', 'error', 'timed_out', 'action_required'].includes(raw)) return 'fail';
|
|
92
|
-
if (['cancel', 'cancelled', 'canceled', 'skipped', 'stale'].includes(raw)) return 'cancel';
|
|
93
|
-
return 'pending';
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function normalizeChecks(value: unknown): CheckSnapshot[] {
|
|
97
|
-
if (!Array.isArray(value)) return [];
|
|
98
|
-
return value.flatMap((raw) => {
|
|
99
|
-
const item = raw as Record<string, unknown>;
|
|
100
|
-
const name = String(item.name || item.context || '');
|
|
101
|
-
return name ? [{
|
|
102
|
-
name,
|
|
103
|
-
bucket: normalizeBucket(item as { bucket?: string; state?: string; conclusion?: string }),
|
|
104
|
-
workflow: item.workflow ? String(item.workflow) : null,
|
|
105
|
-
conclusion: item.conclusion ? String(item.conclusion) : item.state ? String(item.state) : null,
|
|
106
|
-
detailsUrl: item.link ? String(item.link) : item.detailsUrl ? String(item.detailsUrl) : null,
|
|
107
|
-
startedAt: item.startedAt ? String(item.startedAt) : null,
|
|
108
|
-
completedAt: item.completedAt ? String(item.completedAt) : null
|
|
109
|
-
}] : [];
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function inspectGitHubRequiredChecks(client: GitHubClient, repository: string, number: number, cwd: string) {
|
|
114
|
-
const inspected = client.json<unknown>([
|
|
115
|
-
'pr', 'checks', String(number), '--repo', repository,
|
|
116
|
-
'--json', 'name,state,bucket,link,workflow,startedAt,completedAt'
|
|
117
|
-
], { cwd });
|
|
118
|
-
return inspected.ok
|
|
119
|
-
? { ok: true as const, value: normalizeChecks(inspected.value) }
|
|
120
|
-
: { ok: false as const, error: inspected.error };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
76
|
async function resolvedTask(taskRef: string, options: InspectionOptions) {
|
|
124
77
|
const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
|
|
125
78
|
if (!resolved.ok) return { ok: false as const, output: checksResult('failed', { error: { code: resolved.code, message: resolved.message, retryable: false } }) };
|
|
@@ -141,14 +94,12 @@ async function resolvedTask(taskRef: string, options: InspectionOptions) {
|
|
|
141
94
|
async function inspectRequiredChecks(taskRef: string, options: InspectionOptions = {}): Promise<ChecksResult> {
|
|
142
95
|
const base = await resolvedTask(taskRef, options);
|
|
143
96
|
if (!base.ok) return base.output;
|
|
144
|
-
return inspectChecksForResolvedTask(base
|
|
97
|
+
return inspectChecksForResolvedTask(base);
|
|
145
98
|
}
|
|
146
99
|
|
|
147
100
|
async function inspectChecksForResolvedTask(
|
|
148
|
-
base: Extract<Awaited<ReturnType<typeof resolvedTask>>, { ok: true }
|
|
149
|
-
options: InspectionOptions
|
|
101
|
+
base: Extract<Awaited<ReturnType<typeof resolvedTask>>, { ok: true }>
|
|
150
102
|
): Promise<ChecksResult> {
|
|
151
|
-
const repository = base.context.platform.repository!;
|
|
152
103
|
{
|
|
153
104
|
const inspected = base.provider.checks?.inspectRequired
|
|
154
105
|
? await base.provider.checks.inspectRequired({
|
|
@@ -164,7 +115,13 @@ async function inspectChecksForResolvedTask(
|
|
|
164
115
|
pullRequest: base.pullRequest,
|
|
165
116
|
error: providerError(inspected.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
|
|
166
117
|
});
|
|
167
|
-
const required =
|
|
118
|
+
const required = inspected.value.map((check): CheckSnapshot => ({
|
|
119
|
+
name: check.name,
|
|
120
|
+
bucket: checkStatusBucket(check.status),
|
|
121
|
+
conclusion: check.conclusion || null,
|
|
122
|
+
detailsUrl: check.detailsUrl || null,
|
|
123
|
+
workflow: null, startedAt: null, completedAt: null
|
|
124
|
+
}));
|
|
168
125
|
const classified = classifyRequiredChecks(required);
|
|
169
126
|
const status = classified.state === 'passed' || classified.state === 'no-required'
|
|
170
127
|
? 'no-op'
|
|
@@ -184,7 +141,7 @@ async function inspectChecksForResolvedTask(
|
|
|
184
141
|
async function inspectPullRequestReadiness(taskRef: string, options: InspectionOptions = {}): Promise<ChecksResult> {
|
|
185
142
|
const base = await resolvedTask(taskRef, options);
|
|
186
143
|
if (!base.ok) return base.output;
|
|
187
|
-
const checked = await inspectChecksForResolvedTask(base
|
|
144
|
+
const checked = await inspectChecksForResolvedTask(base);
|
|
188
145
|
const classifiedCodes = new Set(['REQUIRED_CHECKS_PENDING', 'REQUIRED_CHECKS_FAILED', 'REQUIRED_CHECKS_CANCELLED']);
|
|
189
146
|
if (checked.error && !classifiedCodes.has(checked.error.code)) return checked;
|
|
190
147
|
const readiness = classifyPullRequestReadiness({
|
|
@@ -271,15 +228,6 @@ async function resolvePlatformCheckRun(taskRef: string, options: SharedOptions &
|
|
|
271
228
|
}
|
|
272
229
|
}
|
|
273
230
|
|
|
274
|
-
function fetchCheckLogText(client: GitHubClient, args: string[], cwd: string) {
|
|
275
|
-
if (!client.text) return { ok: false as const, error: { code: 'PLATFORM_CLIENT_TEXT_UNAVAILABLE', message: 'Platform client does not support text responses', retryable: false } };
|
|
276
|
-
const fetched = client.text(args, { cwd });
|
|
277
|
-
if (fetched.ok || args[0] !== 'api' || !/response contains terminal escape sequences/i.test(fetched.error.message)) {
|
|
278
|
-
return fetched;
|
|
279
|
-
}
|
|
280
|
-
return client.text([...args, '--allow-escape-sequences'], { cwd });
|
|
281
|
-
}
|
|
282
|
-
|
|
283
231
|
async function fetchPlatformCheckLogs(taskRef: string, options: SharedOptions & { run: number; job?: number }): Promise<ChecksResult> {
|
|
284
232
|
const base = await resolvedTask(taskRef, options);
|
|
285
233
|
if (!base.ok) return base.output;
|
|
@@ -308,17 +256,5 @@ async function fetchPlatformCheckLogs(taskRef: string, options: SharedOptions &
|
|
|
308
256
|
}
|
|
309
257
|
}
|
|
310
258
|
|
|
311
|
-
export {
|
|
312
|
-
classifyPullRequestReadiness,
|
|
313
|
-
classifyRequiredChecks,
|
|
314
|
-
fetchCheckLogText,
|
|
315
|
-
fetchPlatformCheckLogs,
|
|
316
|
-
inspectGitHubRequiredChecks,
|
|
317
|
-
inspectRequiredChecks,
|
|
318
|
-
inspectPullRequestReadiness,
|
|
319
|
-
parseRunJobIdentity,
|
|
320
|
-
resolvePlatformCheckRun,
|
|
321
|
-
resolveRunCandidate,
|
|
322
|
-
watchPullRequestReadiness
|
|
323
|
-
};
|
|
259
|
+
export { classifyPullRequestReadiness, classifyRequiredChecks, fetchPlatformCheckLogs, inspectRequiredChecks, inspectPullRequestReadiness, resolvePlatformCheckRun, resolveRunCandidate, watchPullRequestReadiness };
|
|
324
260
|
export type { CheckBucket, CheckSnapshot, ChecksResult, ChecksSnapshot, CheckState, ReadinessSnapshot, ReadinessState, RunCandidate };
|
|
@@ -11,14 +11,16 @@ import type { PrDeliveryFact } from '../task/pr-delivery-fact.ts';
|
|
|
11
11
|
import { resolvePlatformProviderContext } from './context.ts';
|
|
12
12
|
import type { LoadedContext, PlatformClient } from './context.ts';
|
|
13
13
|
import { normalizeCommentContent } from './issue-comments.ts';
|
|
14
|
+
import { CONTROL_MARKER_PATTERN, escapeHtmlText, sanitizeMarkdownDocument, splitDocumentPlaceholder } from './comment-safety.ts';
|
|
14
15
|
import { platformResult } from './types.ts';
|
|
15
16
|
import type { PlatformResult } from './types.ts';
|
|
16
17
|
import type { OperationWarning } from '../task/operation-outcome.ts';
|
|
17
18
|
import { providerError, providerOperationContext, providerStatus, providerResourceToken, resourceIdentityNumber, unsupportedProviderOperation } from './provider-bridge.ts';
|
|
18
|
-
import type { PlatformChangeRequestSnapshot } from './
|
|
19
|
+
import type { PlatformChangeRequestSnapshot } from './snapshots.ts';
|
|
19
20
|
import type { ChangeRequestSnapshot } from './provider-contract.ts';
|
|
20
21
|
import {
|
|
21
22
|
buildPrChangeReport,
|
|
23
|
+
CANONICAL_REPORT_PLACEHOLDER,
|
|
22
24
|
readPrChangeReport,
|
|
23
25
|
replaceCanonicalReportPlaceholder,
|
|
24
26
|
runMechanicalChangeReport,
|
|
@@ -31,6 +33,8 @@ import type {
|
|
|
31
33
|
MechanicalChangeReport,
|
|
32
34
|
PrChangeReport
|
|
33
35
|
} from './pr-change-report.ts';
|
|
36
|
+
import { manualValidationFinalSummaryProjectionMatches } from '../task/manual-validation-receipt.ts';
|
|
37
|
+
import { readManualValidationCompletion } from '../task/manual-validation-completion.ts';
|
|
34
38
|
|
|
35
39
|
type SummaryComment = { id: number | string; body: string };
|
|
36
40
|
type ChangeReportState = 'ready' | 'missing' | 'stale' | 'invalid';
|
|
@@ -48,20 +52,28 @@ type PullRequestSummaryResult = PlatformResult & {
|
|
|
48
52
|
};
|
|
49
53
|
type PullRequestPrimaryResult = 'pr_created' | 'pr_reused' | 'no_op';
|
|
50
54
|
type SummaryOptions = { cwd?: string; client?: PlatformClient; runtimeVersion?: string };
|
|
55
|
+
type ManualValidationSummaryOptions = {
|
|
56
|
+
phase: 'pending' | 'final';
|
|
57
|
+
transactionId?: string;
|
|
58
|
+
receiptDigest?: string;
|
|
59
|
+
prHeadSha?: string;
|
|
60
|
+
authority?: 'coordinator';
|
|
61
|
+
};
|
|
51
62
|
type ReportWriteResult = PlatformResult & {
|
|
52
63
|
report: { path: string; status: 'written' | 'no-op' | 'planned'; precheckVerdict: 'clear' | 'needs-review'; nextAction: 'watch-pr' | 'review-code' } | null;
|
|
53
64
|
};
|
|
65
|
+
type SummaryCommentStateResult = Omit<PlatformResult, 'comment'> & {
|
|
66
|
+
task: { id: string | null; prNumber: number | null };
|
|
67
|
+
pullRequest: PlatformChangeRequestSnapshot | null;
|
|
68
|
+
comment: SummaryComment | null;
|
|
69
|
+
};
|
|
54
70
|
|
|
55
71
|
function summaryMarker(taskId: string): string {
|
|
56
72
|
return `<!-- sync-pr:${taskId}:summary -->`;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
function escapeSummaryAuditText(value: string): string {
|
|
60
|
-
return value
|
|
61
|
-
.replace(/&/g, '&')
|
|
62
|
-
.replace(/</g, '<')
|
|
63
|
-
.replace(/>/g, '>')
|
|
64
|
-
.replace(/\r\n?/g, '\n');
|
|
76
|
+
return escapeHtmlText(value).replace(/\r\n?/g, '\n');
|
|
65
77
|
}
|
|
66
78
|
|
|
67
79
|
function renderSummaryAuditLine(value: string): string {
|
|
@@ -356,6 +368,23 @@ async function summaryContext(taskRef: string, options: SummaryOptions = {}): Pr
|
|
|
356
368
|
};
|
|
357
369
|
}
|
|
358
370
|
|
|
371
|
+
async function summaryCommentState(taskRef: string, options: SummaryOptions = {}): Promise<SummaryCommentStateResult> {
|
|
372
|
+
const context = await summaryContext(taskRef, options);
|
|
373
|
+
if (!context.task.prNumber || !context.pullRequest) return { ...context, comment: null };
|
|
374
|
+
const loaded = await resolvePlatformProviderContext({ cwd: options.cwd, client: options.client });
|
|
375
|
+
if (!loaded.ok || !loaded.value.provider.comments?.list) return { ...context, comment: null };
|
|
376
|
+
const listed = await loaded.value.provider.comments.list({
|
|
377
|
+
context: providerOperationContext(loaded.value),
|
|
378
|
+
parent: providerResourceToken(loaded.value.provider, 'pull-request', String(context.task.prNumber))
|
|
379
|
+
});
|
|
380
|
+
if (!listed.ok) return { ...context, comment: null };
|
|
381
|
+
const matches = listed.value.filter((comment) => comment.body.includes(summaryMarker(context.task.id!)));
|
|
382
|
+
return {
|
|
383
|
+
...context,
|
|
384
|
+
comment: matches.length === 1 ? { id: /^\d+$/u.test(matches[0]!.id) ? Number(matches[0]!.id) : matches[0]!.id, body: matches[0]!.body } : null
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
359
388
|
type ReportWriteOptions = {
|
|
360
389
|
agent: string;
|
|
361
390
|
mechanicalFile: string;
|
|
@@ -452,7 +481,7 @@ async function reportWrite(taskRef: string, options: ReportWriteOptions): Promis
|
|
|
452
481
|
|
|
453
482
|
async function syncPullRequestSummary(
|
|
454
483
|
taskRef: string,
|
|
455
|
-
options: { agent: string; body: string; changeReportFile?: string; cwd?: string; client?: PlatformClient; dryRun?: boolean; strict?: boolean; primaryResult: PullRequestPrimaryResult; runtimeVersion?: string }
|
|
484
|
+
options: { agent: string; body: string; changeReportFile?: string; cwd?: string; client?: PlatformClient; dryRun?: boolean; strict?: boolean; primaryResult: PullRequestPrimaryResult; runtimeVersion?: string; manualValidation?: ManualValidationSummaryOptions; lockAlreadyHeld?: boolean }
|
|
456
485
|
): Promise<PullRequestSummaryResult> {
|
|
457
486
|
const warningResult = warningResultForPrimary(options.primaryResult);
|
|
458
487
|
let knownPrNumber: number | null = null;
|
|
@@ -505,7 +534,7 @@ async function syncPullRequestSummary(
|
|
|
505
534
|
return preserveFailure(context);
|
|
506
535
|
}
|
|
507
536
|
try {
|
|
508
|
-
|
|
537
|
+
const execute = async (): Promise<PullRequestSummaryResult> => {
|
|
509
538
|
const { taskContent, boundFact } = readBoundTaskSnapshot(resolved.taskMdPath);
|
|
510
539
|
if (!boundFact) return {
|
|
511
540
|
...platformResult('failed', { resource: { kind: 'pull-request', number: null }, error: { code: 'PR_NOT_LINKED', message: 'Task has no verified bound pull request', retryable: false } }),
|
|
@@ -521,6 +550,27 @@ async function syncPullRequestSummary(
|
|
|
521
550
|
const prNumber = boundPrNumber;
|
|
522
551
|
const initial = await inspectBoundPullRequest(context, resolved.repoRoot, boundPrNumber, loaded.value);
|
|
523
552
|
if (!initial.ok) return fail(initial.status, context, initial.error);
|
|
553
|
+
const manual = options.manualValidation;
|
|
554
|
+
const hasFinalManualValidation = /###\s+✅\s+(?:Manual Validation Passed|人工验证已通过)/u.test(options.body);
|
|
555
|
+
if (hasFinalManualValidation && (!manual || manual.phase !== 'final')) return fail('failed', context, { code: 'MANUAL_VALIDATION_TRANSACTION_REQUIRED', message: 'final manual-validation summary requires the transaction coordinator', retryable: false }, prNumber);
|
|
556
|
+
if (manual && (manual.phase === 'pending' ? hasFinalManualValidation : !hasFinalManualValidation)) return fail('failed', context, { code: 'MANUAL_VALIDATION_SUMMARY_PHASE_INVALID', message: 'manual-validation summary phase does not match the requested writer phase', retryable: false }, prNumber);
|
|
557
|
+
if (manual) {
|
|
558
|
+
if (manual.phase === 'final' && (!manual.transactionId || !manual.receiptDigest || !manual.prHeadSha || manual.prHeadSha !== initial.value.head.sha)) return fail('failed', context, { code: 'MANUAL_VALIDATION_TRANSACTION_REQUIRED', message: 'final manual-validation summary requires transaction, receipt, and current head identity', retryable: false }, prNumber);
|
|
559
|
+
if (manual.phase === 'final') {
|
|
560
|
+
if (manual.authority !== 'coordinator') return fail('failed', context, { code: 'MANUAL_VALIDATION_TRANSACTION_REQUIRED', message: 'final manual-validation summary requires coordinator authority', retryable: false }, prNumber);
|
|
561
|
+
const completion = readManualValidationCompletion(resolved.taskDir, {
|
|
562
|
+
transactionId: manual.transactionId,
|
|
563
|
+
taskId: resolved.taskId,
|
|
564
|
+
prNumber,
|
|
565
|
+
prHeadSha: initial.value.head.sha,
|
|
566
|
+
receiptDigest: manual.receiptDigest
|
|
567
|
+
});
|
|
568
|
+
if (!completion.ok) return fail('failed', context, platformError(completion.error), prNumber);
|
|
569
|
+
const { receipt, transaction } = completion.value;
|
|
570
|
+
if (transaction.phase !== 'final-promotion-in-progress' || !transaction.eventAppended) return fail('failed', context, { code: 'MANUAL_VALIDATION_TRANSACTION_PHASE_INVALID', message: 'final summary requires a receipt-backed promotion intent', retryable: false }, prNumber);
|
|
571
|
+
if (!manualValidationFinalSummaryProjectionMatches(options.body, receipt)) return fail('failed', context, { code: 'MANUAL_VALIDATION_SUMMARY_PROJECTION_INVALID', message: 'final summary body does not match the canonical receipt projection', retryable: false }, prNumber);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
524
574
|
const expectedReportPath = taskReportPath(resolved.taskDir);
|
|
525
575
|
const suppliedReportPath = path.resolve(resolved.repoRoot, options.changeReportFile!);
|
|
526
576
|
if (suppliedReportPath !== expectedReportPath) return fail('failed', context, { code: 'PR_CHANGE_REPORT_PATH_INVALID', message: 'summary-sync must consume the task-bound pr-change-report.json', retryable: false });
|
|
@@ -528,7 +578,30 @@ async function syncPullRequestSummary(
|
|
|
528
578
|
if (!report.ok) return fail('failed', context, platformError(report.error));
|
|
529
579
|
const checked = currentReportCheck(report.value, initial.value, taskContent, resolved.repoRoot);
|
|
530
580
|
if (!checked.ok) return fail('failed', context, checked.error);
|
|
531
|
-
const
|
|
581
|
+
const placeholder = CANONICAL_REPORT_PLACEHOLDER;
|
|
582
|
+
const split = splitDocumentPlaceholder(options.body, placeholder);
|
|
583
|
+
if (!split.ok) return fail('failed', context, {
|
|
584
|
+
code: 'PR_SUMMARY_BODY_CONTRACT_INVALID',
|
|
585
|
+
message: split.error.message,
|
|
586
|
+
retryable: false
|
|
587
|
+
});
|
|
588
|
+
const prefix = sanitizeMarkdownDocument(split.value.prefix, { reservedMarkers: [CONTROL_MARKER_PATTERN] });
|
|
589
|
+
const suffix = sanitizeMarkdownDocument(split.value.suffix, { reservedMarkers: [CONTROL_MARKER_PATTERN] });
|
|
590
|
+
if (!prefix.ok) {
|
|
591
|
+
return fail('failed', context, {
|
|
592
|
+
code: 'PR_SUMMARY_BODY_CONTRACT_INVALID',
|
|
593
|
+
message: `${prefix.error.message} at offset ${prefix.error.offset}`,
|
|
594
|
+
retryable: false
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
if (!suffix.ok) {
|
|
598
|
+
return fail('failed', context, {
|
|
599
|
+
code: 'PR_SUMMARY_BODY_CONTRACT_INVALID',
|
|
600
|
+
message: `${suffix.error.message} at offset ${suffix.error.offset}`,
|
|
601
|
+
retryable: false
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
const replaced = replaceCanonicalReportPlaceholder(`${prefix.value}${placeholder}${suffix.value}`, report.value);
|
|
532
605
|
if (!replaced.ok) return fail('failed', context, platformError(replaced.error));
|
|
533
606
|
const desired = buildPullRequestSummary(resolved.taskId, replaced.value, initial.value.head.sha, renderHumanOverrideAudit(taskContent));
|
|
534
607
|
if (!isSafeSummaryEnvelope(desired, resolved.taskId)) return fail('failed', context, {
|
|
@@ -630,7 +703,10 @@ async function syncPullRequestSummary(
|
|
|
630
703
|
operations: [{ name: `summary:${reconciliation.action}`, status: 'applied', reasonCode: null }],
|
|
631
704
|
result: null, warnings: [], ...info
|
|
632
705
|
};
|
|
633
|
-
}
|
|
706
|
+
};
|
|
707
|
+
return await (options.lockAlreadyHeld
|
|
708
|
+
? execute()
|
|
709
|
+
: withTaskExecutionLock(resolved.repoRoot, resolved.taskId, options.agent, execute));
|
|
634
710
|
} catch (error) {
|
|
635
711
|
const lockError = error instanceof TaskExecutionLockError
|
|
636
712
|
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
@@ -643,9 +719,10 @@ export {
|
|
|
643
719
|
buildPullRequestSummary,
|
|
644
720
|
reconcileSummaryComment,
|
|
645
721
|
reportWrite,
|
|
722
|
+
summaryCommentState,
|
|
646
723
|
summaryContext,
|
|
647
724
|
summaryMarker,
|
|
648
725
|
syncPullRequestSummary,
|
|
649
726
|
warningResultForPrimary
|
|
650
727
|
};
|
|
651
|
-
export type { PullRequestSummaryResult, ReportWriteOptions, ReportWriteResult, SummaryContextResult };
|
|
728
|
+
export type { ManualValidationSummaryOptions, PullRequestSummaryResult, ReportWriteOptions, ReportWriteResult, SummaryCommentStateResult, SummaryContextResult };
|
|
@@ -22,7 +22,7 @@ type PlatformError = {
|
|
|
22
22
|
|
|
23
23
|
type ProviderResult<T> =
|
|
24
24
|
| { ok: true; value: T }
|
|
25
|
-
| { ok: false; error: PlatformError };
|
|
25
|
+
| { ok: false; error: PlatformError; value?: T };
|
|
26
26
|
|
|
27
27
|
type ProviderOperationContext = {
|
|
28
28
|
repositoryRoot: string;
|
|
@@ -162,6 +162,41 @@ type MutationReceipt = {
|
|
|
162
162
|
operationId?: string;
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
+
type SecurityAlertKind = 'dependabot' | 'code-scanning';
|
|
166
|
+
|
|
167
|
+
type SecurityAlertSnapshot = {
|
|
168
|
+
kind: SecurityAlertKind;
|
|
169
|
+
number: number;
|
|
170
|
+
state: string;
|
|
171
|
+
data: JsonValue;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
type LabelDefinition = {
|
|
175
|
+
name: string;
|
|
176
|
+
color: string;
|
|
177
|
+
description: string;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
type LabelReconciliation = {
|
|
181
|
+
changed: boolean;
|
|
182
|
+
created: string[];
|
|
183
|
+
updated: string[];
|
|
184
|
+
removed: string[];
|
|
185
|
+
skipped: string[];
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
type MilestoneDefinition = {
|
|
189
|
+
title: string;
|
|
190
|
+
description: string;
|
|
191
|
+
state: 'open' | 'closed';
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
type MilestoneInitialization = {
|
|
195
|
+
changed: boolean;
|
|
196
|
+
created: string[];
|
|
197
|
+
skipped: string[];
|
|
198
|
+
};
|
|
199
|
+
|
|
165
200
|
type RepositoryMetadataSnapshot = {
|
|
166
201
|
repository: { identity: ResourceIdentity; name: string; url: string | null };
|
|
167
202
|
labels: Array<{ identity: ResourceIdentity; name: string }>;
|
|
@@ -286,6 +321,8 @@ type PlatformProvider = {
|
|
|
286
321
|
head: string;
|
|
287
322
|
}): Promise<ProviderResult<{ sha: string }>>;
|
|
288
323
|
inspect(input: { context: ProviderOperationContext; target: ResourceIdentity }): Promise<ProviderResult<ChangeRequestSnapshot>>;
|
|
324
|
+
listFiles?(input: { context: ProviderOperationContext; target: ResourceIdentity }): Promise<ProviderResult<string[]>>;
|
|
325
|
+
listClosingIssues?(input: { context: ProviderOperationContext; target: ResourceIdentity }): Promise<ProviderResult<ResourceIdentity[]>>;
|
|
289
326
|
listClosing(input: { context: ProviderOperationContext; issue: ResourceIdentity }): Promise<ProviderResult<ChangeRequestSnapshot[]>>;
|
|
290
327
|
create(input: {
|
|
291
328
|
context: ProviderOperationContext;
|
|
@@ -383,6 +420,34 @@ type PlatformProvider = {
|
|
|
383
420
|
historyLimit: number;
|
|
384
421
|
}): Promise<ProviderResult<ReleaseNotesFacts>>;
|
|
385
422
|
};
|
|
423
|
+
securityAlerts?: {
|
|
424
|
+
inspect(input: {
|
|
425
|
+
context: ProviderOperationContext;
|
|
426
|
+
kind: SecurityAlertKind;
|
|
427
|
+
number: number;
|
|
428
|
+
}): Promise<ProviderResult<SecurityAlertSnapshot>>;
|
|
429
|
+
dismiss(input: {
|
|
430
|
+
context: ProviderOperationContext;
|
|
431
|
+
kind: SecurityAlertKind;
|
|
432
|
+
number: number;
|
|
433
|
+
reason: string;
|
|
434
|
+
comment: string;
|
|
435
|
+
mutation: MutationIdentity;
|
|
436
|
+
}): Promise<ProviderResult<MutationReceipt>>;
|
|
437
|
+
};
|
|
438
|
+
repositoryMetadata?: {
|
|
439
|
+
reconcileLabels(input: {
|
|
440
|
+
context: ProviderOperationContext;
|
|
441
|
+
desired: LabelDefinition[];
|
|
442
|
+
cleanupStaleIn: boolean;
|
|
443
|
+
mutation: MutationIdentity;
|
|
444
|
+
}): Promise<ProviderResult<LabelReconciliation>>;
|
|
445
|
+
reconcileMilestones(input: {
|
|
446
|
+
context: ProviderOperationContext;
|
|
447
|
+
desired: MilestoneDefinition[];
|
|
448
|
+
mutation: MutationIdentity;
|
|
449
|
+
}): Promise<ProviderResult<MilestoneInitialization>>;
|
|
450
|
+
};
|
|
386
451
|
verification?: {
|
|
387
452
|
fetchRemoteFacts(input: {
|
|
388
453
|
context: ProviderOperationContext;
|
|
@@ -414,12 +479,14 @@ function validatePlatformProvider(
|
|
|
414
479
|
providerType: string
|
|
415
480
|
): ProviderResult<PlatformProvider> {
|
|
416
481
|
const operationGroups: Record<string, { required: string[]; optional: string[] }> = {
|
|
417
|
-
issues: { required: ['inspect', 'create', 'update', 'describeRepository'], optional: [] },
|
|
482
|
+
issues: { required: ['inspect', 'create', 'update', 'describeRepository'], optional: ['listLabels', 'listMilestones'] },
|
|
418
483
|
comments: { required: ['list', 'write', 'delete'], optional: [] },
|
|
419
|
-
changeRequests: { required: ['inspect', 'listClosing', 'create', 'update', 'resolveGitEvidence'], optional: ['verifyHead'] },
|
|
484
|
+
changeRequests: { required: ['inspect', 'listClosing', 'create', 'update', 'resolveGitEvidence'], optional: ['verifyHead', 'listFiles', 'listClosingIssues'] },
|
|
420
485
|
checks: { required: ['inspectRequired', 'resolveRun', 'fetchLogs'], optional: [] },
|
|
421
486
|
reviews: { required: ['list', 'publish'], optional: [] },
|
|
422
487
|
releases: { required: ['inspect', 'create', 'update', 'reconcileMilestones', 'publishNotes', 'collectNotes'], optional: [] },
|
|
488
|
+
securityAlerts: { required: ['inspect', 'dismiss'], optional: [] },
|
|
489
|
+
repositoryMetadata: { required: ['reconcileLabels', 'reconcileMilestones'], optional: [] },
|
|
423
490
|
verification: { required: ['fetchRemoteFacts'], optional: [] }
|
|
424
491
|
};
|
|
425
492
|
const resourceKindsByGroup: Record<string, PlatformResourceKind[]> = {
|
|
@@ -429,6 +496,8 @@ function validatePlatformProvider(
|
|
|
429
496
|
checks: ['pull-request'],
|
|
430
497
|
reviews: ['pull-request'],
|
|
431
498
|
releases: ['release', 'issue', 'pull-request'],
|
|
499
|
+
securityAlerts: [],
|
|
500
|
+
repositoryMetadata: [],
|
|
432
501
|
verification: ['issue', 'pull-request']
|
|
433
502
|
};
|
|
434
503
|
if (!isRecord(value)
|
|
@@ -515,6 +584,10 @@ export type {
|
|
|
515
584
|
IssueSnapshot,
|
|
516
585
|
JsonValue,
|
|
517
586
|
MilestoneReconciliation,
|
|
587
|
+
MilestoneDefinition,
|
|
588
|
+
MilestoneInitialization,
|
|
589
|
+
LabelDefinition,
|
|
590
|
+
LabelReconciliation,
|
|
518
591
|
MutationIdentity,
|
|
519
592
|
MutationReceipt,
|
|
520
593
|
PlatformCapabilities,
|
|
@@ -531,6 +604,8 @@ export type {
|
|
|
531
604
|
RepositoryMetadataSnapshot,
|
|
532
605
|
ReleaseNotesFacts,
|
|
533
606
|
ResourceIdentity,
|
|
607
|
+
SecurityAlertKind,
|
|
608
|
+
SecurityAlertSnapshot,
|
|
534
609
|
ReviewSnapshot,
|
|
535
610
|
VerificationRemoteFacts
|
|
536
611
|
};
|
|
@@ -5,7 +5,11 @@ import type {
|
|
|
5
5
|
CheckLogSnapshot,
|
|
6
6
|
CheckRunSnapshot,
|
|
7
7
|
GitEvidenceSnapshot,
|
|
8
|
+
LabelDefinition,
|
|
9
|
+
LabelReconciliation,
|
|
8
10
|
IssueSnapshot,
|
|
11
|
+
MilestoneDefinition,
|
|
12
|
+
MilestoneInitialization,
|
|
9
13
|
MilestoneReconciliation,
|
|
10
14
|
MutationReceipt,
|
|
11
15
|
PlatformContextSnapshot,
|
|
@@ -18,6 +22,8 @@ import type {
|
|
|
18
22
|
RepositoryMetadataSnapshot,
|
|
19
23
|
RequiredCheckSnapshot,
|
|
20
24
|
ReviewSnapshot,
|
|
25
|
+
SecurityAlertKind,
|
|
26
|
+
SecurityAlertSnapshot,
|
|
21
27
|
VerificationRemoteFacts
|
|
22
28
|
} from './provider-contract.ts';
|
|
23
29
|
import type { JsonValue } from './provider-contract.ts';
|
|
@@ -273,6 +279,67 @@ function validateReceipt(value: unknown): MutationReceipt {
|
|
|
273
279
|
};
|
|
274
280
|
}
|
|
275
281
|
|
|
282
|
+
function positiveInteger(value: unknown, label: string): number {
|
|
283
|
+
if (!Number.isSafeInteger(value) || (value as number) <= 0) throw new Error(`${label} must be a positive integer`);
|
|
284
|
+
return value as number;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function validateSecurityAlert(value: unknown): SecurityAlertSnapshot {
|
|
288
|
+
const item = record(value, 'security alert');
|
|
289
|
+
exactKeys(item, ['kind', 'number', 'state', 'data'], 'security alert');
|
|
290
|
+
if (item.kind !== 'dependabot' && item.kind !== 'code-scanning') throw new Error('security alert.kind is invalid');
|
|
291
|
+
return {
|
|
292
|
+
kind: item.kind as SecurityAlertKind,
|
|
293
|
+
number: positiveInteger(item.number, 'security alert.number'),
|
|
294
|
+
state: stringValue(item.state, 'security alert.state'),
|
|
295
|
+
data: jsonValue(item.data, 'security alert.data')
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function validateLabelDefinition(value: unknown, label: string): LabelDefinition {
|
|
300
|
+
const item = record(value, label);
|
|
301
|
+
exactKeys(item, ['name', 'color', 'description'], label);
|
|
302
|
+
return {
|
|
303
|
+
name: stringValue(item.name, `${label}.name`),
|
|
304
|
+
color: stringValue(item.color, `${label}.color`),
|
|
305
|
+
description: stringValue(item.description, `${label}.description`, true)
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function validateLabelReconciliation(value: unknown): LabelReconciliation {
|
|
310
|
+
const item = record(value, 'label reconciliation');
|
|
311
|
+
exactKeys(item, ['changed', 'created', 'updated', 'removed', 'skipped'], 'label reconciliation');
|
|
312
|
+
const names = (field: string) => arrayValue(item[field], `label reconciliation.${field}`).map((entry) => stringValue(entry, `${field}[]`));
|
|
313
|
+
return {
|
|
314
|
+
changed: booleanValue(item.changed, 'label reconciliation.changed'),
|
|
315
|
+
created: names('created'),
|
|
316
|
+
updated: names('updated'),
|
|
317
|
+
removed: names('removed'),
|
|
318
|
+
skipped: names('skipped')
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function validateMilestoneDefinition(value: unknown, label: string): MilestoneDefinition {
|
|
323
|
+
const item = record(value, label);
|
|
324
|
+
exactKeys(item, ['title', 'description', 'state'], label);
|
|
325
|
+
if (item.state !== 'open' && item.state !== 'closed') throw new Error(`${label}.state is invalid`);
|
|
326
|
+
return {
|
|
327
|
+
title: stringValue(item.title, `${label}.title`),
|
|
328
|
+
description: stringValue(item.description, `${label}.description`, true),
|
|
329
|
+
state: item.state
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function validateMilestoneInitialization(value: unknown): MilestoneInitialization {
|
|
334
|
+
const item = record(value, 'milestone initialization');
|
|
335
|
+
exactKeys(item, ['changed', 'created', 'skipped'], 'milestone initialization');
|
|
336
|
+
return {
|
|
337
|
+
changed: booleanValue(item.changed, 'milestone initialization.changed'),
|
|
338
|
+
created: arrayValue(item.created, 'milestone initialization.created').map((entry) => stringValue(entry, 'created[]')),
|
|
339
|
+
skipped: arrayValue(item.skipped, 'milestone initialization.skipped').map((entry) => stringValue(entry, 'skipped[]'))
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
276
343
|
function validateMetadata(value: unknown): RepositoryMetadataSnapshot {
|
|
277
344
|
const item = record(value, 'repository metadata');
|
|
278
345
|
exactKeys(item, ['repository', 'labels', 'milestones', 'issueTypes', 'fields'], 'repository metadata');
|
|
@@ -375,6 +442,11 @@ const PROVIDER_ERROR_CATALOG: Readonly<Record<string, { message: string; retryab
|
|
|
375
442
|
ISSUE_NUMBER_INVALID: { message: 'The issue number is invalid', retryable: false },
|
|
376
443
|
ISSUE_CREATE_RESPONSE_INVALID: { message: 'Issue creation returned an invalid response', retryable: false },
|
|
377
444
|
COMMENT_ID_INVALID: { message: 'The comment identity is invalid', retryable: false },
|
|
445
|
+
SECURITY_KIND_INVALID: { message: 'The security alert kind is invalid', retryable: false },
|
|
446
|
+
SECURITY_NUMBER_INVALID: { message: 'The security alert number is invalid', retryable: false },
|
|
447
|
+
SECURITY_RESPONSE_INVALID: { message: 'The platform returned an invalid security alert', retryable: false },
|
|
448
|
+
LABEL_RESPONSE_INVALID: { message: 'The platform returned an invalid label response', retryable: false },
|
|
449
|
+
MILESTONE_RESPONSE_INVALID: { message: 'The platform returned an invalid milestone response', retryable: false },
|
|
378
450
|
MILESTONE_IDENTITY_INVALID: { message: 'The milestone identity is invalid', retryable: false },
|
|
379
451
|
CHECK_RUN_NOT_FOUND: { message: 'The check run was not found', retryable: false },
|
|
380
452
|
RELEASE_NOTES_AUTHORS_TRUNCATED: { message: 'Release note commit authors exceeded the supported limit', retryable: false },
|
|
@@ -415,6 +487,8 @@ function validators(providerType: string, declaration?: ProviderIdentityDeclarat
|
|
|
415
487
|
return { sha: stringValue(item.sha, 'change request head.sha') };
|
|
416
488
|
},
|
|
417
489
|
'changeRequests.inspect': (value) => validateChangeRequest(value, declaredIdentityKind(declaration, 'pull-request'), true),
|
|
490
|
+
'changeRequests.listFiles': (value) => arrayValue(value, 'pull request files').map((entry) => stringValue(entry, 'pull request files[]')),
|
|
491
|
+
'changeRequests.listClosingIssues': (value) => arrayValue(value, 'closing issues').map((entry) => identity(entry, 'closing issues[]', declaredIdentityKind(declaration, 'issue'))),
|
|
418
492
|
'changeRequests.listClosing': (value) => arrayValue(value, 'changeRequests').map((entry) => validateChangeRequest(entry, declaredIdentityKind(declaration, 'pull-request'), true)),
|
|
419
493
|
'changeRequests.create': validateReceipt,
|
|
420
494
|
'changeRequests.update': validateReceipt,
|
|
@@ -458,6 +532,10 @@ function validators(providerType: string, declaration?: ProviderIdentityDeclarat
|
|
|
458
532
|
},
|
|
459
533
|
'releases.publishNotes': validateReceipt,
|
|
460
534
|
'releases.collectNotes': (value) => validateReleaseNotes(value, declaration),
|
|
535
|
+
'securityAlerts.inspect': validateSecurityAlert,
|
|
536
|
+
'securityAlerts.dismiss': validateReceipt,
|
|
537
|
+
'repositoryMetadata.reconcileLabels': validateLabelReconciliation,
|
|
538
|
+
'repositoryMetadata.reconcileMilestones': validateMilestoneInitialization,
|
|
461
539
|
'verification.fetchRemoteFacts': (value) => {
|
|
462
540
|
const item = record(value, 'verification facts');
|
|
463
541
|
exactKeys(item, ['issue', 'comments', 'changeRequest', 'commit', 'fields'], 'verification facts');
|
|
@@ -491,11 +569,15 @@ async function invokeProviderOperation<T>(
|
|
|
491
569
|
}
|
|
492
570
|
if (envelope.ok === false && envelope.error && typeof envelope.error === 'object' && !Array.isArray(envelope.error)) {
|
|
493
571
|
try {
|
|
494
|
-
exactKeys(envelope, ['ok', 'error'], `${operation} result`);
|
|
572
|
+
exactKeys(envelope, Object.hasOwn(envelope, 'value') ? ['ok', 'error', 'value'] : ['ok', 'error'], `${operation} result`);
|
|
495
573
|
const error = envelope.error as Record<string, unknown>;
|
|
496
574
|
exactKeys(error, ['code', 'message', 'retryable'], `${operation} error`);
|
|
497
575
|
if (typeof error.code !== 'string' || !error.code || typeof error.message !== 'string' || !error.message || typeof error.retryable !== 'boolean') throw new Error('invalid provider error');
|
|
498
|
-
return {
|
|
576
|
+
return {
|
|
577
|
+
ok: false,
|
|
578
|
+
error: safeProviderError(providerType, operation, error),
|
|
579
|
+
...(Object.hasOwn(envelope, 'value') ? { value: validate(envelope.value) } : {})
|
|
580
|
+
};
|
|
499
581
|
} catch {
|
|
500
582
|
return { ok: false, error: validationError(providerType, operation, 'Provider operation returned an invalid error') };
|
|
501
583
|
}
|
|
@@ -510,7 +592,7 @@ function wrapProviderOperations(provider: PlatformProvider): PlatformProvider {
|
|
|
510
592
|
const map = validators(provider.type, provider.identity);
|
|
511
593
|
const wrapped: PlatformProvider = { ...provider, context: { ...provider.context } };
|
|
512
594
|
wrapped.context.resolve = (input) => invokeProviderOperation(provider.type, 'context.resolve', () => provider.context.resolve(input), map['context.resolve']! as ResultValidator<PlatformContextSnapshot>);
|
|
513
|
-
for (const groupName of ['issues', 'comments', 'changeRequests', 'checks', 'reviews', 'releases', 'verification'] as const) {
|
|
595
|
+
for (const groupName of ['issues', 'comments', 'changeRequests', 'checks', 'reviews', 'releases', 'securityAlerts', 'repositoryMetadata', 'verification'] as const) {
|
|
514
596
|
const group = provider[groupName];
|
|
515
597
|
if (!group) continue;
|
|
516
598
|
const target: Record<string, unknown> = { ...group };
|