@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ISSUE_FIELDS_QUERY, graphState, inspectGitHubIssue, inspectGitHubPullRequest, inspectGitHubIssueClosingChangeRequests, inspectGitHubRequiredChecks, parseRunJobIdentity, fetchCheckLogText } from './github-data.ts';
|
|
1
2
|
import { execFileSync } from 'node:child_process';
|
|
2
3
|
import fs from 'node:fs';
|
|
3
4
|
import os from 'node:os';
|
|
@@ -16,8 +17,11 @@ import type {
|
|
|
16
17
|
CheckRunSnapshot,
|
|
17
18
|
GitEvidenceSnapshot,
|
|
18
19
|
IssueSnapshot,
|
|
20
|
+
LabelReconciliation,
|
|
19
21
|
MutationReceipt,
|
|
22
|
+
MilestoneInitialization,
|
|
20
23
|
PlatformContextSnapshot,
|
|
24
|
+
PlatformError,
|
|
21
25
|
ProviderOperationContext,
|
|
22
26
|
PlatformProvider,
|
|
23
27
|
PlatformProviderFactoryInput,
|
|
@@ -27,16 +31,17 @@ import type {
|
|
|
27
31
|
RepositoryMetadataSnapshot,
|
|
28
32
|
ReleaseSnapshot,
|
|
29
33
|
RemoteCommentSnapshot,
|
|
30
|
-
RequiredCheckSnapshot,
|
|
31
34
|
ReviewSnapshot,
|
|
35
|
+
SecurityAlertKind,
|
|
36
|
+
SecurityAlertSnapshot,
|
|
32
37
|
VerificationRemoteFacts
|
|
33
38
|
} from './provider-contract.ts';
|
|
34
39
|
import { resourceIdentityNumber, resourceIdentityString } from './resource-identity.ts';
|
|
35
|
-
import { syncLabelDelta } from './in-label-sync.ts';
|
|
40
|
+
import { extractPullRequestFileNames, syncLabelDelta } from './in-label-sync.ts';
|
|
36
41
|
|
|
37
42
|
const CURRENT_USER_QUERY = 'query { viewer { login } }';
|
|
38
43
|
const ISSUE_TYPES_QUERY = `query($owner:String!){organization(login:$owner){issueTypes(first:20){nodes{id name pinnedFields{__typename ... on IssueFieldSingleSelect{id name options{id name}} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}}}}}`;
|
|
39
|
-
const
|
|
44
|
+
const CLOSING_ISSUES_QUERY = 'query($owner:String!,$name:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$name){pullRequest(number:$number){closingIssuesReferences(first:100,after:$cursor){nodes{number} pageInfo{hasNextPage endCursor}}}}}';
|
|
40
45
|
|
|
41
46
|
function parseGitHubRemote(remote: string): string | null {
|
|
42
47
|
const trimmed = remote.trim().replace(/\.git$/, '');
|
|
@@ -340,6 +345,29 @@ function createReceipt(remoteId: string): ProviderResult<MutationReceipt> {
|
|
|
340
345
|
return { ok: true, value: { changed: true, remoteId } };
|
|
341
346
|
}
|
|
342
347
|
|
|
348
|
+
function partialFailure<T>(response: { ok: false; error: PlatformError }, value: T): ProviderResult<T> {
|
|
349
|
+
return { ok: false, error: response.error, value };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function labelReconciliation(
|
|
353
|
+
created: string[],
|
|
354
|
+
updated: string[],
|
|
355
|
+
removed: string[],
|
|
356
|
+
skipped: string[]
|
|
357
|
+
): LabelReconciliation {
|
|
358
|
+
return {
|
|
359
|
+
changed: created.length > 0 || updated.length > 0 || removed.length > 0,
|
|
360
|
+
created,
|
|
361
|
+
updated,
|
|
362
|
+
removed,
|
|
363
|
+
skipped
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function milestoneInitialization(created: string[], skipped: string[]): MilestoneInitialization {
|
|
368
|
+
return { changed: created.length > 0, created, skipped };
|
|
369
|
+
}
|
|
370
|
+
|
|
343
371
|
function githubResourceToken(identity: ResourceIdentity | null | undefined): string | null {
|
|
344
372
|
return resourceIdentityString(identity) || (identity?.kind === 'number' ? String(identity.value) : null);
|
|
345
373
|
}
|
|
@@ -371,7 +399,7 @@ function syncLabels(
|
|
|
371
399
|
return { status: changed ? 'applied' as const : 'no-op' as const, changed, error: null };
|
|
372
400
|
}
|
|
373
401
|
|
|
374
|
-
function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'issues' | 'comments' | 'changeRequests' | 'checks' | 'reviews' | 'releases' | 'verification'> {
|
|
402
|
+
function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'issues' | 'comments' | 'changeRequests' | 'checks' | 'reviews' | 'releases' | 'securityAlerts' | 'repositoryMetadata' | 'verification'> {
|
|
375
403
|
const issues: NonNullable<PlatformProvider['issues']> = {
|
|
376
404
|
async listLabels({ context }) {
|
|
377
405
|
const response = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/labels?per_page=100`], { cwd: context.workingDirectory });
|
|
@@ -436,13 +464,25 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
436
464
|
async inspect({ context, target }) {
|
|
437
465
|
const number = resourceIdentityNumber(target);
|
|
438
466
|
if (!number) return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
|
|
439
|
-
const
|
|
440
|
-
const fetched = module.inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
|
|
467
|
+
const fetched = inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
|
|
441
468
|
if (!fetched.ok) return fetched;
|
|
442
|
-
const graph =
|
|
469
|
+
const graph = graphState(client, repository(context), number, context.workingDirectory);
|
|
443
470
|
return { ok: true, value: issueSnapshot(fetched.value, graph || undefined) };
|
|
444
471
|
},
|
|
445
472
|
async create({ context, desired }) {
|
|
473
|
+
let milestone: number | null = null;
|
|
474
|
+
if (desired.milestone) {
|
|
475
|
+
const milestones = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=open&per_page=100`], { cwd: context.workingDirectory });
|
|
476
|
+
if (!milestones.ok) return milestones;
|
|
477
|
+
const values = Array.isArray(milestones.value)
|
|
478
|
+
? milestones.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
|
|
479
|
+
: [];
|
|
480
|
+
const selected = values.find((item: any) => item?.title === desired.milestone);
|
|
481
|
+
if (!Number.isSafeInteger(selected?.number) || selected.number <= 0) {
|
|
482
|
+
return invalid('MILESTONE_IDENTITY_INVALID', 'Milestone title does not resolve to a positive number');
|
|
483
|
+
}
|
|
484
|
+
milestone = selected.number;
|
|
485
|
+
}
|
|
446
486
|
const response = client.json<any>(['api', `repos/${repository(context)}/issues`, '-X', 'POST', '--input', '-'], {
|
|
447
487
|
cwd: context.workingDirectory,
|
|
448
488
|
method: 'POST',
|
|
@@ -451,7 +491,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
451
491
|
body: desired.body,
|
|
452
492
|
labels: desired.labels,
|
|
453
493
|
assignees: desired.assignees,
|
|
454
|
-
...(
|
|
494
|
+
...(milestone ? { milestone } : {})
|
|
455
495
|
})
|
|
456
496
|
});
|
|
457
497
|
if (!response.ok) return response;
|
|
@@ -606,16 +646,66 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
606
646
|
async inspect({ context, target }) {
|
|
607
647
|
const number = resourceIdentityNumber(target);
|
|
608
648
|
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
609
|
-
const
|
|
610
|
-
const fetched = module.inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
|
|
649
|
+
const fetched = inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
|
|
611
650
|
if (!fetched.ok) return fetched;
|
|
612
651
|
return { ok: true, value: changeRequestSnapshot(fetched.value) };
|
|
613
652
|
},
|
|
653
|
+
async listFiles({ context, target }) {
|
|
654
|
+
const number = resourceIdentityNumber(target);
|
|
655
|
+
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
656
|
+
const response = client.json<unknown>(['api', '--paginate', '--slurp', `repos/${repository(context)}/pulls/${number}/files?per_page=100`], { cwd: context.workingDirectory });
|
|
657
|
+
if (!response.ok) return response;
|
|
658
|
+
const files = extractPullRequestFileNames(response.value);
|
|
659
|
+
return files
|
|
660
|
+
? { ok: true, value: files }
|
|
661
|
+
: invalid('IN_LABEL_SYNC_FILES_INVALID', 'Pull request files response is incomplete');
|
|
662
|
+
},
|
|
663
|
+
async listClosingIssues({ context, target }) {
|
|
664
|
+
const number = resourceIdentityNumber(target);
|
|
665
|
+
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
666
|
+
const [owner, name] = repository(context).split('/');
|
|
667
|
+
if (!owner || !name) return invalid('IN_LABEL_SYNC_REPOSITORY_INVALID', 'Repository identity is invalid');
|
|
668
|
+
const identities: ResourceIdentity[] = [];
|
|
669
|
+
let cursor: string | null = null;
|
|
670
|
+
for (;;) {
|
|
671
|
+
const args = ['api', 'graphql', '-f', `query=${CLOSING_ISSUES_QUERY}`, '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `number=${number}`];
|
|
672
|
+
if (cursor) args.push('-F', `cursor=${cursor}`);
|
|
673
|
+
const response = client.json<unknown>(args, { cwd: context.workingDirectory });
|
|
674
|
+
if (!response.ok) return response;
|
|
675
|
+
const connection = (response.value as {
|
|
676
|
+
data?: { repository?: { pullRequest?: { closingIssuesReferences?: {
|
|
677
|
+
nodes?: unknown[]; pageInfo?: { hasNextPage?: boolean; endCursor?: string | null };
|
|
678
|
+
} } } };
|
|
679
|
+
})?.data?.repository?.pullRequest?.closingIssuesReferences;
|
|
680
|
+
if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo) {
|
|
681
|
+
return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue response is incomplete');
|
|
682
|
+
}
|
|
683
|
+
for (const node of connection.nodes) {
|
|
684
|
+
const issue = Number((node as { number?: unknown })?.number);
|
|
685
|
+
if (!Number.isSafeInteger(issue) || issue <= 0) {
|
|
686
|
+
return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue identity is invalid');
|
|
687
|
+
}
|
|
688
|
+
identities.push({ kind: 'number', value: issue });
|
|
689
|
+
}
|
|
690
|
+
if (!connection.pageInfo.hasNextPage) {
|
|
691
|
+
const seen = new Set<string>();
|
|
692
|
+
return { ok: true, value: identities.filter((identity) => {
|
|
693
|
+
const key = `${identity.kind}:${identity.value}`;
|
|
694
|
+
if (seen.has(key)) return false;
|
|
695
|
+
seen.add(key);
|
|
696
|
+
return true;
|
|
697
|
+
}) };
|
|
698
|
+
}
|
|
699
|
+
if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor) {
|
|
700
|
+
return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue pagination cursor is invalid');
|
|
701
|
+
}
|
|
702
|
+
cursor = connection.pageInfo.endCursor;
|
|
703
|
+
}
|
|
704
|
+
},
|
|
614
705
|
async listClosing({ context, issue }) {
|
|
615
706
|
const number = resourceIdentityNumber(issue);
|
|
616
707
|
if (!number) return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
|
|
617
|
-
const
|
|
618
|
-
const fetched = module.inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
|
|
708
|
+
const fetched = inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
|
|
619
709
|
if (!fetched.ok) return fetched;
|
|
620
710
|
return { ok: true, value: fetched.value.map(changeRequestSnapshot) };
|
|
621
711
|
},
|
|
@@ -686,8 +776,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
686
776
|
async resolveGitEvidence({ context, target, expected }) {
|
|
687
777
|
const number = resourceIdentityNumber(target);
|
|
688
778
|
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
689
|
-
|
|
690
|
-
return module.resolveGitHubChangeRequestGitEvidence({
|
|
779
|
+
return resolveGitHubChangeRequestGitEvidence({
|
|
691
780
|
cwd: context.workingDirectory,
|
|
692
781
|
repository: repository(context),
|
|
693
782
|
number,
|
|
@@ -701,16 +790,12 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
701
790
|
async inspectRequired({ context, changeRequest }) {
|
|
702
791
|
const number = resourceIdentityNumber(changeRequest);
|
|
703
792
|
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
704
|
-
|
|
705
|
-
const fetched = module.inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
|
|
706
|
-
if (!fetched.ok) return fetched;
|
|
707
|
-
return { ok: true, value: fetched.value.map((check: any): RequiredCheckSnapshot => ({ name: check.name, status: check.bucket, conclusion: check.conclusion, detailsUrl: check.detailsUrl })) };
|
|
793
|
+
return inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
|
|
708
794
|
},
|
|
709
795
|
async resolveRun({ context, changeRequest, checkName, detailsUrl }) {
|
|
710
796
|
const number = resourceIdentityNumber(changeRequest);
|
|
711
797
|
if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
|
|
712
|
-
const
|
|
713
|
-
const direct = detailsUrl ? module.parseRunJobIdentity(detailsUrl) : null;
|
|
798
|
+
const direct = detailsUrl ? parseRunJobIdentity(detailsUrl) : null;
|
|
714
799
|
if (direct) {
|
|
715
800
|
const run = client.json<any>(['api', `repos/${repository(context)}/actions/runs/${direct.runId}`], { cwd: context.workingDirectory });
|
|
716
801
|
if (!run.ok) return run;
|
|
@@ -724,11 +809,10 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
724
809
|
: invalid('CHECK_RUN_NOT_FOUND', 'Check run was not found');
|
|
725
810
|
},
|
|
726
811
|
async fetchLogs({ context, runId, jobId }) {
|
|
727
|
-
const module = await import('./pr-checks.ts');
|
|
728
812
|
const args = jobId
|
|
729
813
|
? ['api', `repos/${repository(context)}/actions/jobs/${jobId}/logs`]
|
|
730
814
|
: ['run', 'view', runId, '--repo', repository(context), '--log-failed'];
|
|
731
|
-
const fetched =
|
|
815
|
+
const fetched = fetchCheckLogText(client, args, context.workingDirectory);
|
|
732
816
|
if (!fetched.ok) return fetched;
|
|
733
817
|
return { ok: true, value: { runId, jobId, text: fetched.value || '' } } as ProviderResult<CheckLogSnapshot>;
|
|
734
818
|
}
|
|
@@ -797,7 +881,12 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
797
881
|
}
|
|
798
882
|
continue;
|
|
799
883
|
}
|
|
800
|
-
const response = client.json([
|
|
884
|
+
const response = client.json([
|
|
885
|
+
'api', '--method', 'POST', `repos/${repository(context)}/milestones`,
|
|
886
|
+
'-f', `title=${item.title}`,
|
|
887
|
+
'-f', `description=${item.description}`,
|
|
888
|
+
'-f', `state=${item.state}`
|
|
889
|
+
], { cwd: context.workingDirectory });
|
|
801
890
|
if (!response.ok) return response;
|
|
802
891
|
created.push(item.title);
|
|
803
892
|
}
|
|
@@ -854,20 +943,148 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
854
943
|
}
|
|
855
944
|
};
|
|
856
945
|
|
|
946
|
+
const securityAlerts: NonNullable<PlatformProvider['securityAlerts']> = {
|
|
947
|
+
async inspect({ context, kind, number }): Promise<ProviderResult<SecurityAlertSnapshot>> {
|
|
948
|
+
if (!Number.isSafeInteger(number) || number <= 0) return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
|
|
949
|
+
const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
|
|
950
|
+
if (!suffix) return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
|
|
951
|
+
const response = client.json<any>(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`], { cwd: context.workingDirectory });
|
|
952
|
+
if (!response.ok) return response;
|
|
953
|
+
const data = response.value;
|
|
954
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) return invalid('SECURITY_RESPONSE_INVALID', 'The platform returned an invalid security alert');
|
|
955
|
+
const value: SecurityAlertSnapshot = {
|
|
956
|
+
kind,
|
|
957
|
+
number,
|
|
958
|
+
state: typeof data.state === 'string' ? data.state : 'invalid',
|
|
959
|
+
data
|
|
960
|
+
};
|
|
961
|
+
return { ok: true, value };
|
|
962
|
+
},
|
|
963
|
+
async dismiss({ context, kind, number, reason, comment }): Promise<ProviderResult<MutationReceipt>> {
|
|
964
|
+
const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
|
|
965
|
+
if (!suffix) return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
|
|
966
|
+
if (!Number.isSafeInteger(number) || number <= 0) return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
|
|
967
|
+
const response = client.json<any>(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`, '-X', 'PATCH', '--input', '-'], {
|
|
968
|
+
cwd: context.workingDirectory,
|
|
969
|
+
method: 'PATCH',
|
|
970
|
+
input: JSON.stringify({ state: 'dismissed', dismissed_reason: reason, dismissed_comment: comment })
|
|
971
|
+
});
|
|
972
|
+
if (!response.ok) return response;
|
|
973
|
+
return createReceipt(String(response.value?.id || `${kind}:${number}`));
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
const repositoryMetadata: NonNullable<PlatformProvider['repositoryMetadata']> = {
|
|
978
|
+
async reconcileLabels({ context, desired, cleanupStaleIn }): Promise<ProviderResult<LabelReconciliation>> {
|
|
979
|
+
const endpoint = `repos/${repository(context)}/labels?per_page=100`;
|
|
980
|
+
const listed = client.json<any>(['api', '--paginate', '--slurp', endpoint], { cwd: context.workingDirectory });
|
|
981
|
+
if (!listed.ok) return listed;
|
|
982
|
+
if (!Array.isArray(listed.value)) return invalid('LABEL_RESPONSE_INVALID', 'The platform returned an invalid label list');
|
|
983
|
+
const values = Array.isArray(listed.value)
|
|
984
|
+
? listed.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
|
|
985
|
+
: [];
|
|
986
|
+
if (values.some((entry: any) => !entry || typeof entry.name !== 'string' || !entry.name)) {
|
|
987
|
+
return invalid('LABEL_RESPONSE_INVALID', 'The platform returned a label without a valid name');
|
|
988
|
+
}
|
|
989
|
+
const current = new Map<string, any>(values.map((entry: any) => [String(entry.name), entry]));
|
|
990
|
+
const created: string[] = [];
|
|
991
|
+
const updated: string[] = [];
|
|
992
|
+
const skipped: string[] = [];
|
|
993
|
+
const removed: string[] = [];
|
|
994
|
+
for (const label of desired) {
|
|
995
|
+
const existing = current.get(label.name);
|
|
996
|
+
if (!existing) {
|
|
997
|
+
const response = client.json(['api', `repos/${repository(context)}/labels`, '-X', 'POST', '--input', '-'], {
|
|
998
|
+
cwd: context.workingDirectory,
|
|
999
|
+
method: 'POST',
|
|
1000
|
+
input: JSON.stringify({ name: label.name, color: label.color, description: label.description })
|
|
1001
|
+
});
|
|
1002
|
+
if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
|
|
1003
|
+
created.push(label.name);
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
const sameColor = typeof existing.color === 'string' && existing.color.toUpperCase() === label.color.toUpperCase();
|
|
1007
|
+
const sameDescription = String(existing.description || '') === label.description;
|
|
1008
|
+
if (sameColor && sameDescription) {
|
|
1009
|
+
skipped.push(label.name);
|
|
1010
|
+
continue;
|
|
1011
|
+
}
|
|
1012
|
+
const response = client.json(['api', `repos/${repository(context)}/labels/${encodeURIComponent(label.name)}`, '-X', 'PATCH', '--input', '-'], {
|
|
1013
|
+
cwd: context.workingDirectory,
|
|
1014
|
+
method: 'PATCH',
|
|
1015
|
+
input: JSON.stringify({ new_name: label.name, color: label.color, description: label.description })
|
|
1016
|
+
});
|
|
1017
|
+
if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
|
|
1018
|
+
updated.push(label.name);
|
|
1019
|
+
}
|
|
1020
|
+
const desiredNames = new Set(desired.map((label) => label.name));
|
|
1021
|
+
if (cleanupStaleIn) {
|
|
1022
|
+
for (const name of current.keys()) {
|
|
1023
|
+
if (!name.startsWith('in:') || desiredNames.has(name)) continue;
|
|
1024
|
+
const response = client.text(['api', `repos/${repository(context)}/labels/${encodeURIComponent(name)}`, '-X', 'DELETE'], {
|
|
1025
|
+
cwd: context.workingDirectory,
|
|
1026
|
+
method: 'DELETE'
|
|
1027
|
+
});
|
|
1028
|
+
if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
|
|
1029
|
+
removed.push(name);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
return {
|
|
1033
|
+
ok: true,
|
|
1034
|
+
value: {
|
|
1035
|
+
changed: created.length > 0 || updated.length > 0 || removed.length > 0,
|
|
1036
|
+
created,
|
|
1037
|
+
updated,
|
|
1038
|
+
removed,
|
|
1039
|
+
skipped
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
},
|
|
1043
|
+
async reconcileMilestones({ context, desired }): Promise<ProviderResult<MilestoneInitialization>> {
|
|
1044
|
+
const listed = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=all&per_page=100`], { cwd: context.workingDirectory });
|
|
1045
|
+
if (!listed.ok) return listed;
|
|
1046
|
+
if (!Array.isArray(listed.value)) return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned an invalid milestone list');
|
|
1047
|
+
const values = Array.isArray(listed.value)
|
|
1048
|
+
? listed.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
|
|
1049
|
+
: [];
|
|
1050
|
+
if (values.some((entry: any) => !entry || typeof entry.title !== 'string' || !entry.title)) {
|
|
1051
|
+
return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned a milestone without a valid title');
|
|
1052
|
+
}
|
|
1053
|
+
const existing = new Set(values.map((entry: any) => String(entry.title)));
|
|
1054
|
+
const created: string[] = [];
|
|
1055
|
+
const skipped: string[] = [];
|
|
1056
|
+
for (const milestone of desired) {
|
|
1057
|
+
if (existing.has(milestone.title)) {
|
|
1058
|
+
skipped.push(milestone.title);
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
const response = client.json(['api', `repos/${repository(context)}/milestones`, '-X', 'POST', '--input', '-'], {
|
|
1062
|
+
cwd: context.workingDirectory,
|
|
1063
|
+
method: 'POST',
|
|
1064
|
+
input: JSON.stringify({ title: milestone.title, description: milestone.description, state: milestone.state })
|
|
1065
|
+
});
|
|
1066
|
+
if (!response.ok) return partialFailure(response, milestoneInitialization(created, skipped));
|
|
1067
|
+
existing.add(milestone.title);
|
|
1068
|
+
created.push(milestone.title);
|
|
1069
|
+
}
|
|
1070
|
+
return { ok: true, value: { changed: created.length > 0, created, skipped } };
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
|
|
857
1074
|
const verification: NonNullable<PlatformProvider['verification']> = {
|
|
858
1075
|
async fetchRemoteFacts(input) {
|
|
859
1076
|
const issue = input.issue && issues.inspect
|
|
860
1077
|
? await issues.inspect({ context: input.context, target: input.issue })
|
|
861
1078
|
: { ok: true as const, value: null };
|
|
862
|
-
if (!issue.ok) return issue;
|
|
1079
|
+
if (!issue.ok) return { ok: false, error: issue.error };
|
|
863
1080
|
const commentFacts = input.includeComments && input.issue && comments.list
|
|
864
1081
|
? await comments.list({ context: input.context, parent: input.issue })
|
|
865
1082
|
: { ok: true as const, value: [] as RemoteCommentSnapshot[] };
|
|
866
|
-
if (!commentFacts.ok) return commentFacts;
|
|
1083
|
+
if (!commentFacts.ok) return { ok: false, error: commentFacts.error };
|
|
867
1084
|
const changeRequest = input.changeRequest && changeRequests.inspect
|
|
868
1085
|
? await changeRequests.inspect({ context: input.context, target: input.changeRequest })
|
|
869
1086
|
: { ok: true as const, value: null };
|
|
870
|
-
if (!changeRequest.ok) return changeRequest;
|
|
1087
|
+
if (!changeRequest.ok) return { ok: false, error: changeRequest.error };
|
|
871
1088
|
return {
|
|
872
1089
|
ok: true,
|
|
873
1090
|
value: {
|
|
@@ -881,7 +1098,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
|
|
|
881
1098
|
}
|
|
882
1099
|
};
|
|
883
1100
|
|
|
884
|
-
return { issues, comments, changeRequests, checks, reviews, releases, verification };
|
|
1101
|
+
return { issues, comments, changeRequests, checks, reviews, releases, securityAlerts, repositoryMetadata, verification };
|
|
885
1102
|
}
|
|
886
1103
|
|
|
887
1104
|
function createGitHubProvider(
|