@h-rig/bundle-default-lifecycle 0.0.6-alpha.133
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 +1 -0
- package/dist/src/closeoutEquivalence.d.ts +37 -0
- package/dist/src/closeoutEquivalence.js +78 -0
- package/dist/src/closeoutShadowHarness.d.ts +27 -0
- package/dist/src/closeoutShadowHarness.js +29 -0
- package/dist/src/defaultPipeline.d.ts +32 -0
- package/dist/src/defaultPipeline.js +191 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.js +535 -0
- package/dist/src/plugin.d.ts +18 -0
- package/dist/src/plugin.js +132 -0
- package/dist/src/stagedCloseout.d.ts +7 -0
- package/dist/src/stagedCloseout.js +325 -0
- package/dist/src/stages/auto-merge.d.ts +11 -0
- package/dist/src/stages/auto-merge.js +27 -0
- package/dist/src/stages/commit.d.ts +11 -0
- package/dist/src/stages/commit.js +27 -0
- package/dist/src/stages/isolation.d.ts +11 -0
- package/dist/src/stages/isolation.js +28 -0
- package/dist/src/stages/journal-append.d.ts +7 -0
- package/dist/src/stages/journal-append.js +25 -0
- package/dist/src/stages/merge-gate.d.ts +1 -0
- package/dist/src/stages/merge-gate.js +21 -0
- package/dist/src/stages/open-pr.d.ts +9 -0
- package/dist/src/stages/open-pr.js +41 -0
- package/dist/src/stages/push.d.ts +8 -0
- package/dist/src/stages/push.js +27 -0
- package/dist/src/stages/source-closeout.d.ts +18 -0
- package/dist/src/stages/source-closeout.js +36 -0
- package/dist/src/stages/types.d.ts +20 -0
- package/dist/src/stages/types.js +12 -0
- package/dist/src/stages/validate.d.ts +3 -0
- package/dist/src/stages/validate.js +24 -0
- package/dist/src/stages/verify.d.ts +7 -0
- package/dist/src/stages/verify.js +24 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @h-rig/bundle-default-lifecycle
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { InProcessCloseoutResult } from "@rig/runtime/control-plane/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;
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
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;
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ProtectedStageGrant, StageMutation } from "@rig/contracts";
|
|
2
|
+
import { type KernelStageResolverResult } from "@rig/kernel/resolver";
|
|
3
|
+
import type { DefaultLifecycleStageDescriptor, DefaultLifecycleStageId } from "./stages/types";
|
|
4
|
+
export declare const DEFAULT_LIFECYCLE_STAGE_IDS: readonly ["validate", "verify", "commit", "push", "open-pr", "merge-gate", "auto-merge", "source-closeout", "isolation", "journal-append"];
|
|
5
|
+
export declare const PROTECTED_DEFAULT_LIFECYCLE_STAGE_IDS: readonly ["merge-gate", "isolation", "journal-append"];
|
|
6
|
+
export declare const defaultLifecycleStages: readonly [DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor, DefaultLifecycleStageDescriptor];
|
|
7
|
+
export type ResolveDefaultLifecycleInput = {
|
|
8
|
+
readonly mutations?: readonly StageMutation[];
|
|
9
|
+
readonly protectedStageGrants?: readonly ProtectedStageGrant[];
|
|
10
|
+
};
|
|
11
|
+
export declare function defaultLifecycleStageById(id: DefaultLifecycleStageId): DefaultLifecycleStageDescriptor;
|
|
12
|
+
export declare function resolveDefaultLifecycle(input?: ResolveDefaultLifecycleInput): KernelStageResolverResult;
|
|
13
|
+
export type PipelineShowStage = {
|
|
14
|
+
readonly index: number | null;
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly contributedBy: string;
|
|
17
|
+
readonly protected: boolean;
|
|
18
|
+
readonly removedBy?: string;
|
|
19
|
+
readonly replacedBy?: string;
|
|
20
|
+
readonly wrappedBy: readonly string[];
|
|
21
|
+
readonly droppedAnchors: readonly string[];
|
|
22
|
+
};
|
|
23
|
+
export type PipelineShowData = {
|
|
24
|
+
readonly title: string;
|
|
25
|
+
readonly stageCount: number;
|
|
26
|
+
readonly stages: readonly PipelineShowStage[];
|
|
27
|
+
readonly droppedAnchors: readonly string[];
|
|
28
|
+
readonly cycles: readonly (readonly string[])[];
|
|
29
|
+
readonly resolvedAt?: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function defaultPipelineShowData(input?: ResolveDefaultLifecycleInput): PipelineShowData;
|
|
32
|
+
export declare function formatDefaultPipelineShow(input?: ResolveDefaultLifecycleInput): string;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/bundle-default-lifecycle/src/defaultPipeline.ts
|
|
3
|
+
import { resolveKernelStages } from "@rig/kernel/resolver";
|
|
4
|
+
|
|
5
|
+
// packages/bundle-default-lifecycle/src/stages/auto-merge.ts
|
|
6
|
+
import { runRepoDefaultMerge } from "@rig/runtime/control-plane/native/pr-automation";
|
|
7
|
+
|
|
8
|
+
// packages/bundle-default-lifecycle/src/stages/types.ts
|
|
9
|
+
function defineDefaultLifecycleStage(input) {
|
|
10
|
+
return {
|
|
11
|
+
...input,
|
|
12
|
+
protected: input.protected ?? false,
|
|
13
|
+
priority: input.priority ?? 0
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// packages/bundle-default-lifecycle/src/stages/auto-merge.ts
|
|
18
|
+
var autoMergeStage = defineDefaultLifecycleStage({
|
|
19
|
+
id: "auto-merge",
|
|
20
|
+
kind: "transform",
|
|
21
|
+
description: "Merge an approved PR using the repository default merge method through the runtime helper.",
|
|
22
|
+
calls: ["runRepoDefaultMerge"]
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// packages/bundle-default-lifecycle/src/stages/commit.ts
|
|
26
|
+
import { commitRunChanges } from "@rig/runtime/control-plane/native/pr-automation";
|
|
27
|
+
var commitStage = defineDefaultLifecycleStage({
|
|
28
|
+
id: "commit",
|
|
29
|
+
kind: "transform",
|
|
30
|
+
description: "Commit the agent worktree changes using the runtime git closeout helper.",
|
|
31
|
+
calls: ["commitRunChanges"]
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// packages/bundle-default-lifecycle/src/stages/isolation.ts
|
|
35
|
+
import { ensureAgentRuntime } from "@rig/runtime/control-plane/runtime/isolation";
|
|
36
|
+
var isolationStage = defineDefaultLifecycleStage({
|
|
37
|
+
id: "isolation",
|
|
38
|
+
kind: "transform",
|
|
39
|
+
description: "Provision the isolated runtime worktree through the runtime isolation subsystem.",
|
|
40
|
+
calls: ["ensureAgentRuntime"],
|
|
41
|
+
protected: true
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// packages/bundle-default-lifecycle/src/stages/journal-append.ts
|
|
45
|
+
var journalAppendStage = defineDefaultLifecycleStage({
|
|
46
|
+
id: "journal-append",
|
|
47
|
+
kind: "observe",
|
|
48
|
+
description: "Record resolved pipeline and per-stage outcome entries through the kernel journal capability.",
|
|
49
|
+
calls: ["journalCapability.append"],
|
|
50
|
+
protected: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// packages/bundle-default-lifecycle/src/stages/merge-gate.ts
|
|
54
|
+
var mergeGateStage = defineDefaultLifecycleStage({
|
|
55
|
+
id: "merge-gate",
|
|
56
|
+
kind: "gate",
|
|
57
|
+
description: "Enforce GitHub review state, required checks, and configured review gates through runtime PR automation.",
|
|
58
|
+
calls: ["runStrictPrMergeGate"],
|
|
59
|
+
protected: true
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// packages/bundle-default-lifecycle/src/stages/open-pr.ts
|
|
63
|
+
import { runPrAutomation } from "@rig/runtime/control-plane/native/pr-automation";
|
|
64
|
+
var openPrStage = defineDefaultLifecycleStage({
|
|
65
|
+
id: "open-pr",
|
|
66
|
+
kind: "transform",
|
|
67
|
+
description: "Open or reuse the closeout PR through the existing runtime PR automation seam.",
|
|
68
|
+
calls: ["runPrAutomation"]
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// packages/bundle-default-lifecycle/src/stages/push.ts
|
|
72
|
+
import { pushBranchSyncedWithOrigin } from "@rig/runtime/control-plane/native/pr-automation";
|
|
73
|
+
var pushStage = defineDefaultLifecycleStage({
|
|
74
|
+
id: "push",
|
|
75
|
+
kind: "transform",
|
|
76
|
+
description: "Synchronize and push the task branch using the runtime closeout git helper.",
|
|
77
|
+
calls: ["pushBranchSyncedWithOrigin"]
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// packages/bundle-default-lifecycle/src/stages/source-closeout.ts
|
|
81
|
+
import { closeIssueAfterMergedPr } from "@rig/runtime/control-plane/native/pr-automation";
|
|
82
|
+
var sourceCloseoutStage = defineDefaultLifecycleStage({
|
|
83
|
+
id: "source-closeout",
|
|
84
|
+
kind: "transform",
|
|
85
|
+
description: "Reflect the merged PR into the task source using the existing runtime closeout helper.",
|
|
86
|
+
calls: ["closeIssueAfterMergedPr"]
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// packages/bundle-default-lifecycle/src/stages/validate.ts
|
|
90
|
+
var validateStage = defineDefaultLifecycleStage({
|
|
91
|
+
id: "validate",
|
|
92
|
+
kind: "transform",
|
|
93
|
+
description: "Run plugin-host validators against the isolated worktree before closeout side effects.",
|
|
94
|
+
calls: ["taskValidate"]
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// packages/bundle-default-lifecycle/src/stages/verify.ts
|
|
98
|
+
var verifyStage = defineDefaultLifecycleStage({
|
|
99
|
+
id: "verify",
|
|
100
|
+
kind: "gate",
|
|
101
|
+
description: "Run the local verifier preflight and block closeout when it rejects the worktree.",
|
|
102
|
+
calls: ["verifierPreflight"]
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// packages/bundle-default-lifecycle/src/defaultPipeline.ts
|
|
106
|
+
var DEFAULT_LIFECYCLE_STAGE_IDS = [
|
|
107
|
+
"validate",
|
|
108
|
+
"verify",
|
|
109
|
+
"commit",
|
|
110
|
+
"push",
|
|
111
|
+
"open-pr",
|
|
112
|
+
"merge-gate",
|
|
113
|
+
"auto-merge",
|
|
114
|
+
"source-closeout",
|
|
115
|
+
"isolation",
|
|
116
|
+
"journal-append"
|
|
117
|
+
];
|
|
118
|
+
var PROTECTED_DEFAULT_LIFECYCLE_STAGE_IDS = ["merge-gate", "isolation", "journal-append"];
|
|
119
|
+
var defaultLifecycleStages = [
|
|
120
|
+
validateStage,
|
|
121
|
+
verifyStage,
|
|
122
|
+
commitStage,
|
|
123
|
+
pushStage,
|
|
124
|
+
openPrStage,
|
|
125
|
+
mergeGateStage,
|
|
126
|
+
autoMergeStage,
|
|
127
|
+
sourceCloseoutStage,
|
|
128
|
+
isolationStage,
|
|
129
|
+
journalAppendStage
|
|
130
|
+
];
|
|
131
|
+
function defaultLifecycleStageById(id) {
|
|
132
|
+
const stage = defaultLifecycleStages.find((candidate) => candidate.id === id);
|
|
133
|
+
if (!stage)
|
|
134
|
+
throw new Error(`Unknown default lifecycle stage: ${id}`);
|
|
135
|
+
return stage;
|
|
136
|
+
}
|
|
137
|
+
function resolveDefaultLifecycle(input = {}) {
|
|
138
|
+
const grants = { protectedStageGrants: input.protectedStageGrants ?? [] };
|
|
139
|
+
return resolveKernelStages(defaultLifecycleStages, input.mutations ?? [], grants);
|
|
140
|
+
}
|
|
141
|
+
function defaultPipelineShowData(input = {}) {
|
|
142
|
+
const resolved = resolveDefaultLifecycle(input);
|
|
143
|
+
const orderIndex = new Map(resolved.order.map((id, index) => [id, index + 1]));
|
|
144
|
+
const stages = resolved.record.map((entry) => ({
|
|
145
|
+
index: orderIndex.get(entry.stageId) ?? null,
|
|
146
|
+
id: entry.stageId,
|
|
147
|
+
contributedBy: entry.contributedBy,
|
|
148
|
+
protected: entry.isProtected,
|
|
149
|
+
...entry.removedBy !== undefined ? { removedBy: entry.removedBy } : {},
|
|
150
|
+
...entry.replacedBy !== undefined ? { replacedBy: entry.replacedBy } : {},
|
|
151
|
+
wrappedBy: entry.wrappedBy ?? [],
|
|
152
|
+
droppedAnchors: entry.droppedAnchors ?? []
|
|
153
|
+
}));
|
|
154
|
+
return {
|
|
155
|
+
title: `resolved run pipeline (${resolved.order.length} stages)`,
|
|
156
|
+
stageCount: resolved.order.length,
|
|
157
|
+
stages,
|
|
158
|
+
droppedAnchors: stages.flatMap((stage) => stage.droppedAnchors.map((anchor) => `${stage.id}:${anchor}`)),
|
|
159
|
+
cycles: resolved.cycles,
|
|
160
|
+
...resolved.resolvedAt !== undefined ? { resolvedAt: resolved.resolvedAt } : {}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function formatDefaultPipelineShow(input = {}) {
|
|
164
|
+
const data = defaultPipelineShowData(input);
|
|
165
|
+
const lines = [`${data.title}:`];
|
|
166
|
+
for (const stage of data.stages) {
|
|
167
|
+
if (stage.removedBy) {
|
|
168
|
+
lines.push(` - ${stage.id.padEnd(20)} [${stage.contributedBy}] removed by [${stage.removedBy}]${stage.protected ? " PROTECTED" : ""}`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const ordinal = stage.index === null ? " -." : `${String(stage.index).padStart(2)}.`;
|
|
172
|
+
const annotations = [
|
|
173
|
+
stage.protected ? "PROTECTED" : "",
|
|
174
|
+
stage.replacedBy ? `replaced by [${stage.replacedBy}]` : "",
|
|
175
|
+
stage.wrappedBy.length > 0 ? `wrapped by [${stage.wrappedBy.join(", ")}]` : ""
|
|
176
|
+
].filter(Boolean);
|
|
177
|
+
lines.push(` ${ordinal} ${stage.id.padEnd(20)} [${stage.contributedBy}]${annotations.length > 0 ? ` ${annotations.join(" ")}` : ""}`);
|
|
178
|
+
}
|
|
179
|
+
lines.push(`dropped anchors: ${data.droppedAnchors.length > 0 ? data.droppedAnchors.join(", ") : "none"} cycles: ${data.cycles.length > 0 ? data.cycles.map((cycle) => cycle.join(" -> ")).join(", ") : "none"}`);
|
|
180
|
+
return lines.join(`
|
|
181
|
+
`);
|
|
182
|
+
}
|
|
183
|
+
export {
|
|
184
|
+
resolveDefaultLifecycle,
|
|
185
|
+
formatDefaultPipelineShow,
|
|
186
|
+
defaultPipelineShowData,
|
|
187
|
+
defaultLifecycleStages,
|
|
188
|
+
defaultLifecycleStageById,
|
|
189
|
+
PROTECTED_DEFAULT_LIFECYCLE_STAGE_IDS,
|
|
190
|
+
DEFAULT_LIFECYCLE_STAGE_IDS
|
|
191
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "./closeoutEquivalence";
|
|
2
|
+
export * from "./closeoutShadowHarness";
|
|
3
|
+
export * from "./defaultPipeline";
|
|
4
|
+
export * from "./stagedCloseout";
|
|
5
|
+
export * from "./plugin";
|
|
6
|
+
export * from "./stages/auto-merge";
|
|
7
|
+
export * from "./stages/commit";
|
|
8
|
+
export * from "./stages/isolation";
|
|
9
|
+
export * from "./stages/journal-append";
|
|
10
|
+
export * from "./stages/merge-gate";
|
|
11
|
+
export * from "./stages/open-pr";
|
|
12
|
+
export * from "./stages/push";
|
|
13
|
+
export * from "./stages/source-closeout";
|
|
14
|
+
export * from "./stages/types";
|
|
15
|
+
export * from "./stages/validate";
|
|
16
|
+
export * from "./stages/verify";
|