@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.
- package/dist/bin/rig-agent-dispatch.js +84 -313
- package/dist/bin/rig-agent.js +85 -27
- package/dist/src/control-plane/agent-wrapper.js +101 -27
- package/dist/src/control-plane/authority-files.js +12 -6
- package/dist/src/control-plane/harness-main.js +1357 -180
- package/dist/src/control-plane/hooks/completion-verification.js +1669 -329
- 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 +134 -68
- package/dist/src/control-plane/native/harness-cli.js +1357 -180
- package/dist/src/control-plane/native/pr-automation.js +1532 -54
- package/dist/src/control-plane/native/pr-review-gate.js +1330 -0
- package/dist/src/control-plane/native/run-ops.js +35 -12
- package/dist/src/control-plane/native/task-ops.js +1274 -155
- package/dist/src/control-plane/native/validator.js +2 -2
- package/dist/src/control-plane/native/verifier.js +1274 -154
- package/dist/src/control-plane/native/workspace-ops.js +12 -6
- 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 +27 -20
- package/dist/src/layout.js +12 -7
- 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
|
@@ -2951,34 +2951,6 @@ async function readSourceAwareTaskStatus(projectRoot, taskId, options = {}) {
|
|
|
2951
2951
|
return null;
|
|
2952
2952
|
}
|
|
2953
2953
|
}
|
|
2954
|
-
function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
|
|
2955
|
-
const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
|
|
2956
|
-
const rawEntry = readRawTaskEntry(configPath, taskId);
|
|
2957
|
-
if (!rawEntry) {
|
|
2958
|
-
const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
|
|
2959
|
-
return configuredFilesPath ? updateFileBackedTask(projectRoot, configuredFilesPath, taskId, update) : false;
|
|
2960
|
-
}
|
|
2961
|
-
const metadata = readMaterializedTaskMetadata(rawEntry);
|
|
2962
|
-
const source = metadata.taskSource;
|
|
2963
|
-
if (source?.kind === "github-issues") {
|
|
2964
|
-
applyGithubIssueUpdate(options.ghBinary ?? "gh", options.spawn ?? spawnSync, taskId, metadata, update);
|
|
2965
|
-
return true;
|
|
2966
|
-
}
|
|
2967
|
-
if (source?.kind === "files" && source.path) {
|
|
2968
|
-
return updateFileBackedTask(projectRoot, source.path, taskId, update);
|
|
2969
|
-
}
|
|
2970
|
-
if (source?.kind && source.kind !== "files" && source.kind !== "legacy-task-config") {
|
|
2971
|
-
return false;
|
|
2972
|
-
}
|
|
2973
|
-
if (!source && options.allowLocalTaskConfigStatusFallback === false) {
|
|
2974
|
-
return false;
|
|
2975
|
-
}
|
|
2976
|
-
if (typeof update.status !== "string" || update.status.trim().length === 0) {
|
|
2977
|
-
return false;
|
|
2978
|
-
}
|
|
2979
|
-
writeLegacyTaskStatus(configPath, taskId, update.status);
|
|
2980
|
-
return true;
|
|
2981
|
-
}
|
|
2982
2954
|
function readMaterializedTaskMetadata(entry) {
|
|
2983
2955
|
const rawRig = entry._rig;
|
|
2984
2956
|
if (!isPlainRecord2(rawRig)) {
|
|
@@ -3052,46 +3024,6 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3052
3024
|
const { validation_descriptions: _legacyDescriptions, _meta, ...tasks } = raw;
|
|
3053
3025
|
return tasks;
|
|
3054
3026
|
}
|
|
3055
|
-
function writeLegacyTaskStatus(configPath, taskId, status) {
|
|
3056
|
-
const rawConfig = readRawTaskConfig(configPath);
|
|
3057
|
-
if (!rawConfig) {
|
|
3058
|
-
return;
|
|
3059
|
-
}
|
|
3060
|
-
const entry = rawConfig[taskId];
|
|
3061
|
-
if (!isPlainRecord2(entry)) {
|
|
3062
|
-
return;
|
|
3063
|
-
}
|
|
3064
|
-
entry.status = status;
|
|
3065
|
-
writeFileSync5(configPath, `${JSON.stringify(rawConfig, null, 2)}
|
|
3066
|
-
`, "utf8");
|
|
3067
|
-
}
|
|
3068
|
-
function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
3069
|
-
const directory = resolve13(projectRoot, sourcePath);
|
|
3070
|
-
const file = findFileBackedTaskFile(directory, taskId);
|
|
3071
|
-
if (!file) {
|
|
3072
|
-
return false;
|
|
3073
|
-
}
|
|
3074
|
-
const raw = JSON.parse(readFileSync6(file, "utf8"));
|
|
3075
|
-
if (!isPlainRecord2(raw)) {
|
|
3076
|
-
return false;
|
|
3077
|
-
}
|
|
3078
|
-
if (update.status)
|
|
3079
|
-
raw.status = update.status;
|
|
3080
|
-
if (update.title !== undefined)
|
|
3081
|
-
raw.title = update.title;
|
|
3082
|
-
if (update.body !== undefined)
|
|
3083
|
-
raw.body = update.body;
|
|
3084
|
-
if (update.comment?.trim()) {
|
|
3085
|
-
const existing = Array.isArray(raw.comments) ? raw.comments : [];
|
|
3086
|
-
raw.comments = [
|
|
3087
|
-
...existing,
|
|
3088
|
-
{ body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
|
|
3089
|
-
];
|
|
3090
|
-
}
|
|
3091
|
-
writeFileSync5(file, `${JSON.stringify(raw, null, 2)}
|
|
3092
|
-
`, "utf8");
|
|
3093
|
-
return true;
|
|
3094
|
-
}
|
|
3095
3027
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3096
3028
|
const directory = resolve13(projectRoot, sourcePath);
|
|
3097
3029
|
if (!existsSync13(directory)) {
|
|
@@ -3159,26 +3091,6 @@ function readGithubIssueTask(bin, spawnFn, id, metadata, rawEntry) {
|
|
|
3159
3091
|
], spawnFn);
|
|
3160
3092
|
return githubIssueToTask(issue, source, rawEntry);
|
|
3161
3093
|
}
|
|
3162
|
-
function applyGithubIssueUpdate(bin, spawnFn, id, metadata, update) {
|
|
3163
|
-
const source = requireGithubIssueSource(metadata, id);
|
|
3164
|
-
const repo = `${source.owner}/${source.repo}`;
|
|
3165
|
-
if (update.status) {
|
|
3166
|
-
applyGithubIssueStatus(bin, repo, spawnFn, id, update.status);
|
|
3167
|
-
}
|
|
3168
|
-
if (typeof update.comment === "string" && update.comment.trim().length > 0) {
|
|
3169
|
-
runGhVoid(bin, ["issue", "comment", String(id), "--repo", repo, "--body", update.comment], spawnFn);
|
|
3170
|
-
}
|
|
3171
|
-
const editArgs = ["issue", "edit", String(id), "--repo", repo];
|
|
3172
|
-
if (typeof update.title === "string" && update.title.trim().length > 0) {
|
|
3173
|
-
editArgs.push("--title", update.title.trim());
|
|
3174
|
-
}
|
|
3175
|
-
if (typeof update.body === "string") {
|
|
3176
|
-
editArgs.push("--body", update.body);
|
|
3177
|
-
}
|
|
3178
|
-
if (editArgs.length > 5) {
|
|
3179
|
-
runGhVoid(bin, editArgs, spawnFn);
|
|
3180
|
-
}
|
|
3181
|
-
}
|
|
3182
3094
|
function requireGithubIssueSource(metadata, id) {
|
|
3183
3095
|
const source = metadata.taskSource;
|
|
3184
3096
|
if (source?.kind === "github-issues" && source.owner && source.repo) {
|
|
@@ -3238,76 +3150,9 @@ function githubStatusFor(issue) {
|
|
|
3238
3150
|
return "cancelled";
|
|
3239
3151
|
return "open";
|
|
3240
3152
|
}
|
|
3241
|
-
function applyGithubIssueStatus(bin, repo, spawnFn, id, status) {
|
|
3242
|
-
if (status === "closed") {
|
|
3243
|
-
runGhVoid(bin, ["issue", "close", String(id), "--repo", repo], spawnFn);
|
|
3244
|
-
return;
|
|
3245
|
-
}
|
|
3246
|
-
const targetLabel = statusLabelFor(status);
|
|
3247
|
-
for (const label of STATUS_LABELS) {
|
|
3248
|
-
if (targetLabel !== null && label === targetLabel) {
|
|
3249
|
-
continue;
|
|
3250
|
-
}
|
|
3251
|
-
try {
|
|
3252
|
-
runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--remove-label", label], spawnFn);
|
|
3253
|
-
} catch {}
|
|
3254
|
-
}
|
|
3255
|
-
if (targetLabel !== null) {
|
|
3256
|
-
try {
|
|
3257
|
-
runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--add-label", targetLabel], spawnFn);
|
|
3258
|
-
} catch (error) {
|
|
3259
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3260
|
-
if (!/not found/i.test(message)) {
|
|
3261
|
-
throw error;
|
|
3262
|
-
}
|
|
3263
|
-
ensureStatusLabel(bin, repo, spawnFn, targetLabel);
|
|
3264
|
-
runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--add-label", targetLabel], spawnFn);
|
|
3265
|
-
}
|
|
3266
|
-
}
|
|
3267
|
-
}
|
|
3268
|
-
function statusLabelFor(status) {
|
|
3269
|
-
switch (status) {
|
|
3270
|
-
case "in_progress":
|
|
3271
|
-
return "in-progress";
|
|
3272
|
-
case "blocked":
|
|
3273
|
-
return "blocked";
|
|
3274
|
-
case "ready":
|
|
3275
|
-
return "ready";
|
|
3276
|
-
case "under_review":
|
|
3277
|
-
return "under-review";
|
|
3278
|
-
case "failed":
|
|
3279
|
-
return "failed";
|
|
3280
|
-
case "cancelled":
|
|
3281
|
-
return "cancelled";
|
|
3282
|
-
case "open":
|
|
3283
|
-
return null;
|
|
3284
|
-
default:
|
|
3285
|
-
throw new Error(`unsupported status: ${status}`);
|
|
3286
|
-
}
|
|
3287
|
-
}
|
|
3288
|
-
function ensureStatusLabel(bin, repo, spawnFn, label) {
|
|
3289
|
-
try {
|
|
3290
|
-
runGhVoid(bin, [
|
|
3291
|
-
"label",
|
|
3292
|
-
"create",
|
|
3293
|
-
label,
|
|
3294
|
-
"--repo",
|
|
3295
|
-
repo,
|
|
3296
|
-
"--color",
|
|
3297
|
-
"6f42c1",
|
|
3298
|
-
"--description",
|
|
3299
|
-
"Task status managed by Rig"
|
|
3300
|
-
], spawnFn);
|
|
3301
|
-
} catch (error) {
|
|
3302
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3303
|
-
if (!/already exists/i.test(message)) {
|
|
3304
|
-
throw error;
|
|
3305
|
-
}
|
|
3306
|
-
}
|
|
3307
|
-
}
|
|
3308
3153
|
function selectedGitHubEnv() {
|
|
3309
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
3310
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
3154
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
3155
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
3311
3156
|
}
|
|
3312
3157
|
function ghSpawnOptions() {
|
|
3313
3158
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -3320,10 +3165,6 @@ function runGh(bin, args, spawnFn) {
|
|
|
3320
3165
|
}
|
|
3321
3166
|
return JSON.parse(res.stdout);
|
|
3322
3167
|
}
|
|
3323
|
-
function runGhVoid(bin, args, spawnFn) {
|
|
3324
|
-
const res = spawnFn(bin, [...args], ghSpawnOptions());
|
|
3325
|
-
assertGhSuccess(args, res);
|
|
3326
|
-
}
|
|
3327
3168
|
function assertGhSuccess(args, res) {
|
|
3328
3169
|
if (res.error) {
|
|
3329
3170
|
const msg = res.error.message ?? String(res.error);
|
|
@@ -3361,19 +3202,6 @@ function isPlainRecord2(candidate) {
|
|
|
3361
3202
|
function hasRunnableTaskSource(source) {
|
|
3362
3203
|
return Boolean(source && typeof source === "object" && !Array.isArray(source));
|
|
3363
3204
|
}
|
|
3364
|
-
function cleanString(value) {
|
|
3365
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
3366
|
-
}
|
|
3367
|
-
function taskIdFromSourceIssueId(value) {
|
|
3368
|
-
const raw = cleanString(value);
|
|
3369
|
-
if (!raw)
|
|
3370
|
-
return null;
|
|
3371
|
-
const issueNumber = raw.match(/#([^#\s]+)$/)?.[1];
|
|
3372
|
-
return issueNumber ?? raw;
|
|
3373
|
-
}
|
|
3374
|
-
function resolveSourceTaskId(taskId, sourceTask) {
|
|
3375
|
-
return cleanString(sourceTask?.id) ?? taskIdFromSourceIssueId(sourceTask?.sourceIssueId) ?? taskIdFromSourceIssueId(sourceTask?.source_issue_id) ?? taskId;
|
|
3376
|
-
}
|
|
3377
3205
|
async function getPluginTask(projectRoot, taskId) {
|
|
3378
3206
|
const ctx = await buildPluginHostContext(projectRoot);
|
|
3379
3207
|
const [source] = ctx?.taskSourceRegistry.list() ?? [];
|
|
@@ -3398,91 +3226,6 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3398
3226
|
task
|
|
3399
3227
|
};
|
|
3400
3228
|
}
|
|
3401
|
-
async function updatePluginTaskSourceTask(projectRoot, taskId, update) {
|
|
3402
|
-
const ctx = await buildPluginHostContext(projectRoot);
|
|
3403
|
-
const [source] = ctx?.taskSourceRegistry.list() ?? [];
|
|
3404
|
-
if (!hasRunnableTaskSource(source)) {
|
|
3405
|
-
return ctx ? { taskId, updated: false, source: "none", sourceKind: null, status: null } : null;
|
|
3406
|
-
}
|
|
3407
|
-
if (source.updateTask) {
|
|
3408
|
-
await source.updateTask(taskId, update);
|
|
3409
|
-
} else if (update.status && source.updateStatus) {
|
|
3410
|
-
await source.updateStatus(taskId, update.status);
|
|
3411
|
-
} else {
|
|
3412
|
-
return {
|
|
3413
|
-
taskId,
|
|
3414
|
-
updated: false,
|
|
3415
|
-
source: "plugin",
|
|
3416
|
-
sourceKind: source.kind,
|
|
3417
|
-
status: null
|
|
3418
|
-
};
|
|
3419
|
-
}
|
|
3420
|
-
const status = source.get ? (await source.get(taskId))?.status ?? update.status ?? null : update.status ?? null;
|
|
3421
|
-
return {
|
|
3422
|
-
taskId,
|
|
3423
|
-
updated: true,
|
|
3424
|
-
source: "plugin",
|
|
3425
|
-
sourceKind: source.kind,
|
|
3426
|
-
status
|
|
3427
|
-
};
|
|
3428
|
-
}
|
|
3429
|
-
async function updateConfiguredTaskSourceTask(projectRoot, input) {
|
|
3430
|
-
const taskId = resolveSourceTaskId(input.taskId, input.sourceTask);
|
|
3431
|
-
let pluginResult = null;
|
|
3432
|
-
try {
|
|
3433
|
-
pluginResult = await updatePluginTaskSourceTask(projectRoot, taskId, input.update);
|
|
3434
|
-
} catch (error) {
|
|
3435
|
-
const fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, input.update, {
|
|
3436
|
-
allowLocalTaskConfigStatusFallback: false
|
|
3437
|
-
});
|
|
3438
|
-
if (!fallbackUpdated) {
|
|
3439
|
-
throw error;
|
|
3440
|
-
}
|
|
3441
|
-
return {
|
|
3442
|
-
taskId,
|
|
3443
|
-
updated: true,
|
|
3444
|
-
source: "compat",
|
|
3445
|
-
sourceKind: null,
|
|
3446
|
-
status: await readSourceAwareTaskStatus(projectRoot, taskId)
|
|
3447
|
-
};
|
|
3448
|
-
}
|
|
3449
|
-
if (pluginResult) {
|
|
3450
|
-
return pluginResult;
|
|
3451
|
-
}
|
|
3452
|
-
const updated = updateSourceAwareTaskConfigTask(projectRoot, taskId, input.update);
|
|
3453
|
-
return {
|
|
3454
|
-
taskId,
|
|
3455
|
-
updated,
|
|
3456
|
-
source: updated ? "compat" : "none",
|
|
3457
|
-
sourceKind: null,
|
|
3458
|
-
status: await readSourceAwareTaskStatus(projectRoot, taskId)
|
|
3459
|
-
};
|
|
3460
|
-
}
|
|
3461
|
-
function buildTaskRunLifecycleComment(input) {
|
|
3462
|
-
const lines = [
|
|
3463
|
-
"<!-- rig:status-comment -->",
|
|
3464
|
-
`### Rig status: ${input.status}`,
|
|
3465
|
-
"",
|
|
3466
|
-
input.summary,
|
|
3467
|
-
"",
|
|
3468
|
-
`- Run: ${input.runId}`,
|
|
3469
|
-
`- Status: ${input.status}`
|
|
3470
|
-
];
|
|
3471
|
-
if (input.errorText?.trim()) {
|
|
3472
|
-
lines.push(`- Error: ${input.errorText.trim()}`);
|
|
3473
|
-
}
|
|
3474
|
-
if (input.runtimeWorkspace?.trim()) {
|
|
3475
|
-
lines.push(`- Runtime workspace: ${input.runtimeWorkspace.trim()}`);
|
|
3476
|
-
}
|
|
3477
|
-
if (input.logsDir?.trim()) {
|
|
3478
|
-
lines.push(`- Logs: ${input.logsDir.trim()}`);
|
|
3479
|
-
}
|
|
3480
|
-
if (input.sessionDir?.trim()) {
|
|
3481
|
-
lines.push(`- Session: ${input.sessionDir.trim()}`);
|
|
3482
|
-
}
|
|
3483
|
-
return lines.join(`
|
|
3484
|
-
`);
|
|
3485
|
-
}
|
|
3486
3229
|
|
|
3487
3230
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3488
3231
|
import { existsSync as existsSync17, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
@@ -5710,20 +5453,23 @@ function hashProjectPath(workspaceDir) {
|
|
|
5710
5453
|
}
|
|
5711
5454
|
function resolveGithubCliBinaryPath() {
|
|
5712
5455
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
5713
|
-
if (explicit && existsSync23(explicit)) {
|
|
5456
|
+
if (explicit && existsSync23(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
5714
5457
|
return explicit;
|
|
5715
5458
|
}
|
|
5716
|
-
const
|
|
5717
|
-
if (bunResolved && existsSync23(bunResolved)) {
|
|
5718
|
-
return bunResolved;
|
|
5719
|
-
}
|
|
5720
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
5459
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5721
5460
|
if (existsSync23(candidate)) {
|
|
5722
5461
|
return candidate;
|
|
5723
5462
|
}
|
|
5724
5463
|
}
|
|
5464
|
+
const bunResolved = Bun.which("gh");
|
|
5465
|
+
if (bunResolved && existsSync23(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5466
|
+
return bunResolved;
|
|
5467
|
+
}
|
|
5725
5468
|
return "";
|
|
5726
5469
|
}
|
|
5470
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
5471
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
5472
|
+
}
|
|
5727
5473
|
async function resolveGithubCliAuthToken(ghBinary = "") {
|
|
5728
5474
|
const gh = ghBinary || resolveGithubCliBinaryPath();
|
|
5729
5475
|
if (!gh) {
|
|
@@ -5824,6 +5570,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5824
5570
|
XDG_CACHE_HOME: runtime.cacheDir,
|
|
5825
5571
|
XDG_STATE_HOME: runtime.stateDir,
|
|
5826
5572
|
RIG_AGENT_ID: runtime.id,
|
|
5573
|
+
...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
|
|
5574
|
+
...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
|
|
5827
5575
|
RIG_TASK_ID: runtime.taskId,
|
|
5828
5576
|
RIG_TASK_RUNTIME_ID: runtime.id,
|
|
5829
5577
|
RIG_TASK_WORKSPACE: runtime.workspaceDir,
|
|
@@ -5887,6 +5635,10 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5887
5635
|
env[key] = value;
|
|
5888
5636
|
}
|
|
5889
5637
|
}
|
|
5638
|
+
const rigGithubToken = process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
5639
|
+
if (rigGithubToken && !env.GITHUB_TOKEN && !env.GH_TOKEN) {
|
|
5640
|
+
env.GITHUB_TOKEN = rigGithubToken;
|
|
5641
|
+
}
|
|
5890
5642
|
const fallbackGithubToken = !env.GITHUB_TOKEN && !env.GH_TOKEN ? await resolveGithubCliAuthToken(hostGhBinary) : "";
|
|
5891
5643
|
if (fallbackGithubToken) {
|
|
5892
5644
|
env.GITHUB_TOKEN = fallbackGithubToken;
|
|
@@ -5897,6 +5649,13 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5897
5649
|
if (!env.GH_TOKEN && env.GITHUB_TOKEN) {
|
|
5898
5650
|
env.GH_TOKEN = env.GITHUB_TOKEN;
|
|
5899
5651
|
}
|
|
5652
|
+
const gitHubToken = env.GITHUB_TOKEN || env.GH_TOKEN || rigGithubToken;
|
|
5653
|
+
if (gitHubToken) {
|
|
5654
|
+
env.RIG_GITHUB_TOKEN = gitHubToken;
|
|
5655
|
+
env.GITHUB_TOKEN = env.GITHUB_TOKEN || gitHubToken;
|
|
5656
|
+
env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
|
|
5657
|
+
applyGitHubCredentialHelperEnv(env);
|
|
5658
|
+
}
|
|
5900
5659
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
5901
5660
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
5902
5661
|
}
|
|
@@ -5977,12 +5736,21 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
5977
5736
|
}
|
|
5978
5737
|
return targetPath;
|
|
5979
5738
|
}
|
|
5739
|
+
function applyGitHubCredentialHelperEnv(env) {
|
|
5740
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
5741
|
+
env.GIT_CONFIG_COUNT = "2";
|
|
5742
|
+
env.GIT_CONFIG_KEY_0 = "credential.helper";
|
|
5743
|
+
env.GIT_CONFIG_VALUE_0 = "";
|
|
5744
|
+
env.GIT_CONFIG_KEY_1 = "credential.helper";
|
|
5745
|
+
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';
|
|
5746
|
+
}
|
|
5980
5747
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
5981
5748
|
const secretsPath = resolve25(runtimeRoot, "runtime-secrets.json");
|
|
5982
5749
|
const persisted = {};
|
|
5983
5750
|
for (const key of [
|
|
5984
5751
|
"GITHUB_TOKEN",
|
|
5985
5752
|
"GH_TOKEN",
|
|
5753
|
+
"RIG_GITHUB_TOKEN",
|
|
5986
5754
|
"GREPTILE_GITHUB_TOKEN",
|
|
5987
5755
|
"GREPTILE_API_KEY",
|
|
5988
5756
|
"AI_REVIEW_MODE",
|
|
@@ -8461,7 +8229,11 @@ async function ensureAgentRuntime(options) {
|
|
|
8461
8229
|
mkdirSync18(runtime.binDir, { recursive: true });
|
|
8462
8230
|
mkdirSync18(workspaceLayout.distDir, { recursive: true });
|
|
8463
8231
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8464
|
-
|
|
8232
|
+
if (options.preserveTaskArtifacts) {
|
|
8233
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
8234
|
+
} else {
|
|
8235
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
8236
|
+
}
|
|
8465
8237
|
const ctx = {
|
|
8466
8238
|
runtimeId: options.id,
|
|
8467
8239
|
taskId: options.taskId,
|
|
@@ -9173,7 +8945,8 @@ async function runAgentWrapper(options = {}) {
|
|
|
9173
8945
|
taskId,
|
|
9174
8946
|
mode: "worktree",
|
|
9175
8947
|
provider,
|
|
9176
|
-
taskRecordReader: taskRecordReaderFromEnv(taskId)
|
|
8948
|
+
taskRecordReader: taskRecordReaderFromEnv(taskId),
|
|
8949
|
+
preserveTaskArtifacts: process.env.RIG_RUN_RESUME === "1" || process.env.RIG_RUNTIME_ARTIFACT_CLEANUP === "preserve"
|
|
9177
8950
|
});
|
|
9178
8951
|
emitWrapperEvent("runtime.provision.completed", {
|
|
9179
8952
|
runtimeId: runtime.id,
|
|
@@ -9278,15 +9051,13 @@ async function runAgentWrapper(options = {}) {
|
|
|
9278
9051
|
throw error;
|
|
9279
9052
|
}
|
|
9280
9053
|
const serverManagedRun = Boolean(process.env.RIG_SERVER_RUN_ID?.trim());
|
|
9281
|
-
if (exitCode === 0 && serverManagedRun) {
|
|
9282
|
-
await updateTaskSourceAfterRun(monorepoRoot, taskId, runtime);
|
|
9283
|
-
}
|
|
9284
9054
|
const taskClosed = await isTaskClosed(monorepoRoot, taskId);
|
|
9285
9055
|
const finalExitCode = resolveFinalProviderExitCode({
|
|
9286
9056
|
providerExitCode: exitCode,
|
|
9287
9057
|
taskClosed,
|
|
9288
9058
|
serverManagedRun
|
|
9289
9059
|
});
|
|
9060
|
+
const handoffRequired = exitCode !== 0 || !taskClosed && !serverManagedRun;
|
|
9290
9061
|
emitWrapperEvent("provider.completed", {
|
|
9291
9062
|
provider,
|
|
9292
9063
|
runtimeId: runtime.id,
|
|
@@ -9295,24 +9066,21 @@ async function runAgentWrapper(options = {}) {
|
|
|
9295
9066
|
providerExitCode: exitCode,
|
|
9296
9067
|
taskClosed,
|
|
9297
9068
|
serverManagedRun,
|
|
9298
|
-
handoffRequired
|
|
9069
|
+
handoffRequired
|
|
9299
9070
|
});
|
|
9300
|
-
if (
|
|
9071
|
+
if (handoffRequired) {
|
|
9301
9072
|
recordRuntimeHandoff(projectRoot, runtime, taskId, exitCode);
|
|
9302
9073
|
}
|
|
9303
|
-
if (exitCode === 0 && !taskClosed && serverManagedRun) {
|
|
9304
|
-
console.error(`[rig-agent] Server-managed task run cannot finish successfully while ${taskId} is still open.`);
|
|
9305
|
-
}
|
|
9306
9074
|
return finalExitCode;
|
|
9307
9075
|
}
|
|
9308
9076
|
function resolveFinalProviderExitCode(input) {
|
|
9309
9077
|
if (input.providerExitCode !== 0) {
|
|
9310
9078
|
return input.providerExitCode;
|
|
9311
9079
|
}
|
|
9312
|
-
if (input.taskClosed) {
|
|
9080
|
+
if (input.taskClosed || input.serverManagedRun) {
|
|
9313
9081
|
return 0;
|
|
9314
9082
|
}
|
|
9315
|
-
return
|
|
9083
|
+
return 0;
|
|
9316
9084
|
}
|
|
9317
9085
|
function shouldBypassProviderSandboxOnPlatform(provider, platform) {
|
|
9318
9086
|
if (platform !== "darwin") {
|
|
@@ -9336,12 +9104,16 @@ function buildProviderArgs(provider, runtime, argv) {
|
|
|
9336
9104
|
}
|
|
9337
9105
|
if (provider === "pi") {
|
|
9338
9106
|
const piArgs = [...argv];
|
|
9107
|
+
const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
|
|
9339
9108
|
if (!hasCliOption(piArgs, "--provider")) {
|
|
9340
|
-
piArgs.unshift(
|
|
9109
|
+
piArgs.unshift(piProvider);
|
|
9341
9110
|
piArgs.unshift("--provider");
|
|
9342
9111
|
}
|
|
9343
|
-
|
|
9344
|
-
|
|
9112
|
+
const model = cliOptionValue(piArgs, "--model") || process.env.RIG_PI_MODEL?.trim() || "gpt-5.5";
|
|
9113
|
+
if (hasCliOption(piArgs, "--model")) {
|
|
9114
|
+
rewriteCliOptionValue(piArgs, "--model", normalizePiModelForProvider(model, piProvider));
|
|
9115
|
+
} else {
|
|
9116
|
+
piArgs.unshift(normalizePiModelForProvider(model, piProvider));
|
|
9345
9117
|
piArgs.unshift("--model");
|
|
9346
9118
|
}
|
|
9347
9119
|
return piArgs;
|
|
@@ -9409,6 +9181,38 @@ function resolveProvider() {
|
|
|
9409
9181
|
function hasCliOption(argv, option) {
|
|
9410
9182
|
return argv.some((arg) => arg === option || arg.startsWith(`${option}=`));
|
|
9411
9183
|
}
|
|
9184
|
+
function cliOptionValue(argv, option) {
|
|
9185
|
+
for (let index = 0;index < argv.length; index += 1) {
|
|
9186
|
+
const arg = argv[index];
|
|
9187
|
+
if (arg === option) {
|
|
9188
|
+
const next = argv[index + 1];
|
|
9189
|
+
return next && !next.startsWith("--") ? next : undefined;
|
|
9190
|
+
}
|
|
9191
|
+
if (arg?.startsWith(`${option}=`)) {
|
|
9192
|
+
return arg.slice(option.length + 1);
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
return;
|
|
9196
|
+
}
|
|
9197
|
+
function rewriteCliOptionValue(argv, option, value) {
|
|
9198
|
+
for (let index = 0;index < argv.length; index += 1) {
|
|
9199
|
+
const arg = argv[index];
|
|
9200
|
+
if (arg === option && argv[index + 1] && !argv[index + 1].startsWith("--")) {
|
|
9201
|
+
argv[index + 1] = value;
|
|
9202
|
+
return;
|
|
9203
|
+
}
|
|
9204
|
+
if (arg?.startsWith(`${option}=`)) {
|
|
9205
|
+
argv[index] = `${option}=${value}`;
|
|
9206
|
+
return;
|
|
9207
|
+
}
|
|
9208
|
+
}
|
|
9209
|
+
}
|
|
9210
|
+
function normalizePiModelForProvider(model, provider) {
|
|
9211
|
+
if (provider === "openrouter" && model === "openai-codex/gpt-5.5") {
|
|
9212
|
+
return "openai/gpt-5.5";
|
|
9213
|
+
}
|
|
9214
|
+
return model;
|
|
9215
|
+
}
|
|
9412
9216
|
function providerBinary(provider) {
|
|
9413
9217
|
if (provider === "codex") {
|
|
9414
9218
|
return Bun.which("codex") || "codex";
|
|
@@ -9507,39 +9311,6 @@ async function readPluginTaskStatus(projectRoot, taskId) {
|
|
|
9507
9311
|
return readSourceAwareTaskStatus(projectRoot, taskId);
|
|
9508
9312
|
}
|
|
9509
9313
|
}
|
|
9510
|
-
async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
|
|
9511
|
-
const comment = buildTaskRunLifecycleComment({
|
|
9512
|
-
runId: process.env.RIG_SERVER_RUN_ID || "(unknown)",
|
|
9513
|
-
status: "closed",
|
|
9514
|
-
summary: "Rig task run completed and closed this task.",
|
|
9515
|
-
runtimeWorkspace: runtime.workspaceDir,
|
|
9516
|
-
logsDir: runtime.logsDir,
|
|
9517
|
-
sessionDir: runtime.sessionDir
|
|
9518
|
-
});
|
|
9519
|
-
try {
|
|
9520
|
-
const result = await updateConfiguredTaskSourceTask(projectRoot, {
|
|
9521
|
-
taskId,
|
|
9522
|
-
update: { status: "closed", comment }
|
|
9523
|
-
});
|
|
9524
|
-
if (result.updated) {
|
|
9525
|
-
return;
|
|
9526
|
-
}
|
|
9527
|
-
throw new Error(result.source === "plugin" || result.sourceKind ? `configured task source${result.sourceKind ? ` (${result.sourceKind})` : ""} does not support lifecycle updates` : "no source-aware task source is configured");
|
|
9528
|
-
} catch (error) {
|
|
9529
|
-
let fallbackUpdated = false;
|
|
9530
|
-
try {
|
|
9531
|
-
fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, { status: "closed", comment });
|
|
9532
|
-
} catch (fallbackError) {
|
|
9533
|
-
console.error(`[rig-agent] Source-aware compatibility update also failed for ${taskId}: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
|
|
9534
|
-
}
|
|
9535
|
-
const message = `[rig-agent] Failed to update task source for ${taskId}${fallbackUpdated ? "; applied source-aware compatibility update" : ""}: ${error instanceof Error ? error.message : String(error)}`;
|
|
9536
|
-
if (fallbackUpdated) {
|
|
9537
|
-
console.log(message);
|
|
9538
|
-
} else {
|
|
9539
|
-
console.error(message);
|
|
9540
|
-
}
|
|
9541
|
-
}
|
|
9542
|
-
}
|
|
9543
9314
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
9544
9315
|
const handoffDir = resolve35(hostProjectRoot, ".rig/runtime/handoffs");
|
|
9545
9316
|
mkdirSync19(handoffDir, { recursive: true });
|