@fitlab-ai/agent-infra 0.8.5 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/README.zh-CN.md +5 -1
- package/bin/cli.ts +2 -2
- package/dist/bin/cli.js +2 -2
- package/dist/bin/internal-cli.js +103 -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/platform-release-notes.js +53 -0
- package/dist/lib/internal/release-workflow.js +320 -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/github-release-notes.js +96 -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 +619 -0
- package/dist/lib/platform/merged-pr-equivalence.js +54 -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 +340 -0
- package/dist/lib/platform/release-notes.js +143 -0
- package/dist/lib/platform/releases.js +82 -0
- package/dist/lib/platform/types.js +22 -0
- package/dist/lib/platform/verification-required.js +102 -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/build-proxy.js +63 -0
- package/dist/lib/sandbox/capture.js +25 -3
- package/dist/lib/sandbox/commands/create.js +93 -31
- package/dist/lib/sandbox/commands/enter.js +34 -11
- package/dist/lib/sandbox/commands/list-running.js +10 -8
- package/dist/lib/sandbox/commands/rebuild.js +24 -7
- package/dist/lib/sandbox/commands/show.js +2 -2
- package/dist/lib/sandbox/commands/start.js +53 -15
- package/dist/lib/sandbox/image-build.js +2 -1
- 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/runtimes/ai-tools.dockerfile +24 -3
- package/dist/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/dist/lib/sandbox/shell.js +2 -1
- 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 +33 -19
- 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 +21 -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 +55 -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 +923 -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/platform-release-notes.ts +55 -0
- package/lib/internal/release-workflow.ts +288 -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/github-release-notes.ts +132 -0
- package/lib/platform/issue-comments.ts +479 -0
- package/lib/platform/issue-metadata.ts +250 -0
- package/lib/platform/issues.ts +693 -0
- package/lib/platform/merged-pr-equivalence.ts +70 -0
- package/lib/platform/metadata-labels.ts +33 -0
- package/lib/platform/pr-checks.ts +247 -0
- package/lib/platform/pr-summary.ts +90 -0
- package/lib/platform/pull-request-metadata.ts +69 -0
- package/lib/platform/pull-requests.ts +386 -0
- package/lib/platform/release-notes.ts +167 -0
- package/lib/platform/releases.ts +71 -0
- package/lib/platform/types.ts +74 -0
- package/lib/platform/verification-required.ts +109 -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/build-proxy.ts +94 -0
- package/lib/sandbox/capture.ts +29 -3
- package/lib/sandbox/commands/create.ts +120 -36
- package/lib/sandbox/commands/enter.ts +38 -11
- package/lib/sandbox/commands/list-running.ts +10 -8
- package/lib/sandbox/commands/rebuild.ts +29 -7
- package/lib/sandbox/commands/show.ts +2 -2
- package/lib/sandbox/commands/start.ts +50 -16
- package/lib/sandbox/image-build.ts +4 -1
- package/lib/sandbox/index.ts +6 -6
- package/lib/sandbox/mounts.ts +55 -0
- package/lib/sandbox/recovery.ts +828 -0
- package/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
- package/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/lib/sandbox/shell.ts +3 -1
- 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 +26 -21
- 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 +24 -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} +26 -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} +230 -421
- package/lib/task/verification-review.ts +10 -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/release-commands.en.md +2 -2
- package/templates/.agents/rules/release-commands.github.en.md +10 -40
- package/templates/.agents/rules/release-commands.github.zh-CN.md +9 -39
- package/templates/.agents/rules/release-commands.zh-CN.md +2 -2
- package/templates/.agents/rules/review-handshake.en.md +10 -6
- package/templates/.agents/rules/review-handshake.zh-CN.md +10 -6
- 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/rules/testing-discipline.en.md +20 -2
- package/templates/.agents/rules/testing-discipline.zh-CN.md +20 -2
- 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 +26 -56
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +30 -60
- 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 +10 -7
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +10 -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-release-note/SKILL.en.md +17 -38
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/create-task/SKILL.en.md +16 -13
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +16 -13
- package/templates/.agents/skills/create-task/config/verify.json +1 -2
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +29 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +29 -0
- 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 +24 -1
- package/templates/.agents/templates/task.zh-CN.md +24 -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,35 @@
|
|
|
1
|
+
import { parseTaskScope } from '../task/command-options.ts';
|
|
2
|
+
import { resolveTaskContext } from '../task/resolve-ref.ts';
|
|
3
|
+
|
|
4
|
+
const USAGE = `Usage: agent-infra-internal task-context resolve [<task-ref> | --task <task-ref> | -t <task-ref>]\n`;
|
|
5
|
+
|
|
6
|
+
function fail(code: string, message: string, usage = false): void {
|
|
7
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code, message } })}\n`);
|
|
8
|
+
if (usage) process.stderr.write(USAGE);
|
|
9
|
+
process.exitCode = 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function taskContext(args: string[] = []): void {
|
|
13
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
14
|
+
if (args[0] !== 'resolve') { fail('TASK_CONTEXT_PAYLOAD_INVALID', "operation 'resolve' is required", true); return; }
|
|
15
|
+
let scope;
|
|
16
|
+
try {
|
|
17
|
+
scope = parseTaskScope(args.slice(1));
|
|
18
|
+
} catch (error) {
|
|
19
|
+
fail('TASK_CONTEXT_PAYLOAD_INVALID', error instanceof Error ? error.message : String(error), true);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
|
|
23
|
+
fail('TASK_CONTEXT_PAYLOAD_INVALID', 'task ref must be provided once', true);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const taskRef = scope.taskRef ?? scope.positionals[0];
|
|
27
|
+
const result = resolveTaskContext(taskRef);
|
|
28
|
+
if (!result.ok) { fail(result.code, result.message); return; }
|
|
29
|
+
process.stdout.write(`${JSON.stringify({
|
|
30
|
+
status: 'resolved', changed: false, taskId: result.taskId, taskDir: result.taskDir,
|
|
31
|
+
taskMdPath: result.taskMdPath, taskState: result.state, error: null
|
|
32
|
+
})}\n`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { taskContext };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { applyTaskEvent, eventCatalog } from '../task/events.ts';
|
|
2
|
+
import type { TaskEventRequest, Verdict } from '../task/events.ts';
|
|
3
|
+
|
|
4
|
+
const USAGE = `Usage: agent-infra-internal task-event <N | TASK-id> <event> --agent <agent> [event options] [--dry-run]
|
|
5
|
+
|
|
6
|
+
Apply one closed-set task lifecycle event and print a structured JSON result.
|
|
7
|
+
Events: ${eventCatalog.join(', ')}
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
const FLAGS: Record<string, keyof TaskEventRequest> = {
|
|
11
|
+
'--agent': 'agent', '--round': 'round', '--question': 'question', '--artifact': 'artifact',
|
|
12
|
+
'--fix-for': 'fixFor', '--implementation-input': 'implementationInput',
|
|
13
|
+
'--verdict': 'verdict', '--blockers': 'blockers', '--major': 'major',
|
|
14
|
+
'--minor': 'minor', '--manual-validation': 'manualValidation', '--files-modified': 'filesModified',
|
|
15
|
+
'--tests-passed': 'testsPassed', '--summary-result': 'summaryResult'
|
|
16
|
+
};
|
|
17
|
+
const NUMERIC = new Set(['round', 'question', 'blockers', 'major', 'minor', 'manualValidation', 'filesModified', 'testsPassed']);
|
|
18
|
+
|
|
19
|
+
function usageFailure(message: string): void {
|
|
20
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'EVENT_PAYLOAD_INVALID', message } })}\n`);
|
|
21
|
+
process.stderr.write(USAGE);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function taskEvent(args: string[] = []): void {
|
|
26
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
27
|
+
if (args.length < 2) { usageFailure('task ref and event are required'); return; }
|
|
28
|
+
const request: TaskEventRequest = { taskRef: args[0]!, event: args[1]!, agent: '' };
|
|
29
|
+
const seen = new Set<string>();
|
|
30
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
31
|
+
const flag = args[index]!;
|
|
32
|
+
if (flag === '--dry-run') {
|
|
33
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
34
|
+
seen.add(flag); request.dryRun = true; continue;
|
|
35
|
+
}
|
|
36
|
+
const key = FLAGS[flag];
|
|
37
|
+
if (!key) { usageFailure(`unknown option '${flag}'`); return; }
|
|
38
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
39
|
+
const value = args[++index];
|
|
40
|
+
if (value === undefined || value.startsWith('--')) { usageFailure(`option '${flag}' requires a value`); return; }
|
|
41
|
+
seen.add(flag);
|
|
42
|
+
if (NUMERIC.has(key)) (request as Record<string, unknown>)[key] = Number(value);
|
|
43
|
+
else if (key === 'verdict') request.verdict = value as Verdict;
|
|
44
|
+
else (request as Record<string, unknown>)[key] = value;
|
|
45
|
+
}
|
|
46
|
+
const result = applyTaskEvent(request);
|
|
47
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
48
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { taskEvent };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import { applyLedgerIntent } from '../task/ledger-intents.ts';
|
|
4
|
+
import type { LedgerIntent } from '../task/ledger-intents.ts';
|
|
5
|
+
import { isReviewStage, parseLedger, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.ts';
|
|
6
|
+
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
7
|
+
|
|
8
|
+
const USAGE = `Usage: agent-infra-internal task-ledger <task-ref> <intent> [intent flags] [--dry-run]\n\nIntents: finding-upsert, finding-respond, finding-review, decision-next-id, decision-upsert, stage-status\n`;
|
|
9
|
+
const FLAGS: Record<string, string> = {
|
|
10
|
+
'--stage': 'stage', '--review-artifact': 'reviewArtifact', '--ordinal': 'ordinal',
|
|
11
|
+
'--severity': 'severity', '--evidence': 'evidence', '--id': 'id', '--round': 'round',
|
|
12
|
+
'--status': 'status', '--artifact': 'artifact'
|
|
13
|
+
};
|
|
14
|
+
const NUMERIC = new Set(['ordinal', 'round']);
|
|
15
|
+
|
|
16
|
+
function usageFailure(message: string): void {
|
|
17
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'LEDGER_PAYLOAD_INVALID', message } })}\n`);
|
|
18
|
+
process.stderr.write(USAGE);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function taskLedger(args: string[] = []): void {
|
|
23
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
24
|
+
const [taskRef, kind] = args;
|
|
25
|
+
if (!taskRef || !kind) { usageFailure('task ref and intent are required'); return; }
|
|
26
|
+
if (!['finding-upsert', 'finding-respond', 'finding-review', 'decision-next-id', 'decision-upsert', 'stage-status'].includes(kind)) {
|
|
27
|
+
usageFailure(`unknown ledger intent '${kind}'`); return;
|
|
28
|
+
}
|
|
29
|
+
const values: Record<string, unknown> = { kind, taskRef };
|
|
30
|
+
const seen = new Set<string>();
|
|
31
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
32
|
+
const flag = args[index]!;
|
|
33
|
+
if (flag === '--dry-run') {
|
|
34
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
35
|
+
seen.add(flag); values.dryRun = true; continue;
|
|
36
|
+
}
|
|
37
|
+
const key = FLAGS[flag];
|
|
38
|
+
if (!key) { usageFailure(`unknown option '${flag}'`); return; }
|
|
39
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
40
|
+
const value = args[++index];
|
|
41
|
+
if (value === undefined || value.startsWith('--')) { usageFailure(`option '${flag}' requires a value`); return; }
|
|
42
|
+
seen.add(flag); values[key] = NUMERIC.has(key) ? Number(value) : value;
|
|
43
|
+
}
|
|
44
|
+
const required: Record<string, string[]> = {
|
|
45
|
+
'finding-upsert': ['stage', 'reviewArtifact', 'ordinal', 'severity', 'evidence'],
|
|
46
|
+
'finding-respond': ['id', 'round', 'status', 'evidence'],
|
|
47
|
+
'finding-review': ['id', 'status', 'evidence'],
|
|
48
|
+
'decision-next-id': [],
|
|
49
|
+
'decision-upsert': ['id', 'stage', 'artifact'],
|
|
50
|
+
'stage-status': ['stage']
|
|
51
|
+
};
|
|
52
|
+
const allowed = new Set(['kind', 'taskRef', 'dryRun', ...required[kind]!]);
|
|
53
|
+
const unexpected = Object.keys(values).find((key) => !allowed.has(key));
|
|
54
|
+
const missing = required[kind]!.find((key) => values[key] === undefined);
|
|
55
|
+
if (unexpected) { usageFailure(`${kind} does not accept '${unexpected}'`); return; }
|
|
56
|
+
if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
|
|
57
|
+
if (kind === 'stage-status') {
|
|
58
|
+
if (!isReviewStage(String(values.stage))) { usageFailure(`stage-status requires a valid review stage`); return; }
|
|
59
|
+
const resolved = resolveTaskRef(taskRef);
|
|
60
|
+
if (!resolved.ok || resolved.state !== 'active') {
|
|
61
|
+
const message = resolved.ok ? `task ${resolved.taskId} is ${resolved.state}, expected active` : resolved.message;
|
|
62
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: resolved.ok ? 'TASK_STATE_MISMATCH' : resolved.code, message } })}\n`);
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const rows = parseLedger(fs.readFileSync(resolved.taskMdPath, 'utf8'));
|
|
68
|
+
const invalid = validateLedgerRows(rows);
|
|
69
|
+
if (invalid) {
|
|
70
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, taskId: resolved.taskId, error: invalid })}\n`);
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
process.stdout.write(`${JSON.stringify({ status: 'ready', changed: false, taskId: resolved.taskId, stageStatus: summarizeLedgerStage(rows, values.stage as 'analysis' | 'plan' | 'code'), error: null })}\n`);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, taskId: resolved.taskId, error: { code: 'LEDGER_DOCUMENT_INVALID', message: error instanceof Error ? error.message : String(error) } })}\n`);
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const result = applyLedgerIntent(values as LedgerIntent);
|
|
82
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
83
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { taskLedger };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { applyTaskLifecycle, lifecycleIntentCatalog } from '../task/lifecycle.ts';
|
|
2
|
+
import type { TaskLifecycleRequest } from '../task/lifecycle.ts';
|
|
3
|
+
|
|
4
|
+
const USAGE = `Usage: agent-infra-internal task-lifecycle <N | TASK-id> <intent> --agent <agent> [intent flags] [--dry-run]\n\nIntents: ${lifecycleIntentCatalog.join(', ')}\n`;
|
|
5
|
+
const FLAGS: Record<string, string> = {
|
|
6
|
+
'--agent': 'agent', '--reason': 'reason', '--unblock-condition': 'unblockCondition',
|
|
7
|
+
'--note': 'note', '--alert-number': 'alertNumber', '--staging-dir': 'stagingDir',
|
|
8
|
+
'--issue-number': 'issueNumber'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function usageFailure(message: string): void {
|
|
12
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'LIFECYCLE_PAYLOAD_INVALID', message } })}\n`);
|
|
13
|
+
process.stderr.write(USAGE);
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function taskLifecycle(args: string[] = []): void {
|
|
18
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
19
|
+
if (args.length < 2) { usageFailure('task ref and intent are required'); return; }
|
|
20
|
+
const values: Record<string, unknown> = { taskRef: args[0], intent: args[1], agent: '' };
|
|
21
|
+
const seen = new Set<string>();
|
|
22
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
23
|
+
const flag = args[index]!;
|
|
24
|
+
if (flag === '--dry-run') {
|
|
25
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
26
|
+
seen.add(flag); values.dryRun = true; continue;
|
|
27
|
+
}
|
|
28
|
+
const key = FLAGS[flag];
|
|
29
|
+
if (!key) { usageFailure(`unknown option '${flag}'`); return; }
|
|
30
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
31
|
+
const value = args[++index];
|
|
32
|
+
if (value === undefined || value.startsWith('--')) { usageFailure(`option '${flag}' requires a value`); return; }
|
|
33
|
+
seen.add(flag);
|
|
34
|
+
values[key] = key === 'alertNumber' || key === 'issueNumber' ? Number(value) : value;
|
|
35
|
+
}
|
|
36
|
+
const result = applyTaskLifecycle(values as TaskLifecycleRequest);
|
|
37
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
38
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { taskLifecycle };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { detectRepoRoot } from '../task/resolve-ref.ts';
|
|
4
|
+
import { configuredShortIdLength, executeShortIdCommand } from '../task/short-id.ts';
|
|
5
|
+
|
|
6
|
+
const USAGE = `Usage: agent-infra-internal task-short-id <alloc|release|resolve|list> [argument] [--active-dir <path>] [--short-id-length <N>] [--verify]\n`;
|
|
7
|
+
|
|
8
|
+
function failure(message: string): void {
|
|
9
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, output: '', error: { code: 'SHORT_ID_PAYLOAD_INVALID', message } })}\n`);
|
|
10
|
+
process.stderr.write(USAGE);
|
|
11
|
+
process.exitCode = 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function taskShortId(args: string[] = []): void {
|
|
15
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
16
|
+
const operation = args[0];
|
|
17
|
+
if (!operation || !['alloc', 'release', 'resolve', 'list'].includes(operation)) { failure('a valid short-id operation is required'); return; }
|
|
18
|
+
const positional: string[] = [];
|
|
19
|
+
let activeDir: string | null = null;
|
|
20
|
+
let shortIdLength: number | null = null;
|
|
21
|
+
let verify = false;
|
|
22
|
+
const seen = new Set<string>();
|
|
23
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
24
|
+
const value = args[index]!;
|
|
25
|
+
if (value === '--verify') {
|
|
26
|
+
if (seen.has(value)) { failure(`duplicate option '${value}'`); return; }
|
|
27
|
+
seen.add(value); verify = true; continue;
|
|
28
|
+
}
|
|
29
|
+
if (value === '--active-dir' || value === '--short-id-length') {
|
|
30
|
+
if (seen.has(value)) { failure(`duplicate option '${value}'`); return; }
|
|
31
|
+
const optionValue = args[++index];
|
|
32
|
+
if (optionValue === undefined || optionValue.startsWith('--')) { failure(`option '${value}' requires a value`); return; }
|
|
33
|
+
seen.add(value);
|
|
34
|
+
if (value === '--active-dir') activeDir = path.resolve(optionValue);
|
|
35
|
+
else shortIdLength = Number(optionValue);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (value.startsWith('--')) { failure(`unknown option '${value}'`); return; }
|
|
39
|
+
positional.push(value);
|
|
40
|
+
}
|
|
41
|
+
if (positional.length > (operation === 'list' ? 0 : 1)) { failure('too many positional arguments'); return; }
|
|
42
|
+
let repoRoot: string | null = null;
|
|
43
|
+
try { repoRoot = detectRepoRoot(); } catch { /* custom active-dir mode */ }
|
|
44
|
+
const resolvedActiveDir = activeDir ?? (repoRoot ? path.join(repoRoot, '.agents', 'workspace', 'active') : null);
|
|
45
|
+
if (!resolvedActiveDir) { failure('cannot determine active task directory'); return; }
|
|
46
|
+
const width = shortIdLength ?? (repoRoot ? configuredShortIdLength(repoRoot) : 2);
|
|
47
|
+
const result = executeShortIdCommand({
|
|
48
|
+
operation: operation as 'alloc' | 'release' | 'resolve' | 'list',
|
|
49
|
+
argument: positional[0], activeDir: resolvedActiveDir, shortIdLength: width, verify
|
|
50
|
+
});
|
|
51
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
52
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { taskShortId };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { collectTaskSnapshot } from '../task/snapshot.ts';
|
|
2
|
+
|
|
3
|
+
const USAGE = 'Usage: agent-infra-internal task-snapshot <N | TASK-id> [--format json|text]\n';
|
|
4
|
+
|
|
5
|
+
function fail(message: string): void {
|
|
6
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'SNAPSHOT_PAYLOAD_INVALID', message } })}\n`);
|
|
7
|
+
process.stderr.write(USAGE);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function taskSnapshot(args: string[] = []): void {
|
|
12
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
13
|
+
if (!args[0] || args[0].startsWith('--')) { fail('task ref is required'); return; }
|
|
14
|
+
let format: 'json' | 'text' = 'json';
|
|
15
|
+
let seenFormat = false;
|
|
16
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
17
|
+
const flag = args[index];
|
|
18
|
+
if (flag !== '--format') { fail(`unknown option '${flag}'`); return; }
|
|
19
|
+
if (seenFormat) { fail("duplicate option '--format'"); return; }
|
|
20
|
+
const value = args[++index];
|
|
21
|
+
if (value !== 'json' && value !== 'text') { fail("option '--format' requires 'json' or 'text'"); return; }
|
|
22
|
+
seenFormat = true;
|
|
23
|
+
format = value;
|
|
24
|
+
}
|
|
25
|
+
const result = collectTaskSnapshot(args[0]);
|
|
26
|
+
if (format === 'text') {
|
|
27
|
+
process.stdout.write(result.status === 'ready' ? `${result.evidence}\n` : `Snapshot failed: ${result.error?.code} - ${result.error?.message}\n`);
|
|
28
|
+
} else process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
29
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { taskSnapshot };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { renderTaskVerification, verifyTaskEvent } from '../task/verification.ts';
|
|
2
|
+
|
|
3
|
+
const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text]\n';
|
|
4
|
+
|
|
5
|
+
function fail(message: string): void {
|
|
6
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'VERIFY_PAYLOAD_INVALID', message } })}\n`);
|
|
7
|
+
process.stderr.write(USAGE);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function taskVerify(args: string[] = []): void {
|
|
12
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
13
|
+
if (!args[0] || !args[1] || args[0].startsWith('--') || args[1].startsWith('--')) { fail('task ref and verification event are required'); return; }
|
|
14
|
+
let artifact: string | undefined;
|
|
15
|
+
let format: 'json' | 'text' = 'json';
|
|
16
|
+
const seen = new Set<string>();
|
|
17
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
18
|
+
const flag = args[index]!;
|
|
19
|
+
if (flag !== '--artifact' && flag !== '--format') { fail(`unknown option '${flag}'`); return; }
|
|
20
|
+
if (seen.has(flag)) { fail(`duplicate option '${flag}'`); return; }
|
|
21
|
+
const value = args[++index];
|
|
22
|
+
if (!value || value.startsWith('--')) { fail(`option '${flag}' requires a value`); return; }
|
|
23
|
+
seen.add(flag);
|
|
24
|
+
if (flag === '--artifact') artifact = value;
|
|
25
|
+
else if (value === 'json' || value === 'text') format = value;
|
|
26
|
+
else { fail("option '--format' requires 'json' or 'text'"); return; }
|
|
27
|
+
}
|
|
28
|
+
const result = verifyTaskEvent({ taskRef: args[0], event: args[1], ...(artifact ? { artifact } : {}) });
|
|
29
|
+
process.stdout.write(format === 'text' ? renderTaskVerification(result) : `${JSON.stringify(result)}\n`);
|
|
30
|
+
process.exitCode = result.status === 'pass' ? 0 : result.status === 'blocked' ? 2 : 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { taskVerify };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
|
|
2
|
+
import type { WorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
|
|
3
|
+
|
|
4
|
+
const USAGE = `Usage: agent-infra-internal task-warning <task-ref> <add|set-status|list> [intent flags] [--dry-run]\n`;
|
|
5
|
+
const FLAGS: Record<string, string> = {
|
|
6
|
+
'--step': 'step', '--severity': 'severity', '--code': 'code', '--target': 'target',
|
|
7
|
+
'--message': 'message', '--action': 'action', '--id': 'id', '--status': 'status', '--resolution': 'resolution'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
function usageFailure(message: string): void {
|
|
11
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'WARNING_PAYLOAD_INVALID', message } })}\n`);
|
|
12
|
+
process.stderr.write(USAGE);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function taskWarning(args: string[] = []): void {
|
|
17
|
+
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
18
|
+
const [taskRef, kind] = args;
|
|
19
|
+
if (!taskRef || !kind || !['add', 'set-status', 'list'].includes(kind)) { usageFailure('task ref and a valid intent are required'); return; }
|
|
20
|
+
const values: Record<string, unknown> = { kind, taskRef };
|
|
21
|
+
const seen = new Set<string>();
|
|
22
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
23
|
+
const flag = args[index]!;
|
|
24
|
+
if (flag === '--dry-run') {
|
|
25
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
26
|
+
seen.add(flag); values.dryRun = true; continue;
|
|
27
|
+
}
|
|
28
|
+
const key = FLAGS[flag];
|
|
29
|
+
if (!key) { usageFailure(`unknown option '${flag}'`); return; }
|
|
30
|
+
if (seen.has(flag)) { usageFailure(`duplicate option '${flag}'`); return; }
|
|
31
|
+
const value = args[++index];
|
|
32
|
+
if (value === undefined || value.startsWith('--')) { usageFailure(`option '${flag}' requires a value`); return; }
|
|
33
|
+
seen.add(flag); values[key] = value;
|
|
34
|
+
}
|
|
35
|
+
const required: Record<string, string[]> = {
|
|
36
|
+
add: ['step', 'severity', 'code', 'target', 'message', 'action'],
|
|
37
|
+
'set-status': ['id', 'status', 'resolution'], list: []
|
|
38
|
+
};
|
|
39
|
+
const optional = kind === 'list' ? ['status'] : [];
|
|
40
|
+
const allowed = new Set(['kind', 'taskRef', 'dryRun', ...required[kind]!, ...optional]);
|
|
41
|
+
const unexpected = Object.keys(values).find((key) => !allowed.has(key));
|
|
42
|
+
const missing = required[kind]!.find((key) => values[key] === undefined);
|
|
43
|
+
if (unexpected) { usageFailure(`${kind} does not accept '${unexpected}'`); return; }
|
|
44
|
+
if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
|
|
45
|
+
const result = applyWorkflowWarningIntent(values as WorkflowWarningIntent);
|
|
46
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
47
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { taskWarning };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PlatformResult } from './types.ts';
|
|
2
|
+
|
|
3
|
+
type PlatformAdapterContext = {
|
|
4
|
+
cwd: string;
|
|
5
|
+
gitRemote?: (cwd: string) => string | null;
|
|
6
|
+
client?: unknown;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type PlatformAdapter = {
|
|
10
|
+
type: string;
|
|
11
|
+
resolveContext(context: PlatformAdapterContext): PlatformResult;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const adapters = new Map<string, PlatformAdapter>();
|
|
15
|
+
|
|
16
|
+
function registerPlatformAdapter(adapter: PlatformAdapter): void {
|
|
17
|
+
if (!adapter.type.trim()) throw new Error('Platform adapter type is required');
|
|
18
|
+
adapters.set(adapter.type, adapter);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getPlatformAdapter(type: string | null): PlatformAdapter | null {
|
|
22
|
+
return type ? adapters.get(type) ?? null : null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function listPlatformAdapters(): string[] {
|
|
26
|
+
return [...adapters.keys()].sort();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { getPlatformAdapter, listPlatformAdapters, registerPlatformAdapter };
|
|
30
|
+
export type { PlatformAdapter, PlatformAdapterContext };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
import semver from 'semver';
|
|
6
|
+
|
|
7
|
+
import { getPlatformAdapter, registerPlatformAdapter } from './adapters.ts';
|
|
8
|
+
import { createGitHubClient, MINIMUM_GITHUB_CLI_VERSION } from './github-client.ts';
|
|
9
|
+
import type { GitHubClient } from './github-client.ts';
|
|
10
|
+
import { platformResult } from './types.ts';
|
|
11
|
+
import type { PlatformResult } from './types.ts';
|
|
12
|
+
|
|
13
|
+
type ContextOptions = {
|
|
14
|
+
cwd?: string;
|
|
15
|
+
gitRemote?: (cwd: string) => string | null;
|
|
16
|
+
client?: {
|
|
17
|
+
version(options?: Parameters<GitHubClient['version']>[0]): ReturnType<GitHubClient['version']>;
|
|
18
|
+
json(args: string[], options?: Parameters<GitHubClient['json']>[1]): ReturnType<GitHubClient['json']>;
|
|
19
|
+
};
|
|
20
|
+
platformType?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function findRepoRoot(cwd: string): string {
|
|
24
|
+
try {
|
|
25
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], {
|
|
26
|
+
cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
|
|
27
|
+
}).trim();
|
|
28
|
+
} catch {
|
|
29
|
+
return cwd;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseGitHubRemote(remote: string): string | null {
|
|
34
|
+
const trimmed = remote.trim().replace(/\.git$/, '');
|
|
35
|
+
const match = trimmed.match(/^(?:https?:\/\/github\.com\/|ssh:\/\/(?:git@)?github\.com\/|git@github\.com:)([^/\s]+\/[^/\s]+)$/i);
|
|
36
|
+
return match?.[1] || null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function defaultGitRemote(cwd: string): string | null {
|
|
40
|
+
try {
|
|
41
|
+
return execFileSync('git', ['remote', 'get-url', 'origin'], {
|
|
42
|
+
cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
|
|
43
|
+
}).trim();
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function readPlatformType(repoRoot: string): string | null {
|
|
50
|
+
try {
|
|
51
|
+
const config = JSON.parse(fs.readFileSync(path.join(repoRoot, '.agents', '.airc.json'), 'utf8'));
|
|
52
|
+
return typeof config?.platform?.type === 'string' ? config.platform.type : null;
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function failure(error: { code: string; message: string; retryable: boolean }, repo: string | null): PlatformResult {
|
|
59
|
+
const blocked = error.retryable || error.code === 'AUTH_REQUIRED' || error.code === 'PLATFORM_DEPENDENCY_MISSING';
|
|
60
|
+
return platformResult(blocked ? 'blocked' : 'failed', {
|
|
61
|
+
platform: { type: 'github', repository: repo, currentUser: null }, error
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function resolveGitHubContext(options: ContextOptions & { cwd: string }): PlatformResult {
|
|
66
|
+
const { cwd } = options;
|
|
67
|
+
const platform = 'github';
|
|
68
|
+
const client = options.client || createGitHubClient();
|
|
69
|
+
const version = client.version({ cwd });
|
|
70
|
+
if (!version.ok) return failure(version.error, null);
|
|
71
|
+
if (!semver.gte(version.value, MINIMUM_GITHUB_CLI_VERSION)) {
|
|
72
|
+
return failure({
|
|
73
|
+
code: 'GH_CLI_VERSION_UNSUPPORTED',
|
|
74
|
+
message: `GitHub CLI ${version.value} is unsupported; install gh >= ${MINIMUM_GITHUB_CLI_VERSION}`,
|
|
75
|
+
retryable: false
|
|
76
|
+
}, null);
|
|
77
|
+
}
|
|
78
|
+
const remote = (options.gitRemote || defaultGitRemote)(cwd);
|
|
79
|
+
if (!remote) {
|
|
80
|
+
return platformResult('no-op', {
|
|
81
|
+
platform: { type: platform, repository: null, currentUser: null },
|
|
82
|
+
error: { code: 'REMOTE_MISSING', message: 'Git origin remote is not configured', retryable: false }
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const ownerRepo = parseGitHubRemote(remote);
|
|
86
|
+
if (!ownerRepo) {
|
|
87
|
+
const nonGitHub = !/github\.com/i.test(remote);
|
|
88
|
+
return platformResult(nonGitHub ? 'no-op' : 'failed', {
|
|
89
|
+
platform: { type: platform, repository: null, currentUser: null },
|
|
90
|
+
error: {
|
|
91
|
+
code: nonGitHub ? 'PLATFORM_UNSUPPORTED' : 'REMOTE_INVALID',
|
|
92
|
+
message: `Unable to parse GitHub owner/repo from '${remote}'`,
|
|
93
|
+
retryable: false
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const repository = client.json(['api', `repos/${ownerRepo}`], { cwd });
|
|
99
|
+
if (!repository.ok) return failure(repository.error, null);
|
|
100
|
+
const repositoryValue = repository.value as { fork?: boolean; full_name?: string; parent?: { full_name?: string } } | null;
|
|
101
|
+
const upstream = repositoryValue?.fork ? repositoryValue.parent?.full_name : repositoryValue?.full_name;
|
|
102
|
+
if (!upstream) {
|
|
103
|
+
return platformResult('blocked', {
|
|
104
|
+
platform: { type: platform, repository: null, currentUser: null },
|
|
105
|
+
error: { code: 'UPSTREAM_UNRESOLVED', message: 'Unable to resolve the upstream repository', retryable: false }
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const user = client.json(['api', 'user'], { cwd });
|
|
109
|
+
if (!user.ok) return failure(user.error, upstream);
|
|
110
|
+
const userValue = user.value as { login?: string } | null;
|
|
111
|
+
const permissions = client.json(['api', `repos/${upstream}`], { cwd });
|
|
112
|
+
if (!permissions.ok) return failure(permissions.error, upstream);
|
|
113
|
+
const permissionValue = permissions.value as { permissions?: Record<string, boolean> } | null;
|
|
114
|
+
const values = permissionValue?.permissions || {};
|
|
115
|
+
const capabilities = {
|
|
116
|
+
authenticated: Boolean(userValue?.login),
|
|
117
|
+
comment: Boolean(userValue?.login),
|
|
118
|
+
triage: Boolean(values.triage || values.push || values.admin),
|
|
119
|
+
push: Boolean(values.push || values.admin),
|
|
120
|
+
admin: Boolean(values.admin)
|
|
121
|
+
};
|
|
122
|
+
const status = Object.values(capabilities).every(Boolean) ? 'no-op' : 'degraded';
|
|
123
|
+
return platformResult(status, {
|
|
124
|
+
changed: false,
|
|
125
|
+
platform: { type: platform, repository: upstream, currentUser: userValue?.login || null },
|
|
126
|
+
resource: { kind: 'repository', number: null },
|
|
127
|
+
capabilities,
|
|
128
|
+
operations: [{ name: 'resolve', status: 'no-op', reasonCode: null }]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
registerPlatformAdapter({
|
|
133
|
+
type: 'github',
|
|
134
|
+
resolveContext(options) {
|
|
135
|
+
return resolveGitHubContext(options as ContextOptions & { cwd: string });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
registerPlatformAdapter({
|
|
140
|
+
type: 'none',
|
|
141
|
+
resolveContext() {
|
|
142
|
+
return platformResult('no-op', {
|
|
143
|
+
platform: { type: 'none', repository: null, currentUser: null },
|
|
144
|
+
operations: [{ name: 'resolve', status: 'no-op', reasonCode: 'PLATFORM_DISABLED' }]
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
function resolvePlatformContext(options: ContextOptions = {}): PlatformResult {
|
|
150
|
+
const cwd = path.resolve(options.cwd || process.cwd());
|
|
151
|
+
const repoRoot = findRepoRoot(cwd);
|
|
152
|
+
const platform = options.platformType ?? readPlatformType(repoRoot);
|
|
153
|
+
const adapter = getPlatformAdapter(platform);
|
|
154
|
+
if (!adapter) {
|
|
155
|
+
return platformResult('no-op', {
|
|
156
|
+
platform: { type: platform, repository: null, currentUser: null },
|
|
157
|
+
error: { code: 'PLATFORM_UNSUPPORTED', message: `Platform '${platform || 'none'}' has no registered adapter`, retryable: false }
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return adapter.resolveContext({ cwd, gitRemote: options.gitRemote, client: options.client });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export { parseGitHubRemote, resolvePlatformContext };
|
|
164
|
+
export type { ContextOptions };
|