@h-rig/runtime 0.0.6-alpha.1 → 0.0.6-alpha.11
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 +133 -14
- package/dist/bin/rig-agent.js +83 -26
- package/dist/src/control-plane/agent-wrapper.js +133 -14
- package/dist/src/control-plane/harness-main.js +83 -26
- package/dist/src/control-plane/hooks/completion-verification.js +85 -28
- package/dist/src/control-plane/hooks/inject-context.js +2 -2
- package/dist/src/control-plane/hooks/submodule-branch.js +26 -3
- package/dist/src/control-plane/hooks/task-runtime-start.js +26 -3
- package/dist/src/control-plane/native/git-ops.js +81 -24
- package/dist/src/control-plane/native/harness-cli.js +83 -26
- 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 +2 -2
- 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 +38 -9
- package/dist/src/control-plane/runtime/isolation/home.js +31 -6
- package/dist/src/control-plane/runtime/isolation/index.js +38 -9
- package/dist/src/control-plane/runtime/isolation/runner.js +31 -6
- package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
- package/dist/src/control-plane/runtime/isolation.js +38 -9
- package/dist/src/control-plane/runtime/queue.js +38 -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/dist/src/index.js +15 -13
- package/dist/src/local-server.js +20 -14
- package/native/darwin-arm64/{bin/rig-git → rig-git} +0 -0
- package/native/darwin-arm64/rig-git.build-manifest.json +4 -0
- package/native/darwin-arm64/{bin/rig-shell → rig-shell} +0 -0
- package/native/darwin-arm64/rig-shell.build-manifest.json +4 -0
- package/native/darwin-arm64/{bin/rig-tools → rig-tools} +0 -0
- package/native/darwin-arm64/rig-tools.build-manifest.json +4 -0
- package/native/darwin-arm64/{lib/runtime-native.dylib → runtime-native.dylib} +0 -0
- package/package.json +6 -6
- package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
- package/native/darwin-arm64/manifest.json +0 -1
- package/native/linux-x64/bin/rig-git +0 -0
- package/native/linux-x64/bin/rig-shell +0 -0
- package/native/linux-x64/bin/rig-tools +0 -0
- package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
- package/native/linux-x64/lib/runtime-native.so +0 -0
- package/native/linux-x64/manifest.json +0 -1
|
@@ -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() } };
|
|
@@ -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);
|
|
@@ -6181,17 +6184,15 @@ function gitOpenPr(options) {
|
|
|
6181
6184
|
const target = options.target || (taskId ? "monorepo" : "project");
|
|
6182
6185
|
let repoRoot = options.projectRoot;
|
|
6183
6186
|
let repoLabel = "project-rig";
|
|
6184
|
-
|
|
6187
|
+
const envBase = target === "monorepo" ? process.env.RIG_PR_BASE_MONOREPO?.trim() || "" : process.env.RIG_PR_BASE_PROJECT?.trim() || "";
|
|
6185
6188
|
if (target === "monorepo") {
|
|
6186
6189
|
repoRoot = resolveOptionalMonorepoRoot(options.projectRoot) || resolveMonorepoRoot2(options.projectRoot);
|
|
6187
6190
|
repoLabel = "monorepo";
|
|
6188
|
-
defaultBase = process.env.RIG_PR_BASE_MONOREPO || "main";
|
|
6189
6191
|
if (taskId) {
|
|
6190
6192
|
gitSyncBranch(options.projectRoot, taskId, "monorepo");
|
|
6191
6193
|
}
|
|
6192
6194
|
} else if (taskId) {
|
|
6193
6195
|
gitSyncBranch(options.projectRoot, taskId, "project");
|
|
6194
|
-
defaultBase = inferProjectBase(options.projectRoot, defaultBase);
|
|
6195
6196
|
}
|
|
6196
6197
|
if (!existsSync21(resolve24(repoRoot, ".git"))) {
|
|
6197
6198
|
throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
|
|
@@ -6200,9 +6201,9 @@ function gitOpenPr(options) {
|
|
|
6200
6201
|
if (!branch || branch === "HEAD") {
|
|
6201
6202
|
throw new Error(`Cannot open PR from detached HEAD in ${repoLabel}. Checkout a branch first.`);
|
|
6202
6203
|
}
|
|
6203
|
-
const base = options.base || defaultBase;
|
|
6204
6204
|
const repoNameWithOwner = resolveRepoNameWithOwner(options.projectRoot, repoRoot);
|
|
6205
6205
|
const networkRemote = resolveNetworkRemoteName(options.projectRoot, repoRoot, repoNameWithOwner);
|
|
6206
|
+
const base = options.base || envBase || inferRepositoryDefaultBase(options.projectRoot, repoRoot, repoNameWithOwner, networkRemote, target === "project" ? inferProjectBase(options.projectRoot, "main") : "main");
|
|
6206
6207
|
refreshRemoteBaseRef(options.projectRoot, repoRoot, base);
|
|
6207
6208
|
let reviewer = (options.reviewer || "").trim();
|
|
6208
6209
|
let reviewerSource = reviewer ? "flag" : undefined;
|
|
@@ -6238,6 +6239,7 @@ function gitOpenPr(options) {
|
|
|
6238
6239
|
"",
|
|
6239
6240
|
"## Task",
|
|
6240
6241
|
`- beads: ${taskId || "n/a"}`,
|
|
6242
|
+
...defaultPrRunLines(taskId, repoNameWithOwner),
|
|
6241
6243
|
"",
|
|
6242
6244
|
"## Review",
|
|
6243
6245
|
"- Completion verification will run validation, verifier review, and PR policy checks.",
|
|
@@ -6329,6 +6331,29 @@ function gitOpenPr(options) {
|
|
|
6329
6331
|
}
|
|
6330
6332
|
return result;
|
|
6331
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
|
+
}
|
|
6332
6357
|
function readPrViewState(gh, repoRoot, repoNameWithOwner, prUrl) {
|
|
6333
6358
|
const view = runCapture2(withGhRepo([
|
|
6334
6359
|
gh,
|
|
@@ -6479,32 +6504,19 @@ function resolveGithubCliBinary(projectRoot) {
|
|
|
6479
6504
|
if (explicit) {
|
|
6480
6505
|
candidates.add(explicit);
|
|
6481
6506
|
}
|
|
6507
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6508
|
+
candidates.add(candidate);
|
|
6509
|
+
}
|
|
6482
6510
|
const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
|
|
6483
6511
|
for (const entry of explicitPathEntries) {
|
|
6484
6512
|
candidates.add(resolve24(entry, "gh"));
|
|
6485
6513
|
}
|
|
6486
|
-
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6487
|
-
if (hostProjectRoot) {
|
|
6488
|
-
candidates.add(resolve24(resolveHostRigBinDir(hostProjectRoot), "gh"));
|
|
6489
|
-
}
|
|
6490
|
-
candidates.add(resolve24(resolveHostRigBinDir(projectRoot), "gh"));
|
|
6491
|
-
const runtimeContext = loadRuntimeContextFromEnv();
|
|
6492
|
-
if (runtimeContext?.binDir) {
|
|
6493
|
-
candidates.add(resolve24(runtimeContext.binDir, "gh"));
|
|
6494
|
-
}
|
|
6495
|
-
const runtimeHome = process.env.RIG_RUNTIME_HOME?.trim();
|
|
6496
|
-
if (runtimeHome) {
|
|
6497
|
-
candidates.add(resolve24(runtimeHome, "bin", "gh"));
|
|
6498
|
-
}
|
|
6499
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
6500
|
-
candidates.add(candidate);
|
|
6501
|
-
}
|
|
6502
6514
|
const bunResolved = Bun.which("gh");
|
|
6503
6515
|
if (bunResolved) {
|
|
6504
6516
|
candidates.add(bunResolved);
|
|
6505
6517
|
}
|
|
6506
6518
|
for (const candidate of candidates) {
|
|
6507
|
-
if (candidate && existsSync21(candidate)) {
|
|
6519
|
+
if (candidate && existsSync21(candidate) && !isRuntimeGatewayGhPath(candidate)) {
|
|
6508
6520
|
return candidate;
|
|
6509
6521
|
}
|
|
6510
6522
|
}
|
|
@@ -6653,6 +6665,32 @@ function withGhRepo(command, repoNameWithOwner) {
|
|
|
6653
6665
|
}
|
|
6654
6666
|
return [command[0], command[1], command[2], ...ghRepoArgs(repoNameWithOwner), ...command.slice(3)];
|
|
6655
6667
|
}
|
|
6668
|
+
function inferRepositoryDefaultBase(projectRoot, repoRoot, repoNameWithOwner, remoteName, fallback) {
|
|
6669
|
+
const remote = remoteName || "origin";
|
|
6670
|
+
const symbolic = runCapture2(gitCmd(projectRoot, repoRoot, "symbolic-ref", "--short", `refs/remotes/${remote}/HEAD`), projectRoot);
|
|
6671
|
+
if (symbolic.exitCode === 0) {
|
|
6672
|
+
const ref = symbolic.stdout.trim().replace(new RegExp(`^${escapeRegExp2(remote)}/`), "");
|
|
6673
|
+
if (ref && ref !== "HEAD") {
|
|
6674
|
+
return ref;
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
const lsRemote = runCapture2(gitCmd(projectRoot, repoRoot, "ls-remote", "--symref", remote, "HEAD"), projectRoot);
|
|
6678
|
+
if (lsRemote.exitCode === 0) {
|
|
6679
|
+
const match = lsRemote.stdout.match(/^ref:\s+refs\/heads\/([^\t\r\n]+)\s+HEAD/m);
|
|
6680
|
+
if (match?.[1]) {
|
|
6681
|
+
return match[1];
|
|
6682
|
+
}
|
|
6683
|
+
}
|
|
6684
|
+
const gh = resolveGithubCliBinary(projectRoot);
|
|
6685
|
+
if (gh && repoNameWithOwner) {
|
|
6686
|
+
const api = runCapture2(withGhRepo([gh, "repo", "view", "--json", "defaultBranchRef", "--jq", ".defaultBranchRef.name"], repoNameWithOwner), repoRoot);
|
|
6687
|
+
const branch = api.exitCode === 0 ? api.stdout.trim() : "";
|
|
6688
|
+
if (branch) {
|
|
6689
|
+
return branch;
|
|
6690
|
+
}
|
|
6691
|
+
}
|
|
6692
|
+
return fallback;
|
|
6693
|
+
}
|
|
6656
6694
|
function inferProjectBase(projectRoot, fallback) {
|
|
6657
6695
|
const containing = runCapture2(gitCmd(projectRoot, projectRoot, "branch", "-r", "--contains", "HEAD"), projectRoot);
|
|
6658
6696
|
if (containing.exitCode !== 0) {
|
|
@@ -7034,6 +7072,10 @@ function runtimeGitEnv(projectRoot) {
|
|
|
7034
7072
|
}
|
|
7035
7073
|
env[key] = value;
|
|
7036
7074
|
}
|
|
7075
|
+
const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
7076
|
+
if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
|
|
7077
|
+
env.GITHUB_TOKEN = rigGithubToken;
|
|
7078
|
+
}
|
|
7037
7079
|
if (!env.GITHUB_TOKEN && env.GH_TOKEN) {
|
|
7038
7080
|
env.GITHUB_TOKEN = env.GH_TOKEN;
|
|
7039
7081
|
}
|
|
@@ -7057,6 +7099,13 @@ function runtimeGitEnv(projectRoot) {
|
|
|
7057
7099
|
if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
|
|
7058
7100
|
env.GH_TOKEN = env.GITHUB_TOKEN;
|
|
7059
7101
|
}
|
|
7102
|
+
const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || env.RIG_GITHUB_TOKEN || rigGithubToken;
|
|
7103
|
+
if (gitHubToken) {
|
|
7104
|
+
env.RIG_GITHUB_TOKEN = gitHubToken;
|
|
7105
|
+
env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
|
|
7106
|
+
env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
|
|
7107
|
+
applyGitHubCredentialHelperEnv(env);
|
|
7108
|
+
}
|
|
7060
7109
|
if (runtimeKnownHosts && existsSync21(runtimeKnownHosts)) {
|
|
7061
7110
|
const sshParts = [
|
|
7062
7111
|
"ssh",
|
|
@@ -7073,6 +7122,14 @@ function runtimeGitEnv(projectRoot) {
|
|
|
7073
7122
|
}
|
|
7074
7123
|
return Object.keys(env).length > 0 ? env : undefined;
|
|
7075
7124
|
}
|
|
7125
|
+
function applyGitHubCredentialHelperEnv(env) {
|
|
7126
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
7127
|
+
env.GIT_CONFIG_COUNT = "2";
|
|
7128
|
+
env.GIT_CONFIG_KEY_0 = "credential.helper";
|
|
7129
|
+
env.GIT_CONFIG_VALUE_0 = "";
|
|
7130
|
+
env.GIT_CONFIG_KEY_1 = "credential.helper";
|
|
7131
|
+
env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
|
|
7132
|
+
}
|
|
7076
7133
|
function loadPersistedRuntimeSecrets(runtimeRoot) {
|
|
7077
7134
|
if (!runtimeRoot) {
|
|
7078
7135
|
return {};
|
|
@@ -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() } };
|
|
@@ -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() } };
|
|
@@ -3848,8 +3848,8 @@ function githubStatusFor(issue) {
|
|
|
3848
3848
|
return "open";
|
|
3849
3849
|
}
|
|
3850
3850
|
function selectedGitHubEnv() {
|
|
3851
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
3852
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
3851
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
3852
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
3853
3853
|
}
|
|
3854
3854
|
function ghSpawnOptions() {
|
|
3855
3855
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -6154,20 +6154,23 @@ function hashProjectPath(workspaceDir) {
|
|
|
6154
6154
|
}
|
|
6155
6155
|
function resolveGithubCliBinaryPath() {
|
|
6156
6156
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
6157
|
-
if (explicit && existsSync24(explicit)) {
|
|
6157
|
+
if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
6158
6158
|
return explicit;
|
|
6159
6159
|
}
|
|
6160
|
-
const
|
|
6161
|
-
if (bunResolved && existsSync24(bunResolved)) {
|
|
6162
|
-
return bunResolved;
|
|
6163
|
-
}
|
|
6164
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
6160
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6165
6161
|
if (existsSync24(candidate)) {
|
|
6166
6162
|
return candidate;
|
|
6167
6163
|
}
|
|
6168
6164
|
}
|
|
6165
|
+
const bunResolved = Bun.which("gh");
|
|
6166
|
+
if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
6167
|
+
return bunResolved;
|
|
6168
|
+
}
|
|
6169
6169
|
return "";
|
|
6170
6170
|
}
|
|
6171
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
6172
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
6173
|
+
}
|
|
6171
6174
|
async function resolveGithubCliAuthToken(ghBinary = "") {
|
|
6172
6175
|
const gh = ghBinary || resolveGithubCliBinaryPath();
|
|
6173
6176
|
if (!gh) {
|
|
@@ -6268,6 +6271,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6268
6271
|
XDG_CACHE_HOME: runtime.cacheDir,
|
|
6269
6272
|
XDG_STATE_HOME: runtime.stateDir,
|
|
6270
6273
|
RIG_AGENT_ID: runtime.id,
|
|
6274
|
+
...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
|
|
6275
|
+
...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
|
|
6271
6276
|
RIG_TASK_ID: runtime.taskId,
|
|
6272
6277
|
RIG_TASK_RUNTIME_ID: runtime.id,
|
|
6273
6278
|
RIG_TASK_WORKSPACE: runtime.workspaceDir,
|
|
@@ -6331,6 +6336,10 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6331
6336
|
env[key] = value;
|
|
6332
6337
|
}
|
|
6333
6338
|
}
|
|
6339
|
+
const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
6340
|
+
if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
|
|
6341
|
+
env.GITHUB_TOKEN = rigGithubToken;
|
|
6342
|
+
}
|
|
6334
6343
|
const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
|
|
6335
6344
|
if (fallbackGithubToken) {
|
|
6336
6345
|
env.GITHUB_TOKEN = fallbackGithubToken;
|
|
@@ -6341,6 +6350,13 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6341
6350
|
if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
|
|
6342
6351
|
env.GH_TOKEN = env.GITHUB_TOKEN;
|
|
6343
6352
|
}
|
|
6353
|
+
const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
|
|
6354
|
+
if (gitHubToken) {
|
|
6355
|
+
env.RIG_GITHUB_TOKEN = gitHubToken;
|
|
6356
|
+
env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
|
|
6357
|
+
env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
|
|
6358
|
+
applyGitHubCredentialHelperEnv(env);
|
|
6359
|
+
}
|
|
6344
6360
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
6345
6361
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
6346
6362
|
}
|
|
@@ -6436,12 +6452,21 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6436
6452
|
}
|
|
6437
6453
|
return targetPath;
|
|
6438
6454
|
}
|
|
6455
|
+
function applyGitHubCredentialHelperEnv(env) {
|
|
6456
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
6457
|
+
env.GIT_CONFIG_COUNT = "2";
|
|
6458
|
+
env.GIT_CONFIG_KEY_0 = "credential.helper";
|
|
6459
|
+
env.GIT_CONFIG_VALUE_0 = "";
|
|
6460
|
+
env.GIT_CONFIG_KEY_1 = "credential.helper";
|
|
6461
|
+
env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
|
|
6462
|
+
}
|
|
6439
6463
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6440
6464
|
const secretsPath = resolve27(runtimeRoot, "runtime-secrets.json");
|
|
6441
6465
|
const persisted = {};
|
|
6442
6466
|
for (const key of [
|
|
6443
6467
|
"GITHUB_TOKEN",
|
|
6444
6468
|
"GH_TOKEN",
|
|
6469
|
+
"RIG_GITHUB_TOKEN",
|
|
6445
6470
|
"GREPTILE_GITHUB_TOKEN",
|
|
6446
6471
|
"GREPTILE_API_KEY",
|
|
6447
6472
|
"AI_REVIEW_MODE",
|
|
@@ -8091,7 +8116,11 @@ async function ensureAgentRuntime(options) {
|
|
|
8091
8116
|
mkdirSync18(runtime.binDir, { recursive: true });
|
|
8092
8117
|
mkdirSync18(workspaceLayout.distDir, { recursive: true });
|
|
8093
8118
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8094
|
-
|
|
8119
|
+
if (options.preserveTaskArtifacts) {
|
|
8120
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
8121
|
+
} else {
|
|
8122
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
8123
|
+
}
|
|
8095
8124
|
const ctx = {
|
|
8096
8125
|
runtimeId: options.id,
|
|
8097
8126
|
taskId: options.taskId,
|
|
@@ -686,20 +686,23 @@ function hashProjectPath(workspaceDir) {
|
|
|
686
686
|
}
|
|
687
687
|
function resolveGithubCliBinaryPath() {
|
|
688
688
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
689
|
-
if (explicit && existsSync5(explicit)) {
|
|
689
|
+
if (explicit && existsSync5(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
690
690
|
return explicit;
|
|
691
691
|
}
|
|
692
|
-
const
|
|
693
|
-
if (bunResolved && existsSync5(bunResolved)) {
|
|
694
|
-
return bunResolved;
|
|
695
|
-
}
|
|
696
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
692
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
697
693
|
if (existsSync5(candidate)) {
|
|
698
694
|
return candidate;
|
|
699
695
|
}
|
|
700
696
|
}
|
|
697
|
+
const bunResolved = Bun.which("gh");
|
|
698
|
+
if (bunResolved && existsSync5(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
699
|
+
return bunResolved;
|
|
700
|
+
}
|
|
701
701
|
return "";
|
|
702
702
|
}
|
|
703
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
704
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
705
|
+
}
|
|
703
706
|
async function resolveGithubCliAuthToken(ghBinary = "") {
|
|
704
707
|
const gh = ghBinary || resolveGithubCliBinaryPath();
|
|
705
708
|
if (!gh) {
|
|
@@ -800,6 +803,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
800
803
|
XDG_CACHE_HOME: runtime.cacheDir,
|
|
801
804
|
XDG_STATE_HOME: runtime.stateDir,
|
|
802
805
|
RIG_AGENT_ID: runtime.id,
|
|
806
|
+
...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
|
|
807
|
+
...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
|
|
803
808
|
RIG_TASK_ID: runtime.taskId,
|
|
804
809
|
RIG_TASK_RUNTIME_ID: runtime.id,
|
|
805
810
|
RIG_TASK_WORKSPACE: runtime.workspaceDir,
|
|
@@ -863,6 +868,10 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
863
868
|
env[key] = value;
|
|
864
869
|
}
|
|
865
870
|
}
|
|
871
|
+
const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
872
|
+
if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
|
|
873
|
+
env.GITHUB_TOKEN = rigGithubToken;
|
|
874
|
+
}
|
|
866
875
|
const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
|
|
867
876
|
if (fallbackGithubToken) {
|
|
868
877
|
env.GITHUB_TOKEN = fallbackGithubToken;
|
|
@@ -873,6 +882,13 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
873
882
|
if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
|
|
874
883
|
env.GH_TOKEN = env.GITHUB_TOKEN;
|
|
875
884
|
}
|
|
885
|
+
const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
|
|
886
|
+
if (gitHubToken) {
|
|
887
|
+
env.RIG_GITHUB_TOKEN = gitHubToken;
|
|
888
|
+
env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
|
|
889
|
+
env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
|
|
890
|
+
applyGitHubCredentialHelperEnv(env);
|
|
891
|
+
}
|
|
876
892
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
877
893
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
878
894
|
}
|
|
@@ -968,12 +984,21 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
968
984
|
}
|
|
969
985
|
return targetPath;
|
|
970
986
|
}
|
|
987
|
+
function applyGitHubCredentialHelperEnv(env) {
|
|
988
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
989
|
+
env.GIT_CONFIG_COUNT = "2";
|
|
990
|
+
env.GIT_CONFIG_KEY_0 = "credential.helper";
|
|
991
|
+
env.GIT_CONFIG_VALUE_0 = "";
|
|
992
|
+
env.GIT_CONFIG_KEY_1 = "credential.helper";
|
|
993
|
+
env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
|
|
994
|
+
}
|
|
971
995
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
972
996
|
const secretsPath = resolve7(runtimeRoot, "runtime-secrets.json");
|
|
973
997
|
const persisted = {};
|
|
974
998
|
for (const key of [
|
|
975
999
|
"GITHUB_TOKEN",
|
|
976
1000
|
"GH_TOKEN",
|
|
1001
|
+
"RIG_GITHUB_TOKEN",
|
|
977
1002
|
"GREPTILE_GITHUB_TOKEN",
|
|
978
1003
|
"GREPTILE_API_KEY",
|
|
979
1004
|
"AI_REVIEW_MODE",
|