@fitlab-ai/agent-infra 0.9.0 → 0.9.2
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 +22 -5
- package/README.zh-CN.md +21 -5
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +20 -0
- package/dist/lib/agent-client.js +163 -0
- package/dist/lib/agent-clients/adapter.js +294 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +62 -0
- package/dist/lib/agent-clients/adapters/codex-sandbox.js +210 -0
- package/dist/lib/agent-clients/adapters/codex.js +54 -0
- package/dist/lib/agent-clients/adapters/gemini-cli.js +64 -0
- package/dist/lib/agent-clients/adapters/index.js +20 -0
- package/dist/lib/agent-clients/adapters/opencode.js +64 -0
- package/dist/lib/agent-clients/config.js +177 -0
- package/dist/lib/agent-clients/custom-tuis.js +99 -0
- package/dist/lib/agent-clients/invocation.js +9 -0
- package/dist/lib/agent-clients/next-steps.js +38 -0
- package/dist/lib/agent-clients/project-assets.js +45 -0
- package/dist/lib/agent-clients/reconcile.js +235 -0
- package/dist/lib/agent-clients/registry.js +72 -0
- package/dist/lib/agent-clients/schema.js +57 -0
- package/dist/lib/agent-clients/types.js +29 -0
- package/dist/lib/builtin-tuis.js +9 -14
- package/dist/lib/defaults.json +85 -73
- package/dist/lib/git/review-snapshot.js +25 -10
- package/dist/lib/git/reviewed-commit-equivalence.js +110 -0
- package/dist/lib/init.js +47 -91
- package/dist/lib/internal/agent-client.js +117 -0
- package/dist/lib/internal/git-workflow.js +1 -1
- package/dist/lib/internal/platform-release-notes.js +53 -0
- package/dist/lib/internal/release-workflow.js +175 -17
- package/dist/lib/internal/task-orchestration.js +151 -0
- package/dist/lib/internal/task-review.js +65 -0
- package/dist/lib/merge.js +2 -1
- package/dist/lib/platform/adapters.js +38 -1
- package/dist/lib/platform/change-request-git-evidence.js +113 -0
- package/dist/lib/platform/github-release-notes.js +96 -0
- package/dist/lib/platform/issues.js +4 -2
- package/dist/lib/platform/merged-pr-equivalence.js +84 -0
- package/dist/lib/platform/pr-checks.js +43 -15
- package/dist/lib/platform/pull-requests.js +113 -7
- package/dist/lib/platform/release-notes.js +143 -0
- package/dist/lib/platform/releases.js +1 -1
- package/dist/lib/platform/verification-required.js +31 -9
- package/dist/lib/prompt.js +15 -3
- package/dist/lib/release/channels.js +4 -1
- package/dist/lib/release/workflow.js +4 -2
- package/dist/lib/remove-dir.js +25 -0
- package/dist/lib/run/tui.js +8 -2
- package/dist/lib/sandbox/agent-client-reconciler.js +234 -0
- package/dist/lib/sandbox/build-proxy.js +63 -0
- package/dist/lib/sandbox/clipboard/linux.js +2 -1
- package/dist/lib/sandbox/commands/create.js +133 -189
- package/dist/lib/sandbox/commands/enter.js +17 -1
- package/dist/lib/sandbox/commands/prune.js +2 -2
- package/dist/lib/sandbox/commands/rebuild.js +24 -7
- package/dist/lib/sandbox/commands/rm.js +3 -2
- package/dist/lib/sandbox/config.js +21 -4
- package/dist/lib/sandbox/constants.js +3 -0
- package/dist/lib/sandbox/dockerfile.js +2 -1
- package/dist/lib/sandbox/image-build.js +2 -1
- package/dist/lib/sandbox/managed-fs.js +10 -5
- package/dist/lib/sandbox/recovery.js +52 -36
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
- package/dist/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/dist/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/dist/lib/sandbox/shell.js +3 -2
- package/dist/lib/sandbox/tool-types.js +8 -0
- package/dist/lib/sandbox/tools.js +2 -126
- package/dist/lib/task/artifact-lifecycle.js +1 -49
- package/dist/lib/task/commands/decisions.js +50 -20
- package/dist/lib/task/commands/issue-body.js +10 -5
- package/dist/lib/task/delegation-receipts.js +107 -0
- package/dist/lib/task/events.js +101 -2
- package/dist/lib/task/issue-form.js +2 -0
- package/dist/lib/task/orchestration.js +420 -0
- package/dist/lib/task/review-artifacts.js +143 -59
- package/dist/lib/task/review-finalization.js +166 -0
- package/dist/lib/task/review-fingerprint.js +13 -0
- package/dist/lib/task/verification-checks.js +2 -1
- package/dist/lib/task/verification-engine.js +168 -23
- package/dist/lib/task/verification-review.js +1 -1
- package/dist/lib/task/verification.js +4 -2
- package/dist/lib/task/workspace-snapshot.js +34 -0
- package/dist/lib/update.js +42 -161
- package/lib/agent-client.ts +214 -0
- package/lib/agent-clients/adapter.ts +461 -0
- package/lib/agent-clients/adapters/claude-code.ts +70 -0
- package/lib/agent-clients/adapters/codex-sandbox.ts +245 -0
- package/lib/agent-clients/adapters/codex.ts +58 -0
- package/lib/agent-clients/adapters/gemini-cli.ts +65 -0
- package/lib/agent-clients/adapters/index.ts +27 -0
- package/lib/agent-clients/adapters/opencode.ts +66 -0
- package/lib/agent-clients/config.ts +278 -0
- package/lib/agent-clients/custom-tuis.ts +149 -0
- package/lib/agent-clients/invocation.ts +19 -0
- package/lib/agent-clients/next-steps.ts +72 -0
- package/lib/agent-clients/project-assets.ts +96 -0
- package/lib/agent-clients/reconcile.ts +324 -0
- package/lib/agent-clients/registry.ts +144 -0
- package/lib/agent-clients/schema.ts +62 -0
- package/lib/agent-clients/types.ts +78 -0
- package/lib/benchmark/schemas/v1.0.0/case-manifest.schema.json +120 -0
- package/lib/benchmark/schemas/v1.0.0/common.schema.json +109 -0
- package/lib/benchmark/schemas/v1.0.0/grader-result.schema.json +160 -0
- package/lib/benchmark/schemas/v1.0.0/run-manifest.schema.json +122 -0
- package/lib/benchmark/schemas/v1.0.0/subject.schema.json +227 -0
- package/lib/builtin-tuis.ts +16 -15
- package/lib/defaults.json +24 -12
- package/lib/git/review-snapshot.ts +39 -9
- package/lib/git/reviewed-commit-equivalence.ts +135 -0
- package/lib/init.ts +53 -121
- package/lib/internal/agent-client.ts +131 -0
- package/lib/internal/git-workflow.ts +1 -1
- package/lib/internal/platform-release-notes.ts +55 -0
- package/lib/internal/release-workflow.ts +172 -18
- package/lib/internal/task-orchestration.ts +132 -0
- package/lib/internal/task-review.ts +65 -0
- package/lib/merge.ts +2 -1
- package/lib/platform/adapters.ts +142 -3
- package/lib/platform/change-request-git-evidence.ts +159 -0
- package/lib/platform/github-release-notes.ts +132 -0
- package/lib/platform/issues.ts +6 -4
- package/lib/platform/merged-pr-equivalence.ts +107 -0
- package/lib/platform/pr-checks.ts +57 -28
- package/lib/platform/pull-requests.ts +140 -25
- package/lib/platform/release-notes.ts +167 -0
- package/lib/platform/releases.ts +1 -1
- package/lib/platform/verification-required.ts +37 -9
- package/lib/prompt.ts +16 -3
- package/lib/release/channels.ts +4 -1
- package/lib/release/workflow.ts +4 -3
- package/lib/remove-dir.ts +28 -0
- package/lib/run/tui.ts +9 -1
- package/lib/sandbox/agent-client-reconciler.ts +378 -0
- package/lib/sandbox/build-proxy.ts +94 -0
- package/lib/sandbox/clipboard/linux.ts +2 -1
- package/lib/sandbox/commands/create.ts +188 -203
- package/lib/sandbox/commands/enter.ts +23 -1
- package/lib/sandbox/commands/prune.ts +2 -2
- package/lib/sandbox/commands/rebuild.ts +29 -7
- package/lib/sandbox/commands/rm.ts +3 -2
- package/lib/sandbox/config.ts +31 -4
- package/lib/sandbox/constants.ts +6 -0
- package/lib/sandbox/dockerfile.ts +2 -1
- package/lib/sandbox/image-build.ts +4 -1
- package/lib/sandbox/managed-fs.ts +18 -5
- package/lib/sandbox/recovery.ts +98 -67
- package/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
- package/lib/sandbox/runtimes/base.dockerfile +8 -1
- package/lib/sandbox/runtimes/java17.dockerfile +8 -1
- package/lib/sandbox/runtimes/java21.dockerfile +8 -1
- package/lib/sandbox/runtimes/node20.dockerfile +8 -1
- package/lib/sandbox/runtimes/node22.dockerfile +8 -1
- package/lib/sandbox/runtimes/python3.dockerfile +8 -1
- package/lib/sandbox/shell.ts +4 -2
- package/lib/sandbox/tool-types.ts +143 -0
- package/lib/sandbox/tools.ts +5 -157
- package/lib/task/artifact-lifecycle.ts +1 -38
- package/lib/task/commands/decisions.ts +53 -20
- package/lib/task/commands/issue-body.ts +10 -5
- package/lib/task/delegation-receipts.ts +170 -0
- package/lib/task/events.ts +111 -3
- package/lib/task/issue-form.ts +4 -0
- package/lib/task/orchestration.ts +543 -0
- package/lib/task/review-artifacts.ts +201 -69
- package/lib/task/review-finalization.ts +275 -0
- package/lib/task/review-fingerprint.ts +15 -1
- package/lib/task/verification-checks.ts +2 -1
- package/lib/task/verification-engine.ts +190 -25
- package/lib/task/verification-review.ts +2 -0
- package/lib/task/verification.ts +6 -3
- package/lib/task/workspace-snapshot.ts +36 -0
- package/lib/update.ts +48 -184
- package/package.json +2 -2
- package/templates/.agents/README.en.md +21 -20
- package/templates/.agents/README.zh-CN.md +21 -20
- package/templates/.agents/hooks/lifecycle-delegation.js +64 -0
- package/templates/.agents/rules/README.en.md +2 -0
- package/templates/.agents/rules/README.zh-CN.md +2 -0
- package/templates/.agents/rules/commit-and-pr.en.md +1 -0
- package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -0
- package/templates/.agents/rules/human-decision-context.en.md +14 -12
- package/templates/.agents/rules/human-decision-context.zh-CN.md +14 -12
- package/templates/.agents/rules/lifecycle-orchestration.en.md +21 -0
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +21 -0
- package/templates/.agents/rules/next-step-output.en.md +16 -0
- package/templates/.agents/rules/next-step-output.zh-CN.md +16 -0
- package/templates/.agents/rules/no-mid-flow-questions.en.md +2 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +2 -0
- package/templates/.agents/rules/release-commands.en.md +2 -2
- package/templates/.agents/rules/release-commands.github.en.md +15 -39
- package/templates/.agents/rules/release-commands.github.zh-CN.md +14 -38
- package/templates/.agents/rules/release-commands.zh-CN.md +2 -2
- package/templates/.agents/rules/review-handshake.en.md +4 -3
- package/templates/.agents/rules/review-handshake.zh-CN.md +4 -3
- package/templates/.agents/rules/review-method.en.md +113 -0
- package/templates/.agents/rules/review-method.zh-CN.md +98 -0
- package/templates/.agents/rules/testing-discipline.en.md +20 -2
- package/templates/.agents/rules/testing-discipline.zh-CN.md +20 -2
- package/templates/.agents/skills/analyze-task/SKILL.en.md +9 -6
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +9 -6
- package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/cancel-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/check-task/SKILL.en.md +16 -16
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -16
- package/templates/.agents/skills/close-codescan/SKILL.en.md +4 -4
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +4 -4
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/code-task/reference/fix-mode.en.md +14 -16
- package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +14 -16
- package/templates/.agents/skills/code-task/reference/output-template.en.md +3 -3
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/SKILL.en.md +11 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +11 -1
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +24 -28
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +24 -28
- 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 +0 -1
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +10 -10
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +10 -10
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +3 -3
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +3 -3
- package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -38
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +16 -37
- package/templates/.agents/skills/create-task/SKILL.en.md +15 -11
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +15 -11
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +29 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +29 -0
- package/templates/.agents/skills/import-codescan/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/init-labels/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.en.md +4 -4
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/release/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -2
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -3
- package/templates/.agents/skills/review-analysis/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +51 -5
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +52 -6
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +25 -22
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +25 -22
- package/templates/.agents/skills/review-code/SKILL.en.md +28 -8
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +28 -8
- package/templates/.agents/skills/review-code/config/verify.en.json +7 -0
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +7 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/concurrency-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.en.md +27 -0
- package/templates/.agents/skills/review-code/reference/cross-platform-risks.zh-CN.md +27 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.en.md +13 -0
- package/templates/.agents/skills/review-code/reference/documentation-antipatterns.zh-CN.md +13 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +22 -24
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +22 -24
- package/templates/.agents/skills/review-code/reference/report-template.en.md +54 -7
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +54 -7
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +29 -24
- package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +29 -24
- package/templates/.agents/skills/review-code/reference/security-risks.en.md +25 -0
- package/templates/.agents/skills/review-code/reference/security-risks.zh-CN.md +25 -0
- package/templates/.agents/skills/review-plan/SKILL.en.md +13 -2
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -3
- package/templates/.agents/skills/review-plan/config/verify.en.json +6 -0
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +6 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +13 -15
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +13 -15
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +61 -5
- package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +61 -5
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +21 -24
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +21 -24
- package/templates/.agents/skills/run-task/SKILL.en.md +22 -0
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +22 -0
- package/templates/.agents/skills/run-task/config/verify.en.json +9 -0
- package/templates/.agents/skills/run-task/config/verify.zh-CN.json +9 -0
- package/templates/.agents/skills/test/SKILL.en.md +4 -4
- package/templates/.agents/skills/test/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.en.md +4 -4
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +5 -5
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +647 -203
- package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +4 -4
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/watch-pr/SKILL.en.md +8 -8
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +8 -8
- package/templates/.agents/templates/task.en.md +18 -0
- package/templates/.agents/templates/task.zh-CN.md +18 -0
- package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +6 -0
- package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +6 -0
- package/templates/.claude/commands/run-task.en.md +8 -0
- package/templates/.claude/commands/run-task.zh-CN.md +8 -0
- package/templates/.claude/settings.json +24 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +3 -0
- package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +3 -0
- package/templates/.gemini/commands/_project_/run-task.en.toml +8 -0
- package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +8 -0
- package/templates/.opencode/commands/run-task.en.md +11 -0
- package/templates/.opencode/commands/run-task.zh-CN.md +11 -0
|
@@ -7,16 +7,23 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
extractReviewBaseline,
|
|
10
|
+
extractReviewDiffBase,
|
|
10
11
|
extractReviewDiffFingerprint,
|
|
11
12
|
extractReviewedSnapshotTree,
|
|
12
13
|
findAuthoritativeReviewCodeArtifact,
|
|
14
|
+
loadPostReviewConfig,
|
|
13
15
|
parseReviewVerdict,
|
|
14
16
|
resolvePostReviewGlobs
|
|
15
17
|
} from "./verification-review.ts";
|
|
16
18
|
import { check as checkPlatformSync } from "../platform/verification-sync.ts";
|
|
17
19
|
import { check as checkRequiredChecks } from "../platform/verification-required.ts";
|
|
20
|
+
import { inspectPlatformPullRequest } from "../platform/pull-requests.ts";
|
|
21
|
+
import { resolveMaterializedReviewedHeadRelation } from "../platform/change-request-git-evidence.ts";
|
|
22
|
+
import { resolveReviewedHeadRelation } from "../platform/merged-pr-equivalence.ts";
|
|
23
|
+
import { resolveLocalReviewedCommitRelation } from "../git/reviewed-commit-equivalence.ts";
|
|
18
24
|
import { parseTypedTaskFrontmatter } from "./frontmatter.ts";
|
|
19
|
-
import { parseLedger } from "./ledger.ts";
|
|
25
|
+
import { parseLedger, summarizeLedgerStage, validateLedgerRows } from "./ledger.ts";
|
|
26
|
+
import { equalCounts, parseReviewSummary } from "./review-artifacts.ts";
|
|
20
27
|
import { loadVerificationConfig } from "./verification-config.ts";
|
|
21
28
|
import { snapshotReview } from "../git/review-snapshot.ts";
|
|
22
29
|
|
|
@@ -107,10 +114,14 @@ function runCheck(type: any, context: any, shared: any): any {
|
|
|
107
114
|
return checkCompletionChecklist(context);
|
|
108
115
|
case "review-ledger":
|
|
109
116
|
return checkReviewLedger(context);
|
|
117
|
+
case "review-summary":
|
|
118
|
+
return checkReviewSummary(context);
|
|
110
119
|
case "review-fact":
|
|
111
120
|
return checkReviewFact(context);
|
|
112
121
|
case "post-review-commit":
|
|
113
122
|
return checkPostReviewCommit(context);
|
|
123
|
+
case "orchestration-state":
|
|
124
|
+
return checkOrchestrationState(context);
|
|
114
125
|
default: {
|
|
115
126
|
const adapter = PLATFORM_ADAPTERS[type];
|
|
116
127
|
if (!adapter) {
|
|
@@ -126,6 +137,32 @@ function runCheck(type: any, context: any, shared: any): any {
|
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
|
|
140
|
+
function checkOrchestrationState({ taskDir }: any): any {
|
|
141
|
+
const file = path.join(taskDir, 'orchestration.json');
|
|
142
|
+
const stat = safeStat(file);
|
|
143
|
+
if (!stat?.isFile()) return failResult('orchestration-state', 'orchestration.json is missing');
|
|
144
|
+
let run: any;
|
|
145
|
+
try {
|
|
146
|
+
run = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
147
|
+
} catch (error) {
|
|
148
|
+
return failResult('orchestration-state', `Invalid orchestration.json: ${String(error)}`);
|
|
149
|
+
}
|
|
150
|
+
if (run.schemaVersion !== 1 || !['paused', 'completed'].includes(run.status)) {
|
|
151
|
+
return failResult('orchestration-state', `Expected paused or completed run, received '${run.status}'`);
|
|
152
|
+
}
|
|
153
|
+
if (run.status === 'paused' && (!run.pause?.code || !run.pause?.message)) {
|
|
154
|
+
return failResult('orchestration-state', 'Paused run requires a stable pause code and message');
|
|
155
|
+
}
|
|
156
|
+
if (run.status === 'completed') {
|
|
157
|
+
if (run.pendingDelegation !== null || !run.commitAuthorization?.consumedAt) {
|
|
158
|
+
return failResult('orchestration-state', 'Completed run must consume commit authorization and clear pending delegation');
|
|
159
|
+
}
|
|
160
|
+
} else if (run.pendingDelegation?.status === 'sealed') {
|
|
161
|
+
return failResult('orchestration-state', 'Paused run has a sealed delegation that could still advance');
|
|
162
|
+
}
|
|
163
|
+
return passResult('orchestration-state', `Orchestration run is safely ${run.status}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
129
166
|
// === Check Functions ===
|
|
130
167
|
|
|
131
168
|
function checkTaskMeta({ taskDir, config }: any): any {
|
|
@@ -268,20 +305,6 @@ function loadProjectName(): any {
|
|
|
268
305
|
}
|
|
269
306
|
}
|
|
270
307
|
|
|
271
|
-
function loadReviewConfig(): any {
|
|
272
|
-
const configPath = path.join(repoRoot, ".agents", ".airc.json");
|
|
273
|
-
if (!fs.existsSync(configPath)) {
|
|
274
|
-
return {};
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
try {
|
|
278
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
279
|
-
return config.review && typeof config.review === "object" ? config.review : {};
|
|
280
|
-
} catch {
|
|
281
|
-
return {};
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
308
|
function checkArtifact({ taskDir, config, artifactFile }: any): any {
|
|
286
309
|
const resolvedArtifact = resolveArtifactPath(taskDir, config.file_pattern, artifactFile);
|
|
287
310
|
if (!resolvedArtifact.ok) {
|
|
@@ -324,6 +347,43 @@ function checkArtifact({ taskDir, config, artifactFile }: any): any {
|
|
|
324
347
|
);
|
|
325
348
|
}
|
|
326
349
|
|
|
350
|
+
function checkReviewSummary({ taskDir, config, artifactFile }: any): any {
|
|
351
|
+
const stage = String(config.stage || "");
|
|
352
|
+
if (!["analysis", "plan", "code"].includes(stage)) {
|
|
353
|
+
return failResult("review-summary", `Invalid review stage '${stage}'`);
|
|
354
|
+
}
|
|
355
|
+
const resolvedArtifact = resolveArtifactPath(taskDir, "", artifactFile);
|
|
356
|
+
if (!resolvedArtifact.ok || !safeStat(resolvedArtifact.path)?.isFile()) {
|
|
357
|
+
return failResult("review-summary", resolvedArtifact.message || "Review artifact is missing");
|
|
358
|
+
}
|
|
359
|
+
const parsed = parseReviewSummary(fs.readFileSync(resolvedArtifact.path, "utf8"));
|
|
360
|
+
if (!parsed.ok) return failResult("review-summary", `${parsed.code}: ${parsed.message}`);
|
|
361
|
+
if (!parsed.summary.counts) {
|
|
362
|
+
return failResult("review-summary", "Review summary finding counts are not finalized");
|
|
363
|
+
}
|
|
364
|
+
const task = loadTask(taskDir);
|
|
365
|
+
if (!task.ok) return failResult("review-summary", task.message);
|
|
366
|
+
let rows;
|
|
367
|
+
try {
|
|
368
|
+
rows = parseLedger(task.content);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
return failResult("review-summary", `Invalid disagreement ledger: ${String(error)}`);
|
|
371
|
+
}
|
|
372
|
+
const invalid = validateLedgerRows(rows);
|
|
373
|
+
if (invalid) return failResult("review-summary", `${invalid.code}: ${invalid.message}`);
|
|
374
|
+
const expected = summarizeLedgerStage(rows, stage as "analysis" | "plan" | "code").unresolvedFindingCounts;
|
|
375
|
+
if (!equalCounts(parsed.summary.counts, expected)) {
|
|
376
|
+
return failResult(
|
|
377
|
+
"review-summary",
|
|
378
|
+
`Review summary counts ${JSON.stringify(parsed.summary.counts)} do not match ledger ${JSON.stringify(expected)}`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
return passResult(
|
|
382
|
+
"review-summary",
|
|
383
|
+
`${path.basename(resolvedArtifact.path)} finding counts match the ${stage} ledger`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
327
387
|
function checkImplementationInput({ taskDir, artifactFile }: any): any {
|
|
328
388
|
const task = loadTask(taskDir);
|
|
329
389
|
if (!task.ok) return failResult("implementation-input", task.message);
|
|
@@ -598,7 +658,7 @@ function resolveReviewSetting(config: any, key: any, fallback: any): any {
|
|
|
598
658
|
if (config && config[key] !== undefined && config[key] !== null) {
|
|
599
659
|
return config[key];
|
|
600
660
|
}
|
|
601
|
-
const reviewConfig =
|
|
661
|
+
const reviewConfig = loadPostReviewConfig(repoRoot);
|
|
602
662
|
if (reviewConfig[key] !== undefined && reviewConfig[key] !== null) {
|
|
603
663
|
return reviewConfig[key];
|
|
604
664
|
}
|
|
@@ -694,8 +754,51 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
694
754
|
}
|
|
695
755
|
|
|
696
756
|
const task = loadTask(taskDir);
|
|
697
|
-
|
|
757
|
+
if (!task.ok) return failResult("post-review-commit", task.message);
|
|
698
758
|
const lastReviewedCommit = task.ok ? (task.metadata.last_reviewed_commit || "").trim() : "";
|
|
759
|
+
const globs = resolvePostReviewGlobs(config, loadPostReviewConfig(repoRoot));
|
|
760
|
+
const hasPullRequest = Number(task.metadata.pr_number) > 0;
|
|
761
|
+
let inspected: ReturnType<typeof inspectPlatformPullRequest> | null = null;
|
|
762
|
+
if (hasPullRequest) {
|
|
763
|
+
inspected = inspectPlatformPullRequest(task.metadata.id, { cwd: gitRoot });
|
|
764
|
+
if (!inspected.pullRequest) {
|
|
765
|
+
const message = inspected.error?.message || "PR merge snapshot is unavailable";
|
|
766
|
+
const code = inspected.error?.code || "PR_INSPECTION_INVALID";
|
|
767
|
+
return inspected.status === "blocked"
|
|
768
|
+
? blockedResult("post-review-commit", message, code)
|
|
769
|
+
: failResult("post-review-commit", message, code);
|
|
770
|
+
}
|
|
771
|
+
if (
|
|
772
|
+
inspected.pullRequest.state === "closed" &&
|
|
773
|
+
inspected.pullRequest.mergedAt &&
|
|
774
|
+
inspected.pullRequest.mergeCommitSha
|
|
775
|
+
) {
|
|
776
|
+
const relation = resolveMaterializedReviewedHeadRelation({
|
|
777
|
+
cwd: gitRoot,
|
|
778
|
+
platformType: inspected.platform.type,
|
|
779
|
+
lastReviewedCommit,
|
|
780
|
+
pullRequest: inspected.pullRequest
|
|
781
|
+
});
|
|
782
|
+
if (relation.status === "merged-equivalent") {
|
|
783
|
+
return passResult(
|
|
784
|
+
"post-review-commit",
|
|
785
|
+
`Reviewed PR head is content-equivalent to squash merge ${relation.mergeCommit.slice(0, 8)} on target ${relation.comparisonHead.slice(0, 8)}`
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
if (relation.status === "blocked") {
|
|
789
|
+
return blockedResult("post-review-commit", relation.message, relation.code);
|
|
790
|
+
}
|
|
791
|
+
if (relation.status === "strict") {
|
|
792
|
+
return failResult(
|
|
793
|
+
"post-review-commit",
|
|
794
|
+
"Merged PR evidence did not establish squash merge equivalence",
|
|
795
|
+
"PR_MERGE_IDENTITY_INVALID"
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
return failResult("post-review-commit", relation.message, relation.code);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
699
802
|
const baselineSource = resolvePostReviewBaseline({
|
|
700
803
|
gitRoot,
|
|
701
804
|
lastReviewedCommit,
|
|
@@ -706,7 +809,6 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
706
809
|
}
|
|
707
810
|
|
|
708
811
|
const sha = baselineSource.sha;
|
|
709
|
-
const globs = resolvePostReviewGlobs(config, loadReviewConfig());
|
|
710
812
|
let commits;
|
|
711
813
|
try {
|
|
712
814
|
const out = execFileSync("git", ["-C", gitRoot, "rev-list", `${sha}..HEAD`, "--", ...globs], { encoding: "utf8" });
|
|
@@ -719,15 +821,50 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
719
821
|
return passResult("post-review-commit", `No post-review commits to code/rule paths since ${sha.slice(0, 8)}`);
|
|
720
822
|
}
|
|
721
823
|
|
|
722
|
-
let
|
|
824
|
+
let localHead = "";
|
|
723
825
|
try {
|
|
724
|
-
|
|
725
|
-
(row) => row.stage === POST_REVIEW_COMMIT_STAGE && row.status === "human-decided"
|
|
726
|
-
);
|
|
826
|
+
localHead = execFileSync("git", ["-C", gitRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
727
827
|
} catch {
|
|
728
|
-
return
|
|
828
|
+
return blockedResult("post-review-commit", "Unable to resolve the local HEAD");
|
|
729
829
|
}
|
|
730
|
-
|
|
830
|
+
|
|
831
|
+
if (hasPullRequest) {
|
|
832
|
+
if (inspected?.pullRequest) {
|
|
833
|
+
const relation = resolveReviewedHeadRelation({
|
|
834
|
+
gitRoot,
|
|
835
|
+
comparisonHead: localHead,
|
|
836
|
+
lastReviewedCommit: sha,
|
|
837
|
+
pullRequest: inspected.pullRequest
|
|
838
|
+
});
|
|
839
|
+
if (relation.status === "merged-equivalent") {
|
|
840
|
+
return passResult("post-review-commit", `Reviewed PR head is content-equivalent to squash merge ${relation.mergeCommit.slice(0, 8)}`);
|
|
841
|
+
}
|
|
842
|
+
if (relation.status === "blocked") {
|
|
843
|
+
return blockedResult("post-review-commit", relation.message, relation.code);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
} else if (commits.length === 1) {
|
|
847
|
+
const relation = resolveLocalReviewedCommitRelation({
|
|
848
|
+
gitRoot,
|
|
849
|
+
localHead,
|
|
850
|
+
lastReviewedCommit: sha,
|
|
851
|
+
rewrittenCommit: commits[0]!,
|
|
852
|
+
pathspecs: globs
|
|
853
|
+
});
|
|
854
|
+
if (relation.status === "local-equivalent") {
|
|
855
|
+
return passResult(
|
|
856
|
+
"post-review-commit",
|
|
857
|
+
`Reviewed commit is content-equivalent to local rewrite ${relation.rewrittenCommit.slice(0, 8)}`
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
if (relation.status === "blocked") {
|
|
861
|
+
return blockedResult("post-review-commit", relation.message);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const exemption = resolvePostReviewExemption(task.content);
|
|
866
|
+
if (!exemption.ok) return failResult("post-review-commit", exemption.message);
|
|
867
|
+
if (exemption.exempt) {
|
|
731
868
|
return passResult(
|
|
732
869
|
"post-review-commit",
|
|
733
870
|
`${commits.length} post-review commit(s) covered by a human-decided exemption`
|
|
@@ -740,6 +877,21 @@ function checkPostReviewCommit({ taskDir, config }: any): any {
|
|
|
740
877
|
);
|
|
741
878
|
}
|
|
742
879
|
|
|
880
|
+
function resolvePostReviewExemption(content: string):
|
|
881
|
+
| { ok: true; exempt: boolean }
|
|
882
|
+
| { ok: false; message: string } {
|
|
883
|
+
try {
|
|
884
|
+
return {
|
|
885
|
+
ok: true,
|
|
886
|
+
exempt: parseLedger(content).some(
|
|
887
|
+
(row) => row.stage === POST_REVIEW_COMMIT_STAGE && row.status === "human-decided"
|
|
888
|
+
)
|
|
889
|
+
};
|
|
890
|
+
} catch {
|
|
891
|
+
return { ok: false, message: "Invalid disagreement ledger" };
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
743
895
|
function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
744
896
|
const resolvedArtifact = resolveArtifactPath(
|
|
745
897
|
taskDir,
|
|
@@ -758,6 +910,7 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
758
910
|
const content = fs.readFileSync(resolvedArtifact.path, "utf8");
|
|
759
911
|
const verdict = parseReviewVerdict(content);
|
|
760
912
|
const reviewBaseline = extractReviewBaseline(content);
|
|
913
|
+
const reviewDiffBase = extractReviewDiffBase(content);
|
|
761
914
|
const reviewedFingerprint = extractReviewDiffFingerprint(content);
|
|
762
915
|
const reviewedTree = extractReviewedSnapshotTree(content);
|
|
763
916
|
|
|
@@ -768,10 +921,16 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
768
921
|
let gitRoot;
|
|
769
922
|
let head;
|
|
770
923
|
let baseline;
|
|
924
|
+
let diffBase;
|
|
771
925
|
try {
|
|
772
926
|
gitRoot = execFileSync("git", ["-C", taskDir, "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
|
|
773
927
|
head = execFileSync("git", ["-C", gitRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
774
928
|
baseline = execFileSync("git", ["-C", gitRoot, "rev-parse", `${reviewBaseline}^{commit}`], { encoding: "utf8" }).trim();
|
|
929
|
+
diffBase = execFileSync(
|
|
930
|
+
"git",
|
|
931
|
+
["-C", gitRoot, "rev-parse", `${reviewDiffBase || reviewBaseline}^{commit}`],
|
|
932
|
+
{ encoding: "utf8" }
|
|
933
|
+
).trim();
|
|
775
934
|
} catch {
|
|
776
935
|
return blockedResult(
|
|
777
936
|
"review-fact",
|
|
@@ -788,7 +947,13 @@ function checkReviewFact({ taskDir, artifactFile }: any): any {
|
|
|
788
947
|
|
|
789
948
|
let actualSnapshot;
|
|
790
949
|
try {
|
|
791
|
-
actualSnapshot = snapshotReview({
|
|
950
|
+
actualSnapshot = snapshotReview({
|
|
951
|
+
cwd: gitRoot,
|
|
952
|
+
mode: "worktree",
|
|
953
|
+
baseline,
|
|
954
|
+
diffBase,
|
|
955
|
+
globs: resolvePostReviewGlobs({}, loadPostReviewConfig(repoRoot))
|
|
956
|
+
});
|
|
792
957
|
} catch {
|
|
793
958
|
return blockedResult(
|
|
794
959
|
"review-fact",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export {
|
|
2
2
|
extractReviewBaseline,
|
|
3
|
+
extractReviewDiffBase,
|
|
3
4
|
extractReviewDiffFingerprint,
|
|
4
5
|
extractReviewedSnapshotTree,
|
|
5
6
|
findAuthoritativeReviewCodeArtifact,
|
|
7
|
+
loadPostReviewConfig,
|
|
6
8
|
parseReviewVerdict,
|
|
7
9
|
resolvePostReviewGlobs
|
|
8
10
|
} from './review-fingerprint.ts';
|
package/lib/task/verification.ts
CHANGED
|
@@ -16,7 +16,8 @@ type VerificationEvent =
|
|
|
16
16
|
| 'complete-task.preflight' | 'complete-task.completed'
|
|
17
17
|
| 'create-pr.completed' | 'create-task.completed'
|
|
18
18
|
| 'import-codescan.completed' | 'import-dependabot.completed'
|
|
19
|
-
| 'import-issue.completed' | 'watch-pr.completed'
|
|
19
|
+
| 'import-issue.completed' | 'watch-pr.completed'
|
|
20
|
+
| 'run-task.paused' | 'run-task.completed';
|
|
20
21
|
type VerificationSpec = {
|
|
21
22
|
skill: string;
|
|
22
23
|
expectedState: 'active' | 'blocked' | 'completed';
|
|
@@ -63,14 +64,16 @@ const VERIFICATION_CATALOG: Readonly<Record<VerificationEvent, VerificationSpec>
|
|
|
63
64
|
'block-task.completed': gate('block-task', 'blocked'),
|
|
64
65
|
'cancel-task.completed': gate('cancel-task', 'completed'),
|
|
65
66
|
'commit.completed': gate('commit', 'active'),
|
|
66
|
-
'complete-task.preflight': { skill: 'complete-task', expectedState: 'active', mode: 'checks', checks: ['review-ledger', 'post-review-commit', '
|
|
67
|
+
'complete-task.preflight': { skill: 'complete-task', expectedState: 'active', mode: 'checks', checks: ['review-ledger', 'post-review-commit', 'platform-sync-preflight'] },
|
|
67
68
|
'complete-task.completed': gate('complete-task', 'completed'),
|
|
68
69
|
'create-pr.completed': gate('create-pr', 'active'),
|
|
69
70
|
'create-task.completed': gate('create-task', 'active'),
|
|
70
71
|
'import-codescan.completed': gate('import-codescan', 'active'),
|
|
71
72
|
'import-dependabot.completed': gate('import-dependabot', 'active'),
|
|
72
73
|
'import-issue.completed': gate('import-issue', 'active'),
|
|
73
|
-
'watch-pr.completed': gate('watch-pr', 'active')
|
|
74
|
+
'watch-pr.completed': gate('watch-pr', 'active'),
|
|
75
|
+
'run-task.paused': { skill: 'run-task', expectedState: 'active', mode: 'checks', checks: ['orchestration-state'] },
|
|
76
|
+
'run-task.completed': { skill: 'run-task', expectedState: 'active', mode: 'checks', checks: ['orchestration-state'] }
|
|
74
77
|
};
|
|
75
78
|
|
|
76
79
|
function failure(request: { taskRef: string; event: string; artifact?: string }, code: string, message: string, extra: Partial<TaskVerificationResult> = {}): TaskVerificationResult {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
function git(repoRoot: string, indexFile: string | null, args: string[]): string {
|
|
7
|
+
const env = indexFile ? { ...process.env, GIT_INDEX_FILE: indexFile } : process.env;
|
|
8
|
+
const result = spawnSync('git', args, { cwd: repoRoot, env, encoding: 'utf8' });
|
|
9
|
+
if (result.status !== 0) {
|
|
10
|
+
throw new Error(String(result.stderr || result.stdout || `git ${args[0]} failed`).trim());
|
|
11
|
+
}
|
|
12
|
+
return result.stdout;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function captureWorkspaceSnapshot(repoRoot: string): string {
|
|
16
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-infra-orchestration-index-'));
|
|
17
|
+
const indexFile = path.join(tempDir, 'index');
|
|
18
|
+
try {
|
|
19
|
+
git(repoRoot, indexFile, ['read-tree', 'HEAD']);
|
|
20
|
+
git(repoRoot, indexFile, ['add', '-A', '--', ':/']);
|
|
21
|
+
const workspace = path.join(repoRoot, '.agents', 'workspace', 'active');
|
|
22
|
+
if (fs.existsSync(workspace)) {
|
|
23
|
+
git(repoRoot, indexFile, ['add', '-f', '--', '.agents/workspace/active']);
|
|
24
|
+
}
|
|
25
|
+
return git(repoRoot, indexFile, ['write-tree']).trim();
|
|
26
|
+
} finally {
|
|
27
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function diffWorkspaceSnapshots(repoRoot: string, before: string, after: string): string[] {
|
|
32
|
+
const output = git(repoRoot, null, ['diff', '--name-only', '-z', before, after]);
|
|
33
|
+
return output.split('\0').filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { captureWorkspaceSnapshot, diffWorkspaceSnapshots };
|