@fitlab-ai/agent-infra 0.9.11 → 0.9.13
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 +13 -13
- package/README.zh-CN.md +13 -13
- package/dist/bin/internal-cli.js +29 -19
- package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
- package/dist/lib/agent-clients/next-steps.js +6 -1
- package/dist/lib/decide.js +3 -3
- package/dist/lib/defaults.json +4 -0
- package/dist/lib/git/workflow.js +43 -1
- package/dist/lib/init.js +1 -0
- package/dist/lib/internal/git-workflow.js +8 -1
- package/dist/lib/internal/platform-checks.js +3 -3
- package/dist/lib/internal/platform-comment.js +9 -9
- package/dist/lib/internal/platform-context.js +2 -2
- package/dist/lib/internal/platform-issue.js +8 -9
- package/dist/lib/internal/platform-pr-review.js +10 -10
- package/dist/lib/internal/platform-pr.js +68 -23
- package/dist/lib/internal/platform-release-notes.js +3 -3
- package/dist/lib/internal/pr-review-grade.js +11 -9
- package/dist/lib/internal/release-workflow.js +4 -4
- package/dist/lib/internal/sandbox-control.js +30 -4
- package/dist/lib/internal/task-activity.js +3 -3
- package/dist/lib/internal/task-artifact.js +76 -24
- package/dist/lib/internal/task-create.js +2 -2
- package/dist/lib/internal/task-delivery.js +59 -0
- package/dist/lib/internal/task-event.js +6 -3
- package/dist/lib/internal/task-finalization.js +2 -2
- package/dist/lib/internal/task-invalidation.js +60 -0
- package/dist/lib/internal/task-ledger.js +9 -6
- package/dist/lib/internal/task-lifecycle.js +2 -2
- package/dist/lib/internal/task-override.js +4 -4
- package/dist/lib/internal/task-review.js +3 -3
- package/dist/lib/internal/task-verify.js +6 -6
- package/dist/lib/internal/task-warning.js +3 -3
- package/dist/lib/platform/adapters.js +1 -3
- package/dist/lib/platform/change-request-git-evidence.js +27 -7
- package/dist/lib/platform/completion-backfill.js +6 -5
- package/dist/lib/platform/context.js +70 -130
- package/dist/lib/platform/github-client.js +8 -2
- package/dist/lib/platform/github-provider.js +903 -0
- package/dist/lib/platform/in-label-sync.js +143 -0
- package/dist/lib/platform/issue-comments.js +94 -41
- package/dist/lib/platform/issues.js +335 -189
- package/dist/lib/platform/metadata-labels.js +6 -2
- package/dist/lib/platform/none-provider.js +28 -0
- package/dist/lib/platform/pr-change-report.js +551 -0
- package/dist/lib/platform/pr-checks.js +124 -106
- package/dist/lib/platform/pr-review.js +88 -72
- package/dist/lib/platform/pr-summary.js +523 -49
- package/dist/lib/platform/provider-bridge.js +45 -0
- package/dist/lib/platform/provider-contract.d.ts +487 -0
- package/dist/lib/platform/provider-contract.js +95 -0
- package/dist/lib/platform/provider-loader.js +251 -0
- package/dist/lib/platform/provider-validation.js +504 -0
- package/dist/lib/platform/pull-request-metadata.js +8 -6
- package/dist/lib/platform/pull-requests.js +1050 -502
- package/dist/lib/platform/release-notes.js +78 -55
- package/dist/lib/platform/releases.js +79 -50
- package/dist/lib/platform/resource-identity.d.ts +26 -0
- package/dist/lib/platform/resource-identity.js +92 -0
- package/dist/lib/platform/task-identities.js +31 -0
- package/dist/lib/platform/verification-required.js +22 -12
- package/dist/lib/platform/verification-sync.js +118 -239
- package/dist/lib/pr-review/evidence-grading.js +30 -9
- package/dist/lib/run/index.js +63 -23
- package/dist/lib/sandbox/config.js +5 -0
- package/dist/lib/sandbox/control/client.js +96 -15
- package/dist/lib/sandbox/control/executor.js +3 -3
- package/dist/lib/sandbox/control/lifecycle.js +29 -7
- package/dist/lib/sandbox/control/protocol.js +77 -0
- package/dist/lib/sandbox/control/server.js +398 -25
- package/dist/lib/sandbox/control/state.js +204 -1
- package/dist/lib/server/process-state.js +2 -2
- package/dist/lib/server/protocol.js +38 -1
- package/dist/lib/task/activity-log.js +8 -1
- package/dist/lib/task/artifact-lifecycle.js +35 -7
- package/dist/lib/task/capabilities.js +239 -0
- package/dist/lib/task/commands/status.js +32 -0
- package/dist/lib/task/commit-intent.js +100 -0
- package/dist/lib/task/commit-operation.js +207 -102
- package/dist/lib/task/control-authority.js +8 -5
- package/dist/lib/task/create-service.js +8 -8
- package/dist/lib/task/create.js +33 -7
- package/dist/lib/task/current-contract.js +5 -1
- package/dist/lib/task/decision-details.js +3 -48
- package/dist/lib/task/delivery-target.js +97 -0
- package/dist/lib/task/delivery.js +153 -0
- package/dist/lib/task/events.js +297 -17
- package/dist/lib/task/finalization.js +37 -13
- package/dist/lib/task/human-override.js +61 -36
- package/dist/lib/task/invalidation-command.js +86 -0
- package/dist/lib/task/invalidation.js +260 -0
- package/dist/lib/task/ledger-intents.js +37 -0
- package/dist/lib/task/lifecycle.js +106 -9
- package/dist/lib/task/local-artifact-finalization.js +374 -0
- package/dist/lib/task/orchestration.js +100 -151
- package/dist/lib/task/pr-delivery-fact.js +183 -0
- package/dist/lib/task/review-finalization.js +4 -8
- package/dist/lib/task/review-fingerprint.js +32 -2
- package/dist/lib/task/rework-intent.js +138 -0
- package/dist/lib/task/skill-scope.js +23 -0
- package/dist/lib/task/task-execution-lock.js +27 -17
- package/dist/lib/task/verification-engine.js +89 -38
- package/dist/lib/task/verification-review.js +1 -1
- package/dist/lib/task/verification.js +3 -3
- package/dist/lib/task/workflow-warning-intents.js +1 -1
- package/dist/lib/task/write.js +11 -0
- package/dist/lib/update.js +9 -0
- package/dist/lib/version.js +11 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
- package/lib/agent-clients/next-steps.ts +6 -1
- package/lib/decide.ts +3 -3
- package/lib/defaults.json +4 -0
- package/lib/git/workflow.ts +38 -1
- package/lib/init.ts +4 -1
- package/lib/internal/git-workflow.ts +7 -1
- package/lib/internal/platform-checks.ts +3 -3
- package/lib/internal/platform-comment.ts +8 -8
- package/lib/internal/platform-context.ts +2 -2
- package/lib/internal/platform-issue.ts +7 -8
- package/lib/internal/platform-pr-review.ts +9 -9
- package/lib/internal/platform-pr.ts +53 -21
- package/lib/internal/platform-release-notes.ts +3 -3
- package/lib/internal/pr-review-grade.ts +10 -8
- package/lib/internal/release-workflow.ts +4 -4
- package/lib/internal/sandbox-control.ts +27 -3
- package/lib/internal/task-activity.ts +3 -3
- package/lib/internal/task-artifact.ts +65 -22
- package/lib/internal/task-create.ts +2 -2
- package/lib/internal/task-delivery.ts +53 -0
- package/lib/internal/task-event.ts +6 -3
- package/lib/internal/task-finalization.ts +3 -3
- package/lib/internal/task-invalidation.ts +39 -0
- package/lib/internal/task-ledger.ts +11 -8
- package/lib/internal/task-lifecycle.ts +2 -2
- package/lib/internal/task-override.ts +6 -6
- package/lib/internal/task-review.ts +3 -3
- package/lib/internal/task-verify.ts +6 -6
- package/lib/internal/task-warning.ts +3 -3
- package/lib/platform/adapters.ts +3 -2
- package/lib/platform/change-request-git-evidence.ts +36 -9
- package/lib/platform/completion-backfill.ts +9 -8
- package/lib/platform/context.ts +97 -134
- package/lib/platform/github-client.ts +10 -3
- package/lib/platform/github-provider.ts +910 -0
- package/lib/platform/in-label-sync.ts +208 -0
- package/lib/platform/issue-comments.ts +97 -47
- package/lib/platform/issues.ts +344 -174
- package/lib/platform/metadata-labels.ts +5 -2
- package/lib/platform/none-provider.ts +35 -0
- package/lib/platform/pr-change-report.ts +645 -0
- package/lib/platform/pr-checks.ts +129 -107
- package/lib/platform/pr-review.ts +88 -85
- package/lib/platform/pr-summary.ts +562 -52
- package/lib/platform/provider-bridge.ts +82 -0
- package/lib/platform/provider-contract.ts +536 -0
- package/lib/platform/provider-loader.ts +307 -0
- package/lib/platform/provider-validation.ts +529 -0
- package/lib/platform/pull-request-metadata.ts +10 -7
- package/lib/platform/pull-requests.ts +1126 -505
- package/lib/platform/release-notes.ts +76 -59
- package/lib/platform/releases.ts +77 -43
- package/lib/platform/resource-identity.ts +121 -0
- package/lib/platform/task-identities.ts +40 -0
- package/lib/platform/types.ts +4 -2
- package/lib/platform/verification-required.ts +21 -13
- package/lib/platform/verification-sync.ts +118 -293
- package/lib/pr-review/evidence-grading.ts +31 -11
- package/lib/run/index.ts +57 -22
- package/lib/sandbox/config.ts +7 -0
- package/lib/sandbox/control/client.ts +105 -15
- package/lib/sandbox/control/executor.ts +4 -4
- package/lib/sandbox/control/lifecycle.ts +30 -8
- package/lib/sandbox/control/protocol.ts +113 -0
- package/lib/sandbox/control/server.ts +431 -23
- package/lib/sandbox/control/state.ts +251 -1
- package/lib/server/process-state.ts +2 -2
- package/lib/server/protocol.ts +36 -1
- package/lib/task/activity-log.ts +8 -0
- package/lib/task/artifact-lifecycle.ts +34 -8
- package/lib/task/capabilities.ts +262 -0
- package/lib/task/commands/status.ts +38 -0
- package/lib/task/commit-intent.ts +137 -0
- package/lib/task/commit-operation.ts +186 -88
- package/lib/task/control-authority.ts +11 -8
- package/lib/task/create-service.ts +8 -8
- package/lib/task/create.ts +34 -9
- package/lib/task/current-contract.ts +6 -1
- package/lib/task/decision-details.ts +8 -64
- package/lib/task/delivery-target.ts +130 -0
- package/lib/task/delivery.ts +160 -0
- package/lib/task/events.ts +296 -16
- package/lib/task/finalization.ts +50 -14
- package/lib/task/human-override.ts +73 -46
- package/lib/task/invalidation-command.ts +86 -0
- package/lib/task/invalidation.ts +332 -0
- package/lib/task/ledger-intents.ts +35 -1
- package/lib/task/lifecycle.ts +93 -4
- package/lib/task/local-artifact-finalization.ts +563 -0
- package/lib/task/orchestration.ts +110 -146
- package/lib/task/pr-delivery-fact.ts +237 -0
- package/lib/task/review-finalization.ts +4 -14
- package/lib/task/review-fingerprint.ts +33 -2
- package/lib/task/rework-intent.ts +165 -0
- package/lib/task/skill-scope.ts +24 -0
- package/lib/task/task-execution-lock.ts +23 -14
- package/lib/task/verification-engine.ts +95 -43
- package/lib/task/verification-review.ts +2 -0
- package/lib/task/verification.ts +4 -4
- package/lib/task/workflow-warning-intents.ts +1 -1
- package/lib/task/write.ts +19 -0
- package/lib/update.ts +11 -1
- package/lib/version.ts +15 -1
- package/package.json +7 -1
- package/templates/.agents/rules/README.en.md +4 -2
- package/templates/.agents/rules/README.zh-CN.md +4 -2
- package/templates/.agents/rules/create-issue.en.md +11 -2
- package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
- package/templates/.agents/rules/issue-pr-commands.en.md +4 -17
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +28 -5
- package/templates/.agents/rules/issue-sync.zh-CN.md +64 -5
- package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
- package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
- package/templates/.agents/rules/local-artifact-repair.en.md +53 -0
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +53 -0
- package/templates/.agents/rules/milestone-inference.en.md +12 -2
- package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
- package/templates/.agents/rules/pr-sync.en.md +28 -13
- package/templates/.agents/rules/pr-sync.zh-CN.md +39 -5
- package/templates/.agents/rules/release-commands.en.md +42 -3
- package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
- package/templates/.agents/rules/security-alerts.en.md +17 -2
- package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
- package/templates/.agents/rules/sync-content-generation.en.md +8 -0
- package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
- package/templates/.agents/rules/task-management.en.md +1 -1
- package/templates/.agents/rules/task-management.zh-CN.md +1 -1
- package/templates/.agents/rules/task-short-id.en.md +1 -4
- package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
- package/templates/.agents/scripts/security-alerts.github.sh +151 -0
- package/templates/.agents/scripts/security-alerts.sh +31 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +14 -3
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -3
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/SKILL.en.md +32 -10
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +35 -13
- package/templates/.agents/skills/code-task/config/verify.en.json +1 -0
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/commit/SKILL.en.md +3 -3
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/config/verify.json +1 -1
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +4 -4
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +4 -4
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -2
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +5 -4
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +5 -4
- package/templates/.agents/skills/complete-task/SKILL.en.md +31 -13
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +30 -13
- package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
- package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
- package/templates/.agents/skills/create-pr/SKILL.en.md +11 -10
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +11 -11
- package/templates/.agents/skills/create-pr/config/verify.json +1 -0
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +1 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/init-labels/SKILL.en.md +9 -10
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
- package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
- package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
- package/templates/.agents/skills/plan-task/SKILL.en.md +14 -3
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +11 -3
- package/templates/.agents/skills/review-analysis/SKILL.en.md +6 -5
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +6 -5
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +10 -9
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +10 -9
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
- package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
- package/templates/.agents/skills/review-plan/SKILL.en.md +6 -5
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +6 -5
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
- package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
- package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -2
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +4 -0
- package/templates/.agents/skills/watch-pr/SKILL.en.md +6 -6
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
- package/templates/.agents/templates/task.en.md +23 -2
- package/templates/.agents/templates/task.zh-CN.md +23 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/feature-development.en.yaml +9 -8
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
- package/templates/.agents/workflows/refactoring.en.yaml +9 -8
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
- package/templates/.github/workflows/pr-label.yml +7 -26
- package/templates/.agents/rules/create-issue.github.en.md +0 -14
- package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
- package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
- package/templates/.agents/rules/issue-sync.github.en.md +0 -40
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
- package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
- package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
- package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
- package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
- package/templates/.agents/rules/pr-sync.github.en.md +0 -43
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
- package/templates/.agents/rules/release-commands.github.en.md +0 -44
- package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -44
- package/templates/.agents/rules/security-alerts.github.en.md +0 -43
- package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
- /package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +0 -0
- /package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +0 -0
package/dist/lib/update.js
CHANGED
|
@@ -43,6 +43,7 @@ async function cmdSync() {
|
|
|
43
43
|
const sandboxAdded = !config.sandbox;
|
|
44
44
|
const taskAdded = !config.task;
|
|
45
45
|
const labelsAdded = !config.labels;
|
|
46
|
+
const deliveryAdded = !config.delivery;
|
|
46
47
|
if (platformAdded)
|
|
47
48
|
config.platform = structuredClone(defaults.platform);
|
|
48
49
|
if (sandboxAdded)
|
|
@@ -51,6 +52,8 @@ async function cmdSync() {
|
|
|
51
52
|
config.task = structuredClone(defaults.task);
|
|
52
53
|
if (labelsAdded)
|
|
53
54
|
config.labels = structuredClone(defaults.labels);
|
|
55
|
+
if (deliveryAdded)
|
|
56
|
+
config.delivery = structuredClone(defaults.delivery);
|
|
54
57
|
const workflowPlan = planAgentClientReconciliation({
|
|
55
58
|
config: config,
|
|
56
59
|
mutation: { type: 'replace-state', state: normalizedOriginal.state },
|
|
@@ -98,6 +101,9 @@ async function cmdSync() {
|
|
|
98
101
|
if (labelsAdded) {
|
|
99
102
|
info(`Default labels.in config added to ${CONFIG_PATH}.`);
|
|
100
103
|
}
|
|
104
|
+
if (deliveryAdded) {
|
|
105
|
+
info(`Default delivery target added to ${CONFIG_PATH}.`);
|
|
106
|
+
}
|
|
101
107
|
}
|
|
102
108
|
else {
|
|
103
109
|
info(`File registry changed in ${CONFIG_PATH}.`);
|
|
@@ -114,6 +120,9 @@ async function cmdSync() {
|
|
|
114
120
|
if (hasNewEntries && platformAdded) {
|
|
115
121
|
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
116
122
|
}
|
|
123
|
+
if (hasNewEntries && deliveryAdded) {
|
|
124
|
+
info(`Default delivery target added to ${CONFIG_PATH}.`);
|
|
125
|
+
}
|
|
117
126
|
ok(`Updated ${CONFIG_PATH}`);
|
|
118
127
|
}
|
|
119
128
|
// done
|
package/dist/lib/version.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import semver from 'semver';
|
|
2
3
|
const packageJsonUrl = [
|
|
3
4
|
new URL('../package.json', import.meta.url),
|
|
4
5
|
new URL('../../package.json', import.meta.url),
|
|
@@ -9,8 +10,17 @@ if (!packageJsonUrl) {
|
|
|
9
10
|
const { version } = JSON.parse(readFileSync(packageJsonUrl, 'utf8'));
|
|
10
11
|
const VERSION = `v${version}`;
|
|
11
12
|
const AGENT_INFRA_VERSION_PATTERN = /^v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
13
|
+
const LEGACY_COMPATIBILITY_CUTOFF_VERSION = '1.0.0';
|
|
12
14
|
function isValidAgentInfraVersion(value) {
|
|
13
15
|
return typeof value === 'string' && AGENT_INFRA_VERSION_PATTERN.test(value);
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
function isLegacyCompatibilityEnabled(runtimeVersion = VERSION) {
|
|
18
|
+
const normalized = runtimeVersion.startsWith('v') ? runtimeVersion.slice(1) : runtimeVersion;
|
|
19
|
+
const parsed = semver.valid(normalized);
|
|
20
|
+
return parsed !== null && semver.lt(parsed, LEGACY_COMPATIBILITY_CUTOFF_VERSION);
|
|
21
|
+
}
|
|
22
|
+
function legacyCompatibilityError(resource, runtimeVersion = VERSION) {
|
|
23
|
+
return Object.assign(new Error(`PLATFORM_IDENTITY_LEGACY_UNSUPPORTED: ${resource} requires migration to the current schema before v${LEGACY_COMPATIBILITY_CUTOFF_VERSION} runtime ${runtimeVersion}`), { code: 'PLATFORM_IDENTITY_LEGACY_UNSUPPORTED' });
|
|
24
|
+
}
|
|
25
|
+
export { LEGACY_COMPATIBILITY_CUTOFF_VERSION, VERSION, isLegacyCompatibilityEnabled, isValidAgentInfraVersion, legacyCompatibilityError };
|
|
16
26
|
//# sourceMappingURL=version.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"protocolVersion": 3,
|
|
3
|
-
"packageVersion": "0.9.
|
|
4
|
-
"sourceInputHash": "
|
|
5
|
-
"internalExecutableBuildHash": "
|
|
3
|
+
"packageVersion": "0.9.13",
|
|
4
|
+
"sourceInputHash": "5e4d3ad1c1e7e3c909489ef59ff318ea9cffe5f538ae37d83923773946357afe",
|
|
5
|
+
"internalExecutableBuildHash": "c8cabf5c6bc776cdcb9621f712172ebda95ff9b12fb6f67213e18bc0159516fd"
|
|
6
6
|
}
|
|
@@ -22,6 +22,14 @@ type LifecycleBuildIdentityOptions = Readonly<{
|
|
|
22
22
|
type LifecycleManifestFiles = Readonly<{
|
|
23
23
|
executableFiles: readonly string[];
|
|
24
24
|
contractFiles: readonly string[];
|
|
25
|
+
launcherShebang: LifecycleLauncherShebang;
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
type LifecycleLauncherShebang = Readonly<{
|
|
29
|
+
sourceFile: string;
|
|
30
|
+
compiledFile: string;
|
|
31
|
+
canonicalLine: string;
|
|
32
|
+
acceptedLines: readonly string[];
|
|
25
33
|
}>;
|
|
26
34
|
|
|
27
35
|
type IdentityVerification = Readonly<{
|
|
@@ -53,6 +61,56 @@ function normalizeRelativePath(value: string): string {
|
|
|
53
61
|
return value.replaceAll('\\', '/');
|
|
54
62
|
}
|
|
55
63
|
|
|
64
|
+
function isSafeLifecyclePath(value: unknown): value is string {
|
|
65
|
+
return exactText(value)
|
|
66
|
+
&& value === normalizeRelativePath(value)
|
|
67
|
+
&& !path.isAbsolute(value)
|
|
68
|
+
&& !/^[A-Za-z]:[\\/]/u.test(value)
|
|
69
|
+
&& !value.split('/').includes('..');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isLifecycleLauncherLine(value: unknown): value is string {
|
|
73
|
+
return typeof value === 'string'
|
|
74
|
+
&& value.length > 1
|
|
75
|
+
&& value.slice(0, -1).trim() === value.slice(0, -1)
|
|
76
|
+
&& value.startsWith('#!')
|
|
77
|
+
&& value.endsWith('\n')
|
|
78
|
+
&& value.indexOf('\n') === value.length - 1
|
|
79
|
+
&& !value.includes('\r');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function readLifecycleLauncherShebang(
|
|
83
|
+
value: unknown,
|
|
84
|
+
executableFiles: readonly string[]
|
|
85
|
+
): LifecycleLauncherShebang {
|
|
86
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
87
|
+
throw new Error('Lifecycle manifest launcher shebang policy is invalid');
|
|
88
|
+
}
|
|
89
|
+
const policy = value as Record<string, unknown>;
|
|
90
|
+
if (!isSafeLifecyclePath(policy.sourceFile)
|
|
91
|
+
|| !isSafeLifecyclePath(policy.compiledFile)
|
|
92
|
+
|| !isLifecycleLauncherLine(policy.canonicalLine)
|
|
93
|
+
|| !Array.isArray(policy.acceptedLines)
|
|
94
|
+
|| !policy.acceptedLines.every(isLifecycleLauncherLine)
|
|
95
|
+
|| new Set(policy.acceptedLines).size !== policy.acceptedLines.length
|
|
96
|
+
|| !policy.acceptedLines.includes(policy.canonicalLine)
|
|
97
|
+
|| !executableFiles.includes(policy.sourceFile)
|
|
98
|
+
|| policy.compiledFile !== normalizeRelativePath(path.join(
|
|
99
|
+
'dist',
|
|
100
|
+
policy.sourceFile.endsWith('.ts')
|
|
101
|
+
? policy.sourceFile.replace(/\.ts$/u, '.js')
|
|
102
|
+
: policy.sourceFile
|
|
103
|
+
))) {
|
|
104
|
+
throw new Error('Lifecycle manifest launcher shebang policy is invalid');
|
|
105
|
+
}
|
|
106
|
+
return Object.freeze({
|
|
107
|
+
sourceFile: policy.sourceFile,
|
|
108
|
+
compiledFile: policy.compiledFile,
|
|
109
|
+
canonicalLine: policy.canonicalLine,
|
|
110
|
+
acceptedLines: Object.freeze([...policy.acceptedLines])
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
56
114
|
function readLifecycleManifestFiles(packageRoot: string): LifecycleManifestFiles {
|
|
57
115
|
const file = path.join(
|
|
58
116
|
packageRoot,
|
|
@@ -65,18 +123,21 @@ function readLifecycleManifestFiles(packageRoot: string): LifecycleManifestFiles
|
|
|
65
123
|
const value = JSON.parse(fs.readFileSync(file, 'utf8')) as {
|
|
66
124
|
executableFiles?: unknown;
|
|
67
125
|
contractFiles?: unknown;
|
|
126
|
+
launcherShebang?: unknown;
|
|
68
127
|
};
|
|
69
128
|
if (!Array.isArray(value.executableFiles)
|
|
70
129
|
|| !Array.isArray(value.contractFiles)
|
|
71
|
-
|| !value.executableFiles.every(
|
|
72
|
-
|| !value.contractFiles.every(
|
|
130
|
+
|| !value.executableFiles.every(isSafeLifecyclePath)
|
|
131
|
+
|| !value.contractFiles.every(isSafeLifecyclePath)
|
|
73
132
|
|| new Set(value.executableFiles).size !== value.executableFiles.length
|
|
74
133
|
|| new Set(value.contractFiles).size !== value.contractFiles.length) {
|
|
75
134
|
throw new Error('Lifecycle manifest file list is invalid');
|
|
76
135
|
}
|
|
136
|
+
const executableFiles = Object.freeze([...value.executableFiles] as string[]);
|
|
77
137
|
return Object.freeze({
|
|
78
|
-
executableFiles
|
|
79
|
-
contractFiles: Object.freeze([...value.contractFiles] as string[])
|
|
138
|
+
executableFiles,
|
|
139
|
+
contractFiles: Object.freeze([...value.contractFiles] as string[]),
|
|
140
|
+
launcherShebang: readLifecycleLauncherShebang(value.launcherShebang, executableFiles)
|
|
80
141
|
});
|
|
81
142
|
}
|
|
82
143
|
|
|
@@ -94,7 +155,28 @@ function executablePackageRoot(): string {
|
|
|
94
155
|
}
|
|
95
156
|
}
|
|
96
157
|
|
|
97
|
-
function
|
|
158
|
+
function normalizeLifecycleLauncherBytes(
|
|
159
|
+
relative: string,
|
|
160
|
+
content: Buffer,
|
|
161
|
+
policy: LifecycleLauncherShebang
|
|
162
|
+
): Buffer {
|
|
163
|
+
const normalized = normalizeRelativePath(relative);
|
|
164
|
+
if (normalized !== policy.sourceFile && normalized !== policy.compiledFile) return content;
|
|
165
|
+
const lineEnd = content.indexOf(0x0a);
|
|
166
|
+
if (lineEnd < 0) return content;
|
|
167
|
+
const firstLine = content.subarray(0, lineEnd + 1);
|
|
168
|
+
if (!policy.acceptedLines.some((line) => Buffer.from(line).equals(firstLine))) return content;
|
|
169
|
+
return Buffer.concat([
|
|
170
|
+
Buffer.from(policy.canonicalLine),
|
|
171
|
+
content.subarray(lineEnd + 1)
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function hashFiles(
|
|
176
|
+
root: string,
|
|
177
|
+
files: readonly string[],
|
|
178
|
+
launcherShebang?: LifecycleLauncherShebang
|
|
179
|
+
): string {
|
|
98
180
|
const hash = crypto.createHash('sha256');
|
|
99
181
|
for (const relative of [...new Set(files.map(normalizeRelativePath))].sort()) {
|
|
100
182
|
if (path.isAbsolute(relative) || relative.split(/[\\/]/u).includes('..')) {
|
|
@@ -107,7 +189,10 @@ function hashFiles(root: string, files: readonly string[]): string {
|
|
|
107
189
|
}
|
|
108
190
|
hash.update(relative);
|
|
109
191
|
hash.update('\0');
|
|
110
|
-
|
|
192
|
+
const content = fs.readFileSync(file);
|
|
193
|
+
hash.update(launcherShebang
|
|
194
|
+
? normalizeLifecycleLauncherBytes(relative, content, launcherShebang)
|
|
195
|
+
: content);
|
|
111
196
|
hash.update('\0');
|
|
112
197
|
}
|
|
113
198
|
return hash.digest('hex');
|
|
@@ -157,7 +242,7 @@ function computeLifecycleBuildIdentity(
|
|
|
157
242
|
if (!exactText(packageJson.version)) throw new Error('Lifecycle package version is invalid');
|
|
158
243
|
let internalExecutableBuildHash: string;
|
|
159
244
|
if (options.executableFiles) {
|
|
160
|
-
internalExecutableBuildHash = hashFiles(repoRoot, options.executableFiles);
|
|
245
|
+
internalExecutableBuildHash = hashFiles(repoRoot, options.executableFiles, defaults.launcherShebang);
|
|
161
246
|
} else {
|
|
162
247
|
const manifestFile = path.join(executableRoot, 'dist', 'lifecycle-build-manifest.json');
|
|
163
248
|
if (fs.existsSync(manifestFile)) {
|
|
@@ -177,16 +262,25 @@ function computeLifecycleBuildIdentity(
|
|
|
177
262
|
const compiledFiles = defaults.executableFiles.map((file) =>
|
|
178
263
|
file.endsWith('.ts') ? path.join('dist', file.replace(/\.ts$/u, '.js')) : file
|
|
179
264
|
);
|
|
180
|
-
if (hashFiles(
|
|
265
|
+
if (hashFiles(
|
|
266
|
+
executableRoot,
|
|
267
|
+
resolveLifecycleExecutableFiles(executableRoot, compiledFiles),
|
|
268
|
+
defaults.launcherShebang
|
|
269
|
+
) !== manifest.internalExecutableBuildHash) {
|
|
181
270
|
throw new Error('Lifecycle compiled executable build does not match its manifest');
|
|
182
271
|
}
|
|
183
|
-
} else if (hashFiles(
|
|
272
|
+
} else if (hashFiles(
|
|
273
|
+
executableRoot,
|
|
274
|
+
resolveLifecycleExecutableFiles(executableRoot, defaults.executableFiles),
|
|
275
|
+
defaults.launcherShebang
|
|
276
|
+
) !== manifest.sourceInputHash) {
|
|
184
277
|
throw new Error('Lifecycle executable build manifest is stale or invalid');
|
|
185
278
|
}
|
|
186
279
|
internalExecutableBuildHash = manifest.internalExecutableBuildHash;
|
|
187
280
|
} else internalExecutableBuildHash = hashFiles(
|
|
188
281
|
executableRoot,
|
|
189
|
-
resolveLifecycleExecutableFiles(executableRoot, defaults.executableFiles)
|
|
282
|
+
resolveLifecycleExecutableFiles(executableRoot, defaults.executableFiles),
|
|
283
|
+
defaults.launcherShebang
|
|
190
284
|
);
|
|
191
285
|
}
|
|
192
286
|
return Object.freeze({
|
|
@@ -249,6 +343,7 @@ export type {
|
|
|
249
343
|
IdentityVerification,
|
|
250
344
|
LifecycleIdentityWarning,
|
|
251
345
|
LifecycleBuildIdentity,
|
|
346
|
+
LifecycleLauncherShebang,
|
|
252
347
|
LifecycleManifestFiles,
|
|
253
348
|
LifecycleBuildIdentityOptions
|
|
254
349
|
};
|
|
@@ -30,5 +30,16 @@
|
|
|
30
30
|
".agents/hooks/lifecycle-delegation.js",
|
|
31
31
|
".agents/skills/run-task/SKILL.md",
|
|
32
32
|
".agents/rules/lifecycle-orchestration.md"
|
|
33
|
-
]
|
|
33
|
+
],
|
|
34
|
+
"launcherShebang": {
|
|
35
|
+
"sourceFile": "bin/internal-cli.ts",
|
|
36
|
+
"compiledFile": "dist/bin/internal-cli.js",
|
|
37
|
+
"canonicalLine": "#!/usr/bin/env node\n",
|
|
38
|
+
"acceptedLines": [
|
|
39
|
+
"#!/usr/bin/env node\n",
|
|
40
|
+
"#!/opt/homebrew/opt/node/bin/node\n",
|
|
41
|
+
"#!/usr/local/opt/node/bin/node\n",
|
|
42
|
+
"#!/home/linuxbrew/.linuxbrew/opt/node/bin/node\n"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
34
45
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { listEnabledAgentClientAdapters } from './registry.ts';
|
|
2
2
|
import { renderAgentClientInvocation } from './invocation.ts';
|
|
3
3
|
import semver from 'semver';
|
|
4
|
+
import { isTaskScopeSkill } from '../task/skill-scope.ts';
|
|
4
5
|
import type { CustomTUI } from './custom-tuis.ts';
|
|
5
6
|
import type { AgentClientId, AgentClientState } from './types.ts';
|
|
6
7
|
|
|
@@ -45,7 +46,11 @@ function renderNextStepCommands(
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const args = [
|
|
48
|
-
...(input.taskRef === undefined
|
|
49
|
+
...(input.taskRef === undefined
|
|
50
|
+
? []
|
|
51
|
+
: isTaskScopeSkill(input.skillName)
|
|
52
|
+
? ['--task', input.taskRef]
|
|
53
|
+
: [input.taskRef]),
|
|
49
54
|
...(input.version === undefined ? [] : [input.version])
|
|
50
55
|
];
|
|
51
56
|
|
package/lib/decide.ts
CHANGED
|
@@ -79,11 +79,11 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
|
|
|
79
79
|
metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
|
|
80
80
|
};
|
|
81
81
|
let result;
|
|
82
|
-
const execute = () => {
|
|
82
|
+
const execute = async () => {
|
|
83
83
|
let current = applyHumanDecision(request, writeOptions);
|
|
84
84
|
if (current.status !== 'failed' || !parsedDecision.overrideTicket) return current;
|
|
85
85
|
if (!parsedDecision.overrideTarget || !parsedDecision.overrideScope) throw new Error('override ticket requires --override-target and --override-scope');
|
|
86
|
-
const consumed = consumeHumanOverride({
|
|
86
|
+
const consumed = await consumeHumanOverride({
|
|
87
87
|
taskRef: resolved.taskId,
|
|
88
88
|
ticketId: parsedDecision.overrideTicket,
|
|
89
89
|
failureId: failureId('decision-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
|
|
@@ -102,7 +102,7 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
|
|
|
102
102
|
if (consumed.status === 'failed') throw new Error(consumed.error.message);
|
|
103
103
|
return current;
|
|
104
104
|
};
|
|
105
|
-
result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
|
|
105
|
+
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
|
|
106
106
|
if (result.error) throw new Error(result.error.message);
|
|
107
107
|
return 0;
|
|
108
108
|
} catch (error) {
|
package/lib/defaults.json
CHANGED
package/lib/git/workflow.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
|
|
5
6
|
type CommandResult = { status: number | null; stdout: string; stderr: string };
|
|
@@ -105,6 +106,42 @@ function commitExplicitPaths(input: { cwd: string; paths: readonly string[]; mes
|
|
|
105
106
|
return { status: 'applied' as const, changed: true, snapshot: after.snapshot, operations: [{ name: 'stage', status: 'applied' as const }, { name: 'commit', status: 'applied' as const }], error: null };
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
function previewCommitTree(input: { cwd: string; paths: readonly string[]; expectedHead: string }) {
|
|
110
|
+
const invalid = validatePaths(input.paths);
|
|
111
|
+
if (invalid) return { status: 'failed' as const, tree: null, error: { code: 'GIT_COMMIT_INPUT_INVALID', message: invalid } };
|
|
112
|
+
const before = inspectGitWorkflow(input.cwd);
|
|
113
|
+
if (!before.snapshot) return { status: 'failed' as const, tree: null, error: { code: 'GIT_INSPECT_FAILED', message: 'Unable to inspect Git repository' } };
|
|
114
|
+
if (before.snapshot.head !== input.expectedHead) {
|
|
115
|
+
return { status: 'failed' as const, tree: null, error: { code: 'GIT_HEAD_MISMATCH', message: `Expected HEAD ${input.expectedHead}, received ${before.snapshot.head}` } };
|
|
116
|
+
}
|
|
117
|
+
const selected = new Set(input.paths);
|
|
118
|
+
const unrelatedStaged = before.snapshot.staged.filter((candidate) => !selected.has(candidate));
|
|
119
|
+
if (unrelatedStaged.length > 0) {
|
|
120
|
+
return { status: 'failed' as const, tree: null, error: { code: 'GIT_STAGED_SCOPE_MISMATCH', message: `Unrelated staged paths: ${unrelatedStaged.join(', ')}` } };
|
|
121
|
+
}
|
|
122
|
+
const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-infra-preview-index-'));
|
|
123
|
+
const indexFile = path.join(temporaryDirectory, 'index');
|
|
124
|
+
const temporaryRunner: GitRunner = (args, cwd) => {
|
|
125
|
+
const result = spawnSync('git', [...args], {
|
|
126
|
+
cwd,
|
|
127
|
+
env: { ...process.env, GIT_INDEX_FILE: indexFile },
|
|
128
|
+
encoding: 'utf8'
|
|
129
|
+
});
|
|
130
|
+
return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
|
|
131
|
+
};
|
|
132
|
+
try {
|
|
133
|
+
const read = run(temporaryRunner, input.cwd, ['read-tree', input.expectedHead]);
|
|
134
|
+
if (read.status !== 0) return { status: 'failed' as const, tree: null, error: { code: 'GIT_PREVIEW_FAILED', message: read.stderr.trim() || 'Unable to prepare a temporary Git index' } };
|
|
135
|
+
const stage = run(temporaryRunner, input.cwd, ['add', '-A', '--', ...input.paths]);
|
|
136
|
+
if (stage.status !== 0) return { status: 'failed' as const, tree: null, error: { code: 'GIT_PREVIEW_FAILED', message: stage.stderr.trim() || 'Unable to stage the requested paths in a temporary index' } };
|
|
137
|
+
const tree = value(temporaryRunner, input.cwd, ['write-tree']);
|
|
138
|
+
if (!tree) return { status: 'failed' as const, tree: null, error: { code: 'GIT_PREVIEW_FAILED', message: 'Unable to write the temporary Git tree' } };
|
|
139
|
+
return { status: 'planned' as const, tree, error: null };
|
|
140
|
+
} finally {
|
|
141
|
+
fs.rmSync(temporaryDirectory, { recursive: true, force: true });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
108
145
|
function pushGitRefs(input: { cwd: string; remote: string; refs: readonly string[]; expectedSha?: string }, runner: GitRunner = defaultRunner) {
|
|
109
146
|
if (!input.remote || input.refs.length === 0) return { status: 'failed' as const, changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [], error: { code: 'GIT_PUSH_INPUT_INVALID', message: 'Remote and refs are required' } };
|
|
110
147
|
const operations: GitOperation[] = [];
|
|
@@ -192,5 +229,5 @@ function pushRebasedBranch(input: PushRebasedInput, runner: GitRunner = defaultR
|
|
|
192
229
|
return { status: 'applied' as const, changed: true, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'push-rebased', status: 'applied' as const, ref: input.branch }], error: null };
|
|
193
230
|
}
|
|
194
231
|
|
|
195
|
-
export { commitExplicitPaths, inspectGitWorkflow, pushGitRefs, pushRebasedBranch };
|
|
232
|
+
export { commitExplicitPaths, inspectGitWorkflow, previewCommitTree, pushGitRefs, pushRebasedBranch };
|
|
196
233
|
export type { CommandResult, GitRunner, PushRebasedInput };
|
package/lib/init.ts
CHANGED
|
@@ -32,6 +32,7 @@ type Defaults = {
|
|
|
32
32
|
files: FileRegistry;
|
|
33
33
|
sandbox: Record<string, unknown>;
|
|
34
34
|
task: { shortIdLength: number };
|
|
35
|
+
delivery: { remote: string; baseRef: string };
|
|
35
36
|
labels: Record<string, unknown>;
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -39,10 +40,11 @@ type AgentConfig = {
|
|
|
39
40
|
project: string;
|
|
40
41
|
org: string;
|
|
41
42
|
language: string;
|
|
42
|
-
platform: { type: string };
|
|
43
|
+
platform: { type: string; providers?: Record<string, unknown> };
|
|
43
44
|
templateVersion: string;
|
|
44
45
|
sandbox: Record<string, unknown>;
|
|
45
46
|
task: { shortIdLength: number };
|
|
47
|
+
delivery: { remote: string; baseRef: string };
|
|
46
48
|
labels: Record<string, unknown>;
|
|
47
49
|
files: FileRegistry;
|
|
48
50
|
agentClients: ReturnType<typeof serializeAgentClients>;
|
|
@@ -244,6 +246,7 @@ async function cmdInit(): Promise<void> {
|
|
|
244
246
|
templateVersion: VERSION,
|
|
245
247
|
sandbox: structuredClone(defaults.sandbox),
|
|
246
248
|
task: structuredClone(defaults.task),
|
|
249
|
+
delivery: structuredClone(defaults.delivery),
|
|
247
250
|
labels: structuredClone(defaults.labels),
|
|
248
251
|
files: { managed: [], merged: [], ejected: [] },
|
|
249
252
|
agentClients: serializeAgentClients(defaultState)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { inspectGitWorkflow, pushRebasedBranch } from '../git/workflow.ts';
|
|
2
|
+
import { inspectGitWorkflow, previewCommitTree, pushRebasedBranch } from '../git/workflow.ts';
|
|
3
3
|
import { compareReviewTrees, snapshotReview } from '../git/review-snapshot.ts';
|
|
4
4
|
import { resolvePostReviewGlobs } from '../task/review-fingerprint.ts';
|
|
5
5
|
import { executeCommitOperation } from '../task/commit-operation.ts';
|
|
@@ -26,6 +26,12 @@ function gitWorkflow(args: string[] = []): void {
|
|
|
26
26
|
const inputIndex = rest.indexOf('--input');
|
|
27
27
|
const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1]!, 'utf8')) : null;
|
|
28
28
|
result = input ? pushRebasedBranch({ cwd: cwd ?? process.cwd(), ...input }) : { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
|
|
29
|
+
} else if (action === 'preview-tree') {
|
|
30
|
+
const inputIndex = rest.indexOf('--input');
|
|
31
|
+
const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1]!, 'utf8')) : null;
|
|
32
|
+
result = input
|
|
33
|
+
? previewCommitTree({ cwd: cwd ?? process.cwd(), paths: input.paths, expectedHead: input.expectedHead })
|
|
34
|
+
: { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
|
|
29
35
|
} else if (action === 'snapshot' || action === 'compare-trees') {
|
|
30
36
|
const inputIndex = rest.indexOf('--input');
|
|
31
37
|
const input = inputIndex >= 0 && rest[inputIndex + 1] ? JSON.parse(fs.readFileSync(rest[inputIndex + 1]!, 'utf8')) : null;
|
|
@@ -70,17 +70,17 @@ async function platformChecks(args: string[] = []): Promise<void> {
|
|
|
70
70
|
};
|
|
71
71
|
const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
|
|
72
72
|
if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
|
|
73
|
-
if (operation === 'inspect') { finish(inspectPullRequestReadiness(taskRef, { cwd })); return; }
|
|
73
|
+
if (operation === 'inspect') { finish(await inspectPullRequestReadiness(taskRef, { cwd })); return; }
|
|
74
74
|
if (operation === 'resolve-run') {
|
|
75
75
|
if (!values.checkName) { fail('resolve-run requires --check-name'); return; }
|
|
76
|
-
finish(resolvePlatformCheckRun(taskRef, { cwd, checkName: values.checkName, detailsUrl: values.detailsUrl }));
|
|
76
|
+
finish(await resolvePlatformCheckRun(taskRef, { cwd, checkName: values.checkName, detailsUrl: values.detailsUrl }));
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
if (operation === 'logs') {
|
|
80
80
|
const run = positive(values.run);
|
|
81
81
|
const job = values.job === undefined ? undefined : positive(values.job);
|
|
82
82
|
if (!run || values.job !== undefined && !job) { fail('logs requires a positive --run and optional positive --job'); return; }
|
|
83
|
-
finish(fetchPlatformCheckLogs(taskRef, { cwd, run, job: job || undefined }));
|
|
83
|
+
finish(await fetchPlatformCheckLogs(taskRef, { cwd, run, job: job || undefined }));
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
const intervalSeconds = positive(values.intervalSeconds);
|
|
@@ -11,7 +11,7 @@ import type { CommentKind } from '../platform/issue-comments.ts';
|
|
|
11
11
|
import type { PlatformResult } from '../platform/types.ts';
|
|
12
12
|
import { backfillCompletionComments } from '../platform/completion-backfill.ts';
|
|
13
13
|
|
|
14
|
-
const USAGE = `Usage: agent-infra-internal platform-comment list --issue <
|
|
14
|
+
const USAGE = `Usage: agent-infra-internal platform-comment list --issue <token> [--cwd <path>]
|
|
15
15
|
agent-infra-internal platform-comment owner <task-ref> [--cwd <path>]
|
|
16
16
|
agent-infra-internal platform-comment backfill <task-ref> --agent <agent> [--cwd <path>]
|
|
17
17
|
agent-infra-internal platform-comment sync <task-ref> --kind <kind> --agent <agent> [--artifact <file>] [--body-file <path|->] [--status-label <label>] [--backfill] [--cwd <path>]
|
|
@@ -52,7 +52,7 @@ function readBodyFile(value: string, cwd: string): string {
|
|
|
52
52
|
return fs.readFileSync(path.resolve(cwd, value), 'utf8');
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function platformComment(args: string[] = []): void {
|
|
55
|
+
async function platformComment(args: string[] = []): Promise<void> {
|
|
56
56
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
57
57
|
const operation = args[0];
|
|
58
58
|
if (!operation || !['list', 'owner', 'backfill', 'sync'].includes(operation)) { fail('a valid operation is required'); return; }
|
|
@@ -63,17 +63,17 @@ function platformComment(args: string[] = []): void {
|
|
|
63
63
|
if (parsed.error) { fail(parsed.error); return; }
|
|
64
64
|
const cwd = path.resolve(typeof parsed.values.cwd === 'string' ? parsed.values.cwd : process.cwd());
|
|
65
65
|
if (operation === 'list') {
|
|
66
|
-
const issue =
|
|
67
|
-
if (
|
|
66
|
+
const issue = parsed.values.issue;
|
|
67
|
+
if (typeof issue !== 'string' || !issue) { fail('list requires --issue <token>'); return; }
|
|
68
68
|
const unexpected = Object.keys(parsed.values).find((key) => !['issue', 'cwd'].includes(key));
|
|
69
69
|
if (unexpected) { fail(`list does not accept '--${unexpected}'`); return; }
|
|
70
|
-
finish(listPlatformComments(issue, cwd));
|
|
70
|
+
finish(await listPlatformComments(issue, cwd));
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
if (operation === 'owner') {
|
|
74
74
|
const unexpected = Object.keys(parsed.values).find((key) => key !== 'cwd');
|
|
75
75
|
if (unexpected) { fail(`owner does not accept '--${unexpected}'`); return; }
|
|
76
|
-
finish(checkPlatformCommentOwner(taskRef!, { cwd }));
|
|
76
|
+
finish(await checkPlatformCommentOwner(taskRef!, { cwd }));
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
if (operation === 'backfill') {
|
|
@@ -83,7 +83,7 @@ function platformComment(args: string[] = []): void {
|
|
|
83
83
|
if (typeof agent !== 'string' || !agent) { fail('backfill requires --agent'); return; }
|
|
84
84
|
const normalizedAgent = normalizeAgentToken(agent);
|
|
85
85
|
if (!normalizedAgent) { fail(`invalid --agent '${agent}': ${AGENT_USAGE_HINT}`); return; }
|
|
86
|
-
finish(backfillCompletionComments(taskRef!, { cwd, agent: normalizedAgent }));
|
|
86
|
+
finish(await backfillCompletionComments(taskRef!, { cwd, agent: normalizedAgent }));
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
const kind = parsed.values.kind;
|
|
@@ -101,7 +101,7 @@ function platformComment(args: string[] = []): void {
|
|
|
101
101
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
|
-
finish(syncPlatformComment(taskRef!, {
|
|
104
|
+
finish(await syncPlatformComment(taskRef!, {
|
|
105
105
|
kind: kind as CommentKind,
|
|
106
106
|
agent: normalizedAgent,
|
|
107
107
|
artifact: typeof parsed.values.artifact === 'string' ? parsed.values.artifact : undefined,
|
|
@@ -10,7 +10,7 @@ function fail(message: string): void {
|
|
|
10
10
|
process.exitCode = 1;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function platformContext(args: string[] = []): void {
|
|
13
|
+
async function platformContext(args: string[] = []): Promise<void> {
|
|
14
14
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
15
15
|
if (args[0] !== 'resolve') { fail("operation must be 'resolve'"); return; }
|
|
16
16
|
let cwd = process.cwd();
|
|
@@ -24,7 +24,7 @@ function platformContext(args: string[] = []): void {
|
|
|
24
24
|
seen.add(flag);
|
|
25
25
|
cwd = path.resolve(value);
|
|
26
26
|
}
|
|
27
|
-
const result = resolvePlatformContext({ cwd });
|
|
27
|
+
const result = await resolvePlatformContext({ cwd });
|
|
28
28
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
29
29
|
if (result.status === 'failed') process.exitCode = 1;
|
|
30
30
|
if (result.status === 'blocked') process.exitCode = 2;
|
|
@@ -11,7 +11,7 @@ import type { IssueResult } from '../platform/issues.ts';
|
|
|
11
11
|
|
|
12
12
|
const USAGE = `Usage: agent-infra-internal platform-issue inspect <task-ref> [--cwd <path>]
|
|
13
13
|
agent-infra-internal platform-issue create <task-ref> --agent <agent> [--dry-run] [--cwd <path>]
|
|
14
|
-
agent-infra-internal platform-issue bind <task-ref> --issue <
|
|
14
|
+
agent-infra-internal platform-issue bind <task-ref> --issue <token> --agent <agent> [--dry-run] [--cwd <path>]
|
|
15
15
|
agent-infra-internal platform-issue sync <task-ref> --agent <agent> [--status <suffix|none>] [--assignees current|none] [--milestone initial|specific|none] [--issue-type] [--fields] [--requirements] [--in-labels from-diff|none] [--base <branch>] [--state open|closed] [--close-reason completed|not_planned] [--dry-run] [--cwd <path>]
|
|
16
16
|
`;
|
|
17
17
|
|
|
@@ -59,7 +59,7 @@ function oneOf(values: Record<string, string | boolean>, name: string, allowed:
|
|
|
59
59
|
return value;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function platformIssue(args: string[] = []): void {
|
|
62
|
+
async function platformIssue(args: string[] = []): Promise<void> {
|
|
63
63
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
64
64
|
const operation = args[0];
|
|
65
65
|
if (!operation || !['inspect', 'create', 'bind', 'sync'].includes(operation)) { fail('a valid operation is required'); return; }
|
|
@@ -75,18 +75,17 @@ function platformIssue(args: string[] = []): void {
|
|
|
75
75
|
};
|
|
76
76
|
const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
|
|
77
77
|
if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
|
|
78
|
-
if (operation === 'inspect') { finish(inspectPlatformIssue(taskRef, { cwd })); return; }
|
|
78
|
+
if (operation === 'inspect') { finish(await inspectPlatformIssue(taskRef, { cwd })); return; }
|
|
79
79
|
if (typeof values.agent !== 'string' || !values.agent) { fail(`${operation} requires --agent`); return; }
|
|
80
80
|
const agent = normalizeAgentToken(values.agent);
|
|
81
81
|
if (!agent) { fail(`invalid --agent '${values.agent}': ${AGENT_USAGE_HINT}`); return; }
|
|
82
82
|
values.agent = agent;
|
|
83
83
|
if (operation === 'create') {
|
|
84
|
-
finish(createPlatformIssue(taskRef, { cwd, agent: values.agent, dryRun: values.dryRun === true })); return;
|
|
84
|
+
finish(await createPlatformIssue(taskRef, { cwd, agent: values.agent, dryRun: values.dryRun === true })); return;
|
|
85
85
|
}
|
|
86
86
|
if (operation === 'bind') {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
finish(bindPlatformIssue(taskRef, { cwd, agent: values.agent, issue, dryRun: values.dryRun === true })); return;
|
|
87
|
+
if (typeof values.issue !== 'string' || !values.issue) { fail('bind requires --issue <token>'); return; }
|
|
88
|
+
finish(await bindPlatformIssue(taskRef, { cwd, agent: values.agent, issue: values.issue, dryRun: values.dryRun === true })); return;
|
|
90
89
|
}
|
|
91
90
|
try {
|
|
92
91
|
const assignees = oneOf(values, 'assignees', ['current', 'none']);
|
|
@@ -99,7 +98,7 @@ function platformIssue(args: string[] = []): void {
|
|
|
99
98
|
if (closeReason && state !== 'closed') throw new Error('--close-reason requires --state closed');
|
|
100
99
|
const desiredKeys = ['status', 'assignees', 'milestone', 'issueType', 'fields', 'requirements', 'inLabels', 'state'];
|
|
101
100
|
if (!desiredKeys.some((name) => values[name] !== undefined)) throw new Error('sync requires at least one desired-state option');
|
|
102
|
-
finish(syncPlatformIssue(taskRef, {
|
|
101
|
+
finish(await syncPlatformIssue(taskRef, {
|
|
103
102
|
cwd, agent: values.agent, dryRun: values.dryRun === true,
|
|
104
103
|
status: typeof values.status === 'string' ? values.status : undefined,
|
|
105
104
|
assignees: assignees as 'current' | 'none' | undefined,
|
|
@@ -6,9 +6,9 @@ import { listPrReviews, publishPrReview } from '../platform/pr-review.ts';
|
|
|
6
6
|
import type { PrReviewEvent } from '../platform/pr-review.ts';
|
|
7
7
|
import type { PlatformResult } from '../platform/types.ts';
|
|
8
8
|
|
|
9
|
-
const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <
|
|
10
|
-
agent-infra-internal platform-pr-review list --pr <
|
|
11
|
-
agent-infra-internal platform-pr-review publish --pr <
|
|
9
|
+
const USAGE = `Usage: agent-infra-internal platform-pr-review inspect --pr <token> [--cwd <path>]
|
|
10
|
+
agent-infra-internal platform-pr-review list --pr <token> [--cwd <path>]
|
|
11
|
+
agent-infra-internal platform-pr-review publish --pr <token> --scope <taskId|pr{N}> --round <N> --commit <sha> --event <COMMENT|APPROVE|REQUEST_CHANGES> --body-file <path|-> [--dry-run] [--cwd <path>]
|
|
12
12
|
`;
|
|
13
13
|
|
|
14
14
|
const BOOLEAN_FLAGS = new Set(['--dry-run']);
|
|
@@ -50,7 +50,7 @@ function readBodyFile(value: string, cwd: string): string {
|
|
|
50
50
|
return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function platformPrReview(args: string[] = []): void {
|
|
53
|
+
async function platformPrReview(args: string[] = []): Promise<void> {
|
|
54
54
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
55
55
|
const operation = args[0];
|
|
56
56
|
if (!operation || !['inspect', 'list', 'publish'].includes(operation)) { fail('a valid operation is required'); return; }
|
|
@@ -65,14 +65,14 @@ function platformPrReview(args: string[] = []): void {
|
|
|
65
65
|
};
|
|
66
66
|
const unexpected = Object.keys(values).find((name) => !allowed[operation]!.includes(name));
|
|
67
67
|
if (unexpected) { fail(`${operation} does not accept --${unexpected}`); return; }
|
|
68
|
-
const pr =
|
|
69
|
-
if (
|
|
68
|
+
const pr = values.pr;
|
|
69
|
+
if (typeof pr !== 'string' || !pr) { fail(`${operation} requires --pr <token>`); return; }
|
|
70
70
|
if (operation === 'inspect') {
|
|
71
|
-
finish(inspectPlatformPullRequestByNumber(pr, { cwd }));
|
|
71
|
+
finish(await inspectPlatformPullRequestByNumber(pr, { cwd }));
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
if (operation === 'list') {
|
|
75
|
-
finish(listPrReviews(pr, { cwd }));
|
|
75
|
+
finish(await listPrReviews(pr, { cwd }));
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
const scope = typeof values.scope === 'string' ? values.scope : '';
|
|
@@ -91,7 +91,7 @@ function platformPrReview(args: string[] = []): void {
|
|
|
91
91
|
fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
finish(publishPrReview({
|
|
94
|
+
finish(await publishPrReview({
|
|
95
95
|
cwd,
|
|
96
96
|
prNumber: pr,
|
|
97
97
|
identity: { scope, round, commitSha: commit },
|