@webpresso/agent-kit 3.1.30 → 3.2.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.
Potentially problematic release.
This version of @webpresso/agent-kit might be problematic. Click here for more details.
- package/README.md +53 -15
- package/bin/_run.js +179 -19
- package/catalog/AGENTS.md.tpl +3 -3
- package/catalog/agent/agents/implementer.md +45 -0
- package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
- package/catalog/agent/rules/pre-implementation.md +28 -1
- package/catalog/agent/rules/supported-agent-clis.md +9 -0
- package/catalog/agent/rules/typescript-version.md +50 -0
- package/catalog/agent/skills/codex/SKILL.md +25 -1
- package/catalog/agent/skills/verify/SKILL.md +4 -2
- package/catalog/docs/templates/blueprint.md +1 -1
- package/dist/esm/audit/agents.js +1 -0
- package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
- package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
- package/dist/esm/audit/blueprint-pr-coverage.js +4 -0
- package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
- package/dist/esm/audit/ci-guardrails-wiring.js +90 -0
- package/dist/esm/audit/ci-test-perf.js +30 -0
- package/dist/esm/audit/command-surface.js +4 -2
- package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
- package/dist/esm/audit/host-substitution-risk.js +256 -0
- package/dist/esm/audit/registry.d.ts +4 -4
- package/dist/esm/audit/registry.js +8 -1
- package/dist/esm/audit/toolchain-isolation.js +1 -2
- package/dist/esm/audit/typescript-version.d.ts +2 -0
- package/dist/esm/audit/typescript-version.js +123 -0
- package/dist/esm/blueprint/core/parser.js +43 -1
- package/dist/esm/blueprint/core/validation/criteria.d.ts +14 -0
- package/dist/esm/blueprint/core/validation/criteria.js +41 -2
- package/dist/esm/blueprint/core/validation/state.js +25 -14
- package/dist/esm/blueprint/db/migrations/run.js +4 -2
- package/dist/esm/blueprint/lifecycle/audit.d.ts +20 -0
- package/dist/esm/blueprint/lifecycle/audit.js +65 -10
- package/dist/esm/blueprint/lifecycle/canonicalize.d.ts +6 -0
- package/dist/esm/blueprint/lifecycle/canonicalize.js +135 -0
- package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
- package/dist/esm/blueprint/lifecycle/local.js +19 -3
- package/dist/esm/blueprint/lifecycle/review-provenance.js +36 -11
- package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
- package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
- package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
- package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
- package/dist/esm/blueprint/trust/command-runner.js +148 -0
- package/dist/esm/blueprint/trust/gates.d.ts +7 -0
- package/dist/esm/blueprint/trust/gates.js +20 -0
- package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
- package/dist/esm/blueprint/trust/promotion.js +62 -112
- package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
- package/dist/esm/blueprint/trust/scaffold.js +64 -0
- package/dist/esm/blueprint/trust/validator.d.ts +1 -0
- package/dist/esm/blueprint/trust/validator.js +7 -1
- package/dist/esm/blueprint/utils/archive.js +27 -5
- package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
- package/dist/esm/blueprint/utils/document-paths.js +45 -12
- package/dist/esm/build/cli-mcp-parity.js +10 -0
- package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
- package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
- package/dist/esm/cli/cli.d.ts +1 -1
- package/dist/esm/cli/cli.js +34 -0
- package/dist/esm/cli/commands/agent-launch.d.ts +6 -1
- package/dist/esm/cli/commands/agent-launch.js +82 -4
- package/dist/esm/cli/commands/audit-core.d.ts +1 -1
- package/dist/esm/cli/commands/audit-core.js +8 -1
- package/dist/esm/cli/commands/audit.js +17 -5
- package/dist/esm/cli/commands/blueprint/execution.js +18 -6
- package/dist/esm/cli/commands/blueprint/mutations.js +59 -40
- package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
- package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
- package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
- package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
- package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
- package/dist/esm/cli/commands/blueprint/router.js +13 -1
- package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
- package/dist/esm/cli/commands/ci-preflight.js +6 -3
- package/dist/esm/cli/commands/compile.js +5 -31
- package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
- package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
- package/dist/esm/cli/commands/doctor.js +5 -0
- package/dist/esm/cli/commands/hook.d.ts +5 -0
- package/dist/esm/cli/commands/hook.js +15 -9
- package/dist/esm/cli/commands/init/config.js +2 -2
- package/dist/esm/cli/commands/init/convergence-apply.d.ts +24 -0
- package/dist/esm/cli/commands/init/convergence-apply.js +221 -0
- package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
- package/dist/esm/cli/commands/init/convergence-state.js +54 -0
- package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
- package/dist/esm/cli/commands/init/convergence.js +57 -0
- package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
- package/dist/esm/cli/commands/init/git-convergence.js +168 -0
- package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
- package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
- package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
- package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
- package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
- package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
- package/dist/esm/cli/commands/init/host-visibility.js +94 -5
- package/dist/esm/cli/commands/init/index.d.ts +1 -0
- package/dist/esm/cli/commands/init/index.js +326 -173
- package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
- package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
- package/dist/esm/cli/commands/init/merge.d.ts +1 -0
- package/dist/esm/cli/commands/init/merge.js +30 -1
- package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
- package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
- package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
- package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
- package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +11 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +56 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +51 -23
- package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
- package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +288 -202
- package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +7 -0
- package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +58 -0
- package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
- package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
- package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
- package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
- package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
- package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
- package/dist/esm/cli/commands/opencode-rotate.d.ts +49 -0
- package/dist/esm/cli/commands/opencode-rotate.js +135 -0
- package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
- package/dist/esm/cli/commands/public-readiness.js +42 -0
- package/dist/esm/cli/commands/review.d.ts +35 -3
- package/dist/esm/cli/commands/review.js +729 -209
- package/dist/esm/cli/commands/run-wait.d.ts +2 -0
- package/dist/esm/cli/commands/run-wait.js +122 -0
- package/dist/esm/cli/commands/setup-help.js +1 -1
- package/dist/esm/cli/commands/setup-repair-help.js +1 -1
- package/dist/esm/cli/commands/worktree/router-dispatch.js +13 -8
- package/dist/esm/cli/direct-provider-launch.js +9 -5
- package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
- package/dist/esm/cli/optional-tool-freshness.js +219 -9
- package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
- package/dist/esm/daemon/domains/git-actions.js +136 -0
- package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
- package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
- package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
- package/dist/esm/daemon/domains/sessions-search.js +29 -0
- package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
- package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
- package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
- package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
- package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
- package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
- package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
- package/dist/esm/daemon/handlers/git-handlers.js +27 -0
- package/dist/esm/daemon/handlers/product.d.ts +7 -0
- package/dist/esm/daemon/handlers/product.js +10 -119
- package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
- package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
- package/dist/esm/daemon/handlers/shared.d.ts +5 -0
- package/dist/esm/daemon/handlers/shared.js +16 -0
- package/dist/esm/daemon/methods.d.ts +8 -1
- package/dist/esm/daemon/methods.js +7 -0
- package/dist/esm/daemon/protocol/contract.d.ts +43 -0
- package/dist/esm/daemon/protocol/contract.js +26 -0
- package/dist/esm/daemon/protocol/index.d.ts +1 -1
- package/dist/esm/daemon/protocol/index.js +1 -1
- package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
- package/dist/esm/hooks/__conformance__/matrix.js +137 -0
- package/dist/esm/hooks/conformance/batch.js +5 -0
- package/dist/esm/hooks/doctor.d.ts +3 -3
- package/dist/esm/hooks/doctor.js +30 -15
- package/dist/esm/hooks/permission-request/index.js +9 -3
- package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
- package/dist/esm/hooks/permission-request/policy.js +13 -0
- package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
- package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
- package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
- package/dist/esm/hooks/pretool-guard/logger.js +16 -0
- package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
- package/dist/esm/hooks/pretool-guard/runner.js +68 -16
- package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +54 -0
- package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
- package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
- package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
- package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
- package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
- package/dist/esm/hooks/shared/guard-outcome.js +215 -0
- package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
- package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
- package/dist/esm/hooks/shared/types.d.ts +8 -5
- package/dist/esm/hooks/shared/types.js +23 -8
- package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +74 -0
- package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
- package/dist/esm/mcp/blueprint/handlers/document-mutations.js +78 -4
- package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
- package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
- package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
- package/dist/esm/mcp/blueprint/registration.js +3 -2
- package/dist/esm/mcp/server.d.ts +1 -0
- package/dist/esm/mcp/server.js +27 -0
- package/dist/esm/mcp/tools/_names.d.ts +1 -1
- package/dist/esm/mcp/tools/_names.js +5 -0
- package/dist/esm/mcp/tools/_registry.js +10 -0
- package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
- package/dist/esm/mcp/tools/_shared/result.js +44 -1
- package/dist/esm/mcp/tools/audit.d.ts +4 -1
- package/dist/esm/mcp/tools/audit.js +30 -0
- package/dist/esm/mcp/tools/audits.d.ts +3 -0
- package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
- package/dist/esm/mcp/tools/ci-preflight.js +183 -0
- package/dist/esm/mcp/tools/pr-upsert.js +39 -1
- package/dist/esm/mcp/tools/review-run.d.ts +28 -0
- package/dist/esm/mcp/tools/review-run.js +216 -0
- package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
- package/dist/esm/mcp/tools/run-wait.js +593 -0
- package/dist/esm/mcp/tools/session-id.d.ts +3 -0
- package/dist/esm/mcp/tools/session-id.js +45 -0
- package/dist/esm/mcp/tools/session-info.d.ts +3 -0
- package/dist/esm/mcp/tools/session-info.js +49 -0
- package/dist/esm/output-transforms/audit.d.ts +23 -0
- package/dist/esm/output-transforms/audit.js +47 -0
- package/dist/esm/output-transforms/index.js +2 -0
- package/dist/esm/review/authority.js +13 -5
- package/dist/esm/review/availability.d.ts +22 -0
- package/dist/esm/review/availability.js +107 -20
- package/dist/esm/review/delivery-verifier.d.ts +27 -0
- package/dist/esm/review/delivery-verifier.js +115 -0
- package/dist/esm/review/events.d.ts +3 -2
- package/dist/esm/review/events.js +23 -3
- package/dist/esm/review/execution/adapters.js +26 -9
- package/dist/esm/review/execution/output-policy.d.ts +2 -0
- package/dist/esm/review/execution/output-policy.js +12 -0
- package/dist/esm/review/execution/review-checkout.js +87 -6
- package/dist/esm/review/execution/supervisor.js +5 -0
- package/dist/esm/review/execution/types.d.ts +8 -0
- package/dist/esm/review/opencode-account.d.ts +24 -0
- package/dist/esm/review/opencode-account.js +68 -0
- package/dist/esm/review/opencode-auth.d.ts +33 -0
- package/dist/esm/review/opencode-auth.js +79 -0
- package/dist/esm/review/subject.d.ts +12 -0
- package/dist/esm/review/subject.js +74 -22
- package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
- package/dist/esm/runtime/opencode-account-materializer.js +33 -0
- package/dist/esm/status/snapshot.js +30 -19
- package/dist/esm/test/duration-sequencer.d.ts +20 -0
- package/dist/esm/test/duration-sequencer.js +54 -0
- package/dist/esm/test/shard-durations.json +922 -0
- package/dist/esm/test/worker-budget.d.ts +6 -0
- package/dist/esm/test/worker-budget.js +59 -1
- package/dist/esm/test-helpers/global-setup.d.ts +1 -1
- package/dist/esm/test-helpers/global-setup.js +68 -24
- package/dist/esm/ultragoal/service.d.ts +7 -0
- package/dist/esm/ultragoal/service.js +42 -2
- package/dist/esm/utils/write-json-file.js +3 -1
- package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
- package/dist/esm/worktrees/codex-project-trust.js +56 -0
- package/dist/esm/worktrees/registry.d.ts +8 -0
- package/dist/esm/worktrees/registry.js +18 -3
- package/package.json +16 -13
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { evaluateApprovalReviewers } from "#lifecycle/audit.js";
|
|
4
|
+
import { collectV2ReviewProvenance } from "#lifecycle/review-provenance.js";
|
|
4
5
|
import { evaluateRequiredChecks } from "#mcp/tools/_shared/required-checks.js";
|
|
5
6
|
import { redactText } from "#mcp/tools/_shared/redact.js";
|
|
6
7
|
import { runCommand } from "#mcp/tools/_shared/run-command.js";
|
|
7
8
|
import { readReviewAuthorityAtRef } from "#review/authority.js";
|
|
8
9
|
import { resolveBlueprintRoot } from "#utils/blueprint-root.js";
|
|
10
|
+
import { parseBlueprintDocumentRelativePath } from "#utils/document-paths.js";
|
|
9
11
|
export const statusLevelSchema = z.enum(["ready", "blocked", "partial", "unknown"]);
|
|
10
12
|
export const requiredCheckEvaluationSchema = z.object({
|
|
11
13
|
total: z.number().int().nonnegative(),
|
|
@@ -80,6 +82,11 @@ export const wpStatusSnapshotSchema = z.object({
|
|
|
80
82
|
});
|
|
81
83
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
82
84
|
const DEFAULT_MAX_OUTPUT_BYTES = 64_000;
|
|
85
|
+
// `gh pr view --json` includes the PR `body`, which alone can exceed the small
|
|
86
|
+
// caller diagnostic budget (GitHub bodies run to tens of KB). Parse that JSON
|
|
87
|
+
// against a generous semantic budget so mergeability/checks/blueprint-linkage
|
|
88
|
+
// fields are never lost to truncation; diagnostics keep the small caller budget.
|
|
89
|
+
const PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES = 1_048_576;
|
|
83
90
|
const DISCLOSURE_FIELDS = [
|
|
84
91
|
"Execution model(s)",
|
|
85
92
|
"Planning/refinement model(s)",
|
|
@@ -115,8 +122,8 @@ async function probe(cwd, command, args, options = {}) {
|
|
|
115
122
|
cwd,
|
|
116
123
|
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
117
124
|
});
|
|
125
|
+
const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
118
126
|
if ("error" in outcome) {
|
|
119
|
-
const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
120
127
|
return {
|
|
121
128
|
passed: false,
|
|
122
129
|
semanticStdout: "",
|
|
@@ -125,11 +132,11 @@ async function probe(cwd, command, args, options = {}) {
|
|
|
125
132
|
missingBinary: outcome.error.code === "ENOENT",
|
|
126
133
|
};
|
|
127
134
|
}
|
|
128
|
-
const
|
|
135
|
+
const semanticMaxOutputBytes = options.semanticMaxOutputBytes ?? maxOutputBytes;
|
|
129
136
|
return {
|
|
130
137
|
passed: outcome.exitCode === 0,
|
|
131
|
-
semanticStdout: clipBytes(outcome.stdout,
|
|
132
|
-
semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") >
|
|
138
|
+
semanticStdout: clipBytes(outcome.stdout, semanticMaxOutputBytes),
|
|
139
|
+
semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") > semanticMaxOutputBytes,
|
|
133
140
|
stdout: clipDiagnostic(outcome.stdout, maxOutputBytes),
|
|
134
141
|
stderr: clipDiagnostic(outcome.stderr, maxOutputBytes),
|
|
135
142
|
exitCode: outcome.exitCode,
|
|
@@ -307,33 +314,29 @@ function selectBlueprintFile(projectRoot, pr) {
|
|
|
307
314
|
const prefix = `${root}/`;
|
|
308
315
|
if (!file.path.startsWith(prefix))
|
|
309
316
|
continue;
|
|
310
|
-
const
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
-
segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
const stableSlug = segments.slice(1, -1).join("/");
|
|
317
|
-
if (stableSlug)
|
|
318
|
-
return [{ ...file, stableSlug }];
|
|
317
|
+
const parsed = parseBlueprintDocumentRelativePath(file.path.slice(prefix.length));
|
|
318
|
+
if (parsed)
|
|
319
|
+
return [{ ...file, stableSlug: parsed.slug }];
|
|
319
320
|
}
|
|
320
321
|
return [];
|
|
321
322
|
});
|
|
322
323
|
const priority = (file) => file.changeType === "ADDED" ? 0 : file.changeType === "RENAMED" ? 1 : 2;
|
|
323
324
|
return candidates.toSorted((left, right) => priority(left) - priority(right))[0];
|
|
324
325
|
}
|
|
325
|
-
function resolveBlueprintEvidence(
|
|
326
|
+
function resolveBlueprintEvidence(projectRoot, pr, targetHash) {
|
|
326
327
|
const blueprintFile = selectBlueprintFile(projectRoot, pr);
|
|
327
328
|
if (!blueprintFile || !targetHash)
|
|
328
329
|
return undefined;
|
|
329
330
|
try {
|
|
330
|
-
const authority = readReviewAuthorityAtRef(
|
|
331
|
+
const authority = readReviewAuthorityAtRef(projectRoot, targetHash, blueprintFile.stableSlug, "delivery");
|
|
331
332
|
if (authority.blueprintPath !== blueprintFile.path)
|
|
332
333
|
return undefined;
|
|
334
|
+
const approvals = collectV2ReviewProvenance(path.resolve(projectRoot, blueprintFile.path), "delivery", targetHash);
|
|
333
335
|
return {
|
|
334
336
|
path: blueprintFile.path,
|
|
335
337
|
lifecycle: authority.lifecycle,
|
|
336
|
-
approvalsSatisfied: evaluateApprovalReviewers(
|
|
338
|
+
approvalsSatisfied: evaluateApprovalReviewers(approvals.map((approval) => approval.reviewer))
|
|
339
|
+
.satisfied,
|
|
337
340
|
};
|
|
338
341
|
}
|
|
339
342
|
catch {
|
|
@@ -582,7 +585,10 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
582
585
|
"files",
|
|
583
586
|
].join(",");
|
|
584
587
|
const [view, checksProbe] = await Promise.all([
|
|
585
|
-
probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields],
|
|
588
|
+
probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields], {
|
|
589
|
+
...probeOptions,
|
|
590
|
+
semanticMaxOutputBytes: PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES,
|
|
591
|
+
}),
|
|
586
592
|
probe(cwd, "gh", ["pr", "checks", ...selector, "--required", "--json", "name,state,bucket,link,description"], probeOptions),
|
|
587
593
|
]);
|
|
588
594
|
pr = view.passed ? parseJsonObject(view.semanticStdout) : undefined;
|
|
@@ -599,7 +605,7 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
599
605
|
readGreptileComments(cwd, pr, probeOptions),
|
|
600
606
|
])
|
|
601
607
|
: [{ complete: false, warning: "PR metadata unavailable." }, { comments: [] }];
|
|
602
|
-
const blueprint = resolveBlueprintEvidence(
|
|
608
|
+
const blueprint = resolveBlueprintEvidence(firstLine(topLevel.semanticStdout) ?? cwd, pr, localHead);
|
|
603
609
|
const readiness = evaluatePrReadiness({
|
|
604
610
|
localHead,
|
|
605
611
|
dirtyWorktree,
|
|
@@ -649,9 +655,14 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
649
655
|
threadsComplete: threads.complete,
|
|
650
656
|
greptile: classifyGreptile(checks ?? [], greptileComments.comments, stringField(pr?.headRefOid)),
|
|
651
657
|
};
|
|
658
|
+
// `body` is fully consumed above (release-evidence + disclosure via
|
|
659
|
+
// `evaluatePrReadiness`, blueprint linkage via `resolveBlueprintEvidence`),
|
|
660
|
+
// so drop it from the emitted metadata to keep the payload from re-ballooning
|
|
661
|
+
// to the size that truncated the parse in the first place.
|
|
662
|
+
const { body: _body, ...metadataWithoutBody } = pr ?? {};
|
|
652
663
|
context.pr = {
|
|
653
664
|
selector: selector[0],
|
|
654
|
-
metadata: pr,
|
|
665
|
+
metadata: pr ? metadataWithoutBody : undefined,
|
|
655
666
|
checks: readiness.checks
|
|
656
667
|
? { ...readiness.checks, checks: [...readiness.checks.checks] }
|
|
657
668
|
: undefined,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseSequencer, type TestSpecification } from "vitest/node";
|
|
2
|
+
export declare function weightFor(project: string, relativePath: string): number;
|
|
3
|
+
interface WeightedSpec {
|
|
4
|
+
readonly spec: TestSpecification;
|
|
5
|
+
readonly weight: number;
|
|
6
|
+
readonly key: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Deterministic greedy LPT partition of `specs` into `count` bins. Files are
|
|
10
|
+
* sorted heaviest-first (ties broken by path so the order is stable across
|
|
11
|
+
* every shard job), then each is placed into the currently-lightest bin (ties
|
|
12
|
+
* broken by lowest bin index). Returns all bins in index order.
|
|
13
|
+
*
|
|
14
|
+
* Exported for the contract test; the sequencer only needs one bin.
|
|
15
|
+
*/
|
|
16
|
+
export declare function partitionByDuration(specs: readonly WeightedSpec[], count: number): readonly (readonly WeightedSpec[])[];
|
|
17
|
+
export declare class DurationSequencer extends BaseSequencer {
|
|
18
|
+
shard(files: TestSpecification[]): Promise<TestSpecification[]>;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { relative } from "node:path";
|
|
2
|
+
import { BaseSequencer } from "vitest/node";
|
|
3
|
+
import rawSnapshot from "./shard-durations.json" with { type: "json" };
|
|
4
|
+
const snapshot = rawSnapshot;
|
|
5
|
+
// A generated snapshot always carries a positive defaultWeight; clamp to 1 only
|
|
6
|
+
// to keep LPT well-defined if the JSON is ever hand-truncated to nothing.
|
|
7
|
+
const DEFAULT_WEIGHT = snapshot.defaultWeight > 0 ? snapshot.defaultWeight : 1;
|
|
8
|
+
export function weightFor(project, relativePath) {
|
|
9
|
+
return snapshot.durations[project]?.[relativePath] ?? DEFAULT_WEIGHT;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Deterministic greedy LPT partition of `specs` into `count` bins. Files are
|
|
13
|
+
* sorted heaviest-first (ties broken by path so the order is stable across
|
|
14
|
+
* every shard job), then each is placed into the currently-lightest bin (ties
|
|
15
|
+
* broken by lowest bin index). Returns all bins in index order.
|
|
16
|
+
*
|
|
17
|
+
* Exported for the contract test; the sequencer only needs one bin.
|
|
18
|
+
*/
|
|
19
|
+
export function partitionByDuration(specs, count) {
|
|
20
|
+
const bins = Array.from({ length: count }, () => []);
|
|
21
|
+
const loads = Array.from({ length: count }, () => 0);
|
|
22
|
+
const ordered = [...specs].sort((a, b) => b.weight !== a.weight ? b.weight - a.weight : a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
23
|
+
for (const item of ordered) {
|
|
24
|
+
let target = 0;
|
|
25
|
+
let targetLoad = loads[0] ?? 0;
|
|
26
|
+
for (let i = 1; i < count; i += 1) {
|
|
27
|
+
const load = loads[i] ?? 0;
|
|
28
|
+
if (load < targetLoad) {
|
|
29
|
+
target = i;
|
|
30
|
+
targetLoad = load;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// target is always in [0, count): bins/loads were sized to `count`.
|
|
34
|
+
(bins[target] ??= []).push(item);
|
|
35
|
+
loads[target] = targetLoad + item.weight;
|
|
36
|
+
}
|
|
37
|
+
return bins;
|
|
38
|
+
}
|
|
39
|
+
export class DurationSequencer extends BaseSequencer {
|
|
40
|
+
async shard(files) {
|
|
41
|
+
const { config } = this.ctx;
|
|
42
|
+
// No --shard (serial lane, local full runs): nothing to partition.
|
|
43
|
+
if (!config.shard)
|
|
44
|
+
return files;
|
|
45
|
+
const { index, count } = config.shard;
|
|
46
|
+
const weighted = files.map((spec) => {
|
|
47
|
+
const key = relative(config.root, spec.moduleId);
|
|
48
|
+
return { spec, key, weight: weightFor(spec.project.name, key) };
|
|
49
|
+
});
|
|
50
|
+
const bins = partitionByDuration(weighted, count);
|
|
51
|
+
// index is 1-based in [1, count]; the bin is always present.
|
|
52
|
+
return (bins[index - 1] ?? []).map((item) => item.spec);
|
|
53
|
+
}
|
|
54
|
+
}
|