@h-rig/runtime 0.0.6-alpha.3 → 0.0.6-alpha.5
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/bin/rig-agent-dispatch.js +73 -14
- package/dist/bin/rig-agent.js +39 -25
- package/dist/src/control-plane/agent-wrapper.js +73 -14
- package/dist/src/control-plane/harness-main.js +39 -25
- package/dist/src/control-plane/hooks/completion-verification.js +36 -22
- package/dist/src/control-plane/hooks/inject-context.js +2 -2
- package/dist/src/control-plane/hooks/submodule-branch.js +7 -3
- package/dist/src/control-plane/hooks/task-runtime-start.js +7 -3
- package/dist/src/control-plane/native/git-ops.js +34 -20
- package/dist/src/control-plane/native/harness-cli.js +39 -25
- package/dist/src/control-plane/native/pr-automation.js +87 -16
- package/dist/src/control-plane/native/run-ops.js +23 -6
- package/dist/src/control-plane/native/task-ops.js +4 -4
- package/dist/src/control-plane/native/validator.js +2 -2
- package/dist/src/control-plane/native/verifier.js +2 -2
- package/dist/src/control-plane/runtime/index.js +18 -9
- package/dist/src/control-plane/runtime/isolation/home.js +11 -6
- package/dist/src/control-plane/runtime/isolation/index.js +18 -9
- package/dist/src/control-plane/runtime/isolation/runner.js +11 -6
- package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
- package/dist/src/control-plane/runtime/isolation.js +18 -9
- package/dist/src/control-plane/runtime/queue.js +18 -9
- package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
- package/dist/src/control-plane/tasks/source-lifecycle.js +2 -2
- package/package.json +6 -6
|
@@ -2645,8 +2645,8 @@ function ensureStatusLabel(bin, repo, spawnFn, label) {
|
|
|
2645
2645
|
}
|
|
2646
2646
|
}
|
|
2647
2647
|
function selectedGitHubEnv() {
|
|
2648
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
2649
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
2648
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
2649
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
2650
2650
|
}
|
|
2651
2651
|
function ghSpawnOptions() {
|
|
2652
2652
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -5993,12 +5993,12 @@ var TASK_ARTIFACT_STAGE_FALLBACK = new Set([
|
|
|
5993
5993
|
"task-result.json",
|
|
5994
5994
|
"validation-summary.json"
|
|
5995
5995
|
]);
|
|
5996
|
-
function resolveHostRigBinDir(root) {
|
|
5997
|
-
return resolve23(root, ".rig", "bin");
|
|
5998
|
-
}
|
|
5999
5996
|
function isRuntimeGatewayGitPath(candidate) {
|
|
6000
5997
|
return /\/\.rig\/bin\/git$/.test(candidate.replace(/\\/g, "/"));
|
|
6001
5998
|
}
|
|
5999
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
6000
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
6001
|
+
}
|
|
6002
6002
|
function resolveOptionalMonorepoRoot(projectRoot) {
|
|
6003
6003
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
6004
6004
|
if (runtimeWorkspace && existsSync20(resolve23(runtimeWorkspace, ".git"))) {
|
|
@@ -6033,6 +6033,9 @@ function resolveGitBinary(projectRoot) {
|
|
|
6033
6033
|
}
|
|
6034
6034
|
return "git";
|
|
6035
6035
|
}
|
|
6036
|
+
function escapeRegExp(value) {
|
|
6037
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6038
|
+
}
|
|
6036
6039
|
function safeCurrentTaskId(projectRoot) {
|
|
6037
6040
|
try {
|
|
6038
6041
|
const taskId = currentTaskId(projectRoot);
|
|
@@ -6156,6 +6159,7 @@ function gitOpenPr(options) {
|
|
|
6156
6159
|
"",
|
|
6157
6160
|
"## Task",
|
|
6158
6161
|
`- beads: ${taskId || "n/a"}`,
|
|
6162
|
+
...defaultPrRunLines(taskId, repoNameWithOwner),
|
|
6159
6163
|
"",
|
|
6160
6164
|
"## Review",
|
|
6161
6165
|
"- Completion verification will run validation, verifier review, and PR policy checks.",
|
|
@@ -6247,6 +6251,29 @@ function gitOpenPr(options) {
|
|
|
6247
6251
|
}
|
|
6248
6252
|
return result;
|
|
6249
6253
|
}
|
|
6254
|
+
function defaultPrRunLines(taskId, repoNameWithOwner) {
|
|
6255
|
+
const lines = [];
|
|
6256
|
+
const runId = process.env.RIG_SERVER_RUN_ID?.trim();
|
|
6257
|
+
if (runId) {
|
|
6258
|
+
lines.push(`- Run: ${runId}`);
|
|
6259
|
+
}
|
|
6260
|
+
const closeout = defaultPrCloseoutLine(taskId, repoNameWithOwner);
|
|
6261
|
+
if (closeout) {
|
|
6262
|
+
lines.push(`- ${closeout}`);
|
|
6263
|
+
}
|
|
6264
|
+
return lines;
|
|
6265
|
+
}
|
|
6266
|
+
function defaultPrCloseoutLine(taskId, repoNameWithOwner) {
|
|
6267
|
+
const sourceIssueId = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
|
|
6268
|
+
if (sourceIssueId) {
|
|
6269
|
+
const match = sourceIssueId.match(/^([^#]+)#(\d+)$/);
|
|
6270
|
+
if (match) {
|
|
6271
|
+
const [, sourceRepo, issueNumber] = match;
|
|
6272
|
+
return sourceRepo.toLowerCase() === repoNameWithOwner.toLowerCase() ? `Closes #${issueNumber}` : `Closes ${sourceRepo}#${issueNumber}`;
|
|
6273
|
+
}
|
|
6274
|
+
}
|
|
6275
|
+
return /^\d+$/.test(taskId) ? `Closes #${taskId}` : "";
|
|
6276
|
+
}
|
|
6250
6277
|
function resolveTaskBranchRef(projectRoot, taskId) {
|
|
6251
6278
|
return `rig/${resolveTaskBranchId(projectRoot, taskId)}`;
|
|
6252
6279
|
}
|
|
@@ -6493,32 +6520,19 @@ function resolveGithubCliBinary(projectRoot) {
|
|
|
6493
6520
|
if (explicit) {
|
|
6494
6521
|
candidates.add(explicit);
|
|
6495
6522
|
}
|
|
6523
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6524
|
+
candidates.add(candidate);
|
|
6525
|
+
}
|
|
6496
6526
|
const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
|
|
6497
6527
|
for (const entry of explicitPathEntries) {
|
|
6498
6528
|
candidates.add(resolve23(entry, "gh"));
|
|
6499
6529
|
}
|
|
6500
|
-
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6501
|
-
if (hostProjectRoot) {
|
|
6502
|
-
candidates.add(resolve23(resolveHostRigBinDir(hostProjectRoot), "gh"));
|
|
6503
|
-
}
|
|
6504
|
-
candidates.add(resolve23(resolveHostRigBinDir(projectRoot), "gh"));
|
|
6505
|
-
const runtimeContext = loadRuntimeContextFromEnv();
|
|
6506
|
-
if (runtimeContext?.binDir) {
|
|
6507
|
-
candidates.add(resolve23(runtimeContext.binDir, "gh"));
|
|
6508
|
-
}
|
|
6509
|
-
const runtimeHome = process.env.RIG_RUNTIME_HOME?.trim();
|
|
6510
|
-
if (runtimeHome) {
|
|
6511
|
-
candidates.add(resolve23(runtimeHome, "bin", "gh"));
|
|
6512
|
-
}
|
|
6513
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
6514
|
-
candidates.add(candidate);
|
|
6515
|
-
}
|
|
6516
6530
|
const bunResolved = Bun.which("gh");
|
|
6517
6531
|
if (bunResolved) {
|
|
6518
6532
|
candidates.add(bunResolved);
|
|
6519
6533
|
}
|
|
6520
6534
|
for (const candidate of candidates) {
|
|
6521
|
-
if (candidate && existsSync20(candidate)) {
|
|
6535
|
+
if (candidate && existsSync20(candidate) && !isRuntimeGatewayGhPath(candidate)) {
|
|
6522
6536
|
return candidate;
|
|
6523
6537
|
}
|
|
6524
6538
|
}
|
|
@@ -2484,8 +2484,8 @@ function githubStatusFor(issue) {
|
|
|
2484
2484
|
return "open";
|
|
2485
2485
|
}
|
|
2486
2486
|
function selectedGitHubEnv() {
|
|
2487
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
2488
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
2487
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
2488
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
2489
2489
|
}
|
|
2490
2490
|
function ghSpawnOptions() {
|
|
2491
2491
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -1706,8 +1706,8 @@ function githubStatusFor(issue) {
|
|
|
1706
1706
|
return "open";
|
|
1707
1707
|
}
|
|
1708
1708
|
function selectedGitHubEnv() {
|
|
1709
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1710
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1709
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1710
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1711
1711
|
}
|
|
1712
1712
|
function ghSpawnOptions() {
|
|
1713
1713
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -7622,7 +7622,11 @@ async function ensureAgentRuntime(options) {
|
|
|
7622
7622
|
mkdirSync21(runtime.binDir, { recursive: true });
|
|
7623
7623
|
mkdirSync21(workspaceLayout.distDir, { recursive: true });
|
|
7624
7624
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
7625
|
-
|
|
7625
|
+
if (options.preserveTaskArtifacts) {
|
|
7626
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
7627
|
+
} else {
|
|
7628
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
7629
|
+
}
|
|
7626
7630
|
const ctx = {
|
|
7627
7631
|
runtimeId: options.id,
|
|
7628
7632
|
taskId: options.taskId,
|
|
@@ -1706,8 +1706,8 @@ function githubStatusFor(issue) {
|
|
|
1706
1706
|
return "open";
|
|
1707
1707
|
}
|
|
1708
1708
|
function selectedGitHubEnv() {
|
|
1709
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1710
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1709
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1710
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1711
1711
|
}
|
|
1712
1712
|
function ghSpawnOptions() {
|
|
1713
1713
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -7622,7 +7622,11 @@ async function ensureAgentRuntime(options) {
|
|
|
7622
7622
|
mkdirSync21(runtime.binDir, { recursive: true });
|
|
7623
7623
|
mkdirSync21(workspaceLayout.distDir, { recursive: true });
|
|
7624
7624
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
7625
|
-
|
|
7625
|
+
if (options.preserveTaskArtifacts) {
|
|
7626
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
7627
|
+
} else {
|
|
7628
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
7629
|
+
}
|
|
7626
7630
|
const ctx = {
|
|
7627
7631
|
runtimeId: options.id,
|
|
7628
7632
|
taskId: options.taskId,
|
|
@@ -1575,12 +1575,12 @@ var TASK_ARTIFACT_STAGE_FALLBACK = new Set([
|
|
|
1575
1575
|
"task-result.json",
|
|
1576
1576
|
"validation-summary.json"
|
|
1577
1577
|
]);
|
|
1578
|
-
function resolveHostRigBinDir(root) {
|
|
1579
|
-
return resolve11(root, ".rig", "bin");
|
|
1580
|
-
}
|
|
1581
1578
|
function isRuntimeGatewayGitPath(candidate) {
|
|
1582
1579
|
return /\/\.rig\/bin\/git$/.test(candidate.replace(/\\/g, "/"));
|
|
1583
1580
|
}
|
|
1581
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
1582
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
1583
|
+
}
|
|
1584
1584
|
function resolveOptionalMonorepoRoot(projectRoot) {
|
|
1585
1585
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
1586
1586
|
if (runtimeWorkspace && existsSync9(resolve11(runtimeWorkspace, ".git"))) {
|
|
@@ -1615,6 +1615,9 @@ function resolveGitBinary(projectRoot) {
|
|
|
1615
1615
|
}
|
|
1616
1616
|
return "git";
|
|
1617
1617
|
}
|
|
1618
|
+
function escapeRegExp(value) {
|
|
1619
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1620
|
+
}
|
|
1618
1621
|
function safeCurrentTaskId(projectRoot) {
|
|
1619
1622
|
try {
|
|
1620
1623
|
const taskId = currentTaskId(projectRoot);
|
|
@@ -1828,6 +1831,7 @@ function gitOpenPr(options) {
|
|
|
1828
1831
|
"",
|
|
1829
1832
|
"## Task",
|
|
1830
1833
|
`- beads: ${taskId || "n/a"}`,
|
|
1834
|
+
...defaultPrRunLines(taskId, repoNameWithOwner),
|
|
1831
1835
|
"",
|
|
1832
1836
|
"## Review",
|
|
1833
1837
|
"- Completion verification will run validation, verifier review, and PR policy checks.",
|
|
@@ -1919,6 +1923,29 @@ function gitOpenPr(options) {
|
|
|
1919
1923
|
}
|
|
1920
1924
|
return result;
|
|
1921
1925
|
}
|
|
1926
|
+
function defaultPrRunLines(taskId, repoNameWithOwner) {
|
|
1927
|
+
const lines = [];
|
|
1928
|
+
const runId = process.env.RIG_SERVER_RUN_ID?.trim();
|
|
1929
|
+
if (runId) {
|
|
1930
|
+
lines.push(`- Run: ${runId}`);
|
|
1931
|
+
}
|
|
1932
|
+
const closeout = defaultPrCloseoutLine(taskId, repoNameWithOwner);
|
|
1933
|
+
if (closeout) {
|
|
1934
|
+
lines.push(`- ${closeout}`);
|
|
1935
|
+
}
|
|
1936
|
+
return lines;
|
|
1937
|
+
}
|
|
1938
|
+
function defaultPrCloseoutLine(taskId, repoNameWithOwner) {
|
|
1939
|
+
const sourceIssueId = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
|
|
1940
|
+
if (sourceIssueId) {
|
|
1941
|
+
const match = sourceIssueId.match(/^([^#]+)#(\d+)$/);
|
|
1942
|
+
if (match) {
|
|
1943
|
+
const [, sourceRepo, issueNumber] = match;
|
|
1944
|
+
return sourceRepo.toLowerCase() === repoNameWithOwner.toLowerCase() ? `Closes #${issueNumber}` : `Closes ${sourceRepo}#${issueNumber}`;
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return /^\d+$/.test(taskId) ? `Closes #${taskId}` : "";
|
|
1948
|
+
}
|
|
1922
1949
|
function resolveTaskBranchRef(projectRoot, taskId) {
|
|
1923
1950
|
return `rig/${resolveTaskBranchId(projectRoot, taskId)}`;
|
|
1924
1951
|
}
|
|
@@ -2169,32 +2196,19 @@ function resolveGithubCliBinary(projectRoot) {
|
|
|
2169
2196
|
if (explicit) {
|
|
2170
2197
|
candidates.add(explicit);
|
|
2171
2198
|
}
|
|
2199
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
2200
|
+
candidates.add(candidate);
|
|
2201
|
+
}
|
|
2172
2202
|
const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
|
|
2173
2203
|
for (const entry of explicitPathEntries) {
|
|
2174
2204
|
candidates.add(resolve11(entry, "gh"));
|
|
2175
2205
|
}
|
|
2176
|
-
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
2177
|
-
if (hostProjectRoot) {
|
|
2178
|
-
candidates.add(resolve11(resolveHostRigBinDir(hostProjectRoot), "gh"));
|
|
2179
|
-
}
|
|
2180
|
-
candidates.add(resolve11(resolveHostRigBinDir(projectRoot), "gh"));
|
|
2181
|
-
const runtimeContext = loadRuntimeContextFromEnv();
|
|
2182
|
-
if (runtimeContext?.binDir) {
|
|
2183
|
-
candidates.add(resolve11(runtimeContext.binDir, "gh"));
|
|
2184
|
-
}
|
|
2185
|
-
const runtimeHome = process.env.RIG_RUNTIME_HOME?.trim();
|
|
2186
|
-
if (runtimeHome) {
|
|
2187
|
-
candidates.add(resolve11(runtimeHome, "bin", "gh"));
|
|
2188
|
-
}
|
|
2189
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
2190
|
-
candidates.add(candidate);
|
|
2191
|
-
}
|
|
2192
2206
|
const bunResolved = Bun.which("gh");
|
|
2193
2207
|
if (bunResolved) {
|
|
2194
2208
|
candidates.add(bunResolved);
|
|
2195
2209
|
}
|
|
2196
2210
|
for (const candidate of candidates) {
|
|
2197
|
-
if (candidate && existsSync9(candidate)) {
|
|
2211
|
+
if (candidate && existsSync9(candidate) && !isRuntimeGatewayGhPath(candidate)) {
|
|
2198
2212
|
return candidate;
|
|
2199
2213
|
}
|
|
2200
2214
|
}
|
|
@@ -1198,8 +1198,8 @@ function githubStatusFor(issue) {
|
|
|
1198
1198
|
return "open";
|
|
1199
1199
|
}
|
|
1200
1200
|
function selectedGitHubEnv() {
|
|
1201
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1202
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1201
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1202
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1203
1203
|
}
|
|
1204
1204
|
function ghSpawnOptions() {
|
|
1205
1205
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -5455,7 +5455,7 @@ This file records approaches that did not work.
|
|
|
5455
5455
|
`, "utf-8");
|
|
5456
5456
|
}
|
|
5457
5457
|
const content = readFileSync10(failedPath, "utf-8");
|
|
5458
|
-
const attempts = (content.match(new RegExp(`^## ${
|
|
5458
|
+
const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
|
|
5459
5459
|
appendFileSync(failedPath, `
|
|
5460
5460
|
## ${activeTask} - Attempt ${attempts} (${nowIso()})
|
|
5461
5461
|
|
|
@@ -5954,7 +5954,7 @@ function printArtifactSection(path, header) {
|
|
|
5954
5954
|
process.stdout.write(readFileSync10(path, "utf-8"));
|
|
5955
5955
|
console.log("");
|
|
5956
5956
|
}
|
|
5957
|
-
function
|
|
5957
|
+
function escapeRegExp(value) {
|
|
5958
5958
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5959
5959
|
}
|
|
5960
5960
|
function changedFilesForTask(projectRoot, taskId, scoped) {
|
|
@@ -5983,12 +5983,12 @@ var TASK_ARTIFACT_STAGE_FALLBACK = new Set([
|
|
|
5983
5983
|
"task-result.json",
|
|
5984
5984
|
"validation-summary.json"
|
|
5985
5985
|
]);
|
|
5986
|
-
function resolveHostRigBinDir(root) {
|
|
5987
|
-
return resolve24(root, ".rig", "bin");
|
|
5988
|
-
}
|
|
5989
5986
|
function isRuntimeGatewayGitPath(candidate) {
|
|
5990
5987
|
return /\/\.rig\/bin\/git$/.test(candidate.replace(/\\/g, "/"));
|
|
5991
5988
|
}
|
|
5989
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
5990
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
5991
|
+
}
|
|
5992
5992
|
function resolveOptionalMonorepoRoot(projectRoot) {
|
|
5993
5993
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
5994
5994
|
if (runtimeWorkspace && existsSync21(resolve24(runtimeWorkspace, ".git"))) {
|
|
@@ -6023,6 +6023,9 @@ function resolveGitBinary(projectRoot) {
|
|
|
6023
6023
|
}
|
|
6024
6024
|
return "git";
|
|
6025
6025
|
}
|
|
6026
|
+
function escapeRegExp2(value) {
|
|
6027
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6028
|
+
}
|
|
6026
6029
|
function safeCurrentTaskId(projectRoot) {
|
|
6027
6030
|
try {
|
|
6028
6031
|
const taskId = currentTaskId(projectRoot);
|
|
@@ -6236,6 +6239,7 @@ function gitOpenPr(options) {
|
|
|
6236
6239
|
"",
|
|
6237
6240
|
"## Task",
|
|
6238
6241
|
`- beads: ${taskId || "n/a"}`,
|
|
6242
|
+
...defaultPrRunLines(taskId, repoNameWithOwner),
|
|
6239
6243
|
"",
|
|
6240
6244
|
"## Review",
|
|
6241
6245
|
"- Completion verification will run validation, verifier review, and PR policy checks.",
|
|
@@ -6327,6 +6331,29 @@ function gitOpenPr(options) {
|
|
|
6327
6331
|
}
|
|
6328
6332
|
return result;
|
|
6329
6333
|
}
|
|
6334
|
+
function defaultPrRunLines(taskId, repoNameWithOwner) {
|
|
6335
|
+
const lines = [];
|
|
6336
|
+
const runId = process.env.RIG_SERVER_RUN_ID?.trim();
|
|
6337
|
+
if (runId) {
|
|
6338
|
+
lines.push(`- Run: ${runId}`);
|
|
6339
|
+
}
|
|
6340
|
+
const closeout = defaultPrCloseoutLine(taskId, repoNameWithOwner);
|
|
6341
|
+
if (closeout) {
|
|
6342
|
+
lines.push(`- ${closeout}`);
|
|
6343
|
+
}
|
|
6344
|
+
return lines;
|
|
6345
|
+
}
|
|
6346
|
+
function defaultPrCloseoutLine(taskId, repoNameWithOwner) {
|
|
6347
|
+
const sourceIssueId = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
|
|
6348
|
+
if (sourceIssueId) {
|
|
6349
|
+
const match = sourceIssueId.match(/^([^#]+)#(\d+)$/);
|
|
6350
|
+
if (match) {
|
|
6351
|
+
const [, sourceRepo, issueNumber] = match;
|
|
6352
|
+
return sourceRepo.toLowerCase() === repoNameWithOwner.toLowerCase() ? `Closes #${issueNumber}` : `Closes ${sourceRepo}#${issueNumber}`;
|
|
6353
|
+
}
|
|
6354
|
+
}
|
|
6355
|
+
return /^\d+$/.test(taskId) ? `Closes #${taskId}` : "";
|
|
6356
|
+
}
|
|
6330
6357
|
function readPrViewState(gh, repoRoot, repoNameWithOwner, prUrl) {
|
|
6331
6358
|
const view = runCapture2(withGhRepo([
|
|
6332
6359
|
gh,
|
|
@@ -6477,32 +6504,19 @@ function resolveGithubCliBinary(projectRoot) {
|
|
|
6477
6504
|
if (explicit) {
|
|
6478
6505
|
candidates.add(explicit);
|
|
6479
6506
|
}
|
|
6507
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6508
|
+
candidates.add(candidate);
|
|
6509
|
+
}
|
|
6480
6510
|
const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
|
|
6481
6511
|
for (const entry of explicitPathEntries) {
|
|
6482
6512
|
candidates.add(resolve24(entry, "gh"));
|
|
6483
6513
|
}
|
|
6484
|
-
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6485
|
-
if (hostProjectRoot) {
|
|
6486
|
-
candidates.add(resolve24(resolveHostRigBinDir(hostProjectRoot), "gh"));
|
|
6487
|
-
}
|
|
6488
|
-
candidates.add(resolve24(resolveHostRigBinDir(projectRoot), "gh"));
|
|
6489
|
-
const runtimeContext = loadRuntimeContextFromEnv();
|
|
6490
|
-
if (runtimeContext?.binDir) {
|
|
6491
|
-
candidates.add(resolve24(runtimeContext.binDir, "gh"));
|
|
6492
|
-
}
|
|
6493
|
-
const runtimeHome = process.env.RIG_RUNTIME_HOME?.trim();
|
|
6494
|
-
if (runtimeHome) {
|
|
6495
|
-
candidates.add(resolve24(runtimeHome, "bin", "gh"));
|
|
6496
|
-
}
|
|
6497
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
6498
|
-
candidates.add(candidate);
|
|
6499
|
-
}
|
|
6500
6514
|
const bunResolved = Bun.which("gh");
|
|
6501
6515
|
if (bunResolved) {
|
|
6502
6516
|
candidates.add(bunResolved);
|
|
6503
6517
|
}
|
|
6504
6518
|
for (const candidate of candidates) {
|
|
6505
|
-
if (candidate && existsSync21(candidate)) {
|
|
6519
|
+
if (candidate && existsSync21(candidate) && !isRuntimeGatewayGhPath(candidate)) {
|
|
6506
6520
|
return candidate;
|
|
6507
6521
|
}
|
|
6508
6522
|
}
|
|
@@ -6655,7 +6669,7 @@ function inferRepositoryDefaultBase(projectRoot, repoRoot, repoNameWithOwner, re
|
|
|
6655
6669
|
const remote = remoteName || "origin";
|
|
6656
6670
|
const symbolic = runCapture2(gitCmd(projectRoot, repoRoot, "symbolic-ref", "--short", `refs/remotes/${remote}/HEAD`), projectRoot);
|
|
6657
6671
|
if (symbolic.exitCode === 0) {
|
|
6658
|
-
const ref = symbolic.stdout.trim().replace(new RegExp(`^${
|
|
6672
|
+
const ref = symbolic.stdout.trim().replace(new RegExp(`^${escapeRegExp2(remote)}/`), "");
|
|
6659
6673
|
if (ref && ref !== "HEAD") {
|
|
6660
6674
|
return ref;
|
|
6661
6675
|
}
|
|
@@ -104,6 +104,44 @@ function parsePrChecks(value) {
|
|
|
104
104
|
}];
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
+
function parsePrViewStatusCheckRollup(value) {
|
|
108
|
+
if (!value?.trim())
|
|
109
|
+
return [];
|
|
110
|
+
try {
|
|
111
|
+
const parsed = JSON.parse(value);
|
|
112
|
+
const rollup = Array.isArray(parsed.statusCheckRollup) ? parsed.statusCheckRollup : [];
|
|
113
|
+
return rollup.flatMap((entry) => {
|
|
114
|
+
if (!entry || typeof entry !== "object")
|
|
115
|
+
return [];
|
|
116
|
+
const record = entry;
|
|
117
|
+
const name = typeof record.name === "string" ? record.name : "";
|
|
118
|
+
if (!name.trim())
|
|
119
|
+
return [];
|
|
120
|
+
return [{
|
|
121
|
+
name,
|
|
122
|
+
status: typeof record.status === "string" ? record.status : null,
|
|
123
|
+
state: typeof record.state === "string" ? record.state : null,
|
|
124
|
+
conclusion: typeof record.conclusion === "string" ? record.conclusion : null,
|
|
125
|
+
detailsUrl: typeof record.detailsUrl === "string" ? record.detailsUrl : typeof record.link === "string" ? record.link : null
|
|
126
|
+
}];
|
|
127
|
+
});
|
|
128
|
+
} catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function readPrChecks(input) {
|
|
133
|
+
const checks = await input.command(["pr", "checks", input.prUrl, "--json", "name,state,link"], input.cwd ? { cwd: input.cwd } : undefined);
|
|
134
|
+
if (checks.exitCode === 0) {
|
|
135
|
+
return parsePrChecks(checks.stdout);
|
|
136
|
+
}
|
|
137
|
+
const combined = `${checks.stderr ?? ""}
|
|
138
|
+
${checks.stdout ?? ""}`;
|
|
139
|
+
if (!/unknown flag.*--json|unknown flag: --json|unknown shorthand flag/i.test(combined)) {
|
|
140
|
+
throw new Error(`gh pr checks ${input.prUrl} --json name,state,link failed (${checks.exitCode}): ${checks.stderr ?? checks.stdout ?? ""}`.trim());
|
|
141
|
+
}
|
|
142
|
+
const view = await runChecked(input.command, ["pr", "view", input.prUrl, "--json", "statusCheckRollup"], input.cwd, "gh");
|
|
143
|
+
return parsePrViewStatusCheckRollup(view.stdout);
|
|
144
|
+
}
|
|
107
145
|
function parsePrViewReviewThreads(value) {
|
|
108
146
|
if (!value?.trim())
|
|
109
147
|
return [];
|
|
@@ -164,6 +202,30 @@ function normalizePrUrl(stdout) {
|
|
|
164
202
|
throw new Error("gh pr create did not return a PR URL");
|
|
165
203
|
return url;
|
|
166
204
|
}
|
|
205
|
+
async function ensureExistingPrBodyHasRigMarkers(input) {
|
|
206
|
+
const view = await input.command(["pr", "view", input.prUrl, "--json", "body"], input.cwd ? { cwd: input.cwd } : undefined);
|
|
207
|
+
if (view.exitCode !== 0) {
|
|
208
|
+
throw new Error(`gh pr view ${input.prUrl} --json body failed (${view.exitCode}): ${view.stderr ?? view.stdout ?? ""}`.trim());
|
|
209
|
+
}
|
|
210
|
+
let currentBody = "";
|
|
211
|
+
try {
|
|
212
|
+
const parsed = JSON.parse(view.stdout ?? "{}");
|
|
213
|
+
currentBody = typeof parsed.body === "string" ? parsed.body : "";
|
|
214
|
+
} catch {
|
|
215
|
+
currentBody = "";
|
|
216
|
+
}
|
|
217
|
+
const requiredBlocks = input.body.split(/\n{2,}/).map((block) => block.trim()).filter((block) => /^Run: /i.test(block) || /^Closes #\d+/i.test(block));
|
|
218
|
+
const missing = requiredBlocks.filter((block) => !currentBody.includes(block));
|
|
219
|
+
if (missing.length === 0)
|
|
220
|
+
return;
|
|
221
|
+
const nextBody = [currentBody.trim(), ...missing].filter(Boolean).join(`
|
|
222
|
+
|
|
223
|
+
`);
|
|
224
|
+
const edit = await input.command(["pr", "edit", input.prUrl, "--body", nextBody], input.cwd ? { cwd: input.cwd } : undefined);
|
|
225
|
+
if (edit.exitCode !== 0) {
|
|
226
|
+
throw new Error(`gh pr edit ${input.prUrl} --body failed (${edit.exitCode}): ${edit.stderr ?? edit.stdout ?? ""}`.trim());
|
|
227
|
+
}
|
|
228
|
+
}
|
|
167
229
|
async function runChecked(command, args, cwd, label = "gh") {
|
|
168
230
|
const result = await command(args, cwd ? { cwd } : undefined);
|
|
169
231
|
if (result.exitCode !== 0) {
|
|
@@ -188,27 +250,33 @@ function statusPathFromShortLine(line) {
|
|
|
188
250
|
}
|
|
189
251
|
return renamedPath;
|
|
190
252
|
}
|
|
253
|
+
function isRuntimeCommitExcludedPath(path) {
|
|
254
|
+
const normalized = path.replace(/^\.\/+/, "").replace(/\/+$/, "");
|
|
255
|
+
return RIG_RUNTIME_COMMIT_EXCLUDES.some((excluded) => normalized === excluded || normalized.startsWith(`${excluded}/`));
|
|
256
|
+
}
|
|
257
|
+
function committableRunChangePaths(statusText) {
|
|
258
|
+
const seen = new Set;
|
|
259
|
+
const paths = [];
|
|
260
|
+
for (const line of statusText.split(/\r?\n/)) {
|
|
261
|
+
const path = statusPathFromShortLine(line);
|
|
262
|
+
if (!path || isRuntimeCommitExcludedPath(path) || seen.has(path))
|
|
263
|
+
continue;
|
|
264
|
+
seen.add(path);
|
|
265
|
+
paths.push(path);
|
|
266
|
+
}
|
|
267
|
+
return paths;
|
|
268
|
+
}
|
|
191
269
|
function hasCommittableRunChanges(statusText) {
|
|
192
|
-
return statusText
|
|
270
|
+
return committableRunChangePaths(statusText).length > 0;
|
|
193
271
|
}
|
|
194
272
|
async function commitRunChanges(input) {
|
|
195
|
-
const status = await runChecked(input.command, ["status", "--short"], input.cwd, "git");
|
|
273
|
+
const status = await runChecked(input.command, ["status", "--short", "--untracked-files=all"], input.cwd, "git");
|
|
196
274
|
const statusText = status.stdout ?? "";
|
|
197
|
-
|
|
275
|
+
const committablePaths = committableRunChangePaths(statusText);
|
|
276
|
+
if (!statusText.trim() || committablePaths.length === 0) {
|
|
198
277
|
return { committed: false, status: statusText };
|
|
199
278
|
}
|
|
200
|
-
await runChecked(input.command, [
|
|
201
|
-
"add",
|
|
202
|
-
"-A",
|
|
203
|
-
"--",
|
|
204
|
-
".",
|
|
205
|
-
":(exclude).rig",
|
|
206
|
-
":(exclude).rig/**",
|
|
207
|
-
":(exclude)artifacts",
|
|
208
|
-
":(exclude)artifacts/**",
|
|
209
|
-
":(exclude)node_modules",
|
|
210
|
-
":(exclude)node_modules/**"
|
|
211
|
-
], input.cwd, "git");
|
|
279
|
+
await runChecked(input.command, ["add", "-A", "--", ...committablePaths], input.cwd, "git");
|
|
212
280
|
const staged = await input.command(["diff", "--cached", "--quiet"], { cwd: input.cwd });
|
|
213
281
|
if (staged.exitCode === 0) {
|
|
214
282
|
return { committed: false, status: statusText };
|
|
@@ -314,12 +382,15 @@ ${createResult.stdout ?? ""}`) : null;
|
|
|
314
382
|
throw new Error(`gh ${createArgs.join(" ")} failed (${createResult.exitCode}): ${createResult.stderr ?? createResult.stdout ?? ""}`.trim());
|
|
315
383
|
}
|
|
316
384
|
const prUrl = existingPrUrl ?? normalizePrUrl(createResult.stdout);
|
|
385
|
+
if (existingPrUrl) {
|
|
386
|
+
await ensureExistingPrBodyHasRigMarkers({ prUrl, body, command: input.command, cwd: input.projectRoot });
|
|
387
|
+
}
|
|
317
388
|
await input.lifecycle?.onPrOpened?.({ prUrl });
|
|
318
389
|
const { maxPrFixIterations } = resolvePrAutomationLimits(input.config);
|
|
319
390
|
let latestFeedback = [];
|
|
320
391
|
for (let iteration = 1;iteration <= maxPrFixIterations; iteration += 1) {
|
|
321
392
|
await input.lifecycle?.onReviewCiStarted?.({ prUrl, iteration });
|
|
322
|
-
const checks = prConfig.watchChecks === false ? [] :
|
|
393
|
+
const checks = prConfig.watchChecks === false ? [] : await readPrChecks({ prUrl, command: input.command, cwd: input.projectRoot });
|
|
323
394
|
const reviewThreads = prConfig.autoFixReview === false ? [] : parsePrViewReviewThreads((await runChecked(input.command, ["pr", "view", prUrl, "--json", "reviewDecision,reviews"], input.projectRoot)).stdout);
|
|
324
395
|
latestFeedback = collectActionablePrFeedback({
|
|
325
396
|
checks,
|
|
@@ -2713,11 +2713,13 @@ function runStatus(projectRoot, runtimeContext) {
|
|
|
2713
2713
|
recentRuns: runs.slice(0, 10)
|
|
2714
2714
|
};
|
|
2715
2715
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2716
|
+
function latestLocalRunForResume(projectRoot) {
|
|
2717
|
+
return listAuthorityRuns(projectRoot).map((entry) => readAuthorityRun(projectRoot, entry.runId)).filter((run) => Boolean(run)).filter((run) => run.mode === "local" && ["created", "preparing", "running", "validating", "reviewing", "stopped", "failed", "needs_attention"].includes(String(run.status ?? ""))).sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? "")))[0] ?? null;
|
|
2718
|
+
}
|
|
2719
|
+
async function submitRunResumeRequest(projectRoot, input) {
|
|
2720
|
+
const run = latestLocalRunForResume(projectRoot);
|
|
2719
2721
|
if (!run) {
|
|
2720
|
-
throw new RemoteCliError(
|
|
2722
|
+
throw new RemoteCliError(input.failureCode, input.nothingMessage, 2);
|
|
2721
2723
|
}
|
|
2722
2724
|
const server = await ensureServerForRuns(projectRoot);
|
|
2723
2725
|
const response = await fetch(`${server.baseUrl}/api/runs/resume`, {
|
|
@@ -2726,14 +2728,28 @@ async function runResume(projectRoot, runtimeContext) {
|
|
|
2726
2728
|
"content-type": "application/json",
|
|
2727
2729
|
...server.authToken ? { authorization: `Bearer ${server.authToken}` } : {}
|
|
2728
2730
|
},
|
|
2729
|
-
body: JSON.stringify({ runId: run.runId, createdAt: new Date().toISOString() })
|
|
2731
|
+
body: JSON.stringify({ runId: run.runId, createdAt: new Date().toISOString(), restart: input.restart })
|
|
2730
2732
|
});
|
|
2731
2733
|
if (!response.ok) {
|
|
2732
2734
|
const text = await response.text();
|
|
2733
|
-
throw new RemoteCliError("RIG_RUN_RESUME_FAILED", text || response.statusText, 1, { runId: run.runId });
|
|
2735
|
+
throw new RemoteCliError(input.restart ? "RIG_RUN_RESTART_FAILED" : "RIG_RUN_RESUME_FAILED", text || response.statusText, 1, { runId: run.runId });
|
|
2734
2736
|
}
|
|
2735
2737
|
return { runId: run.runId };
|
|
2736
2738
|
}
|
|
2739
|
+
async function runResume(projectRoot, runtimeContext) {
|
|
2740
|
+
return submitRunResumeRequest(projectRoot, {
|
|
2741
|
+
restart: false,
|
|
2742
|
+
failureCode: "RIG_RUN_NOTHING_TO_RESUME",
|
|
2743
|
+
nothingMessage: "No resumable local run is available."
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
async function runRestart(projectRoot, runtimeContext) {
|
|
2747
|
+
return submitRunResumeRequest(projectRoot, {
|
|
2748
|
+
restart: true,
|
|
2749
|
+
failureCode: "RIG_RUN_NOTHING_TO_RESTART",
|
|
2750
|
+
nothingMessage: "No local run is available to restart."
|
|
2751
|
+
});
|
|
2752
|
+
}
|
|
2737
2753
|
async function runStop(projectRoot) {
|
|
2738
2754
|
const activeRuns = listAuthorityRuns(projectRoot).map((entry) => readAuthorityRun(projectRoot, entry.runId)).filter((run) => Boolean(run)).filter((run) => run.mode === "local" && ACTIVE_RUN_STATUSES.has(String(run.status ?? "")));
|
|
2739
2755
|
if (activeRuns.length === 0) {
|
|
@@ -3267,6 +3283,7 @@ export {
|
|
|
3267
3283
|
runStop,
|
|
3268
3284
|
runStatus,
|
|
3269
3285
|
runResume,
|
|
3286
|
+
runRestart,
|
|
3270
3287
|
resolvePreferredShellBinary,
|
|
3271
3288
|
resolveLocalControlBinarySourceRoot,
|
|
3272
3289
|
resolveDefaultEpic,
|
|
@@ -1089,8 +1089,8 @@ function githubStatusFor(issue) {
|
|
|
1089
1089
|
return "open";
|
|
1090
1090
|
}
|
|
1091
1091
|
function selectedGitHubEnv() {
|
|
1092
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1093
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1092
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1093
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1094
1094
|
}
|
|
1095
1095
|
function ghSpawnOptions() {
|
|
1096
1096
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -5634,7 +5634,7 @@ This file records approaches that did not work.
|
|
|
5634
5634
|
`, "utf-8");
|
|
5635
5635
|
}
|
|
5636
5636
|
const content = readFileSync10(failedPath, "utf-8");
|
|
5637
|
-
const attempts = (content.match(new RegExp(`^## ${
|
|
5637
|
+
const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
|
|
5638
5638
|
appendFileSync(failedPath, `
|
|
5639
5639
|
## ${activeTask} - Attempt ${attempts} (${nowIso()})
|
|
5640
5640
|
|
|
@@ -6290,7 +6290,7 @@ function printArtifactSection(path, header) {
|
|
|
6290
6290
|
process.stdout.write(readFileSync10(path, "utf-8"));
|
|
6291
6291
|
console.log("");
|
|
6292
6292
|
}
|
|
6293
|
-
function
|
|
6293
|
+
function escapeRegExp(value) {
|
|
6294
6294
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6295
6295
|
}
|
|
6296
6296
|
function changedFilesForTask(projectRoot, taskId, scoped) {
|
|
@@ -1354,8 +1354,8 @@ function githubStatusFor(issue) {
|
|
|
1354
1354
|
return "open";
|
|
1355
1355
|
}
|
|
1356
1356
|
function selectedGitHubEnv() {
|
|
1357
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1358
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1357
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1358
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1359
1359
|
}
|
|
1360
1360
|
function ghSpawnOptions() {
|
|
1361
1361
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -977,8 +977,8 @@ function githubStatusFor(issue) {
|
|
|
977
977
|
return "open";
|
|
978
978
|
}
|
|
979
979
|
function selectedGitHubEnv() {
|
|
980
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
981
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
980
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
981
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
982
982
|
}
|
|
983
983
|
function ghSpawnOptions() {
|
|
984
984
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|