@webpresso/agent-kit 3.1.30 → 3.3.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 +53 -15
- package/bin/_run.js +183 -20
- 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/blueprint-trust.js +14 -10
- package/dist/esm/audit/changeset-evidence.d.ts +23 -0
- package/dist/esm/audit/changeset-evidence.js +30 -0
- package/dist/esm/audit/changeset-required.d.ts +10 -0
- package/dist/esm/audit/changeset-required.js +73 -0
- package/dist/esm/audit/ci-guardrails-detection.d.ts +27 -0
- package/dist/esm/audit/ci-guardrails-detection.js +68 -0
- package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
- package/dist/esm/audit/ci-guardrails-wiring.js +80 -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 +13 -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 +101 -2
- package/dist/esm/blueprint/core/schema.d.ts +1 -0
- package/dist/esm/blueprint/core/schema.js +26 -0
- 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 +87 -20
- 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.d.ts +6 -0
- package/dist/esm/blueprint/lifecycle/review-provenance.js +68 -12
- package/dist/esm/blueprint/lifecycle/rollout-anchor.d.ts +97 -0
- package/dist/esm/blueprint/lifecycle/rollout-anchor.js +161 -0
- 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/sync/client.d.ts +2 -1
- package/dist/esm/blueprint/sync/client.js +1 -1
- 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/dossier.d.ts +1 -0
- package/dist/esm/blueprint/trust/dossier.js +40 -6
- 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 +74 -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 +15 -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 +43 -0
- package/dist/esm/cli/commands/agent-launch.d.ts +8 -1
- package/dist/esm/cli/commands/agent-launch.js +93 -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 +21 -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 +30 -6
- 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 +88 -0
- package/dist/esm/cli/commands/init/convergence-apply.js +325 -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 +3 -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/package-root.d.ts +7 -0
- package/dist/esm/cli/commands/init/package-root.js +10 -2
- 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 +20 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +61 -5
- 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 +54 -24
- 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 +22 -0
- package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +230 -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-probe.d.ts +107 -0
- package/dist/esm/cli/commands/opencode-probe.js +323 -0
- package/dist/esm/cli/commands/opencode-rotate.d.ts +72 -0
- package/dist/esm/cli/commands/opencode-rotate.js +147 -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/quality-runner.js +3 -3
- package/dist/esm/cli/commands/review.d.ts +35 -3
- package/dist/esm/cli/commands/review.js +751 -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/rust-check.d.ts +24 -0
- package/dist/esm/cli/commands/rust-check.js +110 -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/typecheck.d.ts +1 -0
- package/dist/esm/cli/commands/typecheck.js +30 -1
- package/dist/esm/cli/commands/worktree/router-dispatch.d.ts +6 -0
- package/dist/esm/cli/commands/worktree/router-dispatch.js +126 -9
- package/dist/esm/cli/commands/worktree/router.js +10 -0
- 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 +5 -3
- package/dist/esm/hooks/doctor.js +67 -16
- 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/pretool-guard/validators/worktree-discipline.js +6 -1
- 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 +50 -9
- package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +92 -0
- package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
- package/dist/esm/mcp/blueprint/handlers/document-mutations.d.ts +5 -0
- package/dist/esm/mcp/blueprint/handlers/document-mutations.js +109 -11
- 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 +5 -1
- package/dist/esm/mcp/tools/audit.js +42 -0
- package/dist/esm/mcp/tools/audits.d.ts +4 -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-fetch-and-index.d.ts +1 -1
- 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/package.json +2 -0
- package/dist/esm/platform/client.d.ts +7 -1
- package/dist/esm/platform/github-contract-source.d.ts +2 -1
- package/dist/esm/pr-description/contract.js +24 -4
- package/dist/esm/review/authority.js +27 -14
- package/dist/esm/review/availability.d.ts +33 -0
- package/dist/esm/review/availability.js +122 -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.d.ts +11 -1
- package/dist/esm/review/execution/adapters.js +36 -10
- package/dist/esm/review/execution/artifacts.d.ts +1 -1
- 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 +121 -21
- package/dist/esm/review/execution/supervisor.js +36 -4
- package/dist/esm/review/execution/types.d.ts +9 -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 +25 -0
- package/dist/esm/review/subject.js +116 -26
- package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
- package/dist/esm/runtime/opencode-account-materializer.js +33 -0
- package/dist/esm/rust/affected-manifests.d.ts +38 -0
- package/dist/esm/rust/affected-manifests.js +69 -0
- package/dist/esm/session-memory/fetch-index.d.ts +1 -1
- package/dist/esm/status/snapshot.js +32 -25
- 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 -2
- package/dist/esm/test-helpers/global-setup.js +79 -32
- package/dist/esm/typecheck/planner.d.ts +9 -1
- package/dist/esm/typecheck/planner.js +31 -0
- 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/orphan-scan.d.ts +50 -0
- package/dist/esm/worktrees/orphan-scan.js +211 -0
- package/dist/esm/worktrees/registry.d.ts +8 -0
- package/dist/esm/worktrees/registry.js +18 -3
- package/package.json +18 -13
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { hasChangesetEvidence } from "#audit/changeset-evidence.js";
|
|
3
4
|
import { evaluateApprovalReviewers } from "#lifecycle/audit.js";
|
|
5
|
+
import { collectV2ReviewProvenance } from "#lifecycle/review-provenance.js";
|
|
4
6
|
import { evaluateRequiredChecks } from "#mcp/tools/_shared/required-checks.js";
|
|
5
7
|
import { redactText } from "#mcp/tools/_shared/redact.js";
|
|
6
8
|
import { runCommand } from "#mcp/tools/_shared/run-command.js";
|
|
7
9
|
import { readReviewAuthorityAtRef } from "#review/authority.js";
|
|
8
10
|
import { resolveBlueprintRoot } from "#utils/blueprint-root.js";
|
|
11
|
+
import { parseBlueprintDocumentRelativePath } from "#utils/document-paths.js";
|
|
9
12
|
export const statusLevelSchema = z.enum(["ready", "blocked", "partial", "unknown"]);
|
|
10
13
|
export const requiredCheckEvaluationSchema = z.object({
|
|
11
14
|
total: z.number().int().nonnegative(),
|
|
@@ -80,6 +83,11 @@ export const wpStatusSnapshotSchema = z.object({
|
|
|
80
83
|
});
|
|
81
84
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
82
85
|
const DEFAULT_MAX_OUTPUT_BYTES = 64_000;
|
|
86
|
+
// `gh pr view --json` includes the PR `body`, which alone can exceed the small
|
|
87
|
+
// caller diagnostic budget (GitHub bodies run to tens of KB). Parse that JSON
|
|
88
|
+
// against a generous semantic budget so mergeability/checks/blueprint-linkage
|
|
89
|
+
// fields are never lost to truncation; diagnostics keep the small caller budget.
|
|
90
|
+
const PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES = 1_048_576;
|
|
83
91
|
const DISCLOSURE_FIELDS = [
|
|
84
92
|
"Execution model(s)",
|
|
85
93
|
"Planning/refinement model(s)",
|
|
@@ -115,8 +123,8 @@ async function probe(cwd, command, args, options = {}) {
|
|
|
115
123
|
cwd,
|
|
116
124
|
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
117
125
|
});
|
|
126
|
+
const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
118
127
|
if ("error" in outcome) {
|
|
119
|
-
const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
120
128
|
return {
|
|
121
129
|
passed: false,
|
|
122
130
|
semanticStdout: "",
|
|
@@ -125,11 +133,11 @@ async function probe(cwd, command, args, options = {}) {
|
|
|
125
133
|
missingBinary: outcome.error.code === "ENOENT",
|
|
126
134
|
};
|
|
127
135
|
}
|
|
128
|
-
const
|
|
136
|
+
const semanticMaxOutputBytes = options.semanticMaxOutputBytes ?? maxOutputBytes;
|
|
129
137
|
return {
|
|
130
138
|
passed: outcome.exitCode === 0,
|
|
131
|
-
semanticStdout: clipBytes(outcome.stdout,
|
|
132
|
-
semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") >
|
|
139
|
+
semanticStdout: clipBytes(outcome.stdout, semanticMaxOutputBytes),
|
|
140
|
+
semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") > semanticMaxOutputBytes,
|
|
133
141
|
stdout: clipDiagnostic(outcome.stdout, maxOutputBytes),
|
|
134
142
|
stderr: clipDiagnostic(outcome.stderr, maxOutputBytes),
|
|
135
143
|
exitCode: outcome.exitCode,
|
|
@@ -203,12 +211,7 @@ function hasDisclosure(body, label) {
|
|
|
203
211
|
return new RegExp(`(?:^|\\n)\\s*(?:-\\s*)?${escaped}:\\s*\\S`, "iu").test(body);
|
|
204
212
|
}
|
|
205
213
|
function hasReleaseEvidence(pr) {
|
|
206
|
-
|
|
207
|
-
if (files.length > 0 && files.every((file) => file.endsWith(".md")))
|
|
208
|
-
return true;
|
|
209
|
-
if (files.some((file) => /^\.changeset\/[^/]+\.md$/u.test(file)))
|
|
210
|
-
return true;
|
|
211
|
-
return /Changeset-exempt:\s*\S/iu.test(stringField(pr.body) ?? "");
|
|
214
|
+
return hasChangesetEvidence(prFiles(pr), [stringField(pr.body) ?? ""]);
|
|
212
215
|
}
|
|
213
216
|
export function evaluatePrReadiness(evidence) {
|
|
214
217
|
const blockers = [];
|
|
@@ -307,33 +310,29 @@ function selectBlueprintFile(projectRoot, pr) {
|
|
|
307
310
|
const prefix = `${root}/`;
|
|
308
311
|
if (!file.path.startsWith(prefix))
|
|
309
312
|
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 }];
|
|
313
|
+
const parsed = parseBlueprintDocumentRelativePath(file.path.slice(prefix.length));
|
|
314
|
+
if (parsed)
|
|
315
|
+
return [{ ...file, stableSlug: parsed.slug }];
|
|
319
316
|
}
|
|
320
317
|
return [];
|
|
321
318
|
});
|
|
322
319
|
const priority = (file) => file.changeType === "ADDED" ? 0 : file.changeType === "RENAMED" ? 1 : 2;
|
|
323
320
|
return candidates.toSorted((left, right) => priority(left) - priority(right))[0];
|
|
324
321
|
}
|
|
325
|
-
function resolveBlueprintEvidence(
|
|
322
|
+
function resolveBlueprintEvidence(projectRoot, pr, targetHash) {
|
|
326
323
|
const blueprintFile = selectBlueprintFile(projectRoot, pr);
|
|
327
324
|
if (!blueprintFile || !targetHash)
|
|
328
325
|
return undefined;
|
|
329
326
|
try {
|
|
330
|
-
const authority = readReviewAuthorityAtRef(
|
|
327
|
+
const authority = readReviewAuthorityAtRef(projectRoot, targetHash, blueprintFile.stableSlug, "delivery");
|
|
331
328
|
if (authority.blueprintPath !== blueprintFile.path)
|
|
332
329
|
return undefined;
|
|
330
|
+
const approvals = collectV2ReviewProvenance(path.resolve(projectRoot, blueprintFile.path), "delivery", targetHash);
|
|
333
331
|
return {
|
|
334
332
|
path: blueprintFile.path,
|
|
335
333
|
lifecycle: authority.lifecycle,
|
|
336
|
-
approvalsSatisfied: evaluateApprovalReviewers(
|
|
334
|
+
approvalsSatisfied: evaluateApprovalReviewers(approvals.map((approval) => approval.reviewer))
|
|
335
|
+
.satisfied,
|
|
337
336
|
};
|
|
338
337
|
}
|
|
339
338
|
catch {
|
|
@@ -582,7 +581,10 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
582
581
|
"files",
|
|
583
582
|
].join(",");
|
|
584
583
|
const [view, checksProbe] = await Promise.all([
|
|
585
|
-
probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields],
|
|
584
|
+
probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields], {
|
|
585
|
+
...probeOptions,
|
|
586
|
+
semanticMaxOutputBytes: PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES,
|
|
587
|
+
}),
|
|
586
588
|
probe(cwd, "gh", ["pr", "checks", ...selector, "--required", "--json", "name,state,bucket,link,description"], probeOptions),
|
|
587
589
|
]);
|
|
588
590
|
pr = view.passed ? parseJsonObject(view.semanticStdout) : undefined;
|
|
@@ -599,7 +601,7 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
599
601
|
readGreptileComments(cwd, pr, probeOptions),
|
|
600
602
|
])
|
|
601
603
|
: [{ complete: false, warning: "PR metadata unavailable." }, { comments: [] }];
|
|
602
|
-
const blueprint = resolveBlueprintEvidence(
|
|
604
|
+
const blueprint = resolveBlueprintEvidence(firstLine(topLevel.semanticStdout) ?? cwd, pr, localHead);
|
|
603
605
|
const readiness = evaluatePrReadiness({
|
|
604
606
|
localHead,
|
|
605
607
|
dirtyWorktree,
|
|
@@ -649,9 +651,14 @@ export async function buildStatusSnapshot(options = {}) {
|
|
|
649
651
|
threadsComplete: threads.complete,
|
|
650
652
|
greptile: classifyGreptile(checks ?? [], greptileComments.comments, stringField(pr?.headRefOid)),
|
|
651
653
|
};
|
|
654
|
+
// `body` is fully consumed above (release-evidence + disclosure via
|
|
655
|
+
// `evaluatePrReadiness`, blueprint linkage via `resolveBlueprintEvidence`),
|
|
656
|
+
// so drop it from the emitted metadata to keep the payload from re-ballooning
|
|
657
|
+
// to the size that truncated the parse in the first place.
|
|
658
|
+
const { body: _body, ...metadataWithoutBody } = pr ?? {};
|
|
652
659
|
context.pr = {
|
|
653
660
|
selector: selector[0],
|
|
654
|
-
metadata: pr,
|
|
661
|
+
metadata: pr ? metadataWithoutBody : undefined,
|
|
655
662
|
checks: readiness.checks
|
|
656
663
|
? { ...readiness.checks, checks: [...readiness.checks.checks] }
|
|
657
664
|
: 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
|
+
}
|