@fitlab-ai/agent-infra 0.8.5 → 0.9.0
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/bin/cli.ts +2 -2
- package/dist/bin/cli.js +2 -2
- package/dist/bin/internal-cli.js +98 -0
- package/dist/lib/decide.js +81 -90
- package/dist/lib/defaults.json +1 -0
- package/dist/lib/git/review-snapshot.js +79 -0
- package/dist/lib/git/workflow.js +101 -0
- package/dist/lib/internal/git-workflow.js +42 -0
- package/dist/lib/internal/platform-checks.js +119 -0
- package/dist/lib/internal/platform-comment.js +129 -0
- package/dist/lib/internal/platform-context.js +46 -0
- package/dist/lib/internal/platform-issue.js +142 -0
- package/dist/lib/internal/platform-pr.js +146 -0
- package/dist/lib/internal/release-workflow.js +217 -0
- package/dist/lib/internal/task-artifact.js +67 -0
- package/dist/lib/internal/task-context.js +43 -0
- package/dist/lib/internal/task-event.js +70 -0
- package/dist/lib/internal/task-ledger.js +114 -0
- package/dist/lib/internal/task-lifecycle.js +58 -0
- package/dist/lib/internal/task-short-id.js +83 -0
- package/dist/lib/internal/task-snapshot.js +47 -0
- package/dist/lib/internal/task-verify.js +50 -0
- package/dist/lib/internal/task-warning.js +74 -0
- package/dist/lib/platform/adapters.js +14 -0
- package/dist/lib/platform/context.js +146 -0
- package/dist/lib/platform/github-client.js +124 -0
- package/dist/lib/platform/issue-comments.js +409 -0
- package/dist/lib/platform/issue-metadata.js +183 -0
- package/dist/lib/platform/issues.js +617 -0
- package/dist/lib/platform/metadata-labels.js +28 -0
- package/dist/lib/platform/pr-checks.js +216 -0
- package/dist/lib/platform/pr-summary.js +88 -0
- package/dist/lib/platform/pull-request-metadata.js +38 -0
- package/dist/lib/platform/pull-requests.js +338 -0
- package/dist/lib/platform/releases.js +82 -0
- package/dist/lib/platform/types.js +22 -0
- package/dist/lib/platform/verification-required.js +78 -0
- package/dist/lib/platform/verification-sync.js +1014 -0
- package/dist/lib/platform/verification.js +6 -0
- package/dist/lib/release/channels.js +31 -0
- package/dist/lib/release/workflow.js +32 -0
- package/dist/lib/render.js +3 -2
- package/dist/lib/run/index.js +24 -7
- package/dist/lib/sandbox/capture.js +25 -3
- package/dist/lib/sandbox/commands/create.js +36 -22
- package/dist/lib/sandbox/commands/enter.js +34 -11
- package/dist/lib/sandbox/commands/list-running.js +10 -8
- package/dist/lib/sandbox/commands/show.js +2 -2
- package/dist/lib/sandbox/commands/start.js +53 -15
- package/dist/lib/sandbox/index.js +6 -6
- package/dist/lib/sandbox/mounts.js +36 -0
- package/dist/lib/sandbox/recovery.js +562 -0
- package/dist/lib/sandbox/task-resolver.js +5 -1
- package/dist/lib/sandbox/tools.js +19 -0
- package/dist/lib/server/protocol.js +5 -5
- package/dist/lib/task/activity-log.js +61 -0
- package/dist/lib/task/artifact-lifecycle.js +427 -0
- package/dist/lib/task/command-options.js +30 -0
- package/dist/lib/task/commands/cat.js +36 -6
- package/dist/lib/task/commands/decisions.js +80 -46
- package/dist/lib/task/commands/files.js +21 -7
- package/dist/lib/task/commands/grep.js +55 -7
- package/dist/lib/task/commands/issue-body.js +23 -14
- package/dist/lib/task/commands/log.js +27 -70
- package/dist/lib/task/commands/show.js +20 -7
- package/dist/lib/task/commands/status.js +18 -8
- package/dist/lib/task/decision-intents.js +154 -0
- package/dist/lib/task/decision-items.js +53 -0
- package/dist/lib/task/events.js +318 -0
- package/dist/lib/task/frontmatter.js +159 -1
- package/dist/lib/task/implementation-inputs.js +117 -0
- package/dist/lib/task/index.js +12 -9
- package/dist/lib/task/issue-form.js +19 -6
- package/dist/lib/task/ledger-intents.js +185 -0
- package/dist/lib/task/ledger.js +65 -35
- package/dist/lib/task/lifecycle.js +484 -0
- package/dist/lib/task/resolve-ref.js +152 -32
- package/dist/lib/task/review-artifacts.js +101 -0
- package/dist/lib/task/review-fingerprint.js +46 -0
- package/dist/lib/task/sections.js +358 -4
- package/dist/lib/task/short-id.js +292 -7
- package/dist/lib/task/snapshot.js +95 -0
- package/dist/lib/task/verification-checks.js +8 -0
- package/dist/lib/task/verification-config.js +14 -0
- package/dist/lib/task/verification-engine.js +906 -0
- package/dist/lib/task/verification-review.js +3 -0
- package/dist/lib/task/verification-types.js +2 -0
- package/dist/lib/task/verification.js +113 -0
- package/dist/lib/task/workflow-warning-intents.js +131 -0
- package/dist/lib/task/workflow-warnings.js +10 -78
- package/dist/lib/task/write.js +241 -0
- package/lib/decide.ts +57 -97
- package/lib/defaults.json +1 -0
- package/lib/git/review-snapshot.ts +73 -0
- package/lib/git/workflow.ts +101 -0
- package/lib/internal/git-workflow.ts +37 -0
- package/lib/internal/platform-checks.ts +101 -0
- package/lib/internal/platform-comment.ts +99 -0
- package/lib/internal/platform-context.ts +33 -0
- package/lib/internal/platform-issue.ts +116 -0
- package/lib/internal/platform-pr.ts +119 -0
- package/lib/internal/release-workflow.ts +186 -0
- package/lib/internal/task-artifact.ts +47 -0
- package/lib/internal/task-context.ts +35 -0
- package/lib/internal/task-event.ts +51 -0
- package/lib/internal/task-ledger.ts +86 -0
- package/lib/internal/task-lifecycle.ts +41 -0
- package/lib/internal/task-short-id.ts +55 -0
- package/lib/internal/task-snapshot.ts +32 -0
- package/lib/internal/task-verify.ts +33 -0
- package/lib/internal/task-warning.ts +50 -0
- package/lib/platform/adapters.ts +30 -0
- package/lib/platform/context.ts +164 -0
- package/lib/platform/github-client.ts +146 -0
- package/lib/platform/issue-comments.ts +479 -0
- package/lib/platform/issue-metadata.ts +250 -0
- package/lib/platform/issues.ts +691 -0
- package/lib/platform/metadata-labels.ts +33 -0
- package/lib/platform/pr-checks.ts +246 -0
- package/lib/platform/pr-summary.ts +90 -0
- package/lib/platform/pull-request-metadata.ts +69 -0
- package/lib/platform/pull-requests.ts +380 -0
- package/lib/platform/releases.ts +71 -0
- package/lib/platform/types.ts +74 -0
- package/lib/platform/verification-required.ts +83 -0
- package/{runtime/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts} +198 -367
- package/lib/platform/verification.ts +11 -0
- package/lib/release/channels.ts +30 -0
- package/lib/release/workflow.ts +31 -0
- package/lib/render.ts +3 -2
- package/lib/run/index.ts +25 -7
- package/lib/sandbox/capture.ts +29 -3
- package/lib/sandbox/commands/create.ts +43 -25
- package/lib/sandbox/commands/enter.ts +38 -11
- package/lib/sandbox/commands/list-running.ts +10 -8
- package/lib/sandbox/commands/show.ts +2 -2
- package/lib/sandbox/commands/start.ts +50 -16
- package/lib/sandbox/index.ts +6 -6
- package/lib/sandbox/mounts.ts +55 -0
- package/lib/sandbox/recovery.ts +828 -0
- package/lib/sandbox/task-resolver.ts +5 -1
- package/lib/sandbox/tools.ts +31 -0
- package/lib/server/protocol.ts +5 -5
- package/lib/task/activity-log.ts +62 -0
- package/lib/task/artifact-lifecycle.ts +484 -0
- package/lib/task/command-options.ts +32 -0
- package/lib/task/commands/cat.ts +22 -9
- package/lib/task/commands/decisions.ts +49 -47
- package/lib/task/commands/files.ts +14 -6
- package/lib/task/commands/grep.ts +34 -7
- package/lib/task/commands/issue-body.ts +16 -16
- package/lib/task/commands/log.ts +17 -70
- package/lib/task/commands/show.ts +14 -6
- package/lib/task/commands/status.ts +17 -7
- package/lib/task/decision-intents.ts +163 -0
- package/lib/task/decision-items.ts +64 -0
- package/lib/task/events.ts +320 -0
- package/lib/task/frontmatter.ts +202 -2
- package/lib/task/implementation-inputs.ts +137 -0
- package/lib/task/index.ts +12 -9
- package/lib/task/issue-form.ts +20 -6
- package/lib/task/ledger-intents.ts +201 -0
- package/lib/task/ledger.ts +77 -31
- package/lib/task/lifecycle.ts +458 -0
- package/lib/task/resolve-ref.ts +197 -36
- package/{templates/.agents/scripts/lib/review-artifacts.js → lib/task/review-artifacts.ts} +11 -12
- package/{templates/.agents/scripts/lib/post-review-commit.js → lib/task/review-fingerprint.ts} +17 -12
- package/lib/task/sections.ts +486 -4
- package/lib/task/short-id.ts +403 -9
- package/lib/task/snapshot.ts +143 -0
- package/lib/task/verification-checks.ts +9 -0
- package/lib/task/verification-config.ts +20 -0
- package/{templates/.agents/scripts/validate-artifact.js → lib/task/verification-engine.ts} +199 -406
- package/lib/task/verification-review.ts +9 -0
- package/lib/task/verification-types.ts +29 -0
- package/lib/task/verification.ts +156 -0
- package/lib/task/workflow-warning-intents.ts +142 -0
- package/lib/task/workflow-warnings.ts +10 -78
- package/lib/task/write.ts +468 -0
- package/package.json +4 -2
- package/templates/.agents/README.en.md +4 -3
- package/templates/.agents/README.zh-CN.md +4 -3
- package/templates/.agents/rules/README.en.md +6 -5
- package/templates/.agents/rules/README.zh-CN.md +6 -5
- package/templates/.agents/rules/create-issue.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.en.md +5 -184
- package/templates/.agents/rules/create-issue.github.zh-CN.md +12 -178
- package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
- package/templates/.agents/rules/human-decision-context.en.md +36 -0
- package/templates/.agents/rules/human-decision-context.zh-CN.md +36 -0
- package/templates/.agents/rules/issue-fields.github.en.md +4 -148
- package/templates/.agents/rules/issue-fields.github.zh-CN.md +9 -144
- package/templates/.agents/rules/issue-pr-commands.en.md +43 -3
- package/templates/.agents/rules/issue-pr-commands.github.en.md +15 -220
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +23 -213
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +45 -3
- package/templates/.agents/rules/issue-sync.en.md +1 -1
- package/templates/.agents/rules/issue-sync.github.en.md +14 -301
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +36 -287
- package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
- package/templates/.agents/rules/milestone-inference.en.md +1 -1
- package/templates/.agents/rules/milestone-inference.github.en.md +7 -119
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +8 -108
- package/templates/.agents/rules/milestone-inference.zh-CN.md +1 -1
- package/templates/.agents/rules/next-step-output.en.md +12 -11
- package/templates/.agents/rules/next-step-output.zh-CN.md +12 -11
- package/templates/.agents/rules/no-mid-flow-questions.en.md +3 -3
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +3 -3
- package/templates/.agents/rules/pr-checks-commands.en.md +16 -3
- package/templates/.agents/rules/pr-checks-commands.github.en.md +10 -54
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +19 -47
- package/templates/.agents/rules/pr-checks-commands.zh-CN.md +30 -3
- package/templates/.agents/rules/pr-sync.en.md +30 -3
- package/templates/.agents/rules/pr-sync.github.en.md +12 -115
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +26 -104
- package/templates/.agents/rules/pr-sync.zh-CN.md +43 -3
- package/templates/.agents/rules/review-handshake.en.md +8 -5
- package/templates/.agents/rules/review-handshake.zh-CN.md +8 -5
- package/templates/.agents/rules/task-management.en.md +11 -2
- package/templates/.agents/rules/task-management.zh-CN.md +11 -3
- package/templates/.agents/rules/task-short-id.en.md +25 -29
- package/templates/.agents/rules/task-short-id.zh-CN.md +20 -23
- package/templates/.agents/scripts/lib/agent-infra-package.js +1 -9
- package/templates/.agents/scripts/task-short-id.js +71 -533
- package/templates/.agents/skills/analyze-task/SKILL.en.md +22 -55
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +26 -59
- package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -3
- package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -3
- package/templates/.agents/skills/block-task/SKILL.en.md +21 -47
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +23 -47
- package/templates/.agents/skills/block-task/config/verify.json +1 -2
- package/templates/.agents/skills/cancel-task/SKILL.en.md +16 -45
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +16 -45
- package/templates/.agents/skills/cancel-task/config/verify.json +1 -2
- package/templates/.agents/skills/check-task/SKILL.en.md +6 -3
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +6 -3
- package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -24
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -24
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -24
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -24
- package/templates/.agents/skills/code-task/SKILL.en.md +22 -35
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +28 -44
- package/templates/.agents/skills/code-task/config/verify.en.json +3 -3
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +3 -3
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +13 -9
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +13 -9
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/report-template.en.md +11 -1
- package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +11 -1
- package/templates/.agents/skills/commit/SKILL.en.md +13 -11
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +13 -11
- package/templates/.agents/skills/commit/config/verify.json +1 -2
- package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -11
- package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -11
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +4 -8
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +4 -8
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +6 -18
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +5 -17
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +13 -0
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +13 -0
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +13 -36
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +13 -36
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -3
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -3
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +10 -54
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +10 -79
- package/templates/.agents/skills/complete-task/SKILL.en.md +59 -63
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +59 -63
- package/templates/.agents/skills/complete-task/config/verify.en.json +11 -7
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +11 -7
- package/templates/.agents/skills/create-pr/SKILL.en.md +19 -44
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +19 -43
- package/templates/.agents/skills/create-pr/config/verify.json +1 -2
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +8 -12
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +7 -11
- package/templates/.agents/skills/create-task/SKILL.en.md +12 -13
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +12 -13
- package/templates/.agents/skills/create-task/config/verify.json +1 -2
- package/templates/.agents/skills/import-codescan/SKILL.en.md +2 -2
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/import-codescan/config/verify.json +1 -2
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/import-dependabot/config/verify.json +1 -2
- package/templates/.agents/skills/import-issue/SKILL.en.md +9 -13
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -14
- package/templates/.agents/skills/import-issue/config/verify.json +1 -2
- package/templates/.agents/skills/plan-task/SKILL.en.md +17 -42
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -49
- package/templates/.agents/skills/plan-task/config/verify.en.json +1 -3
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -3
- package/templates/.agents/skills/post-release/SKILL.en.md +11 -81
- package/templates/.agents/skills/post-release/SKILL.zh-CN.md +8 -78
- package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/release/SKILL.en.md +16 -163
- package/templates/.agents/skills/release/SKILL.zh-CN.md +15 -162
- package/templates/.agents/skills/restore-task/SKILL.en.md +11 -29
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +11 -29
- package/templates/.agents/skills/restore-task/config/verify.json +1 -2
- package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -25
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +13 -33
- package/templates/.agents/skills/review-analysis/config/verify.en.json +3 -4
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +3 -4
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +9 -12
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +9 -12
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +9 -2
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +9 -2
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +7 -0
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +7 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +22 -36
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +23 -41
- package/templates/.agents/skills/review-code/config/verify.en.json +3 -4
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +3 -4
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +56 -18
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +56 -18
- package/templates/.agents/skills/review-code/reference/report-template.en.md +11 -4
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +11 -4
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +7 -0
- package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +7 -0
- package/templates/.agents/skills/review-plan/SKILL.en.md +13 -25
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +13 -33
- package/templates/.agents/skills/review-plan/config/verify.en.json +3 -4
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +3 -4
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +9 -12
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +9 -12
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +9 -2
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +9 -2
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +7 -0
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +7 -0
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +1 -2
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +1 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -15
- package/templates/.agents/skills/watch-pr/SKILL.en.md +24 -14
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +25 -15
- package/templates/.agents/skills/watch-pr/config/verify.json +1 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
- package/templates/.agents/templates/task.en.md +6 -1
- package/templates/.agents/templates/task.zh-CN.md +6 -1
- package/templates/.claude/commands/analyze-task.en.md +1 -1
- package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
- package/templates/.claude/commands/block-task.en.md +1 -1
- package/templates/.claude/commands/block-task.zh-CN.md +1 -1
- package/templates/.claude/commands/cancel-task.en.md +1 -1
- package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
- package/templates/.claude/commands/check-task.en.md +1 -1
- package/templates/.claude/commands/check-task.zh-CN.md +1 -1
- package/templates/.claude/commands/code-task.en.md +1 -1
- package/templates/.claude/commands/code-task.zh-CN.md +1 -1
- package/templates/.claude/commands/commit.en.md +1 -0
- package/templates/.claude/commands/commit.zh-CN.md +1 -0
- package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
- package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
- package/templates/.claude/commands/complete-task.en.md +1 -1
- package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
- package/templates/.claude/commands/create-pr.en.md +1 -1
- package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
- package/templates/.claude/commands/plan-task.en.md +1 -1
- package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
- package/templates/.claude/commands/review-analysis.en.md +1 -1
- package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
- package/templates/.claude/commands/review-code.en.md +1 -1
- package/templates/.claude/commands/review-code.zh-CN.md +1 -1
- package/templates/.claude/commands/review-plan.en.md +1 -1
- package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.gemini/commands/_project_/analyze-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/block-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/cancel-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/check-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/code-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/commit.en.toml +4 -0
- package/templates/.gemini/commands/_project_/commit.zh-CN.toml +4 -0
- package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +2 -0
- package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/complete-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/create-pr.en.toml +2 -0
- package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/plan-task.en.toml +2 -0
- package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/review-analysis.en.toml +2 -0
- package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/review-code.en.toml +2 -0
- package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/review-plan.en.toml +2 -0
- package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +2 -0
- package/templates/.gemini/commands/_project_/watch-pr.en.toml +2 -0
- package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +2 -0
- package/templates/.git-hooks/check-large-files.cjs +92 -0
- package/templates/.git-hooks/check-version-format.sh +5 -1
- package/templates/.git-hooks/pre-commit +1 -0
- package/templates/.opencode/commands/analyze-task.en.md +1 -1
- package/templates/.opencode/commands/analyze-task.zh-CN.md +1 -1
- package/templates/.opencode/commands/check-task.en.md +1 -1
- package/templates/.opencode/commands/check-task.zh-CN.md +1 -1
- package/templates/.opencode/commands/code-task.en.md +1 -1
- package/templates/.opencode/commands/code-task.zh-CN.md +1 -1
- package/templates/.opencode/commands/commit.en.md +2 -0
- package/templates/.opencode/commands/commit.zh-CN.md +2 -0
- package/templates/.opencode/commands/complete-task.en.md +1 -1
- package/templates/.opencode/commands/complete-task.zh-CN.md +1 -1
- package/templates/.opencode/commands/plan-task.en.md +1 -1
- package/templates/.opencode/commands/plan-task.zh-CN.md +1 -1
- package/templates/.opencode/commands/review-analysis.en.md +1 -1
- package/templates/.opencode/commands/review-analysis.zh-CN.md +1 -1
- package/templates/.opencode/commands/review-code.en.md +1 -1
- package/templates/.opencode/commands/review-code.zh-CN.md +1 -1
- package/templates/.opencode/commands/review-plan.en.md +1 -1
- package/templates/.opencode/commands/review-plan.zh-CN.md +1 -1
- package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +0 -40
- package/templates/.agents/scripts/platform-adapters/platform-sync.js +0 -13
- package/templates/.agents/scripts/review-diff-fingerprint.js +0 -170
- package/templates/.agents/scripts/workflow-warnings.js +0 -290
- package/templates/.agents/skills/code-task/scripts/detect-mode.js +0 -257
- package/templates/.agents/skills/release/scripts/manage-milestones.github.sh +0 -80
- package/templates/.agents/skills/release/scripts/manage-milestones.sh +0 -6
package/{runtime/platform-adapters/platform-sync.github.js → lib/platform/verification-sync.ts}
RENAMED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
-
import
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
import { createGitHubClient } from "./github-client.ts";
|
|
7
|
+
import { resolvePlatformContext } from "./context.ts";
|
|
8
|
+
import { hasCheckedRequirement, resolveRequirementSection } from "./issue-metadata.ts";
|
|
9
|
+
import { inspectGitHubIssueMetadata, requirementSectionAnchors } from "./issues.ts";
|
|
10
|
+
import { listRemoteComments } from "./issue-comments.ts";
|
|
11
|
+
import { taskTypeLabel } from "./metadata-labels.ts";
|
|
12
|
+
import { inspectGitHubPullRequest } from "./pull-requests.ts";
|
|
5
13
|
|
|
6
14
|
const CHECK_TYPE = "platform-sync";
|
|
7
|
-
const DEFAULT_RETRY_DELAYS_MS = [3000, 10000];
|
|
8
15
|
const VERSION_LINE_REGEX = /^[0-9]+\.[0-9]+\.x$/;
|
|
9
16
|
const FRONTMATTER_FIELD_MAP = {
|
|
10
17
|
priority: "Priority",
|
|
@@ -12,17 +19,18 @@ const FRONTMATTER_FIELD_MAP = {
|
|
|
12
19
|
start_date: "Start date",
|
|
13
20
|
target_date: "Target date"
|
|
14
21
|
};
|
|
15
|
-
const OPTION_LOCALIZATION = {
|
|
22
|
+
const OPTION_LOCALIZATION: Record<string, string> = {
|
|
16
23
|
"紧急": "Urgent",
|
|
17
24
|
"高": "High",
|
|
18
25
|
"中": "Medium",
|
|
19
26
|
"低": "Low"
|
|
20
27
|
};
|
|
21
28
|
|
|
22
|
-
let activeShared = null;
|
|
29
|
+
let activeShared: any = null;
|
|
23
30
|
let repoRoot = "";
|
|
31
|
+
const githubClient = createGitHubClient();
|
|
24
32
|
|
|
25
|
-
export function getDefaults() {
|
|
33
|
+
export function getDefaults(): any {
|
|
26
34
|
return {
|
|
27
35
|
statusLabels: {
|
|
28
36
|
pendingDesignWork: "status: pending-design-work",
|
|
@@ -42,7 +50,7 @@ export function getDefaults() {
|
|
|
42
50
|
};
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
function getShared() {
|
|
53
|
+
function getShared(): any {
|
|
46
54
|
if (!activeShared) {
|
|
47
55
|
throw new Error("platform-sync adapter shared utilities are unavailable");
|
|
48
56
|
}
|
|
@@ -50,51 +58,51 @@ function getShared() {
|
|
|
50
58
|
return activeShared;
|
|
51
59
|
}
|
|
52
60
|
|
|
53
|
-
function loadTask(...args) {
|
|
61
|
+
function loadTask(...args: any[]): any {
|
|
54
62
|
return getShared().loadTask(...args);
|
|
55
63
|
}
|
|
56
64
|
|
|
57
|
-
function getCheckedRequirements(...args) {
|
|
65
|
+
function getCheckedRequirements(...args: any[]): any {
|
|
58
66
|
return getShared().getCheckedRequirements(...args);
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
function normalizeContent(...args) {
|
|
69
|
+
function normalizeContent(...args: any[]): any {
|
|
62
70
|
return getShared().normalizeContent(...args);
|
|
63
71
|
}
|
|
64
72
|
|
|
65
|
-
function isBlank(...args) {
|
|
73
|
+
function isBlank(...args: any[]): any {
|
|
66
74
|
return getShared().isBlank(...args);
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
function escapeRegExp(...args) {
|
|
77
|
+
function escapeRegExp(...args: any[]): any {
|
|
70
78
|
return getShared().escapeRegExp(...args);
|
|
71
79
|
}
|
|
72
80
|
|
|
73
|
-
function passResult(...args) {
|
|
81
|
+
function passResult(...args: any[]): any {
|
|
74
82
|
return getShared().passResult(...args);
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
function failResult(...args) {
|
|
85
|
+
function failResult(...args: any[]): any {
|
|
78
86
|
return getShared().failResult(...args);
|
|
79
87
|
}
|
|
80
88
|
|
|
81
|
-
function blockedResult(...args) {
|
|
89
|
+
function blockedResult(...args: any[]): any {
|
|
82
90
|
return getShared().blockedResult(...args);
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
function safeStat(...args) {
|
|
93
|
+
function safeStat(...args: any[]): any {
|
|
86
94
|
return getShared().safeStat(...args);
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
function parseIssueNumber(...args) {
|
|
97
|
+
function parseIssueNumber(...args: any[]): any {
|
|
90
98
|
return getShared().parseIssueNumber(...args);
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
function parsePrNumber(...args) {
|
|
101
|
+
function parsePrNumber(...args: any[]): any {
|
|
94
102
|
return getShared().parsePrNumber(...args);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
export function check({ taskDir, config, artifactFile }, shared) {
|
|
105
|
+
export function check({ taskDir, config, artifactFile }: any, shared: any): any {
|
|
98
106
|
activeShared = shared;
|
|
99
107
|
repoRoot = shared.repoRoot;
|
|
100
108
|
const context = buildSyncContext({ taskDir, config, artifactFile });
|
|
@@ -136,7 +144,7 @@ export function check({ taskDir, config, artifactFile }, shared) {
|
|
|
136
144
|
return passResult(CHECK_TYPE, `GitHub sync checks passed for Issue #${context.issueNumber}`);
|
|
137
145
|
}
|
|
138
146
|
|
|
139
|
-
function buildSyncContext({ taskDir, config, artifactFile }) {
|
|
147
|
+
function buildSyncContext({ taskDir, config, artifactFile }: any): any {
|
|
140
148
|
const task = loadTask(taskDir);
|
|
141
149
|
if (!task.ok) {
|
|
142
150
|
return { earlyReturn: failResult(CHECK_TYPE, task.message) };
|
|
@@ -155,12 +163,20 @@ function buildSyncContext({ taskDir, config, artifactFile }) {
|
|
|
155
163
|
return { earlyReturn: passResult(CHECK_TYPE, "Skipped: platform-sync not required for this task") };
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
const
|
|
159
|
-
if (
|
|
160
|
-
return { earlyReturn:
|
|
166
|
+
const platformContext = resolvePlatformContext({ cwd: repoRoot, client: githubClient });
|
|
167
|
+
if (platformContext.status === "failed") {
|
|
168
|
+
return { earlyReturn: failResult(CHECK_TYPE, platformContext.error?.message || "Platform context failed", "check_failed") };
|
|
169
|
+
}
|
|
170
|
+
if (platformContext.status === "blocked") {
|
|
171
|
+
return { earlyReturn: blockedResult(CHECK_TYPE, platformContext.error?.message || "Platform context blocked", "network_error") };
|
|
172
|
+
}
|
|
173
|
+
if (!platformContext.platform.repository) {
|
|
174
|
+
if (platformContext.error?.code === "REMOTE_MISSING" || platformContext.error?.code === "REMOTE_INVALID") {
|
|
175
|
+
return { earlyReturn: blockedResult(CHECK_TYPE, platformContext.error.message, "network_error") };
|
|
176
|
+
}
|
|
177
|
+
return { earlyReturn: passResult(CHECK_TYPE, `Skipped: ${platformContext.error?.message || "platform unavailable"}`) };
|
|
161
178
|
}
|
|
162
|
-
const
|
|
163
|
-
const repoOwnerType = detectRepoOwnerType(upstreamRepo.value, taskDir);
|
|
179
|
+
const repoOwnerType = detectRepoOwnerType(platformContext.platform.repository, taskDir);
|
|
164
180
|
const expectedValues = resolveExpectedValues(config);
|
|
165
181
|
if (!expectedValues.ok) {
|
|
166
182
|
return { earlyReturn: failResult(CHECK_TYPE, expectedValues.message, "check_failed") };
|
|
@@ -182,17 +198,17 @@ function buildSyncContext({ taskDir, config, artifactFile }) {
|
|
|
182
198
|
artifactPath,
|
|
183
199
|
issueNumber,
|
|
184
200
|
prNumber,
|
|
185
|
-
upstreamRepo:
|
|
201
|
+
upstreamRepo: platformContext.platform.repository,
|
|
186
202
|
repoOwnerType,
|
|
187
|
-
hasTriage:
|
|
188
|
-
hasPush:
|
|
203
|
+
hasTriage: platformContext.capabilities.triage,
|
|
204
|
+
hasPush: platformContext.capabilities.push,
|
|
189
205
|
expectedStatusLabel: expectedValues.statusLabel,
|
|
190
206
|
marker,
|
|
191
207
|
prMarker
|
|
192
208
|
};
|
|
193
209
|
}
|
|
194
210
|
|
|
195
|
-
function resolveExpectedValues(config) {
|
|
211
|
+
function resolveExpectedValues(config: any): any {
|
|
196
212
|
const defaults = getDefaults();
|
|
197
213
|
const statusLabel = resolveDefaultValue({
|
|
198
214
|
collection: defaults.statusLabels,
|
|
@@ -232,7 +248,7 @@ function resolveExpectedValues(config) {
|
|
|
232
248
|
};
|
|
233
249
|
}
|
|
234
250
|
|
|
235
|
-
function resolveDefaultValue({ collection, key, value, configKey }) {
|
|
251
|
+
function resolveDefaultValue({ collection, key, value, configKey }: any): any {
|
|
236
252
|
if (!key) {
|
|
237
253
|
return { ok: true, value: value || null };
|
|
238
254
|
}
|
|
@@ -245,30 +261,28 @@ function resolveDefaultValue({ collection, key, value, configKey }) {
|
|
|
245
261
|
return { ok: true, value: resolvedValue };
|
|
246
262
|
}
|
|
247
263
|
|
|
248
|
-
function fetchRemoteData(context) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
"view",
|
|
252
|
-
String(context.issueNumber),
|
|
253
|
-
"-R",
|
|
264
|
+
function fetchRemoteData(context: any): any {
|
|
265
|
+
const sharedIssue = inspectGitHubIssueMetadata(
|
|
266
|
+
githubClient,
|
|
254
267
|
context.upstreamRepo,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
"api",
|
|
261
|
-
`repos/${context.upstreamRepo}/issues/${context.issueNumber}`
|
|
262
|
-
], context.taskDir));
|
|
263
|
-
if (fallbackIssueResult.ok) {
|
|
264
|
-
issueResult = {
|
|
268
|
+
context.issueNumber,
|
|
269
|
+
context.taskDir
|
|
270
|
+
);
|
|
271
|
+
const issueResult = sharedIssue.ok
|
|
272
|
+
? {
|
|
265
273
|
ok: true,
|
|
266
|
-
value:
|
|
274
|
+
value: {
|
|
275
|
+
state: sharedIssue.value.state.toUpperCase(),
|
|
276
|
+
labels: sharedIssue.value.labels.map((name) => ({ name })),
|
|
277
|
+
body: sharedIssue.value.body,
|
|
278
|
+
milestone: sharedIssue.value.milestone ? { title: sharedIssue.value.milestone } : null
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
: {
|
|
282
|
+
ok: false,
|
|
283
|
+
type: sharedIssue.error.retryable ? "network_error" : "check_failed",
|
|
284
|
+
message: sharedIssue.error.message
|
|
267
285
|
};
|
|
268
|
-
} else {
|
|
269
|
-
issueResult = fallbackIssueResult;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
286
|
if (!issueResult.ok) {
|
|
273
287
|
return {
|
|
274
288
|
earlyReturn: issueResult.type === "check_failed"
|
|
@@ -312,22 +326,22 @@ function fetchRemoteData(context) {
|
|
|
312
326
|
};
|
|
313
327
|
}
|
|
314
328
|
|
|
315
|
-
const prCommentsResult =
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
329
|
+
const prCommentsResult = listRemoteComments(
|
|
330
|
+
githubClient,
|
|
331
|
+
context.upstreamRepo,
|
|
332
|
+
context.prNumber,
|
|
333
|
+
context.taskDir
|
|
334
|
+
);
|
|
321
335
|
|
|
322
336
|
if (!prCommentsResult.ok) {
|
|
323
337
|
return {
|
|
324
|
-
earlyReturn: prCommentsResult.
|
|
325
|
-
?
|
|
326
|
-
:
|
|
338
|
+
earlyReturn: prCommentsResult.error.retryable
|
|
339
|
+
? blockedResult(CHECK_TYPE, prCommentsResult.error.message, "network_error")
|
|
340
|
+
: failResult(CHECK_TYPE, prCommentsResult.error.message, "check_failed")
|
|
327
341
|
};
|
|
328
342
|
}
|
|
329
343
|
|
|
330
|
-
prComments =
|
|
344
|
+
prComments = prCommentsResult.value;
|
|
331
345
|
}
|
|
332
346
|
|
|
333
347
|
let issueType;
|
|
@@ -368,46 +382,37 @@ function fetchRemoteData(context) {
|
|
|
368
382
|
let prLabels = null;
|
|
369
383
|
let prMilestone;
|
|
370
384
|
let prAssignees;
|
|
385
|
+
let prHeadSha;
|
|
371
386
|
if (((context.config.verify_in_labels_match_pr && context.hasTriage)
|
|
372
387
|
|| (context.config.verify_pr_type_label && context.hasTriage)
|
|
373
388
|
|| (context.config.verify_milestone && context.hasTriage)
|
|
374
|
-
|| (context.config.verify_pr_assignee && context.hasPush)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
if (context.config.verify_pr_assignee) {
|
|
383
|
-
prFields.push("assignees");
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const prResult = withRetry(() => ghJson([
|
|
387
|
-
"pr",
|
|
388
|
-
"view",
|
|
389
|
-
String(context.prNumber),
|
|
390
|
-
"--json",
|
|
391
|
-
prFields.join(",")
|
|
392
|
-
], context.taskDir));
|
|
389
|
+
|| (context.config.verify_pr_assignee && context.hasPush)
|
|
390
|
+
|| context.config.verify_pr_comment_last_commit_matches_head) && context.prNumber) {
|
|
391
|
+
const prResult = inspectGitHubPullRequest(
|
|
392
|
+
githubClient,
|
|
393
|
+
context.upstreamRepo,
|
|
394
|
+
context.prNumber,
|
|
395
|
+
context.taskDir
|
|
396
|
+
);
|
|
393
397
|
|
|
394
398
|
if (!prResult.ok) {
|
|
395
399
|
return {
|
|
396
|
-
earlyReturn: prResult.
|
|
397
|
-
?
|
|
398
|
-
:
|
|
400
|
+
earlyReturn: prResult.error.retryable
|
|
401
|
+
? blockedResult(CHECK_TYPE, prResult.error.message, "network_error")
|
|
402
|
+
: failResult(CHECK_TYPE, prResult.error.message, "check_failed")
|
|
399
403
|
};
|
|
400
404
|
}
|
|
401
405
|
|
|
402
406
|
prLabels = (context.config.verify_in_labels_match_pr || context.config.verify_pr_type_label)
|
|
403
|
-
?
|
|
407
|
+
? prResult.value.labels
|
|
404
408
|
: null;
|
|
405
409
|
prMilestone = context.config.verify_milestone
|
|
406
|
-
? prResult.value
|
|
410
|
+
? prResult.value.milestone ? { title: prResult.value.milestone } : null
|
|
407
411
|
: undefined;
|
|
408
412
|
prAssignees = context.config.verify_pr_assignee
|
|
409
|
-
?
|
|
413
|
+
? prResult.value.assignees
|
|
410
414
|
: undefined;
|
|
415
|
+
prHeadSha = prResult.value.head.sha;
|
|
411
416
|
}
|
|
412
417
|
|
|
413
418
|
return {
|
|
@@ -418,27 +423,16 @@ function fetchRemoteData(context) {
|
|
|
418
423
|
issueType,
|
|
419
424
|
issueFields,
|
|
420
425
|
prMilestone,
|
|
421
|
-
prAssignees
|
|
426
|
+
prAssignees,
|
|
427
|
+
prHeadSha
|
|
422
428
|
};
|
|
423
429
|
}
|
|
424
430
|
|
|
425
|
-
function mapTaskTypeToLabel(taskType) {
|
|
426
|
-
|
|
427
|
-
bug: "type: bug",
|
|
428
|
-
bugfix: "type: bug",
|
|
429
|
-
feature: "type: feature",
|
|
430
|
-
enhancement: "type: enhancement",
|
|
431
|
-
refactor: "type: enhancement",
|
|
432
|
-
refactoring: "type: enhancement",
|
|
433
|
-
documentation: "type: documentation",
|
|
434
|
-
"dependency-upgrade": "type: dependency-upgrade",
|
|
435
|
-
task: "type: task"
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
return mapping[taskType] || null;
|
|
431
|
+
function mapTaskTypeToLabel(taskType: any): any {
|
|
432
|
+
return taskTypeLabel(taskType);
|
|
439
433
|
}
|
|
440
434
|
|
|
441
|
-
function shouldFetchComments(config) {
|
|
435
|
+
function shouldFetchComments(config: any): any {
|
|
442
436
|
return Boolean(
|
|
443
437
|
config.expected_comment_marker
|
|
444
438
|
|| config.expected_comment_marker_key
|
|
@@ -450,7 +444,7 @@ function shouldFetchComments(config) {
|
|
|
450
444
|
);
|
|
451
445
|
}
|
|
452
446
|
|
|
453
|
-
function flattenComments(value) {
|
|
447
|
+
function flattenComments(value: any): any {
|
|
454
448
|
if (!Array.isArray(value)) {
|
|
455
449
|
return [];
|
|
456
450
|
}
|
|
@@ -458,7 +452,7 @@ function flattenComments(value) {
|
|
|
458
452
|
return value.flatMap((page) => Array.isArray(page) ? page : []);
|
|
459
453
|
}
|
|
460
454
|
|
|
461
|
-
function checkStatusLabel(context, remoteData) {
|
|
455
|
+
function checkStatusLabel(context: any, remoteData: any): any {
|
|
462
456
|
if (!context.expectedStatusLabel || !context.hasTriage) {
|
|
463
457
|
return null;
|
|
464
458
|
}
|
|
@@ -478,7 +472,7 @@ function checkStatusLabel(context, remoteData) {
|
|
|
478
472
|
);
|
|
479
473
|
}
|
|
480
474
|
|
|
481
|
-
function checkClosedIssueStatusLabels(context, remoteData) {
|
|
475
|
+
function checkClosedIssueStatusLabels(context: any, remoteData: any): any {
|
|
482
476
|
if (!context.config.verify_closed_issue_has_no_status_labels) {
|
|
483
477
|
return null;
|
|
484
478
|
}
|
|
@@ -488,7 +482,7 @@ function checkClosedIssueStatusLabels(context, remoteData) {
|
|
|
488
482
|
}
|
|
489
483
|
|
|
490
484
|
const statusLabels = extractLabelNames(remoteData.issue.labels)
|
|
491
|
-
.filter((label) => label.startsWith("status:"));
|
|
485
|
+
.filter((label: any) => label.startsWith("status:"));
|
|
492
486
|
if (statusLabels.length === 0) {
|
|
493
487
|
return null;
|
|
494
488
|
}
|
|
@@ -499,7 +493,7 @@ function checkClosedIssueStatusLabels(context, remoteData) {
|
|
|
499
493
|
);
|
|
500
494
|
}
|
|
501
495
|
|
|
502
|
-
function checkCommentMarker(context, remoteData) {
|
|
496
|
+
function checkCommentMarker(context: any, remoteData: any): any {
|
|
503
497
|
if (!context.marker) {
|
|
504
498
|
return null;
|
|
505
499
|
}
|
|
@@ -515,7 +509,7 @@ function checkCommentMarker(context, remoteData) {
|
|
|
515
509
|
);
|
|
516
510
|
}
|
|
517
511
|
|
|
518
|
-
function checkPrCommentMarker(context, remoteData) {
|
|
512
|
+
function checkPrCommentMarker(context: any, remoteData: any): any {
|
|
519
513
|
if (!context.prMarker) {
|
|
520
514
|
return null;
|
|
521
515
|
}
|
|
@@ -531,7 +525,7 @@ function checkPrCommentMarker(context, remoteData) {
|
|
|
531
525
|
);
|
|
532
526
|
}
|
|
533
527
|
|
|
534
|
-
function checkPrCommentLastCommit(context, remoteData) {
|
|
528
|
+
function checkPrCommentLastCommit(context: any, remoteData: any): any {
|
|
535
529
|
if (!context.config.verify_pr_comment_last_commit_matches_head) {
|
|
536
530
|
return null;
|
|
537
531
|
}
|
|
@@ -559,15 +553,9 @@ function checkPrCommentLastCommit(context, remoteData) {
|
|
|
559
553
|
);
|
|
560
554
|
}
|
|
561
555
|
|
|
562
|
-
const
|
|
563
|
-
if (!
|
|
564
|
-
|
|
565
|
-
? failResult(CHECK_TYPE, headResult.message, headResult.type)
|
|
566
|
-
: blockedResult(CHECK_TYPE, headResult.message, headResult.type);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
const expectedHead = String(headResult.value || "").trim();
|
|
570
|
-
const actualHead = match[1].trim();
|
|
556
|
+
const expectedHead = String(remoteData.prHeadSha || "").trim();
|
|
557
|
+
if (!expectedHead) return blockedResult(CHECK_TYPE, "Unable to resolve the PR head SHA", "network_error");
|
|
558
|
+
const actualHead = match[1]!.trim();
|
|
571
559
|
if (expectedHead === actualHead) {
|
|
572
560
|
return null;
|
|
573
561
|
}
|
|
@@ -578,7 +566,7 @@ function checkPrCommentLastCommit(context, remoteData) {
|
|
|
578
566
|
);
|
|
579
567
|
}
|
|
580
568
|
|
|
581
|
-
function checkPrCommentRequiredPatterns(context, remoteData) {
|
|
569
|
+
function checkPrCommentRequiredPatterns(context: any, remoteData: any): any {
|
|
582
570
|
const patterns = context.config.expected_pr_comment_required_patterns || [];
|
|
583
571
|
if (!Array.isArray(patterns) || patterns.length === 0) {
|
|
584
572
|
return null;
|
|
@@ -613,7 +601,7 @@ function checkPrCommentRequiredPatterns(context, remoteData) {
|
|
|
613
601
|
return null;
|
|
614
602
|
}
|
|
615
603
|
|
|
616
|
-
function checkCommentContent(context, remoteData) {
|
|
604
|
+
function checkCommentContent(context: any, remoteData: any): any {
|
|
617
605
|
if (!context.config.verify_comment_content) {
|
|
618
606
|
return null;
|
|
619
607
|
}
|
|
@@ -648,7 +636,7 @@ function checkCommentContent(context, remoteData) {
|
|
|
648
636
|
);
|
|
649
637
|
}
|
|
650
638
|
|
|
651
|
-
function checkTaskCommentContent(context, remoteData) {
|
|
639
|
+
function checkTaskCommentContent(context: any, remoteData: any): any {
|
|
652
640
|
if (!context.config.verify_task_comment_content) {
|
|
653
641
|
return null;
|
|
654
642
|
}
|
|
@@ -675,7 +663,7 @@ function checkTaskCommentContent(context, remoteData) {
|
|
|
675
663
|
);
|
|
676
664
|
}
|
|
677
665
|
|
|
678
|
-
function checkPrTypeLabel(context, remoteData) {
|
|
666
|
+
function checkPrTypeLabel(context: any, remoteData: any): any {
|
|
679
667
|
if (!context.config.verify_pr_type_label || !context.hasTriage || !context.prNumber || !remoteData.prLabels) {
|
|
680
668
|
return null;
|
|
681
669
|
}
|
|
@@ -695,16 +683,16 @@ function checkPrTypeLabel(context, remoteData) {
|
|
|
695
683
|
);
|
|
696
684
|
}
|
|
697
685
|
|
|
698
|
-
function checkInLabelsMatchPr(context, remoteData) {
|
|
686
|
+
function checkInLabelsMatchPr(context: any, remoteData: any): any {
|
|
699
687
|
if (!context.config.verify_in_labels_match_pr || !context.hasTriage || !context.prNumber || !remoteData.prLabels) {
|
|
700
688
|
return null;
|
|
701
689
|
}
|
|
702
690
|
|
|
703
691
|
const issueInLabels = extractLabelNames(remoteData.issue.labels)
|
|
704
|
-
.filter((label) => label.startsWith("in:"))
|
|
692
|
+
.filter((label: any) => label.startsWith("in:"))
|
|
705
693
|
.sort();
|
|
706
694
|
const prInLabels = remoteData.prLabels
|
|
707
|
-
.filter((label) => label.startsWith("in:"))
|
|
695
|
+
.filter((label: any) => label.startsWith("in:"))
|
|
708
696
|
.sort();
|
|
709
697
|
|
|
710
698
|
if (arraysEqual(issueInLabels, prInLabels)) {
|
|
@@ -717,7 +705,7 @@ function checkInLabelsMatchPr(context, remoteData) {
|
|
|
717
705
|
);
|
|
718
706
|
}
|
|
719
707
|
|
|
720
|
-
function checkInLabelsComputed(context, remoteData) {
|
|
708
|
+
function checkInLabelsComputed(context: any, remoteData: any): any {
|
|
721
709
|
if (!context.config.verify_in_labels_computed || !context.hasTriage) {
|
|
722
710
|
return null;
|
|
723
711
|
}
|
|
@@ -734,7 +722,7 @@ function checkInLabelsComputed(context, remoteData) {
|
|
|
734
722
|
}
|
|
735
723
|
|
|
736
724
|
const actualInLabels = extractLabelNames(remoteData.issue.labels)
|
|
737
|
-
.filter((label) => label.startsWith("in:"))
|
|
725
|
+
.filter((label: any) => label.startsWith("in:"))
|
|
738
726
|
.sort();
|
|
739
727
|
|
|
740
728
|
if (arraysEqual(expectedInLabels.labels, actualInLabels)) {
|
|
@@ -748,7 +736,7 @@ function checkInLabelsComputed(context, remoteData) {
|
|
|
748
736
|
);
|
|
749
737
|
}
|
|
750
738
|
|
|
751
|
-
function checkSyncedRequirements(context, remoteData) {
|
|
739
|
+
function checkSyncedRequirements(context: any, remoteData: any): any {
|
|
752
740
|
if (!context.config.sync_checked_requirements || !context.hasTriage) {
|
|
753
741
|
return null;
|
|
754
742
|
}
|
|
@@ -759,8 +747,22 @@ function checkSyncedRequirements(context, remoteData) {
|
|
|
759
747
|
}
|
|
760
748
|
|
|
761
749
|
const issueBody = remoteData.issue.body || "";
|
|
750
|
+
const resolution = resolveRequirementSection(
|
|
751
|
+
issueBody,
|
|
752
|
+
requirementSectionAnchors(repoRoot, context.task.metadata.type || "task")
|
|
753
|
+
);
|
|
754
|
+
if (resolution.status === "missing") {
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
if (resolution.status === "ambiguous") {
|
|
758
|
+
return failResult(CHECK_TYPE,
|
|
759
|
+
`Issue #${context.issueNumber} requirements section is ambiguous`,
|
|
760
|
+
"check_failed"
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
const requirementBody = issueBody.slice(resolution.bodyStart, resolution.bodyEnd);
|
|
762
764
|
const missingRequirements = checkedRequirements.filter(
|
|
763
|
-
(item) => !
|
|
765
|
+
(item: any) => !hasCheckedRequirement(requirementBody, item)
|
|
764
766
|
);
|
|
765
767
|
if (missingRequirements.length === 0) {
|
|
766
768
|
return null;
|
|
@@ -772,7 +774,7 @@ function checkSyncedRequirements(context, remoteData) {
|
|
|
772
774
|
);
|
|
773
775
|
}
|
|
774
776
|
|
|
775
|
-
function checkIssueType(context, remoteData) {
|
|
777
|
+
function checkIssueType(context: any, remoteData: any): any {
|
|
776
778
|
if (!context.config.verify_issue_type || !context.hasPush) {
|
|
777
779
|
return null;
|
|
778
780
|
}
|
|
@@ -803,7 +805,7 @@ function checkIssueType(context, remoteData) {
|
|
|
803
805
|
return null;
|
|
804
806
|
}
|
|
805
807
|
|
|
806
|
-
function checkIssueFields(context, remoteData) {
|
|
808
|
+
function checkIssueFields(context: any, remoteData: any): any {
|
|
807
809
|
if (!context.config.verify_issue_fields || !context.hasPush) {
|
|
808
810
|
return null;
|
|
809
811
|
}
|
|
@@ -842,7 +844,7 @@ function checkIssueFields(context, remoteData) {
|
|
|
842
844
|
return null;
|
|
843
845
|
}
|
|
844
846
|
|
|
845
|
-
function checkPrAssignee(context, remoteData) {
|
|
847
|
+
function checkPrAssignee(context: any, remoteData: any): any {
|
|
846
848
|
if (!context.config.verify_pr_assignee || !context.hasPush || !context.prNumber) {
|
|
847
849
|
return null;
|
|
848
850
|
}
|
|
@@ -857,7 +859,7 @@ function checkPrAssignee(context, remoteData) {
|
|
|
857
859
|
return null;
|
|
858
860
|
}
|
|
859
861
|
|
|
860
|
-
function checkMilestone(context, remoteData) {
|
|
862
|
+
function checkMilestone(context: any, remoteData: any): any {
|
|
861
863
|
if (!context.config.verify_milestone || !context.hasTriage) {
|
|
862
864
|
return null;
|
|
863
865
|
}
|
|
@@ -895,48 +897,48 @@ function checkMilestone(context, remoteData) {
|
|
|
895
897
|
return null;
|
|
896
898
|
}
|
|
897
899
|
|
|
898
|
-
function findCommentByMarker(comments, marker) {
|
|
899
|
-
return (comments || []).find((comment) => typeof comment.body === "string" && comment.body.includes(marker)) || null;
|
|
900
|
+
function findCommentByMarker(comments: any, marker: any): any {
|
|
901
|
+
return (comments || []).find((comment: any) => typeof comment.body === "string" && comment.body.includes(marker)) || null;
|
|
900
902
|
}
|
|
901
903
|
|
|
902
|
-
function isGeneratedMarkerLine(line) {
|
|
904
|
+
function isGeneratedMarkerLine(line: any): any {
|
|
903
905
|
return line.startsWith("<!--") && line.endsWith("-->");
|
|
904
906
|
}
|
|
905
907
|
|
|
906
|
-
function extractCommentBody(commentBody) {
|
|
908
|
+
function extractCommentBody(commentBody: any): any {
|
|
907
909
|
const lines = String(commentBody || "").split(/\r?\n/);
|
|
908
910
|
|
|
909
911
|
let start = 0;
|
|
910
|
-
while (start < lines.length && (lines[start]
|
|
912
|
+
while (start < lines.length && (lines[start]!.trim() === "" || isGeneratedMarkerLine(lines[start]!.trim()))) {
|
|
911
913
|
start += 1;
|
|
912
914
|
}
|
|
913
915
|
|
|
914
|
-
if (start < lines.length && lines[start]
|
|
916
|
+
if (start < lines.length && lines[start]!.startsWith("## ")) {
|
|
915
917
|
start += 1;
|
|
916
918
|
}
|
|
917
919
|
|
|
918
|
-
while (start < lines.length && lines[start]
|
|
920
|
+
while (start < lines.length && lines[start]!.trim() === "") {
|
|
919
921
|
start += 1;
|
|
920
922
|
}
|
|
921
923
|
|
|
922
|
-
if (start < lines.length && /^> \*\*.+\*\* · .+$/.test(lines[start]
|
|
924
|
+
if (start < lines.length && /^> \*\*.+\*\* · .+$/.test(lines[start]!.trim())) {
|
|
923
925
|
start += 1;
|
|
924
926
|
}
|
|
925
927
|
|
|
926
|
-
while (start < lines.length && lines[start]
|
|
928
|
+
while (start < lines.length && lines[start]!.trim() === "") {
|
|
927
929
|
start += 1;
|
|
928
930
|
}
|
|
929
931
|
|
|
930
932
|
let end = lines.length;
|
|
931
933
|
for (let index = lines.length - 1; index >= start; index -= 1) {
|
|
932
|
-
const trimmed = lines[index]
|
|
934
|
+
const trimmed = lines[index]!.trim();
|
|
933
935
|
if (trimmed === "") {
|
|
934
936
|
continue;
|
|
935
937
|
}
|
|
936
938
|
|
|
937
939
|
if (/^\*.*\*$/.test(trimmed)) {
|
|
938
940
|
end = index;
|
|
939
|
-
if (end > start && lines[end - 1]
|
|
941
|
+
if (end > start && lines[end - 1]!.trim() === "---") {
|
|
940
942
|
end -= 1;
|
|
941
943
|
}
|
|
942
944
|
}
|
|
@@ -946,7 +948,7 @@ function extractCommentBody(commentBody) {
|
|
|
946
948
|
return lines.slice(start, end).join("\n");
|
|
947
949
|
}
|
|
948
950
|
|
|
949
|
-
function buildExpectedTaskBody(taskContent) {
|
|
951
|
+
function buildExpectedTaskBody(taskContent: any): any {
|
|
950
952
|
const frontmatterMatch = taskContent.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
951
953
|
if (!frontmatterMatch) {
|
|
952
954
|
return taskContent.trim();
|
|
@@ -966,7 +968,7 @@ function buildExpectedTaskBody(taskContent) {
|
|
|
966
968
|
].join("\n").trim();
|
|
967
969
|
}
|
|
968
970
|
|
|
969
|
-
function buildTaskFrontmatterSummary() {
|
|
971
|
+
function buildTaskFrontmatterSummary(): any {
|
|
970
972
|
const language = loadProjectLanguage();
|
|
971
973
|
if (language === "en" || language === "en-US") {
|
|
972
974
|
return "<details><summary>Metadata (frontmatter)</summary>";
|
|
@@ -975,7 +977,7 @@ function buildTaskFrontmatterSummary() {
|
|
|
975
977
|
return "<details><summary>元数据 (frontmatter)</summary>";
|
|
976
978
|
}
|
|
977
979
|
|
|
978
|
-
function loadProjectLanguage() {
|
|
980
|
+
function loadProjectLanguage(): any {
|
|
979
981
|
const override = process.env.VALIDATE_ARTIFACT_LANGUAGE;
|
|
980
982
|
if (!isBlank(override)) {
|
|
981
983
|
return String(override).trim();
|
|
@@ -994,14 +996,14 @@ function loadProjectLanguage() {
|
|
|
994
996
|
}
|
|
995
997
|
}
|
|
996
998
|
|
|
997
|
-
function buildCommentContentMismatchMessage(fileStem, issueNumber, localContent, commentContent) {
|
|
999
|
+
function buildCommentContentMismatchMessage(fileStem: any, issueNumber: any, localContent: any, commentContent: any): any {
|
|
998
1000
|
const diffIndex = firstDifferenceIndex(localContent, commentContent);
|
|
999
1001
|
const position = indexToLineColumn(localContent, diffIndex);
|
|
1000
1002
|
|
|
1001
1003
|
return `Comment content mismatch for '${fileStem}' on Issue #${issueNumber}: local file has ${localContent.length} chars, comment body has ${commentContent.length} chars (first difference near char ${diffIndex + 1}, line ${position.line}, column ${position.column})`;
|
|
1002
1004
|
}
|
|
1003
1005
|
|
|
1004
|
-
function firstDifferenceIndex(left, right) {
|
|
1006
|
+
function firstDifferenceIndex(left: any, right: any): any {
|
|
1005
1007
|
const limit = Math.max(left.length, right.length);
|
|
1006
1008
|
for (let index = 0; index < limit; index += 1) {
|
|
1007
1009
|
if (left[index] !== right[index]) {
|
|
@@ -1012,7 +1014,7 @@ function firstDifferenceIndex(left, right) {
|
|
|
1012
1014
|
return limit;
|
|
1013
1015
|
}
|
|
1014
1016
|
|
|
1015
|
-
function indexToLineColumn(text, index) {
|
|
1017
|
+
function indexToLineColumn(text: any, index: any): any {
|
|
1016
1018
|
const prefix = text.slice(0, Math.min(index, text.length));
|
|
1017
1019
|
const lines = prefix.split("\n");
|
|
1018
1020
|
return {
|
|
@@ -1021,14 +1023,14 @@ function indexToLineColumn(text, index) {
|
|
|
1021
1023
|
};
|
|
1022
1024
|
}
|
|
1023
1025
|
|
|
1024
|
-
function extractLabelNames(labels) {
|
|
1026
|
+
function extractLabelNames(labels: any): any {
|
|
1025
1027
|
return (labels || [])
|
|
1026
|
-
.map((label) => typeof label === "string" ? label : label?.name)
|
|
1027
|
-
.filter((label) => typeof label === "string" && label.length > 0);
|
|
1028
|
+
.map((label: any) => typeof label === "string" ? label : label?.name)
|
|
1029
|
+
.filter((label: any) => typeof label === "string" && label.length > 0);
|
|
1028
1030
|
}
|
|
1029
1031
|
|
|
1030
|
-
function mapTaskTypeToIssueType(taskType) {
|
|
1031
|
-
const mapping = {
|
|
1032
|
+
function mapTaskTypeToIssueType(taskType: any): any {
|
|
1033
|
+
const mapping: Record<string, string> = {
|
|
1032
1034
|
bug: "Bug",
|
|
1033
1035
|
bugfix: "Bug",
|
|
1034
1036
|
enhancement: "Feature",
|
|
@@ -1047,7 +1049,7 @@ function mapTaskTypeToIssueType(taskType) {
|
|
|
1047
1049
|
|
|
1048
1050
|
const ISSUE_FIELDS_QUERY = `query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){issue(number:$number){issueType{name pinnedFields{__typename ... on IssueFieldSingleSelect{id name} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}} issueFieldValues(first:50){nodes{__typename ... on IssueFieldSingleSelectValue{name optionId field{... on IssueFieldSingleSelect{name}}} ... on IssueFieldDateValue{value field{... on IssueFieldDate{name}}} ... on IssueFieldTextValue{value field{... on IssueFieldText{name}}} ... on IssueFieldNumberValue{value field{... on IssueFieldNumber{name}}}}}}}}`;
|
|
1049
1051
|
|
|
1050
|
-
function normalizeIssueFields(payload) {
|
|
1052
|
+
function normalizeIssueFields(payload: any): any {
|
|
1051
1053
|
const issue = payload?.data?.repository?.issue;
|
|
1052
1054
|
const pinnedFields = Array.isArray(issue?.issueType?.pinnedFields)
|
|
1053
1055
|
? issue.issueType.pinnedFields
|
|
@@ -1057,7 +1059,7 @@ function normalizeIssueFields(payload) {
|
|
|
1057
1059
|
: [];
|
|
1058
1060
|
const pinnedNames = new Set(
|
|
1059
1061
|
pinnedFields
|
|
1060
|
-
.map((field) => typeof field?.name === "string" ? field.name : "")
|
|
1062
|
+
.map((field: any) => typeof field?.name === "string" ? field.name : "")
|
|
1061
1063
|
.filter(Boolean)
|
|
1062
1064
|
);
|
|
1063
1065
|
const normalizedValues = new Map();
|
|
@@ -1084,7 +1086,7 @@ function normalizeIssueFields(payload) {
|
|
|
1084
1086
|
return { pinnedNames, values: normalizedValues };
|
|
1085
1087
|
}
|
|
1086
1088
|
|
|
1087
|
-
function normalizeExpectedIssueField(metadataKey, rawValue) {
|
|
1089
|
+
function normalizeExpectedIssueField(metadataKey: any, rawValue: any): any {
|
|
1088
1090
|
const value = String(rawValue || "").trim();
|
|
1089
1091
|
if (!value) {
|
|
1090
1092
|
return null;
|
|
@@ -1097,30 +1099,30 @@ function normalizeExpectedIssueField(metadataKey, rawValue) {
|
|
|
1097
1099
|
return { kind: "single-select", value: normalizeOptionName(value) };
|
|
1098
1100
|
}
|
|
1099
1101
|
|
|
1100
|
-
function normalizeOptionName(value) {
|
|
1102
|
+
function normalizeOptionName(value: any): any {
|
|
1101
1103
|
const normalized = String(value || "").trim();
|
|
1102
1104
|
return OPTION_LOCALIZATION[normalized] || normalized;
|
|
1103
1105
|
}
|
|
1104
1106
|
|
|
1105
|
-
function normalizeDateValue(value) {
|
|
1107
|
+
function normalizeDateValue(value: any): any {
|
|
1106
1108
|
const normalized = String(value || "").trim();
|
|
1107
1109
|
const match = normalized.match(/^\d{4}-\d{2}-\d{2}/);
|
|
1108
1110
|
return match ? match[0] : normalized;
|
|
1109
1111
|
}
|
|
1110
1112
|
|
|
1111
|
-
function arraysEqual(left, right) {
|
|
1113
|
+
function arraysEqual(left: any, right: any): any {
|
|
1112
1114
|
if (left.length !== right.length) {
|
|
1113
1115
|
return false;
|
|
1114
1116
|
}
|
|
1115
1117
|
|
|
1116
|
-
return left.every((value, index) => value === right[index]);
|
|
1118
|
+
return left.every((value: any, index: any) => value === right[index]);
|
|
1117
1119
|
}
|
|
1118
1120
|
|
|
1119
|
-
function formatLabelList(labels) {
|
|
1121
|
+
function formatLabelList(labels: any): any {
|
|
1120
1122
|
return labels.length > 0 ? labels.join(", ") : "none";
|
|
1121
1123
|
}
|
|
1122
1124
|
|
|
1123
|
-
function computeExpectedInLabels(taskDir) {
|
|
1125
|
+
function computeExpectedInLabels(taskDir: any): any {
|
|
1124
1126
|
const changedFilesResult = gitText(["diff", "main...HEAD", "--name-only"], taskDir);
|
|
1125
1127
|
if (!changedFilesResult.ok) {
|
|
1126
1128
|
return changedFilesResult;
|
|
@@ -1136,12 +1138,12 @@ function computeExpectedInLabels(taskDir) {
|
|
|
1136
1138
|
return mapping;
|
|
1137
1139
|
}
|
|
1138
1140
|
|
|
1139
|
-
if (Object.keys(mapping.value).length > 0) {
|
|
1141
|
+
if (Object.keys(mapping.value ?? {}).length > 0) {
|
|
1140
1142
|
const labels = new Set();
|
|
1141
1143
|
|
|
1142
1144
|
for (const file of changedFiles) {
|
|
1143
|
-
for (const [label, prefixes] of Object.entries(mapping.value)) {
|
|
1144
|
-
if (prefixes.some((prefix) => file.startsWith(prefix))) {
|
|
1145
|
+
for (const [label, prefixes] of Object.entries(mapping.value ?? {}) as Array<[string, string[]]>) {
|
|
1146
|
+
if (prefixes.some((prefix: any) => file.startsWith(prefix))) {
|
|
1145
1147
|
labels.add(`in: ${label}`);
|
|
1146
1148
|
}
|
|
1147
1149
|
}
|
|
@@ -1164,7 +1166,7 @@ function computeExpectedInLabels(taskDir) {
|
|
|
1164
1166
|
|
|
1165
1167
|
const repoInLabels = new Set(
|
|
1166
1168
|
extractLabelNames(repoLabelsResult.value)
|
|
1167
|
-
.filter((label) => label.startsWith("in:"))
|
|
1169
|
+
.filter((label: any) => label.startsWith("in:"))
|
|
1168
1170
|
);
|
|
1169
1171
|
|
|
1170
1172
|
if (repoInLabels.size === 0) {
|
|
@@ -1187,7 +1189,7 @@ function computeExpectedInLabels(taskDir) {
|
|
|
1187
1189
|
return { ok: true, labels: Array.from(labels).sort(), mode: "fallback" };
|
|
1188
1190
|
}
|
|
1189
1191
|
|
|
1190
|
-
function loadInLabelMapping() {
|
|
1192
|
+
function loadInLabelMapping(): any {
|
|
1191
1193
|
const configPath = path.join(repoRoot, ".agents", ".airc.json");
|
|
1192
1194
|
if (!fs.existsSync(configPath)) {
|
|
1193
1195
|
return { ok: true, value: {} };
|
|
@@ -1200,7 +1202,7 @@ function loadInLabelMapping() {
|
|
|
1200
1202
|
return { ok: true, value: {} };
|
|
1201
1203
|
}
|
|
1202
1204
|
|
|
1203
|
-
const normalized = {};
|
|
1205
|
+
const normalized: Record<string, string[]> = {};
|
|
1204
1206
|
for (const [label, prefixes] of Object.entries(mapping)) {
|
|
1205
1207
|
if (!Array.isArray(prefixes)) {
|
|
1206
1208
|
continue;
|
|
@@ -1215,89 +1217,14 @@ function loadInLabelMapping() {
|
|
|
1215
1217
|
}
|
|
1216
1218
|
|
|
1217
1219
|
return { ok: true, value: normalized };
|
|
1218
|
-
} catch (error) {
|
|
1220
|
+
} catch (error: any) {
|
|
1219
1221
|
return { ok: false, type: "check_failed", message: `Unable to parse .agents/.airc.json: ${error.message}` };
|
|
1220
1222
|
}
|
|
1221
1223
|
}
|
|
1222
1224
|
|
|
1223
1225
|
// === GitHub API ===
|
|
1224
1226
|
|
|
1225
|
-
function
|
|
1226
|
-
return {
|
|
1227
|
-
state: String(payload?.state || "").toUpperCase(),
|
|
1228
|
-
labels: Array.isArray(payload?.labels) ? payload.labels : [],
|
|
1229
|
-
body: typeof payload?.body === "string" ? payload.body : "",
|
|
1230
|
-
milestone: payload?.milestone ?? null
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
function resolveUpstreamRepo(taskDir) {
|
|
1235
|
-
const ownerRepo = resolveOwnerRepo(taskDir);
|
|
1236
|
-
if (!ownerRepo.ok) {
|
|
1237
|
-
return ownerRepo;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
const repoResult = withRetry(() => ghJson([
|
|
1241
|
-
"api",
|
|
1242
|
-
`repos/${ownerRepo.value}`
|
|
1243
|
-
], taskDir));
|
|
1244
|
-
|
|
1245
|
-
if (!repoResult.ok) {
|
|
1246
|
-
return repoResult;
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
const repo = repoResult.value && typeof repoResult.value === "object" ? repoResult.value : {};
|
|
1250
|
-
const upstreamRepo = repo.fork ? repo.parent?.full_name : repo.full_name;
|
|
1251
|
-
if (isBlank(upstreamRepo)) {
|
|
1252
|
-
return { ok: false, message: "Unable to resolve upstream repository" };
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
return { ok: true, value: upstreamRepo };
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
function resolveOwnerRepo(taskDir) {
|
|
1259
|
-
const gitResult = spawn.sync("git", ["remote", "get-url", "origin"], {
|
|
1260
|
-
cwd: taskDir,
|
|
1261
|
-
encoding: "utf8",
|
|
1262
|
-
env: process.env
|
|
1263
|
-
});
|
|
1264
|
-
|
|
1265
|
-
if (gitResult.status !== 0) {
|
|
1266
|
-
return { ok: false, message: `Unable to resolve git remote: ${gitResult.stderr.trim() || gitResult.stdout.trim()}` };
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
const remote = gitResult.stdout.trim();
|
|
1270
|
-
const sshMatch = remote.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
1271
|
-
if (!sshMatch) {
|
|
1272
|
-
return { ok: false, message: `Unable to parse owner/repo from remote '${remote}'` };
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
return { ok: true, value: sshMatch[1] };
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
function detectPermissions(upstreamRepo, taskDir) {
|
|
1279
|
-
const permissionsResult = withRetry(() => ghJson([
|
|
1280
|
-
"api",
|
|
1281
|
-
`repos/${upstreamRepo}`,
|
|
1282
|
-
"--jq",
|
|
1283
|
-
".permissions"
|
|
1284
|
-
], taskDir));
|
|
1285
|
-
|
|
1286
|
-
if (!permissionsResult.ok) {
|
|
1287
|
-
return { hasTriage: false, hasPush: false };
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
const permissions = permissionsResult.value && typeof permissionsResult.value === "object"
|
|
1291
|
-
? permissionsResult.value
|
|
1292
|
-
: {};
|
|
1293
|
-
|
|
1294
|
-
return {
|
|
1295
|
-
hasTriage: permissions.triage === true,
|
|
1296
|
-
hasPush: permissions.push === true
|
|
1297
|
-
};
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
function detectRepoOwnerType(upstreamRepo, taskDir) {
|
|
1227
|
+
function detectRepoOwnerType(upstreamRepo: any, taskDir: any): any {
|
|
1301
1228
|
const ownerTypeResult = withRetry(() => ghText([
|
|
1302
1229
|
"api",
|
|
1303
1230
|
`repos/${upstreamRepo}`,
|
|
@@ -1312,88 +1239,43 @@ function detectRepoOwnerType(upstreamRepo, taskDir) {
|
|
|
1312
1239
|
return ownerTypeResult.value || "unknown";
|
|
1313
1240
|
}
|
|
1314
1241
|
|
|
1315
|
-
function ghJson(args, cwd) {
|
|
1316
|
-
|
|
1317
|
-
if (!result.ok) {
|
|
1318
|
-
return result;
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
try {
|
|
1322
|
-
return { ok: true, value: JSON.parse(result.value || "null") };
|
|
1323
|
-
} catch (error) {
|
|
1324
|
-
return { ok: false, type: "network_error", message: `Invalid JSON from gh: ${error.message}` };
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
function ghText(args, cwd) {
|
|
1329
|
-
const result = ghCommand(args, cwd);
|
|
1330
|
-
if (!result.ok) {
|
|
1331
|
-
return result;
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
return { ok: true, value: String(result.value || "").trim() };
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
function ghCommand(args, cwd) {
|
|
1338
|
-
const gh = resolveGhCommand();
|
|
1339
|
-
const result = spawn.sync(gh.command, [...gh.preArgs, ...args], {
|
|
1340
|
-
cwd,
|
|
1341
|
-
encoding: "utf8",
|
|
1342
|
-
env: process.env
|
|
1343
|
-
});
|
|
1344
|
-
|
|
1345
|
-
if (result.status !== 0) {
|
|
1346
|
-
const stderr = `${result.stderr || ""}${result.stdout || ""}`.trim();
|
|
1347
|
-
const classified = classifyGhFailure(stderr, args);
|
|
1348
|
-
return { ok: false, type: classified.type, message: classified.message };
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
return { ok: true, value: result.stdout };
|
|
1242
|
+
function ghJson(args: any, cwd: any): any {
|
|
1243
|
+
return mapClientResult(githubClient.json(args, { cwd }));
|
|
1352
1244
|
}
|
|
1353
1245
|
|
|
1354
|
-
function
|
|
1355
|
-
|
|
1356
|
-
const rawPreArgs = process.env.AGENT_INFRA_GH_ARGS_JSON;
|
|
1357
|
-
if (!rawPreArgs) {
|
|
1358
|
-
return { command, preArgs: [] };
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
|
-
try {
|
|
1362
|
-
const preArgs = JSON.parse(rawPreArgs);
|
|
1363
|
-
if (Array.isArray(preArgs) && preArgs.every((arg) => typeof arg === "string")) {
|
|
1364
|
-
return { command, preArgs };
|
|
1365
|
-
}
|
|
1366
|
-
} catch {
|
|
1367
|
-
return { command, preArgs: [] };
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
return { command, preArgs: [] };
|
|
1246
|
+
function ghText(args: any, cwd: any): any {
|
|
1247
|
+
return mapClientResult(githubClient.text(args, { cwd }));
|
|
1371
1248
|
}
|
|
1372
1249
|
|
|
1373
|
-
function ghPaginatedJson(args, cwd) {
|
|
1250
|
+
function ghPaginatedJson(args: any, cwd: any): any {
|
|
1374
1251
|
return ghJson(args, cwd);
|
|
1375
1252
|
}
|
|
1376
1253
|
|
|
1377
|
-
function
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1254
|
+
function mapClientResult(result: any): any {
|
|
1255
|
+
if (result.ok) return result;
|
|
1256
|
+
const checkFailed = ["RESOURCE_NOT_FOUND", "PERMISSION_DENIED", "PLATFORM_REQUEST_INVALID"].includes(result.error.code);
|
|
1257
|
+
return {
|
|
1258
|
+
ok: false,
|
|
1259
|
+
type: checkFailed ? "check_failed" : "network_error",
|
|
1260
|
+
message: result.error.message
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1383
1263
|
|
|
1384
|
-
|
|
1385
|
-
|
|
1264
|
+
function gitText(args: any, cwd: any): any {
|
|
1265
|
+
try {
|
|
1266
|
+
const value = execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1267
|
+
return { ok: true, value: String(value || "").trim() };
|
|
1268
|
+
} catch (error: any) {
|
|
1269
|
+
const stderr = `${error?.stderr || ""}${error?.stdout || ""}`.trim();
|
|
1386
1270
|
return {
|
|
1387
1271
|
ok: false,
|
|
1388
1272
|
type: "check_failed",
|
|
1389
1273
|
message: stderr || `git ${args.join(" ")} failed`
|
|
1390
1274
|
};
|
|
1391
1275
|
}
|
|
1392
|
-
|
|
1393
|
-
return { ok: true, value: String(result.stdout || "").trim() };
|
|
1394
1276
|
}
|
|
1395
1277
|
|
|
1396
|
-
function resolvePrHeadSha(context) {
|
|
1278
|
+
function resolvePrHeadSha(context: any): any {
|
|
1397
1279
|
const fallback = () => withRetry(() => gitText(["rev-parse", "HEAD"], context.taskDir));
|
|
1398
1280
|
const branch = String(context.task?.metadata?.branch || "").trim();
|
|
1399
1281
|
if (!branch) {
|
|
@@ -1418,7 +1300,7 @@ function resolvePrHeadSha(context) {
|
|
|
1418
1300
|
return headInWorktree;
|
|
1419
1301
|
}
|
|
1420
1302
|
|
|
1421
|
-
function findWorktreeForBranch(porcelainOutput, branch) {
|
|
1303
|
+
function findWorktreeForBranch(porcelainOutput: any, branch: any): any {
|
|
1422
1304
|
let currentWorktree = "";
|
|
1423
1305
|
for (const rawLine of String(porcelainOutput || "").split("\n")) {
|
|
1424
1306
|
const line = rawLine.trimEnd();
|
|
@@ -1438,62 +1320,11 @@ function findWorktreeForBranch(porcelainOutput, branch) {
|
|
|
1438
1320
|
return null;
|
|
1439
1321
|
}
|
|
1440
1322
|
|
|
1441
|
-
function withRetry(operation) {
|
|
1442
|
-
|
|
1443
|
-
let lastFailure = null;
|
|
1444
|
-
|
|
1445
|
-
for (let attempt = 0; attempt <= delays.length; attempt += 1) {
|
|
1446
|
-
const result = operation();
|
|
1447
|
-
if (result.ok) {
|
|
1448
|
-
return result;
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
lastFailure = result;
|
|
1452
|
-
if (result.type === "check_failed") {
|
|
1453
|
-
return result;
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
if (attempt < delays.length) {
|
|
1457
|
-
sleep(delays[attempt]);
|
|
1458
|
-
}
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
return lastFailure || { ok: false, type: "network_error", message: "Unknown GitHub sync failure" };
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
function classifyGhFailure(stderr, args) {
|
|
1465
|
-
const message = stderr || `gh ${args.join(" ")} failed`;
|
|
1466
|
-
|
|
1467
|
-
if (/not found|could not resolve to an issue|http 404/i.test(message)) {
|
|
1468
|
-
return { type: "check_failed", message };
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
return { type: "network_error", message };
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
function getRetryDelays() {
|
|
1475
|
-
const override = process.env.VALIDATE_ARTIFACT_RETRY_DELAYS_MS;
|
|
1476
|
-
if (!override) {
|
|
1477
|
-
return DEFAULT_RETRY_DELAYS_MS;
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
const parsed = override
|
|
1481
|
-
.split(",")
|
|
1482
|
-
.map((value) => Number(value.trim()))
|
|
1483
|
-
.filter((value) => Number.isFinite(value) && value >= 0);
|
|
1484
|
-
|
|
1485
|
-
return parsed.length > 0 ? parsed : DEFAULT_RETRY_DELAYS_MS;
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
function sleep(delayMs) {
|
|
1489
|
-
if (delayMs <= 0) {
|
|
1490
|
-
return;
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delayMs);
|
|
1323
|
+
function withRetry(operation: any): any {
|
|
1324
|
+
return operation();
|
|
1494
1325
|
}
|
|
1495
1326
|
|
|
1496
|
-
function interpolate(template, taskDir, artifactFile) {
|
|
1327
|
+
function interpolate(template: any, taskDir: any, artifactFile: any): any {
|
|
1497
1328
|
const artifactStem = artifactFile ? path.basename(artifactFile, path.extname(artifactFile)) : "";
|
|
1498
1329
|
return template
|
|
1499
1330
|
.replace(/\{task-id\}/g, path.basename(taskDir))
|