@h-rig/bundle-default-lifecycle 0.0.6-alpha.157 → 0.0.6-alpha.159
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/dist/src/cli.d.ts +1 -7
- package/dist/src/cli.js +5 -2
- package/dist/src/control-plane/completion-verification.js +1591 -118
- package/dist/src/control-plane/hooks/inject-context.d.ts +2 -0
- package/dist/src/control-plane/hooks/inject-context.js +175 -0
- package/dist/src/control-plane/hooks/shared.d.ts +11 -0
- package/dist/src/control-plane/hooks/shared.js +44 -0
- package/dist/src/control-plane/hooks/submodule-branch.d.ts +2 -0
- package/dist/src/control-plane/hooks/submodule-branch.js +432 -0
- package/dist/src/control-plane/hooks/task-runtime-start.d.ts +2 -0
- package/dist/src/control-plane/hooks/task-runtime-start.js +429 -0
- package/dist/src/control-plane/materialize-task-config.d.ts +29 -0
- package/dist/src/control-plane/materialize-task-config.js +95 -0
- package/dist/src/control-plane/native/git-ops.d.ts +67 -0
- package/dist/src/control-plane/native/git-ops.js +1390 -0
- package/dist/src/control-plane/policy.d.ts +3 -0
- package/dist/src/control-plane/policy.js +226 -0
- package/dist/src/control-plane/pr-automation.d.ts +2 -0
- package/dist/src/control-plane/pr-automation.js +26 -16
- package/dist/src/control-plane/pr-merge-gate-cap.d.ts +10 -0
- package/dist/src/control-plane/pr-merge-gate-cap.js +13 -0
- package/dist/src/control-plane/task-data.d.ts +13 -0
- package/dist/src/control-plane/task-data.js +12 -0
- package/dist/src/control-plane/task-verify.js +131 -59
- package/dist/src/control-plane/verifier.d.ts +1 -3
- package/dist/src/control-plane/verifier.js +133 -57
- package/dist/src/defaultPipeline.d.ts +1 -1
- package/dist/src/defaultPipeline.js +5 -2
- package/dist/src/index.d.ts +0 -2
- package/dist/src/index.js +1908 -290
- package/dist/src/native/closeout-runners.js +22 -2
- package/dist/src/native/github-auth-env.d.ts +2 -0
- package/dist/src/native/github-auth-env.js +25 -0
- package/dist/src/native/host-git.d.ts +6 -0
- package/dist/src/native/host-git.js +62 -0
- package/dist/src/native/in-process-closeout.d.ts +1 -3
- package/dist/src/native/in-process-closeout.js +0 -794
- package/dist/src/pipelineCloseout.js +1905 -185
- package/dist/src/plugin.js +2843 -145
- package/dist/src/stages/auto-merge.js +28 -16
- package/dist/src/stages/commit.js +28 -16
- package/dist/src/stages/isolation.d.ts +1 -1
- package/dist/src/stages/isolation.js +5 -3
- package/dist/src/stages/merge-gate.js +35 -3
- package/dist/src/stages/open-pr.js +28 -16
- package/dist/src/stages/push.js +28 -16
- package/dist/src/stages/source-closeout.js +28 -16
- package/package.json +29 -16
- package/dist/src/branch-naming.d.ts +0 -15
- package/dist/src/branch-naming.js +0 -33
- package/dist/src/closeoutEquivalence.d.ts +0 -37
- package/dist/src/closeoutEquivalence.js +0 -78
- package/dist/src/closeoutShadowHarness.d.ts +0 -27
- package/dist/src/closeoutShadowHarness.js +0 -29
|
@@ -15,6 +15,19 @@ var __export = (target, all) => {
|
|
|
15
15
|
};
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
17
|
|
|
18
|
+
// packages/bundle-default-lifecycle/src/control-plane/pr-merge-gate-cap.ts
|
|
19
|
+
import { PR_MERGE_GATE } from "@rig/contracts";
|
|
20
|
+
import { defineCapability } from "@rig/core/capability";
|
|
21
|
+
import { resolvePluginHost } from "@rig/core/project-plugins";
|
|
22
|
+
async function resolvePrMergeGateService(projectRoot) {
|
|
23
|
+
const { host } = await resolvePluginHost(projectRoot);
|
|
24
|
+
return PrMergeGateCap.require(host);
|
|
25
|
+
}
|
|
26
|
+
var PrMergeGateCap;
|
|
27
|
+
var init_pr_merge_gate_cap = __esm(() => {
|
|
28
|
+
PrMergeGateCap = defineCapability(PR_MERGE_GATE);
|
|
29
|
+
});
|
|
30
|
+
|
|
18
31
|
// packages/bundle-default-lifecycle/src/control-plane/pr-automation.ts
|
|
19
32
|
var exports_pr_automation = {};
|
|
20
33
|
__export(exports_pr_automation, {
|
|
@@ -32,11 +45,7 @@ __export(exports_pr_automation, {
|
|
|
32
45
|
buildPrAutomationBody: () => buildPrAutomationBody,
|
|
33
46
|
UPLOADED_SNAPSHOT_PR_MARKER: () => UPLOADED_SNAPSHOT_PR_MARKER
|
|
34
47
|
});
|
|
35
|
-
import { assertSafeGitBranchName } from "@rig/
|
|
36
|
-
import { runStrictPrMergeGate } from "@rig/pr-review-plugin";
|
|
37
|
-
import {
|
|
38
|
-
strictMergeHeadShaFromGate
|
|
39
|
-
} from "@rig/contracts";
|
|
48
|
+
import { assertSafeGitBranchName } from "@rig/core/safe-identifiers";
|
|
40
49
|
function positiveInt(value, fallback) {
|
|
41
50
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
|
|
42
51
|
}
|
|
@@ -339,7 +348,7 @@ async function commitRunChanges(input) {
|
|
|
339
348
|
async function closeIssueAfterMergedPr(input) {
|
|
340
349
|
await input.updateTaskSource(input.projectRoot, {
|
|
341
350
|
taskId: input.taskId,
|
|
342
|
-
sourceTask: input.sourceTask,
|
|
351
|
+
...input.sourceTask !== undefined ? { sourceTask: input.sourceTask } : {},
|
|
343
352
|
update: {
|
|
344
353
|
status: "closed",
|
|
345
354
|
comment: [
|
|
@@ -385,11 +394,12 @@ async function runRepoDefaultMerge(input) {
|
|
|
385
394
|
if (merge.mode === "off")
|
|
386
395
|
return;
|
|
387
396
|
const requireGreptile = (input.config?.review?.provider ?? "greptile") === "greptile";
|
|
388
|
-
const
|
|
397
|
+
const mergeGate = await resolvePrMergeGateService(input.projectRoot ?? input.cwd ?? process.cwd());
|
|
398
|
+
const matchHeadSha = mergeGate.resolveHeadSha({ result: input.strictGate, prUrl: input.prUrl, requireGreptile });
|
|
389
399
|
const method = merge.method ?? "repo-default";
|
|
390
400
|
const args = ["pr", "merge", input.prUrl];
|
|
391
401
|
if (method === "repo-default") {
|
|
392
|
-
args.push(await resolveRepoDefaultMergeFlag({ prUrl: input.prUrl, command: input.command, cwd: input.cwd }));
|
|
402
|
+
args.push(await resolveRepoDefaultMergeFlag({ prUrl: input.prUrl, command: input.command, ...input.cwd !== undefined ? { cwd: input.cwd } : {} }));
|
|
393
403
|
} else {
|
|
394
404
|
args.push(`--${method}`);
|
|
395
405
|
}
|
|
@@ -466,6 +476,7 @@ async function syncBranchAfterPrFeedback(input) {
|
|
|
466
476
|
}
|
|
467
477
|
async function runPrAutomation(input) {
|
|
468
478
|
const branch = assertSafeGitBranchName(input.branch, "PR branch");
|
|
479
|
+
const mergeGate = await resolvePrMergeGateService(input.projectRoot);
|
|
469
480
|
const prConfig = input.config?.pr ?? {};
|
|
470
481
|
const requireGreptile = (input.config?.review?.provider ?? "greptile") === "greptile";
|
|
471
482
|
if (prConfig.mode === "off" || prConfig.mode === "ask") {
|
|
@@ -475,7 +486,7 @@ async function runPrAutomation(input) {
|
|
|
475
486
|
taskId: input.taskId,
|
|
476
487
|
runId: input.runId,
|
|
477
488
|
summary: input.sourceTask?.title ? `Rig completed: ${input.sourceTask.title}` : null,
|
|
478
|
-
uploadedSnapshot: input.uploadedSnapshot
|
|
489
|
+
...input.uploadedSnapshot !== undefined ? { uploadedSnapshot: input.uploadedSnapshot } : {}
|
|
479
490
|
});
|
|
480
491
|
if (input.gitCommand) {
|
|
481
492
|
await pushBranchSyncedWithOrigin({ projectRoot: input.projectRoot, branch, gitCommand: input.gitCommand });
|
|
@@ -547,16 +558,16 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
547
558
|
await syncBranchAfterPrFeedback({ projectRoot: input.projectRoot, taskId: input.taskId, branch, gitCommand: input.gitCommand });
|
|
548
559
|
continue;
|
|
549
560
|
}
|
|
550
|
-
const gate = await
|
|
561
|
+
const gate = await mergeGate.runGate({
|
|
551
562
|
projectRoot: input.projectRoot,
|
|
552
563
|
prUrl,
|
|
553
564
|
taskId: input.taskId,
|
|
554
565
|
runId: input.runId,
|
|
555
566
|
cycle: iteration,
|
|
556
567
|
command: input.command,
|
|
557
|
-
artifactRoot: input.artifactRoot,
|
|
568
|
+
...input.artifactRoot !== undefined ? { artifactRoot: input.artifactRoot } : {},
|
|
558
569
|
allowedFailures: input.config?.merge?.allowedFailures ?? [],
|
|
559
|
-
greptileApi
|
|
570
|
+
...requireGreptile && input.greptileApi ? { greptileApi: input.greptileApi } : {},
|
|
560
571
|
requireGreptile
|
|
561
572
|
});
|
|
562
573
|
latestFeedback = [...gate.actionableFeedback];
|
|
@@ -586,22 +597,22 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
586
597
|
}
|
|
587
598
|
if (gate.approved) {
|
|
588
599
|
pendingElapsedMs = 0;
|
|
589
|
-
const finalGate = await
|
|
600
|
+
const finalGate = await mergeGate.runGate({
|
|
590
601
|
projectRoot: input.projectRoot,
|
|
591
602
|
prUrl,
|
|
592
603
|
taskId: input.taskId,
|
|
593
604
|
runId: input.runId,
|
|
594
605
|
cycle: iteration,
|
|
595
606
|
command: input.command,
|
|
596
|
-
artifactRoot: input.artifactRoot,
|
|
607
|
+
...input.artifactRoot !== undefined ? { artifactRoot: input.artifactRoot } : {},
|
|
597
608
|
allowedFailures: input.config?.merge?.allowedFailures ?? [],
|
|
598
|
-
greptileApi
|
|
609
|
+
...requireGreptile && input.greptileApi ? { greptileApi: input.greptileApi } : {},
|
|
599
610
|
requireGreptile,
|
|
600
611
|
final: true
|
|
601
612
|
});
|
|
602
613
|
if (finalGate.approved) {
|
|
603
614
|
await input.lifecycle?.onMergeStarted?.({ prUrl });
|
|
604
|
-
await runRepoDefaultMerge({ prUrl, config: input.config, command: input.command, cwd: input.projectRoot, strictGate: finalGate });
|
|
615
|
+
await runRepoDefaultMerge({ prUrl, ...input.config !== undefined ? { config: input.config } : {}, command: input.command, cwd: input.projectRoot, strictGate: finalGate });
|
|
605
616
|
await input.lifecycle?.onMerged?.({ prUrl });
|
|
606
617
|
return { status: "merged", prUrl, iterations: iteration, actionableFeedback: [], merged: true };
|
|
607
618
|
}
|
|
@@ -648,6 +659,7 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
648
659
|
}
|
|
649
660
|
var UPLOADED_SNAPSHOT_PR_MARKER = "<!-- rig:uploaded-snapshot -->", RIG_RUNTIME_COMMIT_EXCLUDES, GREPTILE_REREVIEW_MARKER_PREFIX = "rig:greptile-rereview";
|
|
650
661
|
var init_pr_automation = __esm(() => {
|
|
662
|
+
init_pr_merge_gate_cap();
|
|
651
663
|
RIG_RUNTIME_COMMIT_EXCLUDES = [
|
|
652
664
|
".rig",
|
|
653
665
|
"artifacts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/bundle-default-lifecycle",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.159",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Default Rig run lifecycle stage bundle wrapping the existing closeout runtime.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -13,14 +13,6 @@
|
|
|
13
13
|
"types": "./dist/src/plugin.d.ts",
|
|
14
14
|
"import": "./dist/src/plugin.js"
|
|
15
15
|
},
|
|
16
|
-
"./closeout-equivalence": {
|
|
17
|
-
"types": "./dist/src/closeoutEquivalence.d.ts",
|
|
18
|
-
"import": "./dist/src/closeoutEquivalence.js"
|
|
19
|
-
},
|
|
20
|
-
"./closeout-shadow-harness": {
|
|
21
|
-
"types": "./dist/src/closeoutShadowHarness.d.ts",
|
|
22
|
-
"import": "./dist/src/closeoutShadowHarness.js"
|
|
23
|
-
},
|
|
24
16
|
"./default-pipeline": {
|
|
25
17
|
"types": "./dist/src/defaultPipeline.d.ts",
|
|
26
18
|
"import": "./dist/src/defaultPipeline.js"
|
|
@@ -56,6 +48,30 @@
|
|
|
56
48
|
"./control-plane/verifier": {
|
|
57
49
|
"types": "./dist/src/control-plane/verifier.d.ts",
|
|
58
50
|
"import": "./dist/src/control-plane/verifier.js"
|
|
51
|
+
},
|
|
52
|
+
"./control-plane/native/git-ops": {
|
|
53
|
+
"types": "./dist/src/control-plane/native/git-ops.d.ts",
|
|
54
|
+
"import": "./dist/src/control-plane/native/git-ops.js"
|
|
55
|
+
},
|
|
56
|
+
"./control-plane/materialize-task-config": {
|
|
57
|
+
"types": "./dist/src/control-plane/materialize-task-config.d.ts",
|
|
58
|
+
"import": "./dist/src/control-plane/materialize-task-config.js"
|
|
59
|
+
},
|
|
60
|
+
"./control-plane/hooks/inject-context": {
|
|
61
|
+
"types": "./dist/src/control-plane/hooks/inject-context.d.ts",
|
|
62
|
+
"import": "./dist/src/control-plane/hooks/inject-context.js"
|
|
63
|
+
},
|
|
64
|
+
"./control-plane/hooks/task-runtime-start": {
|
|
65
|
+
"types": "./dist/src/control-plane/hooks/task-runtime-start.d.ts",
|
|
66
|
+
"import": "./dist/src/control-plane/hooks/task-runtime-start.js"
|
|
67
|
+
},
|
|
68
|
+
"./control-plane/hooks/submodule-branch": {
|
|
69
|
+
"types": "./dist/src/control-plane/hooks/submodule-branch.d.ts",
|
|
70
|
+
"import": "./dist/src/control-plane/hooks/submodule-branch.js"
|
|
71
|
+
},
|
|
72
|
+
"./control-plane/hooks/shared": {
|
|
73
|
+
"types": "./dist/src/control-plane/hooks/shared.d.ts",
|
|
74
|
+
"import": "./dist/src/control-plane/hooks/shared.js"
|
|
59
75
|
}
|
|
60
76
|
},
|
|
61
77
|
"engines": {
|
|
@@ -65,12 +81,9 @@
|
|
|
65
81
|
"module": "./dist/src/index.js",
|
|
66
82
|
"types": "./dist/src/index.d.ts",
|
|
67
83
|
"dependencies": {
|
|
68
|
-
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.
|
|
69
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
70
|
-
"@rig/hook-kit": "npm:@h-rig/hook-kit@0.0.6-alpha.
|
|
71
|
-
"@rig/kernel": "npm:@h-rig/kernel@0.0.6-alpha.
|
|
72
|
-
"@rig/pr-review-plugin": "npm:@h-rig/pr-review-plugin@0.0.6-alpha.157",
|
|
73
|
-
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.157",
|
|
74
|
-
"@rig/shared": "npm:@h-rig/shared@0.0.6-alpha.157"
|
|
84
|
+
"@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.159",
|
|
85
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.159",
|
|
86
|
+
"@rig/hook-kit": "npm:@h-rig/hook-kit@0.0.6-alpha.159",
|
|
87
|
+
"@rig/kernel-seed": "npm:@h-rig/kernel-seed@0.0.6-alpha.159"
|
|
75
88
|
}
|
|
76
89
|
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sanitize an arbitrary string into a valid, lowercase git branch fragment.
|
|
3
|
-
* Strips quotes, collapses separators, limits to 64 chars.
|
|
4
|
-
*/
|
|
5
|
-
export declare function sanitizeBranchFragment(raw: string): string;
|
|
6
|
-
/**
|
|
7
|
-
* Sanitize a string into a `feature/…` branch name.
|
|
8
|
-
* Preserves an existing `feature/` prefix or slash-separated namespace.
|
|
9
|
-
*/
|
|
10
|
-
export declare function sanitizeFeatureBranchName(raw: string): string;
|
|
11
|
-
/**
|
|
12
|
-
* Resolve a unique `feature/…` branch name that doesn't collide with
|
|
13
|
-
* any existing branch. Appends a numeric suffix when needed.
|
|
14
|
-
*/
|
|
15
|
-
export declare function resolveAutoFeatureBranchName(existingBranchNames: readonly string[], preferredBranch?: string): string;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/bundle-default-lifecycle/src/branch-naming.ts
|
|
3
|
-
function sanitizeBranchFragment(raw) {
|
|
4
|
-
const normalized = raw.trim().toLowerCase().replace(/['"`]/g, "").replace(/^[./\s_-]+|[./\s_-]+$/g, "");
|
|
5
|
-
const branchFragment = normalized.replace(/[^a-z0-9/_-]+/g, "-").replace(/\/+/g, "/").replace(/-+/g, "-").replace(/^[./_-]+|[./_-]+$/g, "").slice(0, 64).replace(/[./_-]+$/g, "");
|
|
6
|
-
return branchFragment.length > 0 ? branchFragment : "update";
|
|
7
|
-
}
|
|
8
|
-
function sanitizeFeatureBranchName(raw) {
|
|
9
|
-
const sanitized = sanitizeBranchFragment(raw);
|
|
10
|
-
if (sanitized.includes("/")) {
|
|
11
|
-
return sanitized.startsWith("feature/") ? sanitized : `feature/${sanitized}`;
|
|
12
|
-
}
|
|
13
|
-
return `feature/${sanitized}`;
|
|
14
|
-
}
|
|
15
|
-
var AUTO_FEATURE_BRANCH_FALLBACK = "feature/update";
|
|
16
|
-
function resolveAutoFeatureBranchName(existingBranchNames, preferredBranch) {
|
|
17
|
-
const preferred = preferredBranch?.trim();
|
|
18
|
-
const resolvedBase = sanitizeFeatureBranchName(preferred && preferred.length > 0 ? preferred : AUTO_FEATURE_BRANCH_FALLBACK);
|
|
19
|
-
const existingNames = new Set(existingBranchNames.map((branch) => branch.toLowerCase()));
|
|
20
|
-
if (!existingNames.has(resolvedBase)) {
|
|
21
|
-
return resolvedBase;
|
|
22
|
-
}
|
|
23
|
-
let suffix = 2;
|
|
24
|
-
while (existingNames.has(`${resolvedBase}-${suffix}`)) {
|
|
25
|
-
suffix += 1;
|
|
26
|
-
}
|
|
27
|
-
return `${resolvedBase}-${suffix}`;
|
|
28
|
-
}
|
|
29
|
-
export {
|
|
30
|
-
sanitizeFeatureBranchName,
|
|
31
|
-
sanitizeBranchFragment,
|
|
32
|
-
resolveAutoFeatureBranchName
|
|
33
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { InProcessCloseoutResult } from "./native/in-process-closeout";
|
|
2
|
-
export declare const CLOSEOUT_EQUIVALENCE_ARTIFACTS: readonly ["review-status.txt", "review-feedback.md", "review-state.json", "pr-state.json", "git-state.txt", "validation-summary.json"];
|
|
3
|
-
export declare const CLOSEOUT_EQUIVALENCE_STATE_FILES: readonly ["task-repo-commits.json", "failed_approaches.md"];
|
|
4
|
-
export type CloseoutEquivalenceArtifactName = typeof CLOSEOUT_EQUIVALENCE_ARTIFACTS[number] | typeof CLOSEOUT_EQUIVALENCE_STATE_FILES[number];
|
|
5
|
-
export type CloseoutArtifactSnapshot = Readonly<Record<CloseoutEquivalenceArtifactName, string | null>>;
|
|
6
|
-
export type CloseoutTaskSourceCall = {
|
|
7
|
-
readonly method: string;
|
|
8
|
-
readonly taskId: string;
|
|
9
|
-
readonly status?: string;
|
|
10
|
-
readonly summary?: string;
|
|
11
|
-
};
|
|
12
|
-
export type CloseoutEquivalenceRun = {
|
|
13
|
-
readonly label: "imperative" | "staged";
|
|
14
|
-
readonly result: InProcessCloseoutResult;
|
|
15
|
-
readonly artifacts: CloseoutArtifactSnapshot;
|
|
16
|
-
readonly taskSourceCalls: readonly CloseoutTaskSourceCall[];
|
|
17
|
-
};
|
|
18
|
-
export type CloseoutEquivalenceDiff = {
|
|
19
|
-
readonly kind: "artifact" | "task-source" | "result";
|
|
20
|
-
readonly path: string;
|
|
21
|
-
readonly imperative: string | null;
|
|
22
|
-
readonly staged: string | null;
|
|
23
|
-
};
|
|
24
|
-
export type CloseoutEquivalenceReport = {
|
|
25
|
-
readonly equivalent: boolean;
|
|
26
|
-
readonly diffs: readonly CloseoutEquivalenceDiff[];
|
|
27
|
-
};
|
|
28
|
-
export declare function snapshotCloseoutArtifacts(input: {
|
|
29
|
-
readonly projectRoot: string;
|
|
30
|
-
readonly taskId: string;
|
|
31
|
-
readonly artifactRoot?: string;
|
|
32
|
-
readonly stateRoot?: string;
|
|
33
|
-
}): CloseoutArtifactSnapshot;
|
|
34
|
-
export declare function compareCloseoutEquivalence(input: {
|
|
35
|
-
readonly imperative: CloseoutEquivalenceRun;
|
|
36
|
-
readonly staged: CloseoutEquivalenceRun;
|
|
37
|
-
}): CloseoutEquivalenceReport;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/bundle-default-lifecycle/src/closeoutEquivalence.ts
|
|
3
|
-
import { existsSync, readFileSync } from "fs";
|
|
4
|
-
import { resolve } from "path";
|
|
5
|
-
var CLOSEOUT_EQUIVALENCE_ARTIFACTS = [
|
|
6
|
-
"review-status.txt",
|
|
7
|
-
"review-feedback.md",
|
|
8
|
-
"review-state.json",
|
|
9
|
-
"pr-state.json",
|
|
10
|
-
"git-state.txt",
|
|
11
|
-
"validation-summary.json"
|
|
12
|
-
];
|
|
13
|
-
var CLOSEOUT_EQUIVALENCE_STATE_FILES = [
|
|
14
|
-
"task-repo-commits.json",
|
|
15
|
-
"failed_approaches.md"
|
|
16
|
-
];
|
|
17
|
-
function snapshotCloseoutArtifacts(input) {
|
|
18
|
-
const artifactRoot = input.artifactRoot ?? resolve(input.projectRoot, "artifacts", input.taskId);
|
|
19
|
-
const stateRoot = input.stateRoot ?? resolve(input.projectRoot, ".rig", "state");
|
|
20
|
-
const entries = [
|
|
21
|
-
...CLOSEOUT_EQUIVALENCE_ARTIFACTS.map((name) => {
|
|
22
|
-
const path = resolve(artifactRoot, name);
|
|
23
|
-
return [name, existsSync(path) ? readFileSync(path, "utf-8") : null];
|
|
24
|
-
}),
|
|
25
|
-
...CLOSEOUT_EQUIVALENCE_STATE_FILES.map((name) => {
|
|
26
|
-
const path = resolve(stateRoot, name);
|
|
27
|
-
return [name, existsSync(path) ? readFileSync(path, "utf-8") : null];
|
|
28
|
-
})
|
|
29
|
-
];
|
|
30
|
-
return Object.fromEntries(entries);
|
|
31
|
-
}
|
|
32
|
-
function compareCloseoutEquivalence(input) {
|
|
33
|
-
const diffs = [];
|
|
34
|
-
for (const name of [...CLOSEOUT_EQUIVALENCE_ARTIFACTS, ...CLOSEOUT_EQUIVALENCE_STATE_FILES]) {
|
|
35
|
-
const imperative = input.imperative.artifacts[name];
|
|
36
|
-
const staged = input.staged.artifacts[name];
|
|
37
|
-
if (imperative !== staged) {
|
|
38
|
-
diffs.push({ kind: "artifact", path: name, imperative, staged });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const imperativeCalls = JSON.stringify(input.imperative.taskSourceCalls.map((call) => ({
|
|
42
|
-
method: call.method,
|
|
43
|
-
taskId: call.taskId,
|
|
44
|
-
status: call.status ?? null,
|
|
45
|
-
summary: call.summary ?? null
|
|
46
|
-
})));
|
|
47
|
-
const stagedCalls = JSON.stringify(input.staged.taskSourceCalls.map((call) => ({
|
|
48
|
-
method: call.method,
|
|
49
|
-
taskId: call.taskId,
|
|
50
|
-
status: call.status ?? null,
|
|
51
|
-
summary: call.summary ?? null
|
|
52
|
-
})));
|
|
53
|
-
if (imperativeCalls !== stagedCalls) {
|
|
54
|
-
diffs.push({ kind: "task-source", path: "task-source-calls", imperative: imperativeCalls, staged: stagedCalls });
|
|
55
|
-
}
|
|
56
|
-
const imperativeResult = JSON.stringify({
|
|
57
|
-
status: input.imperative.result.status,
|
|
58
|
-
prUrl: input.imperative.result.prUrl ?? null,
|
|
59
|
-
iterations: input.imperative.result.iterations,
|
|
60
|
-
feedback: [...input.imperative.result.feedback]
|
|
61
|
-
});
|
|
62
|
-
const stagedResult = JSON.stringify({
|
|
63
|
-
status: input.staged.result.status,
|
|
64
|
-
prUrl: input.staged.result.prUrl ?? null,
|
|
65
|
-
iterations: input.staged.result.iterations,
|
|
66
|
-
feedback: [...input.staged.result.feedback]
|
|
67
|
-
});
|
|
68
|
-
if (imperativeResult !== stagedResult) {
|
|
69
|
-
diffs.push({ kind: "result", path: "closeout-result", imperative: imperativeResult, staged: stagedResult });
|
|
70
|
-
}
|
|
71
|
-
return { equivalent: diffs.length === 0, diffs };
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
snapshotCloseoutArtifacts,
|
|
75
|
-
compareCloseoutEquivalence,
|
|
76
|
-
CLOSEOUT_EQUIVALENCE_STATE_FILES,
|
|
77
|
-
CLOSEOUT_EQUIVALENCE_ARTIFACTS
|
|
78
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export type CloseoutShadowEffectKind = "git-push" | "pr-open" | "review-gate" | "merge" | "task-source";
|
|
2
|
-
export type CloseoutShadowEffect = {
|
|
3
|
-
readonly kind: CloseoutShadowEffectKind;
|
|
4
|
-
readonly target: string;
|
|
5
|
-
readonly detail?: string;
|
|
6
|
-
};
|
|
7
|
-
export type CloseoutShadowRun = {
|
|
8
|
-
readonly label: "imperative" | "staged";
|
|
9
|
-
readonly effects: readonly CloseoutShadowEffect[];
|
|
10
|
-
};
|
|
11
|
-
export type CloseoutShadowDiff = {
|
|
12
|
-
readonly index: number;
|
|
13
|
-
readonly imperative: CloseoutShadowEffect | null;
|
|
14
|
-
readonly staged: CloseoutShadowEffect | null;
|
|
15
|
-
};
|
|
16
|
-
export type CloseoutShadowComparison = {
|
|
17
|
-
readonly equivalent: boolean;
|
|
18
|
-
readonly diffs: readonly CloseoutShadowDiff[];
|
|
19
|
-
};
|
|
20
|
-
export declare function compareCloseoutShadowRuns(input: {
|
|
21
|
-
readonly imperative: CloseoutShadowRun;
|
|
22
|
-
readonly staged: CloseoutShadowRun;
|
|
23
|
-
}): CloseoutShadowComparison;
|
|
24
|
-
export declare function assertCloseoutShadowEquivalent(input: {
|
|
25
|
-
readonly imperative: CloseoutShadowRun;
|
|
26
|
-
readonly staged: CloseoutShadowRun;
|
|
27
|
-
}): CloseoutShadowComparison;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/bundle-default-lifecycle/src/closeoutShadowHarness.ts
|
|
3
|
-
function effectKey(effect) {
|
|
4
|
-
return effect === null ? null : JSON.stringify({ kind: effect.kind, target: effect.target, detail: effect.detail ?? null });
|
|
5
|
-
}
|
|
6
|
-
function compareCloseoutShadowRuns(input) {
|
|
7
|
-
const max = Math.max(input.imperative.effects.length, input.staged.effects.length);
|
|
8
|
-
const diffs = [];
|
|
9
|
-
for (let index = 0;index < max; index += 1) {
|
|
10
|
-
const imperative = input.imperative.effects[index] ?? null;
|
|
11
|
-
const staged = input.staged.effects[index] ?? null;
|
|
12
|
-
if (effectKey(imperative) !== effectKey(staged)) {
|
|
13
|
-
diffs.push({ index, imperative, staged });
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return { equivalent: diffs.length === 0, diffs };
|
|
17
|
-
}
|
|
18
|
-
function assertCloseoutShadowEquivalent(input) {
|
|
19
|
-
const comparison = compareCloseoutShadowRuns(input);
|
|
20
|
-
if (!comparison.equivalent) {
|
|
21
|
-
const details = comparison.diffs.map((diff) => `#${diff.index}: imperative=${effectKey(diff.imperative) ?? "<missing>"} staged=${effectKey(diff.staged) ?? "<missing>"}`).join("; ");
|
|
22
|
-
throw new Error(`Closeout shadow side effects differ: ${details}`);
|
|
23
|
-
}
|
|
24
|
-
return comparison;
|
|
25
|
-
}
|
|
26
|
-
export {
|
|
27
|
-
compareCloseoutShadowRuns,
|
|
28
|
-
assertCloseoutShadowEquivalent
|
|
29
|
-
};
|