@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
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/bundle-default-lifecycle/src/control-plane/policy.ts
|
|
3
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
import {
|
|
6
|
+
POLICY_VERSION
|
|
7
|
+
} from "@rig/contracts";
|
|
8
|
+
var DEFAULT_SCOPE = {
|
|
9
|
+
fail_closed: true,
|
|
10
|
+
harness_paths_exempt: true,
|
|
11
|
+
runtime_paths_exempt: true
|
|
12
|
+
};
|
|
13
|
+
var DEFAULT_SANDBOX = {
|
|
14
|
+
mode: "enforce",
|
|
15
|
+
network: true,
|
|
16
|
+
read_deny: [],
|
|
17
|
+
write_allow_from_runtime: true
|
|
18
|
+
};
|
|
19
|
+
var DEFAULT_ISOLATION = {
|
|
20
|
+
default_mode: "worktree",
|
|
21
|
+
repo_symlink_fallback: false,
|
|
22
|
+
strict_provisioning: true,
|
|
23
|
+
fail_closed_on_provision_error: true
|
|
24
|
+
};
|
|
25
|
+
var DEFAULT_COMPLETION = {
|
|
26
|
+
derive_checks_from_scope: true,
|
|
27
|
+
checks: [],
|
|
28
|
+
typescript_config_probe: ["tsconfig.json"],
|
|
29
|
+
eslint_config_probe: [".eslintrc.js", ".eslintrc.json", "eslint.config.js"]
|
|
30
|
+
};
|
|
31
|
+
var DEFAULT_RUNTIME_IMAGE = {
|
|
32
|
+
deps: {
|
|
33
|
+
monorepo_install: false,
|
|
34
|
+
hp_next_install: false
|
|
35
|
+
},
|
|
36
|
+
plugins_require_binaries: true
|
|
37
|
+
};
|
|
38
|
+
var DEFAULT_RUNTIME_SNAPSHOT = {
|
|
39
|
+
enabled: true
|
|
40
|
+
};
|
|
41
|
+
var policyCache = null;
|
|
42
|
+
var policyCachePath = null;
|
|
43
|
+
var seededPolicyConfig = null;
|
|
44
|
+
function defaultPolicy() {
|
|
45
|
+
return {
|
|
46
|
+
version: POLICY_VERSION,
|
|
47
|
+
mode: "enforce",
|
|
48
|
+
scope: { ...DEFAULT_SCOPE },
|
|
49
|
+
rules: [],
|
|
50
|
+
sandbox: { ...DEFAULT_SANDBOX },
|
|
51
|
+
isolation: { ...DEFAULT_ISOLATION },
|
|
52
|
+
completion: { ...DEFAULT_COMPLETION },
|
|
53
|
+
runtime_image: {
|
|
54
|
+
deps: { ...DEFAULT_RUNTIME_IMAGE.deps },
|
|
55
|
+
plugins_require_binaries: DEFAULT_RUNTIME_IMAGE.plugins_require_binaries
|
|
56
|
+
},
|
|
57
|
+
runtime_snapshot: { ...DEFAULT_RUNTIME_SNAPSHOT }
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function seedPolicyFromContent(rawJson) {
|
|
61
|
+
try {
|
|
62
|
+
seededPolicyConfig = mergeWithDefaults(JSON.parse(rawJson));
|
|
63
|
+
} catch {
|
|
64
|
+
seededPolicyConfig = null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function loadPolicy(projectRoot) {
|
|
68
|
+
if (seededPolicyConfig) {
|
|
69
|
+
return seededPolicyConfig;
|
|
70
|
+
}
|
|
71
|
+
const configPath = resolve(projectRoot, "rig/policy/policy.json");
|
|
72
|
+
if (!existsSync(configPath)) {
|
|
73
|
+
return defaultPolicy();
|
|
74
|
+
}
|
|
75
|
+
let mtimeMs;
|
|
76
|
+
try {
|
|
77
|
+
mtimeMs = statSync(configPath).mtimeMs;
|
|
78
|
+
} catch {
|
|
79
|
+
return defaultPolicy();
|
|
80
|
+
}
|
|
81
|
+
if (policyCache && policyCachePath === configPath && policyCache.mtimeMs === mtimeMs) {
|
|
82
|
+
return policyCache.config;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const config = mergeWithDefaults(JSON.parse(readFileSync(configPath, "utf-8")));
|
|
86
|
+
policyCache = { mtimeMs, config };
|
|
87
|
+
policyCachePath = configPath;
|
|
88
|
+
return config;
|
|
89
|
+
} catch {
|
|
90
|
+
return defaultPolicy();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function mergeWithDefaults(parsed) {
|
|
94
|
+
const base = defaultPolicy();
|
|
95
|
+
if (typeof parsed.mode === "string" && isValidMode(parsed.mode)) {
|
|
96
|
+
base.mode = parsed.mode;
|
|
97
|
+
}
|
|
98
|
+
if (parsed.scope && typeof parsed.scope === "object" && !Array.isArray(parsed.scope)) {
|
|
99
|
+
const scope = parsed.scope;
|
|
100
|
+
if (typeof scope.fail_closed === "boolean")
|
|
101
|
+
base.scope.fail_closed = scope.fail_closed;
|
|
102
|
+
if (typeof scope.harness_paths_exempt === "boolean")
|
|
103
|
+
base.scope.harness_paths_exempt = scope.harness_paths_exempt;
|
|
104
|
+
if (typeof scope.runtime_paths_exempt === "boolean")
|
|
105
|
+
base.scope.runtime_paths_exempt = scope.runtime_paths_exempt;
|
|
106
|
+
}
|
|
107
|
+
if (Array.isArray(parsed.rules)) {
|
|
108
|
+
base.rules = precompilePolicyRuleRegexes(parsed.rules.filter(isValidRule));
|
|
109
|
+
}
|
|
110
|
+
if (Array.isArray(parsed.deny) && base.rules.length === 0) {
|
|
111
|
+
base.rules = precompilePolicyRuleRegexes(migrateLegacyDeny(parsed.deny));
|
|
112
|
+
}
|
|
113
|
+
if (parsed.sandbox && typeof parsed.sandbox === "object" && !Array.isArray(parsed.sandbox)) {
|
|
114
|
+
const sandbox = parsed.sandbox;
|
|
115
|
+
if (typeof sandbox.mode === "string" && isValidMode(sandbox.mode))
|
|
116
|
+
base.sandbox.mode = sandbox.mode;
|
|
117
|
+
if (typeof sandbox.network === "boolean")
|
|
118
|
+
base.sandbox.network = sandbox.network;
|
|
119
|
+
if (Array.isArray(sandbox.read_deny))
|
|
120
|
+
base.sandbox.read_deny = sandbox.read_deny.filter((value) => typeof value === "string");
|
|
121
|
+
if (typeof sandbox.write_allow_from_runtime === "boolean")
|
|
122
|
+
base.sandbox.write_allow_from_runtime = sandbox.write_allow_from_runtime;
|
|
123
|
+
}
|
|
124
|
+
if (parsed.isolation && typeof parsed.isolation === "object" && !Array.isArray(parsed.isolation)) {
|
|
125
|
+
const isolation = parsed.isolation;
|
|
126
|
+
if (isolation.default_mode === "worktree")
|
|
127
|
+
base.isolation.default_mode = isolation.default_mode;
|
|
128
|
+
if (typeof isolation.repo_symlink_fallback === "boolean")
|
|
129
|
+
base.isolation.repo_symlink_fallback = isolation.repo_symlink_fallback;
|
|
130
|
+
if (typeof isolation.strict_provisioning === "boolean")
|
|
131
|
+
base.isolation.strict_provisioning = isolation.strict_provisioning;
|
|
132
|
+
if (typeof isolation.fail_closed_on_provision_error === "boolean")
|
|
133
|
+
base.isolation.fail_closed_on_provision_error = isolation.fail_closed_on_provision_error;
|
|
134
|
+
}
|
|
135
|
+
if (parsed.completion && typeof parsed.completion === "object" && !Array.isArray(parsed.completion)) {
|
|
136
|
+
const completion = parsed.completion;
|
|
137
|
+
if (typeof completion.derive_checks_from_scope === "boolean")
|
|
138
|
+
base.completion.derive_checks_from_scope = completion.derive_checks_from_scope;
|
|
139
|
+
if (Array.isArray(completion.checks))
|
|
140
|
+
base.completion.checks = completion.checks.filter((value) => typeof value === "string");
|
|
141
|
+
if (Array.isArray(completion.typescript_config_probe))
|
|
142
|
+
base.completion.typescript_config_probe = completion.typescript_config_probe.filter((value) => typeof value === "string");
|
|
143
|
+
if (Array.isArray(completion.eslint_config_probe))
|
|
144
|
+
base.completion.eslint_config_probe = completion.eslint_config_probe.filter((value) => typeof value === "string");
|
|
145
|
+
}
|
|
146
|
+
if (parsed.runtime_image && typeof parsed.runtime_image === "object" && !Array.isArray(parsed.runtime_image)) {
|
|
147
|
+
const runtimeImage = parsed.runtime_image;
|
|
148
|
+
if (runtimeImage.deps && typeof runtimeImage.deps === "object" && !Array.isArray(runtimeImage.deps)) {
|
|
149
|
+
const deps = runtimeImage.deps;
|
|
150
|
+
if (typeof deps.monorepo_install === "boolean")
|
|
151
|
+
base.runtime_image.deps.monorepo_install = deps.monorepo_install;
|
|
152
|
+
if (typeof deps.hp_next_install === "boolean")
|
|
153
|
+
base.runtime_image.deps.hp_next_install = deps.hp_next_install;
|
|
154
|
+
}
|
|
155
|
+
if (typeof runtimeImage.plugins_require_binaries === "boolean") {
|
|
156
|
+
base.runtime_image.plugins_require_binaries = runtimeImage.plugins_require_binaries;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (parsed.runtime_snapshot && typeof parsed.runtime_snapshot === "object" && !Array.isArray(parsed.runtime_snapshot)) {
|
|
160
|
+
const runtimeSnapshot = parsed.runtime_snapshot;
|
|
161
|
+
if (typeof runtimeSnapshot.enabled === "boolean")
|
|
162
|
+
base.runtime_snapshot.enabled = runtimeSnapshot.enabled;
|
|
163
|
+
}
|
|
164
|
+
return base;
|
|
165
|
+
}
|
|
166
|
+
function isValidMode(value) {
|
|
167
|
+
return value === "off" || value === "observe" || value === "enforce";
|
|
168
|
+
}
|
|
169
|
+
function isValidRule(value) {
|
|
170
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
171
|
+
return false;
|
|
172
|
+
const rule = value;
|
|
173
|
+
return typeof rule.id === "string" && typeof rule.category === "string" && !!rule.match && typeof rule.match === "object";
|
|
174
|
+
}
|
|
175
|
+
function migrateLegacyDeny(deny) {
|
|
176
|
+
const rules = [];
|
|
177
|
+
for (const entry of deny) {
|
|
178
|
+
if (typeof entry.id !== "string")
|
|
179
|
+
continue;
|
|
180
|
+
const match = {};
|
|
181
|
+
if (typeof entry.pattern === "string")
|
|
182
|
+
match.pattern = entry.pattern;
|
|
183
|
+
if (typeof entry.regex === "string")
|
|
184
|
+
match.regex = entry.regex;
|
|
185
|
+
if (!match.pattern && !match.regex)
|
|
186
|
+
continue;
|
|
187
|
+
const rule = {
|
|
188
|
+
id: entry.id,
|
|
189
|
+
category: "command",
|
|
190
|
+
match,
|
|
191
|
+
action: entry.action === "warn" ? "warn" : "block"
|
|
192
|
+
};
|
|
193
|
+
if (typeof entry.reason === "string") {
|
|
194
|
+
rule.description = entry.reason;
|
|
195
|
+
}
|
|
196
|
+
rules.push(rule);
|
|
197
|
+
}
|
|
198
|
+
return rules;
|
|
199
|
+
}
|
|
200
|
+
function precompilePolicyRuleRegexes(rules) {
|
|
201
|
+
return rules.map((rule) => {
|
|
202
|
+
const compiled = { ...rule };
|
|
203
|
+
const matchRegex = compileRegex(rule.match?.regex);
|
|
204
|
+
const unlessRegex = compileRegex(rule.unless?.regex);
|
|
205
|
+
if (matchRegex) {
|
|
206
|
+
compiled.compiledRegex = matchRegex;
|
|
207
|
+
}
|
|
208
|
+
if (unlessRegex) {
|
|
209
|
+
compiled.compiledUnlessRegex = unlessRegex;
|
|
210
|
+
}
|
|
211
|
+
return compiled;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function compileRegex(pattern) {
|
|
215
|
+
if (!pattern)
|
|
216
|
+
return;
|
|
217
|
+
try {
|
|
218
|
+
return new RegExp(pattern);
|
|
219
|
+
} catch {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export {
|
|
224
|
+
seedPolicyFromContent,
|
|
225
|
+
loadPolicy
|
|
226
|
+
};
|
|
@@ -53,6 +53,8 @@ export declare function runRepoDefaultMerge(input: {
|
|
|
53
53
|
readonly config?: RigAutomationConfig;
|
|
54
54
|
readonly command: GitHubCommandRunner;
|
|
55
55
|
readonly cwd?: string;
|
|
56
|
+
/** Project root used to resolve the PR_MERGE_GATE capability; falls back to cwd. */
|
|
57
|
+
readonly projectRoot?: string;
|
|
56
58
|
readonly strictGate: StrictPrMergeGateResult;
|
|
57
59
|
}): Promise<void>;
|
|
58
60
|
export declare function gateNeedsGreptileRereview(result: StrictPrMergeGateResult): boolean;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/bundle-default-lifecycle/src/control-plane/pr-automation.ts
|
|
3
|
-
import { assertSafeGitBranchName } from "@rig/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "@rig/
|
|
3
|
+
import { assertSafeGitBranchName } from "@rig/core/safe-identifiers";
|
|
4
|
+
|
|
5
|
+
// packages/bundle-default-lifecycle/src/control-plane/pr-merge-gate-cap.ts
|
|
6
|
+
import { PR_MERGE_GATE } from "@rig/contracts";
|
|
7
|
+
import { defineCapability } from "@rig/core/capability";
|
|
8
|
+
import { resolvePluginHost } from "@rig/core/project-plugins";
|
|
9
|
+
var PrMergeGateCap = defineCapability(PR_MERGE_GATE);
|
|
10
|
+
async function resolvePrMergeGateService(projectRoot) {
|
|
11
|
+
const { host } = await resolvePluginHost(projectRoot);
|
|
12
|
+
return PrMergeGateCap.require(host);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// packages/bundle-default-lifecycle/src/control-plane/pr-automation.ts
|
|
8
16
|
var UPLOADED_SNAPSHOT_PR_MARKER = "<!-- rig:uploaded-snapshot -->";
|
|
9
17
|
function positiveInt(value, fallback) {
|
|
10
18
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
|
|
@@ -313,7 +321,7 @@ async function commitRunChanges(input) {
|
|
|
313
321
|
async function closeIssueAfterMergedPr(input) {
|
|
314
322
|
await input.updateTaskSource(input.projectRoot, {
|
|
315
323
|
taskId: input.taskId,
|
|
316
|
-
sourceTask: input.sourceTask,
|
|
324
|
+
...input.sourceTask !== undefined ? { sourceTask: input.sourceTask } : {},
|
|
317
325
|
update: {
|
|
318
326
|
status: "closed",
|
|
319
327
|
comment: [
|
|
@@ -359,11 +367,12 @@ async function runRepoDefaultMerge(input) {
|
|
|
359
367
|
if (merge.mode === "off")
|
|
360
368
|
return;
|
|
361
369
|
const requireGreptile = (input.config?.review?.provider ?? "greptile") === "greptile";
|
|
362
|
-
const
|
|
370
|
+
const mergeGate = await resolvePrMergeGateService(input.projectRoot ?? input.cwd ?? process.cwd());
|
|
371
|
+
const matchHeadSha = mergeGate.resolveHeadSha({ result: input.strictGate, prUrl: input.prUrl, requireGreptile });
|
|
363
372
|
const method = merge.method ?? "repo-default";
|
|
364
373
|
const args = ["pr", "merge", input.prUrl];
|
|
365
374
|
if (method === "repo-default") {
|
|
366
|
-
args.push(await resolveRepoDefaultMergeFlag({ prUrl: input.prUrl, command: input.command, cwd: input.cwd }));
|
|
375
|
+
args.push(await resolveRepoDefaultMergeFlag({ prUrl: input.prUrl, command: input.command, ...input.cwd !== undefined ? { cwd: input.cwd } : {} }));
|
|
367
376
|
} else {
|
|
368
377
|
args.push(`--${method}`);
|
|
369
378
|
}
|
|
@@ -441,6 +450,7 @@ async function syncBranchAfterPrFeedback(input) {
|
|
|
441
450
|
}
|
|
442
451
|
async function runPrAutomation(input) {
|
|
443
452
|
const branch = assertSafeGitBranchName(input.branch, "PR branch");
|
|
453
|
+
const mergeGate = await resolvePrMergeGateService(input.projectRoot);
|
|
444
454
|
const prConfig = input.config?.pr ?? {};
|
|
445
455
|
const requireGreptile = (input.config?.review?.provider ?? "greptile") === "greptile";
|
|
446
456
|
if (prConfig.mode === "off" || prConfig.mode === "ask") {
|
|
@@ -450,7 +460,7 @@ async function runPrAutomation(input) {
|
|
|
450
460
|
taskId: input.taskId,
|
|
451
461
|
runId: input.runId,
|
|
452
462
|
summary: input.sourceTask?.title ? `Rig completed: ${input.sourceTask.title}` : null,
|
|
453
|
-
uploadedSnapshot: input.uploadedSnapshot
|
|
463
|
+
...input.uploadedSnapshot !== undefined ? { uploadedSnapshot: input.uploadedSnapshot } : {}
|
|
454
464
|
});
|
|
455
465
|
if (input.gitCommand) {
|
|
456
466
|
await pushBranchSyncedWithOrigin({ projectRoot: input.projectRoot, branch, gitCommand: input.gitCommand });
|
|
@@ -522,16 +532,16 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
522
532
|
await syncBranchAfterPrFeedback({ projectRoot: input.projectRoot, taskId: input.taskId, branch, gitCommand: input.gitCommand });
|
|
523
533
|
continue;
|
|
524
534
|
}
|
|
525
|
-
const gate = await
|
|
535
|
+
const gate = await mergeGate.runGate({
|
|
526
536
|
projectRoot: input.projectRoot,
|
|
527
537
|
prUrl,
|
|
528
538
|
taskId: input.taskId,
|
|
529
539
|
runId: input.runId,
|
|
530
540
|
cycle: iteration,
|
|
531
541
|
command: input.command,
|
|
532
|
-
artifactRoot: input.artifactRoot,
|
|
542
|
+
...input.artifactRoot !== undefined ? { artifactRoot: input.artifactRoot } : {},
|
|
533
543
|
allowedFailures: input.config?.merge?.allowedFailures ?? [],
|
|
534
|
-
greptileApi
|
|
544
|
+
...requireGreptile && input.greptileApi ? { greptileApi: input.greptileApi } : {},
|
|
535
545
|
requireGreptile
|
|
536
546
|
});
|
|
537
547
|
latestFeedback = [...gate.actionableFeedback];
|
|
@@ -561,22 +571,22 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
561
571
|
}
|
|
562
572
|
if (gate.approved) {
|
|
563
573
|
pendingElapsedMs = 0;
|
|
564
|
-
const finalGate = await
|
|
574
|
+
const finalGate = await mergeGate.runGate({
|
|
565
575
|
projectRoot: input.projectRoot,
|
|
566
576
|
prUrl,
|
|
567
577
|
taskId: input.taskId,
|
|
568
578
|
runId: input.runId,
|
|
569
579
|
cycle: iteration,
|
|
570
580
|
command: input.command,
|
|
571
|
-
artifactRoot: input.artifactRoot,
|
|
581
|
+
...input.artifactRoot !== undefined ? { artifactRoot: input.artifactRoot } : {},
|
|
572
582
|
allowedFailures: input.config?.merge?.allowedFailures ?? [],
|
|
573
|
-
greptileApi
|
|
583
|
+
...requireGreptile && input.greptileApi ? { greptileApi: input.greptileApi } : {},
|
|
574
584
|
requireGreptile,
|
|
575
585
|
final: true
|
|
576
586
|
});
|
|
577
587
|
if (finalGate.approved) {
|
|
578
588
|
await input.lifecycle?.onMergeStarted?.({ prUrl });
|
|
579
|
-
await runRepoDefaultMerge({ prUrl, config: input.config, command: input.command, cwd: input.projectRoot, strictGate: finalGate });
|
|
589
|
+
await runRepoDefaultMerge({ prUrl, ...input.config !== undefined ? { config: input.config } : {}, command: input.command, cwd: input.projectRoot, strictGate: finalGate });
|
|
580
590
|
await input.lifecycle?.onMerged?.({ prUrl });
|
|
581
591
|
return { status: "merged", prUrl, iterations: iteration, actionableFeedback: [], merged: true };
|
|
582
592
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-plugin seam (doc §3): the default lifecycle bundle resolves the
|
|
3
|
+
* merge-gate operations off the host's PR_MERGE_GATE capability instead of
|
|
4
|
+
* importing `@rig/pr-review-plugin`. `@rig/pr-review-plugin` OWNS the impl and
|
|
5
|
+
* registers it under {@link PR_MERGE_GATE}; this module is the bundle-side
|
|
6
|
+
* resolver so no bundle file `import`s the review plugin directly.
|
|
7
|
+
*/
|
|
8
|
+
import { type PrMergeGateService } from "@rig/contracts";
|
|
9
|
+
/** Resolve the merge-gate service from the project's plugin host (throws if absent). */
|
|
10
|
+
export declare function resolvePrMergeGateService(projectRoot: string): Promise<PrMergeGateService>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/bundle-default-lifecycle/src/control-plane/pr-merge-gate-cap.ts
|
|
3
|
+
import { PR_MERGE_GATE } from "@rig/contracts";
|
|
4
|
+
import { defineCapability } from "@rig/core/capability";
|
|
5
|
+
import { resolvePluginHost } from "@rig/core/project-plugins";
|
|
6
|
+
var PrMergeGateCap = defineCapability(PR_MERGE_GATE);
|
|
7
|
+
async function resolvePrMergeGateService(projectRoot) {
|
|
8
|
+
const { host } = await resolvePluginHost(projectRoot);
|
|
9
|
+
return PrMergeGateCap.require(host);
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
resolvePrMergeGateService
|
|
13
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task-data seam accessor for the default lifecycle bundle.
|
|
3
|
+
*
|
|
4
|
+
* The lifecycle's git-ops / verifier / closeout stages read task-state, task
|
|
5
|
+
* facts (changed/pending files), artifacts, validation, and source-aware status.
|
|
6
|
+
* Those reads are owned by `@rig/task-sources-plugin`; the bundle resolves them
|
|
7
|
+
* through the boot-installed TASK-DATA capability instead of importing that
|
|
8
|
+
* plugin's impl modules cross-plugin (SEAM-ONLY §6.4). The service is installed
|
|
9
|
+
* by `buildPluginHostContext`, which every lifecycle entry point runs through.
|
|
10
|
+
*/
|
|
11
|
+
import { type TaskDataService } from "@rig/contracts";
|
|
12
|
+
/** Resolve the boot-installed task-data service, or throw a precise error. */
|
|
13
|
+
export declare function taskData(): TaskDataService;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/bundle-default-lifecycle/src/control-plane/task-data.ts
|
|
3
|
+
import { TASK_DATA_SERVICE_CAPABILITY } from "@rig/contracts";
|
|
4
|
+
import { defineCapability } from "@rig/core/capability";
|
|
5
|
+
import { requireInstalledCapability } from "@rig/core/capability-loaders";
|
|
6
|
+
var TaskDataCap = defineCapability(TASK_DATA_SERVICE_CAPABILITY);
|
|
7
|
+
function taskData() {
|
|
8
|
+
return requireInstalledCapability(TaskDataCap, "task-data capability unavailable: load @rig/task-sources-plugin (default bundle) before running the lifecycle.");
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
taskData
|
|
12
|
+
};
|