@h-rig/runtime 0.0.6-alpha.2 → 0.0.6-alpha.21

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.
Files changed (46) hide show
  1. package/dist/bin/rig-agent-dispatch.js +84 -313
  2. package/dist/bin/rig-agent.js +85 -27
  3. package/dist/src/control-plane/agent-wrapper.js +101 -27
  4. package/dist/src/control-plane/authority-files.js +12 -6
  5. package/dist/src/control-plane/harness-main.js +1357 -180
  6. package/dist/src/control-plane/hooks/completion-verification.js +1669 -329
  7. package/dist/src/control-plane/hooks/inject-context.js +2 -2
  8. package/dist/src/control-plane/hooks/submodule-branch.js +26 -3
  9. package/dist/src/control-plane/hooks/task-runtime-start.js +26 -3
  10. package/dist/src/control-plane/native/git-ops.js +134 -68
  11. package/dist/src/control-plane/native/harness-cli.js +1357 -180
  12. package/dist/src/control-plane/native/pr-automation.js +1532 -54
  13. package/dist/src/control-plane/native/pr-review-gate.js +1330 -0
  14. package/dist/src/control-plane/native/run-ops.js +35 -12
  15. package/dist/src/control-plane/native/task-ops.js +1274 -155
  16. package/dist/src/control-plane/native/validator.js +2 -2
  17. package/dist/src/control-plane/native/verifier.js +1274 -154
  18. package/dist/src/control-plane/native/workspace-ops.js +12 -6
  19. package/dist/src/control-plane/runtime/index.js +38 -9
  20. package/dist/src/control-plane/runtime/isolation/home.js +31 -6
  21. package/dist/src/control-plane/runtime/isolation/index.js +38 -9
  22. package/dist/src/control-plane/runtime/isolation/runner.js +31 -6
  23. package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
  24. package/dist/src/control-plane/runtime/isolation.js +38 -9
  25. package/dist/src/control-plane/runtime/queue.js +38 -9
  26. package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
  27. package/dist/src/control-plane/tasks/source-lifecycle.js +2 -2
  28. package/dist/src/index.js +27 -20
  29. package/dist/src/layout.js +12 -7
  30. package/dist/src/local-server.js +20 -14
  31. package/native/darwin-arm64/{bin/rig-git → rig-git} +0 -0
  32. package/native/darwin-arm64/rig-git.build-manifest.json +4 -0
  33. package/native/darwin-arm64/{bin/rig-shell → rig-shell} +0 -0
  34. package/native/darwin-arm64/rig-shell.build-manifest.json +4 -0
  35. package/native/darwin-arm64/{bin/rig-tools → rig-tools} +0 -0
  36. package/native/darwin-arm64/rig-tools.build-manifest.json +4 -0
  37. package/native/darwin-arm64/{lib/runtime-native.dylib → runtime-native.dylib} +0 -0
  38. package/package.json +6 -6
  39. package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
  40. package/native/darwin-arm64/manifest.json +0 -1
  41. package/native/linux-x64/bin/rig-git +0 -0
  42. package/native/linux-x64/bin/rig-shell +0 -0
  43. package/native/linux-x64/bin/rig-tools +0 -0
  44. package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
  45. package/native/linux-x64/lib/runtime-native.so +0 -0
  46. package/native/linux-x64/manifest.json +0 -1
@@ -169,10 +169,6 @@ function runBelongsToProject(projectRoot, run, runsDir) {
169
169
  if (recordedProjectRoot) {
170
170
  return resolve2(recordedProjectRoot) === normalizedRoot;
171
171
  }
172
- const projectLocalRunsDir = resolve2(normalizedRoot, ".rig", "runs");
173
- if (isPathWithin(projectLocalRunsDir, resolve2(runsDir))) {
174
- return true;
175
- }
176
172
  const pathFields = [
177
173
  run.worktreePath,
178
174
  run.artifactRoot,
@@ -180,10 +176,20 @@ function runBelongsToProject(projectRoot, run, runsDir) {
180
176
  run.sessionPath,
181
177
  run.sessionLogPath
182
178
  ].filter((value) => typeof value === "string" && value.trim().length > 0);
183
- if (pathFields.length === 0) {
179
+ if (pathFields.length > 0) {
180
+ if (pathFields.some((value) => isPathWithin(normalizedRoot, resolve2(value)))) {
181
+ return true;
182
+ }
183
+ const pointsAtManagedWorkspace = pathFields.some((value) => /(?:^|[/\\])\.worktrees(?:[/\\]|$)/.test(value));
184
+ if (pointsAtManagedWorkspace) {
185
+ return false;
186
+ }
187
+ }
188
+ const projectLocalRunsDir = resolve2(normalizedRoot, ".rig", "runs");
189
+ if (isPathWithin(projectLocalRunsDir, resolve2(runsDir))) {
184
190
  return true;
185
191
  }
186
- return pathFields.some((value) => isPathWithin(normalizedRoot, resolve2(value)));
192
+ return pathFields.length === 0;
187
193
  }
188
194
  function isPathWithin(root, candidate) {
189
195
  const relativePath = relative(root, candidate);
@@ -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 bunResolved = Bun.which("gh");
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
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
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 bunResolved = Bun.which("gh");
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",
@@ -3148,8 +3148,8 @@ function githubStatusFor(issue) {
3148
3148
  return "open";
3149
3149
  }
3150
3150
  function selectedGitHubEnv() {
3151
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
3152
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
3151
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
3152
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
3153
3153
  }
3154
3154
  function ghSpawnOptions() {
3155
3155
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -5454,20 +5454,23 @@ function hashProjectPath(workspaceDir) {
5454
5454
  }
5455
5455
  function resolveGithubCliBinaryPath() {
5456
5456
  const explicit = process.env.RIG_GH_BIN?.trim();
5457
- if (explicit && existsSync23(explicit)) {
5457
+ if (explicit && existsSync23(explicit) && !isRuntimeGatewayGhPath(explicit)) {
5458
5458
  return explicit;
5459
5459
  }
5460
- const bunResolved = Bun.which("gh");
5461
- if (bunResolved && existsSync23(bunResolved)) {
5462
- return bunResolved;
5463
- }
5464
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
5460
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
5465
5461
  if (existsSync23(candidate)) {
5466
5462
  return candidate;
5467
5463
  }
5468
5464
  }
5465
+ const bunResolved = Bun.which("gh");
5466
+ if (bunResolved && existsSync23(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
5467
+ return bunResolved;
5468
+ }
5469
5469
  return "";
5470
5470
  }
5471
+ function isRuntimeGatewayGhPath(candidate) {
5472
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
5473
+ }
5471
5474
  async function resolveGithubCliAuthToken(ghBinary = "") {
5472
5475
  const gh = ghBinary || resolveGithubCliBinaryPath();
5473
5476
  if (!gh) {
@@ -5568,6 +5571,8 @@ async function runtimeEnv(projectRoot, runtime) {
5568
5571
  XDG_CACHE_HOME: runtime.cacheDir,
5569
5572
  XDG_STATE_HOME: runtime.stateDir,
5570
5573
  RIG_AGENT_ID: runtime.id,
5574
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
5575
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
5571
5576
  RIG_TASK_ID: runtime.taskId,
5572
5577
  RIG_TASK_RUNTIME_ID: runtime.id,
5573
5578
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -5631,6 +5636,10 @@ async function runtimeEnv(projectRoot, runtime) {
5631
5636
  env[key] = value;
5632
5637
  }
5633
5638
  }
5639
+ const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
5640
+ if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
5641
+ env.GITHUB_TOKEN = rigGithubToken;
5642
+ }
5634
5643
  const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
5635
5644
  if (fallbackGithubToken) {
5636
5645
  env.GITHUB_TOKEN = fallbackGithubToken;
@@ -5641,6 +5650,13 @@ async function runtimeEnv(projectRoot, runtime) {
5641
5650
  if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
5642
5651
  env.GH_TOKEN = env.GITHUB_TOKEN;
5643
5652
  }
5653
+ const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
5654
+ if (gitHubToken) {
5655
+ env.RIG_GITHUB_TOKEN = gitHubToken;
5656
+ env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
5657
+ env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
5658
+ applyGitHubCredentialHelperEnv(env);
5659
+ }
5644
5660
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
5645
5661
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
5646
5662
  }
@@ -5736,12 +5752,21 @@ async function materializeRuntimeCertBundle(runtime) {
5736
5752
  }
5737
5753
  return targetPath;
5738
5754
  }
5755
+ function applyGitHubCredentialHelperEnv(env) {
5756
+ env.GIT_TERMINAL_PROMPT = "0";
5757
+ env.GIT_CONFIG_COUNT = "2";
5758
+ env.GIT_CONFIG_KEY_0 = "credential.helper";
5759
+ env.GIT_CONFIG_VALUE_0 = "";
5760
+ env.GIT_CONFIG_KEY_1 = "credential.helper";
5761
+ 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';
5762
+ }
5739
5763
  function persistRuntimeSecrets(runtimeRoot, env) {
5740
5764
  const secretsPath = resolve25(runtimeRoot, "runtime-secrets.json");
5741
5765
  const persisted = {};
5742
5766
  for (const key of [
5743
5767
  "GITHUB_TOKEN",
5744
5768
  "GH_TOKEN",
5769
+ "RIG_GITHUB_TOKEN",
5745
5770
  "GREPTILE_GITHUB_TOKEN",
5746
5771
  "GREPTILE_API_KEY",
5747
5772
  "AI_REVIEW_MODE",
@@ -8060,7 +8085,11 @@ async function ensureAgentRuntime(options) {
8060
8085
  mkdirSync18(runtime.binDir, { recursive: true });
8061
8086
  mkdirSync18(workspaceLayout.distDir, { recursive: true });
8062
8087
  prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
8063
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8088
+ if (options.preserveTaskArtifacts) {
8089
+ console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
8090
+ } else {
8091
+ await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8092
+ }
8064
8093
  const ctx = {
8065
8094
  runtimeId: options.id,
8066
8095
  taskId: options.taskId,
@@ -2091,20 +2091,23 @@ function taskRuntimeId(taskId) {
2091
2091
  }
2092
2092
  function resolveGithubCliBinaryPath() {
2093
2093
  const explicit = process.env.RIG_GH_BIN?.trim();
2094
- if (explicit && existsSync8(explicit)) {
2094
+ if (explicit && existsSync8(explicit) && !isRuntimeGatewayGhPath(explicit)) {
2095
2095
  return explicit;
2096
2096
  }
2097
- const bunResolved = Bun.which("gh");
2098
- if (bunResolved && existsSync8(bunResolved)) {
2099
- return bunResolved;
2100
- }
2101
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
2097
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
2102
2098
  if (existsSync8(candidate)) {
2103
2099
  return candidate;
2104
2100
  }
2105
2101
  }
2102
+ const bunResolved = Bun.which("gh");
2103
+ if (bunResolved && existsSync8(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
2104
+ return bunResolved;
2105
+ }
2106
2106
  return "";
2107
2107
  }
2108
+ function isRuntimeGatewayGhPath(candidate) {
2109
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
2110
+ }
2108
2111
  async function resolveGithubCliAuthToken(ghBinary = "") {
2109
2112
  const gh = ghBinary || resolveGithubCliBinaryPath();
2110
2113
  if (!gh) {
@@ -2198,6 +2201,8 @@ async function runtimeEnv(projectRoot, runtime) {
2198
2201
  XDG_CACHE_HOME: runtime.cacheDir,
2199
2202
  XDG_STATE_HOME: runtime.stateDir,
2200
2203
  RIG_AGENT_ID: runtime.id,
2204
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
2205
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
2201
2206
  RIG_TASK_ID: runtime.taskId,
2202
2207
  RIG_TASK_RUNTIME_ID: runtime.id,
2203
2208
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -2261,6 +2266,10 @@ async function runtimeEnv(projectRoot, runtime) {
2261
2266
  env[key] = value;
2262
2267
  }
2263
2268
  }
2269
+ const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
2270
+ if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
2271
+ env.GITHUB_TOKEN = rigGithubToken;
2272
+ }
2264
2273
  const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
2265
2274
  if (fallbackGithubToken) {
2266
2275
  env.GITHUB_TOKEN = fallbackGithubToken;
@@ -2271,6 +2280,13 @@ async function runtimeEnv(projectRoot, runtime) {
2271
2280
  if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
2272
2281
  env.GH_TOKEN = env.GITHUB_TOKEN;
2273
2282
  }
2283
+ const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
2284
+ if (gitHubToken) {
2285
+ env.RIG_GITHUB_TOKEN = gitHubToken;
2286
+ env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
2287
+ env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
2288
+ applyGitHubCredentialHelperEnv(env);
2289
+ }
2274
2290
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
2275
2291
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
2276
2292
  }
@@ -2318,12 +2334,21 @@ async function materializeRuntimeCertBundle(runtime) {
2318
2334
  }
2319
2335
  return targetPath;
2320
2336
  }
2337
+ function applyGitHubCredentialHelperEnv(env) {
2338
+ env.GIT_TERMINAL_PROMPT = "0";
2339
+ env.GIT_CONFIG_COUNT = "2";
2340
+ env.GIT_CONFIG_KEY_0 = "credential.helper";
2341
+ env.GIT_CONFIG_VALUE_0 = "";
2342
+ env.GIT_CONFIG_KEY_1 = "credential.helper";
2343
+ 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';
2344
+ }
2321
2345
  function persistRuntimeSecrets(runtimeRoot, env) {
2322
2346
  const secretsPath = resolve11(runtimeRoot, "runtime-secrets.json");
2323
2347
  const persisted = {};
2324
2348
  for (const key of [
2325
2349
  "GITHUB_TOKEN",
2326
2350
  "GH_TOKEN",
2351
+ "RIG_GITHUB_TOKEN",
2327
2352
  "GREPTILE_GITHUB_TOKEN",
2328
2353
  "GREPTILE_API_KEY",
2329
2354
  "AI_REVIEW_MODE",
@@ -417,20 +417,23 @@ function hashProjectPath(workspaceDir) {
417
417
  }
418
418
  function resolveGithubCliBinaryPath() {
419
419
  const explicit = process.env.RIG_GH_BIN?.trim();
420
- if (explicit && existsSync3(explicit)) {
420
+ if (explicit && existsSync3(explicit) && !isRuntimeGatewayGhPath(explicit)) {
421
421
  return explicit;
422
422
  }
423
- const bunResolved = Bun.which("gh");
424
- if (bunResolved && existsSync3(bunResolved)) {
425
- return bunResolved;
426
- }
427
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
423
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
428
424
  if (existsSync3(candidate)) {
429
425
  return candidate;
430
426
  }
431
427
  }
428
+ const bunResolved = Bun.which("gh");
429
+ if (bunResolved && existsSync3(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
430
+ return bunResolved;
431
+ }
432
432
  return "";
433
433
  }
434
+ function isRuntimeGatewayGhPath(candidate) {
435
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
436
+ }
434
437
  async function resolveGithubCliAuthToken(ghBinary = "") {
435
438
  const gh = ghBinary || resolveGithubCliBinaryPath();
436
439
  if (!gh) {
@@ -3148,8 +3148,8 @@ function githubStatusFor(issue) {
3148
3148
  return "open";
3149
3149
  }
3150
3150
  function selectedGitHubEnv() {
3151
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
3152
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
3151
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
3152
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
3153
3153
  }
3154
3154
  function ghSpawnOptions() {
3155
3155
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -5454,20 +5454,23 @@ function hashProjectPath(workspaceDir) {
5454
5454
  }
5455
5455
  function resolveGithubCliBinaryPath() {
5456
5456
  const explicit = process.env.RIG_GH_BIN?.trim();
5457
- if (explicit && existsSync23(explicit)) {
5457
+ if (explicit && existsSync23(explicit) && !isRuntimeGatewayGhPath(explicit)) {
5458
5458
  return explicit;
5459
5459
  }
5460
- const bunResolved = Bun.which("gh");
5461
- if (bunResolved && existsSync23(bunResolved)) {
5462
- return bunResolved;
5463
- }
5464
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
5460
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
5465
5461
  if (existsSync23(candidate)) {
5466
5462
  return candidate;
5467
5463
  }
5468
5464
  }
5465
+ const bunResolved = Bun.which("gh");
5466
+ if (bunResolved && existsSync23(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
5467
+ return bunResolved;
5468
+ }
5469
5469
  return "";
5470
5470
  }
5471
+ function isRuntimeGatewayGhPath(candidate) {
5472
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
5473
+ }
5471
5474
  async function resolveGithubCliAuthToken(ghBinary = "") {
5472
5475
  const gh = ghBinary || resolveGithubCliBinaryPath();
5473
5476
  if (!gh) {
@@ -5568,6 +5571,8 @@ async function runtimeEnv(projectRoot, runtime) {
5568
5571
  XDG_CACHE_HOME: runtime.cacheDir,
5569
5572
  XDG_STATE_HOME: runtime.stateDir,
5570
5573
  RIG_AGENT_ID: runtime.id,
5574
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
5575
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
5571
5576
  RIG_TASK_ID: runtime.taskId,
5572
5577
  RIG_TASK_RUNTIME_ID: runtime.id,
5573
5578
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -5631,6 +5636,10 @@ async function runtimeEnv(projectRoot, runtime) {
5631
5636
  env[key] = value;
5632
5637
  }
5633
5638
  }
5639
+ const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
5640
+ if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
5641
+ env.GITHUB_TOKEN = rigGithubToken;
5642
+ }
5634
5643
  const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
5635
5644
  if (fallbackGithubToken) {
5636
5645
  env.GITHUB_TOKEN = fallbackGithubToken;
@@ -5641,6 +5650,13 @@ async function runtimeEnv(projectRoot, runtime) {
5641
5650
  if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
5642
5651
  env.GH_TOKEN = env.GITHUB_TOKEN;
5643
5652
  }
5653
+ const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
5654
+ if (gitHubToken) {
5655
+ env.RIG_GITHUB_TOKEN = gitHubToken;
5656
+ env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
5657
+ env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
5658
+ applyGitHubCredentialHelperEnv(env);
5659
+ }
5644
5660
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
5645
5661
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
5646
5662
  }
@@ -5736,12 +5752,21 @@ async function materializeRuntimeCertBundle(runtime) {
5736
5752
  }
5737
5753
  return targetPath;
5738
5754
  }
5755
+ function applyGitHubCredentialHelperEnv(env) {
5756
+ env.GIT_TERMINAL_PROMPT = "0";
5757
+ env.GIT_CONFIG_COUNT = "2";
5758
+ env.GIT_CONFIG_KEY_0 = "credential.helper";
5759
+ env.GIT_CONFIG_VALUE_0 = "";
5760
+ env.GIT_CONFIG_KEY_1 = "credential.helper";
5761
+ 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';
5762
+ }
5739
5763
  function persistRuntimeSecrets(runtimeRoot, env) {
5740
5764
  const secretsPath = resolve25(runtimeRoot, "runtime-secrets.json");
5741
5765
  const persisted = {};
5742
5766
  for (const key of [
5743
5767
  "GITHUB_TOKEN",
5744
5768
  "GH_TOKEN",
5769
+ "RIG_GITHUB_TOKEN",
5745
5770
  "GREPTILE_GITHUB_TOKEN",
5746
5771
  "GREPTILE_API_KEY",
5747
5772
  "AI_REVIEW_MODE",
@@ -8060,7 +8085,11 @@ async function ensureAgentRuntime(options) {
8060
8085
  mkdirSync18(runtime.binDir, { recursive: true });
8061
8086
  mkdirSync18(workspaceLayout.distDir, { recursive: true });
8062
8087
  prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
8063
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8088
+ if (options.preserveTaskArtifacts) {
8089
+ console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
8090
+ } else {
8091
+ await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8092
+ }
8064
8093
  const ctx = {
8065
8094
  runtimeId: options.id,
8066
8095
  taskId: options.taskId,
@@ -4560,8 +4560,8 @@ function githubStatusFor(issue) {
4560
4560
  return "open";
4561
4561
  }
4562
4562
  function selectedGitHubEnv() {
4563
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
4564
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
4563
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
4564
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
4565
4565
  }
4566
4566
  function ghSpawnOptions() {
4567
4567
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -6178,20 +6178,23 @@ function hashProjectPath(workspaceDir) {
6178
6178
  }
6179
6179
  function resolveGithubCliBinaryPath() {
6180
6180
  const explicit = process.env.RIG_GH_BIN?.trim();
6181
- if (explicit && existsSync24(explicit)) {
6181
+ if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
6182
6182
  return explicit;
6183
6183
  }
6184
- const bunResolved = Bun.which("gh");
6185
- if (bunResolved && existsSync24(bunResolved)) {
6186
- return bunResolved;
6187
- }
6188
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
6184
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
6189
6185
  if (existsSync24(candidate)) {
6190
6186
  return candidate;
6191
6187
  }
6192
6188
  }
6189
+ const bunResolved = Bun.which("gh");
6190
+ if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
6191
+ return bunResolved;
6192
+ }
6193
6193
  return "";
6194
6194
  }
6195
+ function isRuntimeGatewayGhPath(candidate) {
6196
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
6197
+ }
6195
6198
  async function resolveGithubCliAuthToken(ghBinary = "") {
6196
6199
  const gh = ghBinary || resolveGithubCliBinaryPath();
6197
6200
  if (!gh) {
@@ -6292,6 +6295,8 @@ async function runtimeEnv(projectRoot, runtime) {
6292
6295
  XDG_CACHE_HOME: runtime.cacheDir,
6293
6296
  XDG_STATE_HOME: runtime.stateDir,
6294
6297
  RIG_AGENT_ID: runtime.id,
6298
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
6299
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
6295
6300
  RIG_TASK_ID: runtime.taskId,
6296
6301
  RIG_TASK_RUNTIME_ID: runtime.id,
6297
6302
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -6355,6 +6360,10 @@ async function runtimeEnv(projectRoot, runtime) {
6355
6360
  env[key] = value;
6356
6361
  }
6357
6362
  }
6363
+ const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
6364
+ if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
6365
+ env.GITHUB_TOKEN = rigGithubToken;
6366
+ }
6358
6367
  const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
6359
6368
  if (fallbackGithubToken) {
6360
6369
  env.GITHUB_TOKEN = fallbackGithubToken;
@@ -6365,6 +6374,13 @@ async function runtimeEnv(projectRoot, runtime) {
6365
6374
  if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
6366
6375
  env.GH_TOKEN = env.GITHUB_TOKEN;
6367
6376
  }
6377
+ const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
6378
+ if (gitHubToken) {
6379
+ env.RIG_GITHUB_TOKEN = gitHubToken;
6380
+ env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
6381
+ env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
6382
+ applyGitHubCredentialHelperEnv(env);
6383
+ }
6368
6384
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
6369
6385
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
6370
6386
  }
@@ -6460,12 +6476,21 @@ async function materializeRuntimeCertBundle(runtime) {
6460
6476
  }
6461
6477
  return targetPath;
6462
6478
  }
6479
+ function applyGitHubCredentialHelperEnv(env) {
6480
+ env.GIT_TERMINAL_PROMPT = "0";
6481
+ env.GIT_CONFIG_COUNT = "2";
6482
+ env.GIT_CONFIG_KEY_0 = "credential.helper";
6483
+ env.GIT_CONFIG_VALUE_0 = "";
6484
+ env.GIT_CONFIG_KEY_1 = "credential.helper";
6485
+ 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';
6486
+ }
6463
6487
  function persistRuntimeSecrets(runtimeRoot, env) {
6464
6488
  const secretsPath = resolve27(runtimeRoot, "runtime-secrets.json");
6465
6489
  const persisted = {};
6466
6490
  for (const key of [
6467
6491
  "GITHUB_TOKEN",
6468
6492
  "GH_TOKEN",
6493
+ "RIG_GITHUB_TOKEN",
6469
6494
  "GREPTILE_GITHUB_TOKEN",
6470
6495
  "GREPTILE_API_KEY",
6471
6496
  "AI_REVIEW_MODE",
@@ -8045,7 +8070,11 @@ async function ensureAgentRuntime(options) {
8045
8070
  mkdirSync18(runtime.binDir, { recursive: true });
8046
8071
  mkdirSync18(workspaceLayout.distDir, { recursive: true });
8047
8072
  prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
8048
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8073
+ if (options.preserveTaskArtifacts) {
8074
+ console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
8075
+ } else {
8076
+ await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8077
+ }
8049
8078
  const ctx = {
8050
8079
  runtimeId: options.id,
8051
8080
  taskId: options.taskId,