@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
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export {
|
|
2
|
+
extractReviewBaseline,
|
|
3
|
+
extractReviewDiffFingerprint,
|
|
4
|
+
extractReviewedSnapshotTree,
|
|
5
|
+
findAuthoritativeReviewCodeArtifact,
|
|
6
|
+
parseReviewVerdict,
|
|
7
|
+
resolvePostReviewGlobs
|
|
8
|
+
} from './review-fingerprint.ts';
|
|
9
|
+
export { parseLedger, summarizeLedgerStage, validateLedgerRows } from './ledger.ts';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type VerificationStatus = 'pass' | 'fail' | 'blocked';
|
|
2
|
+
type VerificationCheckResult = {
|
|
3
|
+
type: string;
|
|
4
|
+
status: VerificationStatus;
|
|
5
|
+
message: string;
|
|
6
|
+
fail_type?: string;
|
|
7
|
+
warnings?: string[];
|
|
8
|
+
};
|
|
9
|
+
type VerificationContext = {
|
|
10
|
+
skillName: string;
|
|
11
|
+
taskDir: string;
|
|
12
|
+
artifactFile?: string;
|
|
13
|
+
config: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
type VerificationEngineRequest = {
|
|
16
|
+
mode: 'gate' | 'checks';
|
|
17
|
+
skillName: string;
|
|
18
|
+
taskDir: string;
|
|
19
|
+
artifactFile?: string;
|
|
20
|
+
checks: readonly string[];
|
|
21
|
+
repositoryRoot?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type {
|
|
25
|
+
VerificationCheckResult,
|
|
26
|
+
VerificationContext,
|
|
27
|
+
VerificationEngineRequest,
|
|
28
|
+
VerificationStatus
|
|
29
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
// Verification runs in-process; configuration, review parsing and platform
|
|
3
|
+
// checks are provided by typed domain modules without a stdout protocol.
|
|
4
|
+
import { verifyInProcess } from './verification-engine.ts';
|
|
5
|
+
|
|
6
|
+
import { parseArtifactName } from './artifact-lifecycle.ts';
|
|
7
|
+
import type { ArtifactFamily } from './artifact-lifecycle.ts';
|
|
8
|
+
import { resolveTaskRef } from './resolve-ref.ts';
|
|
9
|
+
import type { TaskWorkspaceState } from './resolve-ref.ts';
|
|
10
|
+
|
|
11
|
+
type VerificationEvent =
|
|
12
|
+
| 'analyze.awaiting-input' | 'analyze.completed'
|
|
13
|
+
| 'review-analysis.completed' | 'plan.completed' | 'review-plan.completed'
|
|
14
|
+
| 'code.completed' | 'review-code.completed' | 'manual-validation.completed'
|
|
15
|
+
| 'block-task.completed' | 'cancel-task.completed' | 'commit.completed'
|
|
16
|
+
| 'complete-task.preflight' | 'complete-task.completed'
|
|
17
|
+
| 'create-pr.completed' | 'create-task.completed'
|
|
18
|
+
| 'import-codescan.completed' | 'import-dependabot.completed'
|
|
19
|
+
| 'import-issue.completed' | 'watch-pr.completed';
|
|
20
|
+
type VerificationSpec = {
|
|
21
|
+
skill: string;
|
|
22
|
+
expectedState: 'active' | 'blocked' | 'completed';
|
|
23
|
+
mode: 'gate' | 'checks';
|
|
24
|
+
checks?: readonly string[];
|
|
25
|
+
artifactFamily?: ArtifactFamily;
|
|
26
|
+
};
|
|
27
|
+
type VerificationInvocation = {
|
|
28
|
+
status: 'pass' | 'fail' | 'blocked';
|
|
29
|
+
exitCode: 0 | 1 | 2;
|
|
30
|
+
payload: Record<string, unknown>;
|
|
31
|
+
};
|
|
32
|
+
type TaskVerificationResult = {
|
|
33
|
+
status: 'pass' | 'fail' | 'blocked' | 'failed';
|
|
34
|
+
changed: false;
|
|
35
|
+
event: VerificationEvent | string;
|
|
36
|
+
requestRef: string;
|
|
37
|
+
taskId: string | null;
|
|
38
|
+
taskDir: string | null;
|
|
39
|
+
taskState: TaskWorkspaceState | null;
|
|
40
|
+
skill: string | null;
|
|
41
|
+
mode: 'gate' | 'checks' | null;
|
|
42
|
+
artifact: string | null;
|
|
43
|
+
invocations: readonly VerificationInvocation[];
|
|
44
|
+
error: { code: string; message: string } | null;
|
|
45
|
+
};
|
|
46
|
+
type VerificationOptions = {
|
|
47
|
+
repoRoot?: string;
|
|
48
|
+
engine?: typeof verifyInProcess;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const gate = (skill: string, expectedState: VerificationSpec['expectedState'], artifactFamily?: ArtifactFamily): VerificationSpec => ({
|
|
52
|
+
skill, expectedState, mode: 'gate', ...(artifactFamily ? { artifactFamily } : {})
|
|
53
|
+
});
|
|
54
|
+
const VERIFICATION_CATALOG: Readonly<Record<VerificationEvent, VerificationSpec>> = {
|
|
55
|
+
'analyze.awaiting-input': { skill: 'analyze-task', expectedState: 'active', mode: 'checks', checks: ['task-meta'] },
|
|
56
|
+
'analyze.completed': gate('analyze-task', 'active', 'analysis'),
|
|
57
|
+
'review-analysis.completed': gate('review-analysis', 'active', 'review-analysis'),
|
|
58
|
+
'plan.completed': gate('plan-task', 'active', 'plan'),
|
|
59
|
+
'review-plan.completed': gate('review-plan', 'active', 'review-plan'),
|
|
60
|
+
'code.completed': gate('code-task', 'active', 'code'),
|
|
61
|
+
'review-code.completed': gate('review-code', 'active', 'review-code'),
|
|
62
|
+
'manual-validation.completed': gate('complete-manual-validation', 'active', 'manual-validation'),
|
|
63
|
+
'block-task.completed': gate('block-task', 'blocked'),
|
|
64
|
+
'cancel-task.completed': gate('cancel-task', 'completed'),
|
|
65
|
+
'commit.completed': gate('commit', 'active'),
|
|
66
|
+
'complete-task.preflight': { skill: 'complete-task', expectedState: 'active', mode: 'checks', checks: ['review-ledger', 'post-review-commit', 'required-checks', 'platform-sync-preflight'] },
|
|
67
|
+
'complete-task.completed': gate('complete-task', 'completed'),
|
|
68
|
+
'create-pr.completed': gate('create-pr', 'active'),
|
|
69
|
+
'create-task.completed': gate('create-task', 'active'),
|
|
70
|
+
'import-codescan.completed': gate('import-codescan', 'active'),
|
|
71
|
+
'import-dependabot.completed': gate('import-dependabot', 'active'),
|
|
72
|
+
'import-issue.completed': gate('import-issue', 'active'),
|
|
73
|
+
'watch-pr.completed': gate('watch-pr', 'active')
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function failure(request: { taskRef: string; event: string; artifact?: string }, code: string, message: string, extra: Partial<TaskVerificationResult> = {}): TaskVerificationResult {
|
|
77
|
+
return {
|
|
78
|
+
status: 'failed', changed: false, event: request.event, requestRef: request.taskRef,
|
|
79
|
+
taskId: null, taskDir: null, taskState: null, skill: null, mode: null,
|
|
80
|
+
artifact: request.artifact ?? null, invocations: [], error: { code, message }, ...extra
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function verifyTaskEvent(request: { taskRef: string; event: string; artifact?: string }, options: VerificationOptions = {}): TaskVerificationResult {
|
|
85
|
+
const spec = VERIFICATION_CATALOG[request.event as VerificationEvent];
|
|
86
|
+
if (!spec) return failure(request, 'VERIFY_EVENT_UNKNOWN', `unknown verification event '${request.event}'`);
|
|
87
|
+
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
88
|
+
if (!resolved.ok) return failure(request, resolved.code, resolved.message, { taskId: resolved.taskId, skill: spec.skill, mode: spec.mode });
|
|
89
|
+
const identity = { taskId: resolved.taskId, taskDir: resolved.taskDir, taskState: resolved.state, skill: spec.skill, mode: spec.mode } as const;
|
|
90
|
+
if (resolved.state !== spec.expectedState) {
|
|
91
|
+
return failure(request, 'VERIFY_TASK_STATE_MISMATCH', `event '${request.event}' requires workspace '${spec.expectedState}', received '${resolved.state}'`, identity);
|
|
92
|
+
}
|
|
93
|
+
if (spec.artifactFamily) {
|
|
94
|
+
if (!request.artifact) return failure(request, 'VERIFY_ARTIFACT_REQUIRED', `event '${request.event}' requires an artifact`, identity);
|
|
95
|
+
const parsed = parseArtifactName(request.artifact);
|
|
96
|
+
if (path.basename(request.artifact) !== request.artifact || !parsed || parsed.family !== spec.artifactFamily) {
|
|
97
|
+
return failure(request, 'VERIFY_ARTIFACT_INVALID', `artifact '${request.artifact}' is not a canonical ${spec.artifactFamily} artifact`, identity);
|
|
98
|
+
}
|
|
99
|
+
} else if (request.artifact) {
|
|
100
|
+
return failure(request, 'VERIFY_ARTIFACT_UNEXPECTED', `event '${request.event}' does not accept an artifact`, identity);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const invocations: VerificationInvocation[] = [];
|
|
104
|
+
const engine = options.engine ?? verifyInProcess;
|
|
105
|
+
if (spec.mode === 'gate') {
|
|
106
|
+
const payload = engine({ mode: 'gate', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [], repositoryRoot: resolved.repoRoot }) as Record<string, unknown>;
|
|
107
|
+
const status = payload.gate as 'pass' | 'fail' | 'blocked';
|
|
108
|
+
invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
|
|
109
|
+
} else {
|
|
110
|
+
for (const check of spec.checks ?? []) {
|
|
111
|
+
const payload = engine({ mode: 'checks', skillName: spec.skill, taskDir: resolved.taskDir, artifactFile: request.artifact, checks: [check], repositoryRoot: resolved.repoRoot }) as Record<string, unknown>;
|
|
112
|
+
const status = payload.status as 'pass' | 'fail' | 'blocked';
|
|
113
|
+
invocations.push({ status, exitCode: ({ pass: 0, fail: 1, blocked: 2 } as const)[status], payload });
|
|
114
|
+
if (status !== 'pass') break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const status = invocations.some((item) => item.status === 'blocked') ? 'blocked'
|
|
118
|
+
: invocations.some((item) => item.status === 'fail') ? 'fail' : 'pass';
|
|
119
|
+
return {
|
|
120
|
+
status, changed: false, event: request.event, requestRef: request.taskRef,
|
|
121
|
+
...identity, artifact: request.artifact ?? null, invocations, error: null
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function statusLabel(status: unknown): string {
|
|
126
|
+
return status === 'fail' ? 'FAIL' : status === 'blocked' ? 'BLOCKED' : 'pass';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function renderPayload(payload: Record<string, unknown>): string {
|
|
130
|
+
const lines: string[] = [];
|
|
131
|
+
if (Array.isArray(payload.checks)) {
|
|
132
|
+
lines.push(`Verification: ${payload.gate} | Skill: ${payload.skill}`, '');
|
|
133
|
+
for (const check of payload.checks as Array<Record<string, unknown>>) {
|
|
134
|
+
lines.push(` [${statusLabel(check.status)}] ${check.type} - ${check.message}`);
|
|
135
|
+
}
|
|
136
|
+
lines.push('', `Result: ${payload.summary} - ${payload.action}`);
|
|
137
|
+
} else {
|
|
138
|
+
lines.push(`Check: ${payload.status} | Skill: ${payload.skill} | Type: ${payload.type}`, '');
|
|
139
|
+
lines.push(` [${statusLabel(payload.status)}] ${payload.type} - ${payload.message}`);
|
|
140
|
+
const summary = payload.status === 'pass' ? '1 passed, 0 failed'
|
|
141
|
+
: payload.status === 'blocked' ? '0 passed, 0 failed, 1 blocked' : '0 passed, 1 failed';
|
|
142
|
+
const action = payload.status === 'pass' ? 'Requested check passed'
|
|
143
|
+
: payload.status === 'blocked' ? `Resolve blocked ${payload.type} check and re-run check`
|
|
144
|
+
: `Fix ${payload.type} issues and re-run check`;
|
|
145
|
+
lines.push('', `Result: ${summary} - ${action}`);
|
|
146
|
+
}
|
|
147
|
+
return `${lines.join('\n')}\n`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function renderTaskVerification(result: TaskVerificationResult): string {
|
|
151
|
+
if (result.status === 'failed') return `Verification failed: ${result.error?.code ?? 'VERIFY_FAILED'} - ${result.error?.message ?? 'unknown error'}\n`;
|
|
152
|
+
return result.invocations.map((invocation) => renderPayload(invocation.payload)).join('');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { VERIFICATION_CATALOG, renderTaskVerification, verifyTaskEvent };
|
|
156
|
+
export type { TaskVerificationResult, VerificationEvent, VerificationInvocation, VerificationOptions, VerificationSpec };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import { resolveTaskRef } from './resolve-ref.ts';
|
|
4
|
+
import {
|
|
5
|
+
WORKFLOW_WARNING_COLUMNS,
|
|
6
|
+
WORKFLOW_WARNING_HEADINGS,
|
|
7
|
+
WORKFLOW_WARNING_SEVERITIES,
|
|
8
|
+
WORKFLOW_WARNING_STATUSES,
|
|
9
|
+
parseWorkflowWarnings
|
|
10
|
+
} from './workflow-warnings.ts';
|
|
11
|
+
import type { WorkflowWarning } from './workflow-warnings.ts';
|
|
12
|
+
import { captureTaskWriteMetadata, writeTask } from './write.ts';
|
|
13
|
+
import type { TaskMutation, TaskOperationSummary, TaskWriteOptions } from './write.ts';
|
|
14
|
+
|
|
15
|
+
type WarningSeverity = 'IMPORTANT' | 'ACTION_REQUIRED';
|
|
16
|
+
type WarningStatus = 'open' | 'resolved' | 'ignored';
|
|
17
|
+
type WorkflowWarningIntent =
|
|
18
|
+
| { kind: 'add'; taskRef: string; step: string; severity: WarningSeverity; code: string; target: string; message: string; action: string; dryRun?: boolean }
|
|
19
|
+
| { kind: 'set-status'; taskRef: string; id: string; status: 'resolved' | 'ignored'; resolution: string; dryRun?: boolean }
|
|
20
|
+
| { kind: 'list'; taskRef: string; status?: WarningStatus };
|
|
21
|
+
|
|
22
|
+
type WorkflowWarningIntentResult = {
|
|
23
|
+
status: 'planned' | 'applied' | 'no-op' | 'failed'; changed: boolean;
|
|
24
|
+
intent: WorkflowWarningIntent['kind']; taskId: string | null; entityId: string | null;
|
|
25
|
+
before: WorkflowWarning | null; after: WorkflowWarning | null;
|
|
26
|
+
warnings: readonly WorkflowWarning[]; operations: readonly TaskOperationSummary[];
|
|
27
|
+
error: { code: string; message: string } | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function failed(intent: WorkflowWarningIntent, code: string, message: string, taskId: string | null = null, entityId: string | null = null): WorkflowWarningIntentResult {
|
|
31
|
+
return { status: 'failed', changed: false, intent: intent.kind, taskId, entityId, before: null, after: null, warnings: [], operations: [], error: { code, message } };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function oneLine(value: string): string {
|
|
35
|
+
return value.replace(/\s*\r?\n\s*/g, ' ').trim();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function nextWarningId(rows: readonly WorkflowWarning[]): string {
|
|
39
|
+
let max = 0;
|
|
40
|
+
for (const row of rows) {
|
|
41
|
+
const match = /^WW-(\d+)$/.exec(row.id);
|
|
42
|
+
if (match) max = Math.max(max, Number(match[1]));
|
|
43
|
+
}
|
|
44
|
+
return `WW-${max + 1}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function validateRows(rows: readonly WorkflowWarning[]): { code: string; message: string } | null {
|
|
48
|
+
const ids = new Set<string>();
|
|
49
|
+
for (const row of rows) {
|
|
50
|
+
if (!/^WW-[1-9]\d*$/.test(row.id)) return { code: 'WARNING_ID_INVALID', message: `warning id '${row.id}' is invalid` };
|
|
51
|
+
if (ids.has(row.id)) return { code: 'WARNING_DUPLICATE_ID', message: `duplicate warning id '${row.id}'` };
|
|
52
|
+
ids.add(row.id);
|
|
53
|
+
if (!WORKFLOW_WARNING_SEVERITIES.has(row.severity) || !WORKFLOW_WARNING_STATUSES.has(row.status)) return { code: 'WARNING_DOCUMENT_INVALID', message: `warning '${row.id}' has invalid severity or status` };
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function sectionMutation(content: string): TaskMutation[] {
|
|
59
|
+
if (/^##\s+(工作流告警|Workflow Warnings)\s*$/m.test(content)) return [];
|
|
60
|
+
const english = /^##\s+Activity Log\s*$/m.test(content);
|
|
61
|
+
return [{
|
|
62
|
+
kind: 'section', aliases: WORKFLOW_WARNING_HEADINGS, heading: english ? 'Workflow Warnings' : '工作流告警',
|
|
63
|
+
body: `| ${WORKFLOW_WARNING_COLUMNS.join(' | ')} |\n|----|------|------|----------|------|--------|--------|---------|--------|-------------|------------|`
|
|
64
|
+
}];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function rowMutation(row: WorkflowWarning): TaskMutation {
|
|
68
|
+
return {
|
|
69
|
+
kind: 'table-row', action: 'upsert', sectionAliases: WORKFLOW_WARNING_HEADINGS,
|
|
70
|
+
columns: WORKFLOW_WARNING_COLUMNS, keyColumn: 'id', key: row.id,
|
|
71
|
+
values: {
|
|
72
|
+
time: row.time, step: row.step, severity: row.severity, code: row.code, status: row.status,
|
|
73
|
+
target: row.target, message: row.message, action: row.action,
|
|
74
|
+
resolved_at: row.resolvedAt, resolution: row.resolution
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function applyWorkflowWarningIntent(intent: WorkflowWarningIntent, options: TaskWriteOptions = {}): WorkflowWarningIntentResult {
|
|
80
|
+
const resolved = resolveTaskRef(intent.taskRef, { repoRoot: options.repoRoot });
|
|
81
|
+
if (!resolved.ok) return failed(intent, resolved.code, resolved.message, resolved.taskId);
|
|
82
|
+
if (resolved.state !== 'active') return failed(intent, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected active`, resolved.taskId);
|
|
83
|
+
let content: string;
|
|
84
|
+
let rows: WorkflowWarning[];
|
|
85
|
+
try {
|
|
86
|
+
content = fs.readFileSync(resolved.taskMdPath, 'utf8');
|
|
87
|
+
rows = parseWorkflowWarnings(content);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const code = error && typeof error === 'object' && 'code' in error ? String(error.code) : 'WARNING_DOCUMENT_INVALID';
|
|
90
|
+
return failed(intent, code, error instanceof Error ? error.message : String(error), resolved.taskId);
|
|
91
|
+
}
|
|
92
|
+
const invalid = validateRows(rows);
|
|
93
|
+
if (invalid) return failed(intent, invalid.code, invalid.message, resolved.taskId);
|
|
94
|
+
if (intent.kind === 'list') {
|
|
95
|
+
if (intent.status && !WORKFLOW_WARNING_STATUSES.has(intent.status)) return failed(intent, 'WARNING_PAYLOAD_INVALID', 'warning status is invalid', resolved.taskId);
|
|
96
|
+
const warnings = rows.filter((row) => !intent.status || row.status === intent.status);
|
|
97
|
+
return { status: 'no-op', changed: false, intent: intent.kind, taskId: resolved.taskId, entityId: null, before: null, after: null, warnings, operations: [], error: null };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let metadata;
|
|
101
|
+
try { metadata = (options.metadataProvider ?? captureTaskWriteMetadata)(); }
|
|
102
|
+
catch (error) { return failed(intent, 'METADATA_CAPTURE_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId); }
|
|
103
|
+
let before: WorkflowWarning | null;
|
|
104
|
+
let after: WorkflowWarning;
|
|
105
|
+
if (intent.kind === 'add') {
|
|
106
|
+
const step = oneLine(intent.step); const code = oneLine(intent.code); const target = oneLine(intent.target);
|
|
107
|
+
const message = oneLine(intent.message); const action = oneLine(intent.action);
|
|
108
|
+
if (!step || !code || !target || !message || !action || !WORKFLOW_WARNING_SEVERITIES.has(intent.severity)) {
|
|
109
|
+
return failed(intent, 'WARNING_PAYLOAD_INVALID', 'warning add payload is invalid', resolved.taskId);
|
|
110
|
+
}
|
|
111
|
+
before = rows.find((row) => row.status === 'open' && row.step === step && row.code === code && row.target === target) ?? null;
|
|
112
|
+
after = before
|
|
113
|
+
? { ...before, severity: intent.severity, message, action }
|
|
114
|
+
: { id: nextWarningId(rows), time: metadata.timestamp, step, severity: intent.severity, code, status: 'open', target, message, action, resolvedAt: '', resolution: '' };
|
|
115
|
+
} else {
|
|
116
|
+
if (!/^WW-[1-9]\d*$/.test(intent.id) || !['resolved', 'ignored'].includes(intent.status) || !oneLine(intent.resolution)) {
|
|
117
|
+
return failed(intent, 'WARNING_PAYLOAD_INVALID', 'warning status payload is invalid', resolved.taskId, intent.id);
|
|
118
|
+
}
|
|
119
|
+
before = rows.find((row) => row.id === intent.id) ?? null;
|
|
120
|
+
if (!before) return failed(intent, 'WARNING_NOT_FOUND', `warning '${intent.id}' was not found`, resolved.taskId, intent.id);
|
|
121
|
+
const resolution = oneLine(intent.resolution);
|
|
122
|
+
if (before.status === intent.status && before.resolution === resolution) after = { ...before };
|
|
123
|
+
else if (before.status !== 'open') return failed(intent, 'WARNING_TRANSITION_INVALID', `warning '${intent.id}' cannot transition from ${before.status}`, resolved.taskId, intent.id);
|
|
124
|
+
else after = { ...before, status: intent.status, resolvedAt: metadata.timestamp, resolution };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const writeResult = writeTask({
|
|
128
|
+
taskRef: intent.taskRef, expectedState: 'active', mutations: [...sectionMutation(content), rowMutation(after)], dryRun: intent.dryRun
|
|
129
|
+
}, {
|
|
130
|
+
...options,
|
|
131
|
+
taskLocation: { repoRoot: resolved.repoRoot, taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, state: resolved.state },
|
|
132
|
+
metadataProvider: () => metadata
|
|
133
|
+
});
|
|
134
|
+
if (writeResult.status === 'failed') return failed(intent, writeResult.error.code, writeResult.error.message, writeResult.taskId, after.id);
|
|
135
|
+
return {
|
|
136
|
+
status: writeResult.status, changed: writeResult.changed, intent: intent.kind, taskId: writeResult.taskId,
|
|
137
|
+
entityId: after.id, before, after, warnings: [], operations: writeResult.operations, error: null
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { applyWorkflowWarningIntent };
|
|
142
|
+
export type { WarningSeverity, WarningStatus, WorkflowWarningIntent, WorkflowWarningIntentResult };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseTable } from './sections.ts';
|
|
2
2
|
|
|
3
3
|
const WORKFLOW_WARNING_HEADINGS = ['工作流告警', 'Workflow Warnings'];
|
|
4
4
|
const WORKFLOW_WARNING_STATUSES = new Set(['open', 'resolved', 'ignored']);
|
|
5
5
|
const WORKFLOW_WARNING_SEVERITIES = new Set(['IMPORTANT', 'ACTION_REQUIRED']);
|
|
6
|
+
const WORKFLOW_WARNING_COLUMNS = ['id', 'time', 'step', 'severity', 'code', 'status', 'target', 'message', 'action', 'resolved_at', 'resolution'] as const;
|
|
6
7
|
|
|
7
8
|
type WorkflowWarning = {
|
|
8
9
|
id: string;
|
|
@@ -18,84 +19,14 @@ type WorkflowWarning = {
|
|
|
18
19
|
resolution: string;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
let value = line.trim();
|
|
23
|
-
if (!value.startsWith('|')) return [];
|
|
24
|
-
value = value.replace(/^\|/, '').replace(/\|$/, '');
|
|
25
|
-
|
|
26
|
-
const cells: string[] = [];
|
|
27
|
-
let cell = '';
|
|
28
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
29
|
-
const char = value[index]!;
|
|
30
|
-
if (char === '|' && !isEscapedAt(value, index)) {
|
|
31
|
-
cells.push(unescapeTableCell(cell.trim()));
|
|
32
|
-
cell = '';
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
cell += char;
|
|
36
|
-
}
|
|
37
|
-
cells.push(unescapeTableCell(cell.trim()));
|
|
38
|
-
return cells;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function unescapeTableCell(value: string): string {
|
|
42
|
-
let output = '';
|
|
43
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
44
|
-
const char = value[index]!;
|
|
45
|
-
const next = value[index + 1];
|
|
46
|
-
if (char === '\\' && (next === '\\' || next === '|')) {
|
|
47
|
-
output += next;
|
|
48
|
-
index += 1;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
output += char;
|
|
52
|
-
}
|
|
53
|
-
return output;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isEscapedAt(value: string, index: number): boolean {
|
|
57
|
-
let backslashes = 0;
|
|
58
|
-
for (let cursor = index - 1; cursor >= 0 && value[cursor] === '\\'; cursor -= 1) {
|
|
59
|
-
backslashes += 1;
|
|
60
|
-
}
|
|
61
|
-
return backslashes % 2 === 1;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isSeparatorRow(cells: string[]): boolean {
|
|
65
|
-
return cells.length > 0 && cells.every((cell) => /^:?-{3,}:?$/.test(cell));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Parses well-formed workflow warning rows. Malformed rows are intentionally
|
|
70
|
-
* ignored here; validate-artifact is responsible for reporting structure errors.
|
|
71
|
-
*/
|
|
22
|
+
/** Parses workflow warning rows and fails closed on malformed table structure. */
|
|
72
23
|
function parseWorkflowWarnings(content: string): WorkflowWarning[] {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (cells.length === 0) continue;
|
|
80
|
-
if ((cells[0] ?? '').toLowerCase() === 'id') continue;
|
|
81
|
-
if (isSeparatorRow(cells)) continue;
|
|
82
|
-
if (cells.length < 11) continue;
|
|
83
|
-
|
|
84
|
-
rows.push({
|
|
85
|
-
id: cells[0] ?? '',
|
|
86
|
-
time: cells[1] ?? '',
|
|
87
|
-
step: cells[2] ?? '',
|
|
88
|
-
severity: cells[3] ?? '',
|
|
89
|
-
code: cells[4] ?? '',
|
|
90
|
-
status: cells[5] ?? '',
|
|
91
|
-
target: cells[6] ?? '',
|
|
92
|
-
message: cells[7] ?? '',
|
|
93
|
-
action: cells[8] ?? '',
|
|
94
|
-
resolvedAt: cells[9] ?? '',
|
|
95
|
-
resolution: cells[10] ?? ''
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return rows;
|
|
24
|
+
const table = parseTable(content, { sectionAliases: WORKFLOW_WARNING_HEADINGS, columns: WORKFLOW_WARNING_COLUMNS });
|
|
25
|
+
return table?.rows.map(({ values }) => ({
|
|
26
|
+
id: values.id!, time: values.time!, step: values.step!, severity: values.severity!,
|
|
27
|
+
code: values.code!, status: values.status!, target: values.target!, message: values.message!,
|
|
28
|
+
action: values.action!, resolvedAt: values.resolved_at!, resolution: values.resolution!
|
|
29
|
+
})) ?? [];
|
|
99
30
|
}
|
|
100
31
|
|
|
101
32
|
function getOpenWorkflowWarnings(content: string): WorkflowWarning[] {
|
|
@@ -114,6 +45,7 @@ export {
|
|
|
114
45
|
WORKFLOW_WARNING_HEADINGS,
|
|
115
46
|
WORKFLOW_WARNING_STATUSES,
|
|
116
47
|
WORKFLOW_WARNING_SEVERITIES,
|
|
48
|
+
WORKFLOW_WARNING_COLUMNS,
|
|
117
49
|
parseWorkflowWarnings,
|
|
118
50
|
getOpenWorkflowWarnings,
|
|
119
51
|
formatWorkflowWarningSummary
|