@fitlab-ai/agent-infra 0.9.14 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/README.zh-CN.md +10 -0
- package/bin/internal-cli.sh +45 -0
- package/dist/bin/internal-cli.js +93 -30
- package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +9 -4
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +43 -3
- package/dist/lib/defaults.json +103 -103
- package/dist/lib/fs/durable-write.js +39 -0
- package/dist/lib/fs/file-lock.js +111 -0
- package/dist/lib/host-control/audit.js +19 -0
- package/dist/lib/host-control/client.js +142 -0
- package/dist/lib/host-control/command.js +49 -0
- package/dist/lib/host-control/path.js +160 -0
- package/dist/lib/host-control/secure-fs.js +140 -0
- package/dist/lib/host-control/server.js +159 -0
- package/dist/lib/host-control/service.js +112 -0
- package/dist/lib/init.js +11 -2
- package/dist/lib/internal/cli-route-inventory.js +4 -2
- package/dist/lib/internal/codex-lifecycle.js +6 -6
- package/dist/lib/internal/demo-promotion.js +322 -0
- package/dist/lib/internal/demo-transcript.js +454 -0
- package/dist/lib/internal/host-control.js +28 -0
- package/dist/lib/internal/manual-validation.js +331 -0
- package/dist/lib/internal/platform-pr.js +18 -4
- package/dist/lib/internal/release-workflow.js +63 -84
- package/dist/lib/internal/sandbox-control.js +149 -2
- package/dist/lib/internal/task-artifact.js +16 -263
- package/dist/lib/internal/task-create.js +6 -5
- package/dist/lib/internal/task-event.js +37 -37
- package/dist/lib/internal/task-lifecycle.js +2 -2
- package/dist/lib/internal/task-operation-registry.js +101 -4
- package/dist/lib/internal/task-review.js +11 -56
- package/dist/lib/internal/task-validate.js +30 -10
- package/dist/lib/owned-path.js +33 -0
- package/dist/lib/platform/check-status.js +11 -0
- package/dist/lib/platform/comment-safety.js +4 -1
- package/dist/lib/platform/completion-backfill.js +1 -1
- package/dist/lib/platform/github-data.js +241 -0
- package/dist/lib/platform/github-provider.js +15 -20
- package/dist/lib/platform/issue-comments.js +18 -12
- package/dist/lib/platform/issues.js +2 -180
- package/dist/lib/platform/pr-change-report.js +5 -4
- package/dist/lib/platform/pr-checks.js +12 -65
- package/dist/lib/platform/pr-summary.js +117 -33
- package/dist/lib/platform/pull-requests.js +5 -108
- package/dist/lib/platform/snapshots.js +2 -0
- package/dist/lib/platform/task-identities.js +2 -9
- package/dist/lib/platform/verification-sync.js +132 -143
- package/dist/lib/pr-review/evidence-grading.js +4 -8
- package/dist/lib/release/workflow.js +1 -1
- package/dist/lib/sandbox/commands/create.js +7 -2
- package/dist/lib/sandbox/commands/rm.js +19 -1511
- package/dist/lib/sandbox/control/audit.js +203 -0
- package/dist/lib/sandbox/control/client.js +93 -54
- package/dist/lib/sandbox/control/executor.js +129 -65
- package/dist/lib/sandbox/control/finalization-response.js +27 -0
- package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
- package/dist/lib/sandbox/control/lifecycle.js +36 -2
- package/dist/lib/sandbox/control/native-file-lock.js +6 -98
- package/dist/lib/sandbox/control/protocol.js +55 -4
- package/dist/lib/sandbox/control/server.js +518 -127
- package/dist/lib/sandbox/control/state.js +64 -0
- package/dist/lib/sandbox/control/task-workflow.js +74 -0
- package/dist/lib/sandbox/control/workflow-executor.js +89 -0
- package/dist/lib/sandbox/index.js +1 -2
- package/dist/lib/sandbox/recovery.js +28 -4
- package/dist/lib/sandbox/removal.js +822 -0
- package/dist/lib/sandbox/task-cleanup.js +217 -0
- package/dist/lib/sandbox/workspace-identity.js +17 -1
- package/dist/lib/sandbox/workspace-view.js +13 -14
- package/dist/lib/task/activity-intent.js +2 -1
- package/dist/lib/task/activity-log.js +30 -24
- package/dist/lib/task/artifact-command.js +79 -0
- package/dist/lib/task/artifact-lifecycle.js +30 -28
- package/dist/lib/task/artifact-name.js +36 -0
- package/dist/lib/task/artifact-operations.js +29 -289
- package/dist/lib/task/artifact-receipts.js +3 -15
- package/dist/lib/task/artifact-recovery.js +430 -0
- package/dist/lib/task/artifact-repair-intent.js +134 -29
- package/dist/lib/task/artifact-schema.js +6 -14
- package/dist/lib/task/capabilities.js +12 -19
- package/dist/lib/task/codex-orchestration.js +71 -25
- package/dist/lib/task/commit-identity.js +28 -0
- package/dist/lib/task/commit-operation.js +33 -20
- package/dist/lib/task/control-authority.js +403 -6
- package/dist/lib/task/control-recovery.js +140 -0
- package/dist/lib/task/create-service.js +1 -8
- package/dist/lib/task/create.js +62 -9
- package/dist/lib/task/decision-details.js +2 -46
- package/dist/lib/task/delegation-receipts.js +64 -3
- package/dist/lib/task/events.js +275 -22
- package/dist/lib/task/finalization-state.js +9 -0
- package/dist/lib/task/human-override.js +8 -14
- package/dist/lib/task/implementation-inputs.js +3 -3
- package/dist/lib/task/intermediate-cleanup.js +441 -0
- package/dist/lib/task/invalidation.js +18 -65
- package/dist/lib/task/ledger-intents.js +7 -22
- package/dist/lib/task/ledger.js +1 -3
- package/dist/lib/task/lifecycle-recovery.js +549 -0
- package/dist/lib/task/lifecycle.js +31 -4
- package/dist/lib/task/local-artifact-finalization.js +197 -197
- package/dist/lib/task/manual-validation-completion.js +26 -0
- package/dist/lib/task/manual-validation-evidence.js +130 -0
- package/dist/lib/task/manual-validation-receipt.js +105 -0
- package/dist/lib/task/manual-validation-shared.js +40 -0
- package/dist/lib/task/manual-validation-transaction.js +243 -0
- package/dist/lib/task/markdown.js +47 -0
- package/dist/lib/task/orchestration.js +66 -19
- package/dist/lib/task/pr-delivery-fact.js +12 -56
- package/dist/lib/task/qualification-audit.js +20 -34
- package/dist/lib/task/recovery-warning.js +19 -0
- package/dist/lib/task/review-artifacts.js +2 -18
- package/dist/lib/task/review-command.js +26 -0
- package/dist/lib/task/review-finalization.js +175 -216
- package/dist/lib/task/review-fingerprint.js +2 -2
- package/dist/lib/task/sections.js +34 -56
- package/dist/lib/task/short-id.js +15 -7
- package/dist/lib/task/task-execution-lock.js +1 -1
- package/dist/lib/task/verification-engine.js +119 -337
- package/dist/lib/task/verification.js +1 -1
- package/dist/lib/task/workflow-command.js +16 -0
- package/dist/lib/task/workflow-warning-intents.js +0 -16
- package/dist/lib/task/workflow-warnings.js +28 -2
- package/dist/lib/update.js +2 -0
- package/dist/lib/version.js +1 -11
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +10 -4
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +55 -3
- package/lib/fs/durable-write.ts +30 -0
- package/lib/fs/file-lock.ts +113 -0
- package/lib/host-control/audit.ts +22 -0
- package/lib/host-control/client.ts +172 -0
- package/lib/host-control/command.ts +60 -0
- package/lib/host-control/path.ts +167 -0
- package/lib/host-control/secure-fs.ts +135 -0
- package/lib/host-control/server.ts +180 -0
- package/lib/host-control/service.ts +133 -0
- package/lib/init.ts +15 -2
- package/lib/internal/cli-route-inventory.ts +4 -2
- package/lib/internal/codex-lifecycle.ts +6 -6
- package/lib/internal/demo-promotion.ts +354 -0
- package/lib/internal/demo-transcript.ts +419 -0
- package/lib/internal/host-control.ts +28 -0
- package/lib/internal/manual-validation.ts +315 -0
- package/lib/internal/platform-pr.ts +15 -4
- package/lib/internal/release-workflow.ts +74 -82
- package/lib/internal/sandbox-control.ts +162 -1
- package/lib/internal/task-artifact.ts +14 -217
- package/lib/internal/task-create.ts +5 -5
- package/lib/internal/task-event.ts +20 -11
- package/lib/internal/task-lifecycle.ts +4 -3
- package/lib/internal/task-operation-registry.ts +111 -4
- package/lib/internal/task-review.ts +9 -54
- package/lib/internal/task-validate.ts +26 -10
- package/lib/owned-path.ts +26 -0
- package/lib/platform/check-status.ts +9 -0
- package/lib/platform/comment-safety.ts +5 -0
- package/lib/platform/completion-backfill.ts +1 -1
- package/lib/platform/github-data.ts +322 -0
- package/lib/platform/github-provider.ts +15 -20
- package/lib/platform/issue-comments.ts +21 -14
- package/lib/platform/issues.ts +5 -246
- package/lib/platform/pr-change-report.ts +7 -5
- package/lib/platform/pr-checks.ts +13 -77
- package/lib/platform/pr-summary.ts +123 -35
- package/lib/platform/pull-requests.ts +6 -173
- package/lib/platform/snapshots.ts +53 -0
- package/lib/platform/task-identities.ts +3 -14
- package/lib/platform/verification-sync.ts +150 -156
- package/lib/pr-review/evidence-grading.ts +4 -9
- package/lib/release/workflow.ts +3 -3
- package/lib/sandbox/commands/create.ts +7 -6
- package/lib/sandbox/commands/rm.ts +21 -1895
- package/lib/sandbox/control/audit.ts +253 -0
- package/lib/sandbox/control/client.ts +109 -66
- package/lib/sandbox/control/executor.ts +134 -74
- package/lib/sandbox/control/finalization-response.ts +29 -0
- package/lib/sandbox/control/identity-sentinel.ts +137 -0
- package/lib/sandbox/control/lifecycle.ts +45 -3
- package/lib/sandbox/control/native-file-lock.ts +6 -107
- package/lib/sandbox/control/protocol.ts +80 -6
- package/lib/sandbox/control/server.ts +567 -132
- package/lib/sandbox/control/state.ts +86 -0
- package/lib/sandbox/control/task-workflow.ts +95 -0
- package/lib/sandbox/control/workflow-executor.ts +92 -0
- package/lib/sandbox/index.ts +1 -2
- package/lib/sandbox/recovery.ts +28 -5
- package/lib/sandbox/removal.ts +1142 -0
- package/lib/sandbox/task-cleanup.ts +209 -0
- package/lib/sandbox/workspace-identity.ts +19 -3
- package/lib/sandbox/workspace-view.ts +17 -15
- package/lib/task/activity-intent.ts +2 -2
- package/lib/task/activity-log.ts +27 -19
- package/lib/task/artifact-command.ts +85 -0
- package/lib/task/artifact-lifecycle.ts +31 -26
- package/lib/task/artifact-name.ts +55 -0
- package/lib/task/artifact-operations.ts +34 -310
- package/lib/task/artifact-receipts.ts +3 -14
- package/lib/task/artifact-recovery.ts +519 -0
- package/lib/task/artifact-repair-intent.ts +162 -33
- package/lib/task/artifact-schema.ts +5 -34
- package/lib/task/capabilities.ts +13 -22
- package/lib/task/codex-orchestration.ts +85 -24
- package/lib/task/commit-identity.ts +31 -0
- package/lib/task/commit-operation.ts +37 -20
- package/lib/task/control-authority.ts +540 -10
- package/lib/task/control-recovery.ts +186 -0
- package/lib/task/create-service.ts +1 -10
- package/lib/task/create.ts +63 -8
- package/lib/task/decision-details.ts +3 -71
- package/lib/task/delegation-receipts.ts +73 -2
- package/lib/task/events.ts +309 -24
- package/lib/task/finalization-state.ts +11 -0
- package/lib/task/human-override.ts +8 -16
- package/lib/task/implementation-inputs.ts +3 -3
- package/lib/task/intermediate-cleanup.ts +493 -0
- package/lib/task/invalidation.ts +18 -62
- package/lib/task/ledger-intents.ts +7 -24
- package/lib/task/ledger.ts +1 -3
- package/lib/task/lifecycle-recovery.ts +691 -0
- package/lib/task/lifecycle.ts +30 -5
- package/lib/task/local-artifact-finalization.ts +244 -234
- package/lib/task/manual-validation-completion.ts +40 -0
- package/lib/task/manual-validation-evidence.ts +209 -0
- package/lib/task/manual-validation-receipt.ts +156 -0
- package/lib/task/manual-validation-shared.ts +50 -0
- package/lib/task/manual-validation-transaction.ts +304 -0
- package/lib/task/markdown.ts +70 -0
- package/lib/task/orchestration.ts +84 -19
- package/lib/task/pr-delivery-fact.ts +15 -62
- package/lib/task/qualification-audit.ts +22 -33
- package/lib/task/recovery-warning.ts +21 -0
- package/lib/task/review-artifacts.ts +1 -20
- package/lib/task/review-command.ts +24 -0
- package/lib/task/review-finalization.ts +183 -292
- package/lib/task/review-fingerprint.ts +2 -2
- package/lib/task/sections.ts +33 -54
- package/lib/task/short-id.ts +27 -5
- package/lib/task/task-execution-lock.ts +1 -1
- package/lib/task/verification-engine.ts +113 -383
- package/lib/task/verification-types.ts +15 -0
- package/lib/task/verification.ts +1 -1
- package/lib/task/workflow-command.ts +17 -0
- package/lib/task/workflow-warning-intents.ts +0 -13
- package/lib/task/workflow-warnings.ts +21 -2
- package/lib/update.ts +6 -0
- package/lib/version.ts +1 -15
- package/package.json +6 -6
- package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
- package/templates/.agents/rules/create-issue.en.md +1 -1
- package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.en.md +4 -2
- package/templates/.agents/rules/issue-sync.zh-CN.md +4 -3
- package/templates/.agents/rules/local-artifact-repair.en.md +46 -39
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +43 -36
- package/templates/.agents/rules/testing-discipline.en.md +2 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
- package/templates/.agents/scripts/package.json +3 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +6 -6
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -1
- package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/block-task/config/verify.json +1 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -3
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/cancel-task/config/verify.json +1 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +7 -7
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +7 -7
- package/templates/.agents/skills/code-task/config/verify.en.json +1 -1
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +33 -21
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +33 -21
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
- package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/complete-task/config/verify.en.json +2 -2
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +2 -2
- package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +1 -1
- package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/create-pr/config/verify.json +1 -1
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +2 -2
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +2 -2
- package/templates/.agents/skills/create-task/SKILL.en.md +5 -5
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/create-task/config/verify.json +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +8 -8
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/import-issue/config/verify.json +2 -2
- package/templates/.agents/skills/plan-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/plan-task/config/verify.en.json +1 -1
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/release/SKILL.en.md +7 -3
- package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
- package/templates/.agents/skills/restore-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/restore-task/config/verify.json +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -1
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +7 -7
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +6 -6
- package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-code/config/verify.en.json +1 -1
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/review-code/reference/report-template.en.md +12 -12
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +12 -12
- package/templates/.agents/skills/review-plan/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-plan/config/verify.en.json +1 -1
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +7 -7
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +7 -7
- package/templates/.agents/skills/review-pr/config/verify.en.json +1 -1
- package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +3 -3
- package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +3 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +20 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +20 -3
- package/templates/.agents/skills/run-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/test/SKILL.en.md +17 -6
- package/templates/.agents/skills/test/SKILL.zh-CN.md +17 -6
- package/templates/.agents/templates/task.en.md +1 -1
- package/templates/.agents/templates/task.zh-CN.md +1 -1
- package/templates/.claude/commands/import-issue.en.md +1 -1
- package/templates/.claude/commands/import-issue.zh-CN.md +1 -1
- package/templates/.claude/commands/restore-task.en.md +1 -1
- package/templates/.claude/commands/restore-task.zh-CN.md +1 -1
- package/templates/.claude/commands/run-manual-validation.en.md +1 -1
- package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
- package/dist/lib/platform/adapters.js +0 -56
- package/lib/platform/adapters.ts +0 -197
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ResourceIdentity } from '../platform/resource-identity.ts';
|
|
2
|
-
import { isLegacyCompatibilityEnabled, legacyCompatibilityError, VERSION } from '../version.ts';
|
|
3
2
|
import {
|
|
4
3
|
isResourceIdentity,
|
|
5
4
|
parseResourceIdentity,
|
|
@@ -17,14 +16,6 @@ type PrDeliveryIdentity = {
|
|
|
17
16
|
base: { repository: string; ref: string; sha: string };
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
type LegacyPrDeliveryIdentity = {
|
|
21
|
-
repository: string;
|
|
22
|
-
number: number;
|
|
23
|
-
nodeId: string;
|
|
24
|
-
url: string;
|
|
25
|
-
head: { repository: string; ref: string; sha: string };
|
|
26
|
-
base: { repository: string; ref: string; sha: string };
|
|
27
|
-
};
|
|
28
19
|
type CurrentPrDeliveryIdentityInput = {
|
|
29
20
|
resource: ResourceIdentity;
|
|
30
21
|
repository: string;
|
|
@@ -93,10 +84,6 @@ function timestamp(value: unknown, label: string): string {
|
|
|
93
84
|
if (Number.isNaN(Date.parse(result))) throw factError(`${label} must be a valid timestamp`);
|
|
94
85
|
return new Date(result).toISOString();
|
|
95
86
|
}
|
|
96
|
-
function positiveNumber(value: unknown, label: string): number {
|
|
97
|
-
if (!Number.isSafeInteger(value) || (value as number) <= 0) throw factError(`${label} must be a positive integer`);
|
|
98
|
-
return value as number;
|
|
99
|
-
}
|
|
100
87
|
function parseRef(value: unknown, label: string): { repository: string; ref: string; sha: string } {
|
|
101
88
|
if (!isRecord(value)) throw factError(`${label} must be an object`);
|
|
102
89
|
exactKeys(value, ['repository', 'ref', 'sha'], label);
|
|
@@ -115,35 +102,19 @@ function canonicalIdentity(value: unknown): PrDeliveryIdentity {
|
|
|
115
102
|
};
|
|
116
103
|
}
|
|
117
104
|
|
|
118
|
-
function decodeLegacyIdentity(value: unknown): PrDeliveryIdentity {
|
|
119
|
-
if (!isRecord(value)) throw factError('legacy identity must be an object');
|
|
120
|
-
// TODO(compat): Remove the v1 identity decoder before the first stable v1.0.0 release.
|
|
121
|
-
exactKeys(value, ['repository', 'number', 'nodeId', 'url', 'head', 'base'], 'legacy identity');
|
|
122
|
-
const legacy = {
|
|
123
|
-
number: positiveNumber(value.number, 'legacy identity.number'),
|
|
124
|
-
repository: text(value.repository, 'identity.repository'),
|
|
125
|
-
nodeId: text(value.nodeId, 'legacy identity.nodeId'),
|
|
126
|
-
url: text(value.url, 'identity.url'),
|
|
127
|
-
head: parseRef(value.head, 'identity.head'),
|
|
128
|
-
base: parseRef(value.base, 'identity.base')
|
|
129
|
-
} satisfies LegacyPrDeliveryIdentity;
|
|
130
|
-
return {
|
|
131
|
-
resource: { kind: 'number', value: legacy.number },
|
|
132
|
-
repository: legacy.repository,
|
|
133
|
-
url: legacy.url,
|
|
134
|
-
head: legacy.head,
|
|
135
|
-
base: legacy.base
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
105
|
function provenanceForSource(source: PrDeliveryBindingSource): PrDeliveryProvenance { return source === 'created' ? 'create-post' : source === 'reused' ? 'reuse' : source; }
|
|
140
106
|
|
|
141
|
-
function
|
|
107
|
+
function legacyFactError(): PrDeliveryFactError {
|
|
108
|
+
return Object.assign(
|
|
109
|
+
new Error('PLATFORM_IDENTITY_LEGACY_UNSUPPORTED: v1 PR delivery fact is unsupported; use the previous tool version to view this task or migrate its fact to version 2 before using this version'),
|
|
110
|
+
{ code: 'PLATFORM_IDENTITY_LEGACY_UNSUPPORTED' }
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseFact(value: unknown): PrDeliveryFact {
|
|
142
115
|
if (!isRecord(value)) throw factError('fact must be an object');
|
|
143
|
-
if (
|
|
144
|
-
if (value.version
|
|
145
|
-
throw legacyCompatibilityError('v1 PR delivery fact', runtimeVersion);
|
|
146
|
-
}
|
|
116
|
+
if (value.version === 1) throw legacyFactError();
|
|
117
|
+
if (value.version !== 2 || typeof value.state !== 'string') throw factError('version or state is invalid');
|
|
147
118
|
if (value.state === 'unbound') {
|
|
148
119
|
exactKeys(value, ['version', 'state', 'reason'], 'unbound fact');
|
|
149
120
|
if (value.reason !== 'initial') throw factError('unbound reason is invalid');
|
|
@@ -155,24 +126,6 @@ function parseFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
|
|
|
155
126
|
return { version: 2, state: 'skipped', reason: 'explicit', decidedAt: timestamp(value.decidedAt, 'skipped.decidedAt') };
|
|
156
127
|
}
|
|
157
128
|
if (value.state !== 'bound') throw factError('state is invalid');
|
|
158
|
-
if (value.version === 1) {
|
|
159
|
-
// TODO(compat): Remove this v1-to-v2 shape conversion before the first stable v1.0.0 release.
|
|
160
|
-
exactKeys(value, ['version', 'state', 'identity', 'binding', 'provenance'], 'legacy bound fact');
|
|
161
|
-
if (!isRecord(value.binding) || !isRecord(value.provenance)) throw factError('legacy binding or provenance is invalid');
|
|
162
|
-
exactKeys(value.binding, ['status', 'source', 'verifiedAt', 'issueNumber', 'remoteState', 'mergedAt', 'mergeCommitSha'], 'legacy binding');
|
|
163
|
-
const issueNumber = value.binding.issueNumber === null ? null : positiveNumber(value.binding.issueNumber, 'legacy binding.issueNumber');
|
|
164
|
-
return parseFact({
|
|
165
|
-
version: 2,
|
|
166
|
-
state: 'bound',
|
|
167
|
-
identity: decodeLegacyIdentity(value.identity),
|
|
168
|
-
binding: {
|
|
169
|
-
status: 'verified', source: value.binding.source, verifiedAt: timestamp(value.binding.verifiedAt, 'binding.verifiedAt'),
|
|
170
|
-
issueIdentity: issueNumber === null ? null : { kind: 'number', value: issueNumber }, remoteState: value.binding.remoteState,
|
|
171
|
-
mergedAt: value.binding.mergedAt === null ? null : timestamp(value.binding.mergedAt, 'binding.mergedAt'), mergeCommitSha: nullableText(value.binding.mergeCommitSha, 'binding.mergeCommitSha')
|
|
172
|
-
},
|
|
173
|
-
provenance: value.provenance
|
|
174
|
-
}, runtimeVersion);
|
|
175
|
-
}
|
|
176
129
|
exactKeys(value, ['version', 'state', 'identity', 'binding', 'provenance'], 'bound fact');
|
|
177
130
|
if (!isRecord(value.binding) || !isRecord(value.provenance)) throw factError('binding or provenance is invalid');
|
|
178
131
|
exactKeys(value.binding, ['status', 'source', 'verifiedAt', 'issueIdentity', 'remoteState', 'mergedAt', 'mergeCommitSha'], 'binding');
|
|
@@ -195,19 +148,19 @@ function parseFact(value: unknown, runtimeVersion = VERSION): PrDeliveryFact {
|
|
|
195
148
|
};
|
|
196
149
|
}
|
|
197
150
|
|
|
198
|
-
function decodePrDeliveryFact(value: unknown,
|
|
151
|
+
function decodePrDeliveryFact(value: unknown, _runtimeVersion?: string): PrDeliveryFact {
|
|
199
152
|
if (typeof value === 'string') {
|
|
200
153
|
let decoded: unknown;
|
|
201
154
|
try { decoded = JSON.parse(value); }
|
|
202
155
|
catch { throw factError('value is not valid JSON'); }
|
|
203
|
-
return parseFact(decoded
|
|
156
|
+
return parseFact(decoded);
|
|
204
157
|
}
|
|
205
|
-
return parseFact(value
|
|
158
|
+
return parseFact(value);
|
|
206
159
|
}
|
|
207
160
|
function encodePrDeliveryFact(fact: PrDeliveryFact): string { return JSON.stringify(parseFact(fact)); }
|
|
208
|
-
function readPrDeliveryFact(metadata: Record<string, unknown>,
|
|
161
|
+
function readPrDeliveryFact(metadata: Record<string, unknown>, _runtimeVersion?: string): PrDeliveryFactReadResult {
|
|
209
162
|
if (!Object.hasOwn(metadata, PR_DELIVERY_FACT_KEY) || metadata[PR_DELIVERY_FACT_KEY] === '') return { status: 'missing', fact: null };
|
|
210
|
-
try { return { status: 'valid', fact: decodePrDeliveryFact(metadata[PR_DELIVERY_FACT_KEY]
|
|
163
|
+
try { return { status: 'valid', fact: decodePrDeliveryFact(metadata[PR_DELIVERY_FACT_KEY]) }; }
|
|
211
164
|
catch (error) { return { status: 'invalid', fact: null, error: asFactError(error) }; }
|
|
212
165
|
}
|
|
213
166
|
function buildUnboundFact(): PrDeliveryFact { return { version: 2, state: 'unbound', reason: 'initial' }; }
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
|
|
3
|
+
import { parseArtifactName } from './artifact-name.ts';
|
|
3
4
|
import { parseTypedTaskFrontmatter } from './frontmatter.ts';
|
|
4
|
-
import { parseTable } from './sections.ts';
|
|
5
|
+
import { findSectionRange, parseTable } from './sections.ts';
|
|
6
|
+
import { scanVisibleMarkdown } from './markdown.ts';
|
|
5
7
|
|
|
6
8
|
const TASK_CONSTRAINT_HEADINGS = ['约束', 'Constraints'] as const;
|
|
7
9
|
const TASK_CANDIDATE_HEADINGS = ['候选与否决方案', 'Candidate and Rejected Options', 'Candidates and Rejected Options', 'Candidates and Rejected Alternatives'] as const;
|
|
@@ -170,21 +172,9 @@ function taskInputDigest(qualification: Pick<TaskQualification, 'constraints' |
|
|
|
170
172
|
return digest(canonicalTaskInput(qualification));
|
|
171
173
|
}
|
|
172
174
|
|
|
173
|
-
function sectionBody(content: string, aliases: readonly string[], level = 2): string | null {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
const match = new RegExp(`^${marker}\\s+(${heading})\\s*$`, 'm').exec(content);
|
|
177
|
-
if (!match) return null;
|
|
178
|
-
const rest = content.slice((match.index ?? 0) + match[0].length);
|
|
179
|
-
const end = rest.search(new RegExp(`^#{2,${level}}\\s+`, 'm'));
|
|
180
|
-
return rest.slice(0, end < 0 ? rest.length : end);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function stripSection(content: string, aliases: readonly string[]): string {
|
|
184
|
-
const body = sectionBody(content, aliases);
|
|
185
|
-
if (body === null) return normalizeText(content);
|
|
186
|
-
const heading = aliases.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
|
|
187
|
-
return normalizeText(content.replace(new RegExp(`^##\\s+(?:${heading})\\s*$[\\s\\S]*?(?=^##\\s+|(?![\\s\\S]))`, 'm'), ''));
|
|
175
|
+
function sectionBody(content: string, aliases: readonly string[], level: 2 | 3 = 2): string | null {
|
|
176
|
+
const section = findSectionRange(content, aliases, level);
|
|
177
|
+
return section ? content.slice(section.bodyStart, section.end) : null;
|
|
188
178
|
}
|
|
189
179
|
|
|
190
180
|
function stripFrontmatter(content: string): string {
|
|
@@ -218,7 +208,7 @@ function nonConstraintInputDigest(content: string): string {
|
|
|
218
208
|
['返工意图', 'Rework Intents'],
|
|
219
209
|
CONFIRMATION_HEADINGS,
|
|
220
210
|
['完成检查清单', 'Completion Checklist']
|
|
221
|
-
].reduce((value, aliases) =>
|
|
211
|
+
].reduce((value, aliases) => stripSectionAtLevel(value, aliases, 2), projection);
|
|
222
212
|
return digest(projection);
|
|
223
213
|
}
|
|
224
214
|
|
|
@@ -231,12 +221,9 @@ function stripTaskInputSection(content: string, aliases: readonly string[]): str
|
|
|
231
221
|
return stripSectionAtLevel(result, aliases, 2);
|
|
232
222
|
}
|
|
233
223
|
|
|
234
|
-
function stripSectionAtLevel(content: string, aliases: readonly string[], level:
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
const heading = aliases.map((value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
|
|
238
|
-
const marker = '#'.repeat(level);
|
|
239
|
-
return normalizeText(content.replace(new RegExp(`^${marker}\\s+(?:${heading})\\s*$[\\s\\S]*?(?=^#{2,${level}}\\s+|(?![\\s\\S]))`, 'm'), ''));
|
|
224
|
+
function stripSectionAtLevel(content: string, aliases: readonly string[], level: 2 | 3): string {
|
|
225
|
+
const section = findSectionRange(content, aliases, level);
|
|
226
|
+
return normalizeText(section ? content.slice(0, section.start) + content.slice(section.end) : content);
|
|
240
227
|
}
|
|
241
228
|
|
|
242
229
|
function parseTaskQualification(content: string): { ok: true; qualification: TaskQualification } | { ok: false; code: string; message: string } {
|
|
@@ -246,12 +233,14 @@ function parseTaskQualification(content: string): { ok: true; qualification: Tas
|
|
|
246
233
|
const hasCandidateHeading = candidateBody !== null;
|
|
247
234
|
if ((!hasConstraintHeading && !hasCandidateHeading)
|
|
248
235
|
|| (hasConstraintHeading && hasCandidateHeading
|
|
249
|
-
&&
|
|
236
|
+
&& !scanVisibleMarkdown(constraintBody!).lines.some((line) => line.text.trim().startsWith('|'))
|
|
237
|
+
&& !scanVisibleMarkdown(candidateBody!).lines.some((line) => line.text.trim().startsWith('|')))) {
|
|
250
238
|
return { ok: true, qualification: { present: false, constraints: [], candidates: [], constraintDigest: digest([]), taskInputDigest: digest({ constraints: [], candidates: [] }), nonConstraintInputDigest: nonConstraintInputDigest(content) } };
|
|
251
239
|
}
|
|
252
240
|
if (!hasConstraintHeading || !hasCandidateHeading) {
|
|
253
|
-
const
|
|
254
|
-
|
|
241
|
+
const visible = scanVisibleMarkdown(content).lines.map((line) => line.text).join('\n');
|
|
242
|
+
const hasCanonicalTable = new RegExp(`\\|\\s*${CONSTRAINT_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(visible)
|
|
243
|
+
|| new RegExp(`\\|\\s*${CANDIDATE_COLUMNS.join('\\s*\\|\\s*')}\\s*\\|`).test(visible);
|
|
255
244
|
if (hasCanonicalTable) return { ok: false, code: 'QUALIFICATION_TASK_CONTRACT_INVALID', message: 'task qualification requires both constraints and candidates sections' };
|
|
256
245
|
return { ok: true, qualification: { present: false, constraints: [], candidates: [], constraintDigest: digest([]), taskInputDigest: digest({ constraints: [], candidates: [] }), nonConstraintInputDigest: nonConstraintInputDigest(content) } };
|
|
257
246
|
}
|
|
@@ -315,10 +304,10 @@ function parseAuditTable(content: string, heading: (typeof AUDIT_SUBSECTIONS)[nu
|
|
|
315
304
|
return table?.rows.map((row) => ({ ...row.values })) ?? null;
|
|
316
305
|
}
|
|
317
306
|
|
|
318
|
-
function
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
307
|
+
function parseAuditArtifactName(value: string): { family: ArtifactFamily; round: number } | null {
|
|
308
|
+
const identity = parseArtifactName(value);
|
|
309
|
+
return identity && ARTIFACT_FAMILIES.includes(identity.family as ArtifactFamily)
|
|
310
|
+
? { family: identity.family as ArtifactFamily, round: identity.round } : null;
|
|
322
311
|
}
|
|
323
312
|
|
|
324
313
|
function upstreamArtifactDigest(rows: readonly UpstreamRelation[]): string {
|
|
@@ -327,7 +316,7 @@ function upstreamArtifactDigest(rows: readonly UpstreamRelation[]): string {
|
|
|
327
316
|
}
|
|
328
317
|
|
|
329
318
|
function validateUpstreamRelation(row: UpstreamRelation): void {
|
|
330
|
-
const identity =
|
|
319
|
+
const identity = parseAuditArtifactName(row.upstreamArtifact);
|
|
331
320
|
if (!ARTIFACT_FAMILIES.includes(row.upstreamFamily) || !identity || identity.family !== row.upstreamFamily
|
|
332
321
|
|| identity.round !== row.upstreamRound || !Number.isSafeInteger(row.upstreamRound)
|
|
333
322
|
|| !/^[a-f0-9]{64}$/i.test(row.upstreamSha256) || !RELATIONS.includes(row.relation)) {
|
|
@@ -368,7 +357,7 @@ function expectedQualificationRelations(
|
|
|
368
357
|
const inputName = family === 'code' ? frontmatter.code_input_artifact : family.startsWith('review-') ? frontmatter.review_input_artifact : '';
|
|
369
358
|
const inputSha256 = family === 'code' ? frontmatter.code_input_sha256 : family.startsWith('review-') ? frontmatter.review_input_sha256 : '';
|
|
370
359
|
if (typeof inputName !== 'string' || !inputName || typeof inputSha256 !== 'string' || !inputSha256) return { ok: true, relations: undefined };
|
|
371
|
-
const identity =
|
|
360
|
+
const identity = parseAuditArtifactName(inputName);
|
|
372
361
|
if (!identity) return { ok: false, code: 'QUALIFICATION_STARTED_INPUT_INVALID', message: `started input '${inputName}' is not canonical` };
|
|
373
362
|
const relation: UpstreamRelation = {
|
|
374
363
|
upstreamFamily: identity.family, upstreamArtifact: inputName, upstreamRound: identity.round,
|
|
@@ -507,7 +496,7 @@ function validateQualificationAudit(
|
|
|
507
496
|
|| upstreamArtifactDigest(options.expectedUpstreamRelations) !== upstreamArtifactDigest(audit.audit.upstreamRelations)
|
|
508
497
|
)) return { ok: false, code: 'QUALIFICATION_UPSTREAM_RELATION_MISMATCH', message: 'qualification audit upstream relations do not match the started artifact inputs' };
|
|
509
498
|
if (options.family && options.artifact) {
|
|
510
|
-
const identity =
|
|
499
|
+
const identity = parseAuditArtifactName(options.artifact);
|
|
511
500
|
if (!identity || identity.family !== options.family) return { ok: false, code: 'QUALIFICATION_ARTIFACT_IDENTITY_INVALID', message: `artifact '${options.artifact}' is not canonical for '${options.family}'` };
|
|
512
501
|
}
|
|
513
502
|
return { ok: true, qualification: task.qualification, audit: audit.audit };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type RecoveryWarning = Readonly<{ code: string; message: string; action: string }>;
|
|
2
|
+
|
|
3
|
+
function warningText(value: unknown): value is string {
|
|
4
|
+
return typeof value === 'string' && value.length > 0 && value.trim() === value && !/[\r\n]/u.test(value);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function isRecoveryWarning(value: unknown): value is RecoveryWarning {
|
|
8
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
9
|
+
const warning = value as Record<string, unknown>;
|
|
10
|
+
return Object.keys(warning).sort().join(',') === 'action,code,message'
|
|
11
|
+
&& warningText(warning.code)
|
|
12
|
+
&& warningText(warning.message)
|
|
13
|
+
&& warningText(warning.action);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function sameRecoveryWarning(left: unknown, right: unknown): boolean {
|
|
17
|
+
return isRecoveryWarning(left) && isRecoveryWarning(right)
|
|
18
|
+
&& left.code === right.code
|
|
19
|
+
&& left.message === right.message
|
|
20
|
+
&& left.action === right.action;
|
|
21
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import { scanVisibleMarkdown } from './
|
|
4
|
+
import { scanVisibleMarkdown } from './markdown.ts';
|
|
5
5
|
|
|
6
6
|
type ReviewFindingCounts = {
|
|
7
7
|
blocker: number;
|
|
@@ -53,23 +53,6 @@ function escapeRegExp(value: string): string {
|
|
|
53
53
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function maxRound(entries: string[], stem: string): number {
|
|
57
|
-
let max = 0;
|
|
58
|
-
for (const entry of entries) {
|
|
59
|
-
if (entry === `${stem}.md`) {
|
|
60
|
-
max = Math.max(max, 1);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
const match = entry.match(new RegExp(`^${escapeRegExp(stem)}-r(\\d+)\\.md$`));
|
|
64
|
-
if (match) max = Math.max(max, Number(match[1]));
|
|
65
|
-
}
|
|
66
|
-
return max;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function artifactName(stem: string, round: number): string {
|
|
70
|
-
return round === 1 ? `${stem}.md` : `${stem}-r${round}.md`;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
56
|
function normalizeVerdict(raw: unknown): ReviewVerdict | '' {
|
|
74
57
|
const value = String(raw).trim().toLowerCase();
|
|
75
58
|
if (value === '通过' || value === 'approved') return 'Approved';
|
|
@@ -260,12 +243,10 @@ function parseVerdict(reviewPath: string): PathVerdictResult {
|
|
|
260
243
|
}
|
|
261
244
|
|
|
262
245
|
export {
|
|
263
|
-
artifactName,
|
|
264
246
|
equalCounts,
|
|
265
247
|
escapeRegExp,
|
|
266
248
|
extractSection,
|
|
267
249
|
finalizeReviewSummaryContent,
|
|
268
|
-
maxRound,
|
|
269
250
|
normalizeVerdict,
|
|
270
251
|
parseReviewSummary,
|
|
271
252
|
parseVerdict,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReviewFinalizationRequest } from './review-finalization.ts';
|
|
2
|
+
|
|
3
|
+
export function parseReviewCommand(args: readonly string[]): ReviewFinalizationRequest & {
|
|
4
|
+
overrideTicket?: string; overrideTarget?: string; overrideScope?: string;
|
|
5
|
+
} {
|
|
6
|
+
if (!args[0] || args[1] !== 'finalize-summary') throw new Error('task ref and finalize-summary are required');
|
|
7
|
+
const values: Record<string, string | boolean> = {};
|
|
8
|
+
const flags = {
|
|
9
|
+
'--stage': 'stage', '--artifact': 'artifact', '--orchestrated': 'orchestrated', '--dry-run': 'dryRun',
|
|
10
|
+
'--recovery-id': 'recoveryId',
|
|
11
|
+
'--override-ticket': 'overrideTicket', '--override-target': 'overrideTarget', '--override-scope': 'overrideScope'
|
|
12
|
+
} as const;
|
|
13
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
14
|
+
const flag = args[index]!;
|
|
15
|
+
if (!Object.hasOwn(flags, flag)) throw new Error(`unknown option '${flag}'`);
|
|
16
|
+
const key = flags[flag as keyof typeof flags];
|
|
17
|
+
if (Object.hasOwn(values, key)) throw new Error(`duplicate option '${flag}'`);
|
|
18
|
+
const value = flag === '--orchestrated' || flag === '--dry-run' ? true : args[++index];
|
|
19
|
+
if (!value || typeof value === 'string' && value.startsWith('--')) throw new Error(`option '${flag}' requires a value`);
|
|
20
|
+
values[key] = value;
|
|
21
|
+
}
|
|
22
|
+
if (!values.stage || !values.artifact) throw new Error("options '--stage' and '--artifact' are required");
|
|
23
|
+
return { taskRef: args[0], ...values } as ReturnType<typeof parseReviewCommand>;
|
|
24
|
+
}
|