@h-rig/cli 0.0.6-alpha.2 → 0.0.6-alpha.4
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.js +81 -13
- package/dist/src/commands/_authority-runs.js +1 -0
- package/dist/src/commands/agent.js +1 -0
- package/dist/src/commands/run.js +27 -1
- package/dist/src/commands/task-run-driver.js +54 -12
- package/dist/src/commands.js +81 -13
- package/dist/src/index.js +81 -13
- package/package.json +4 -4
package/dist/bin/rig.js
CHANGED
|
@@ -3446,6 +3446,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3446
3446
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
3447
3447
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
3448
3448
|
const next = {
|
|
3449
|
+
...existing ?? {},
|
|
3449
3450
|
runId: input.runId,
|
|
3450
3451
|
projectRoot,
|
|
3451
3452
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
|
@@ -6118,6 +6119,7 @@ import {
|
|
|
6118
6119
|
listOpenEpics,
|
|
6119
6120
|
resolveDefaultEpic,
|
|
6120
6121
|
runResume,
|
|
6122
|
+
runRestart,
|
|
6121
6123
|
runStatus,
|
|
6122
6124
|
runStop,
|
|
6123
6125
|
startRun,
|
|
@@ -6226,6 +6228,17 @@ async function attachRunOperatorView(context, input) {
|
|
|
6226
6228
|
}
|
|
6227
6229
|
|
|
6228
6230
|
// packages/cli/src/commands/run.ts
|
|
6231
|
+
function normalizeRemoteRunDetails(payload) {
|
|
6232
|
+
const run = payload.run;
|
|
6233
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
6234
|
+
return null;
|
|
6235
|
+
return {
|
|
6236
|
+
...run,
|
|
6237
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
6238
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
6239
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
6240
|
+
};
|
|
6241
|
+
}
|
|
6229
6242
|
function shouldPromptForEpicSelection(context, command, promptEpic, noEpicPrompt) {
|
|
6230
6243
|
if (noEpicPrompt) {
|
|
6231
6244
|
return false;
|
|
@@ -6364,7 +6377,7 @@ async function executeRun(context, args) {
|
|
|
6364
6377
|
if (!run.value) {
|
|
6365
6378
|
throw new CliError2("run show requires --run <id>.");
|
|
6366
6379
|
}
|
|
6367
|
-
const record = readAuthorityRun4(context.projectRoot, run.value);
|
|
6380
|
+
const record = readAuthorityRun4(context.projectRoot, run.value) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, run.value).catch(() => ({})));
|
|
6368
6381
|
if (!record) {
|
|
6369
6382
|
throw new CliError2(`Run not found: ${run.value}`, 2);
|
|
6370
6383
|
}
|
|
@@ -6545,6 +6558,20 @@ async function executeRun(context, args) {
|
|
|
6545
6558
|
}
|
|
6546
6559
|
return { ok: true, group: "run", command, details: resumed };
|
|
6547
6560
|
}
|
|
6561
|
+
case "restart": {
|
|
6562
|
+
requireNoExtraArgs(rest, "bun run rig run restart");
|
|
6563
|
+
if (context.dryRun) {
|
|
6564
|
+
if (context.outputMode === "text") {
|
|
6565
|
+
console.log("[dry-run] rig run restart");
|
|
6566
|
+
}
|
|
6567
|
+
return { ok: true, group: "run", command };
|
|
6568
|
+
}
|
|
6569
|
+
const restarted = await runRestart(context.projectRoot, runtimeContext);
|
|
6570
|
+
if (context.outputMode === "text") {
|
|
6571
|
+
console.log(`Restarted run: ${restarted.runId}`);
|
|
6572
|
+
}
|
|
6573
|
+
return { ok: true, group: "run", command, details: restarted };
|
|
6574
|
+
}
|
|
6548
6575
|
case "stop": {
|
|
6549
6576
|
const runOption = takeOption(rest, "--run");
|
|
6550
6577
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
@@ -7276,7 +7303,24 @@ import {
|
|
|
7276
7303
|
commitRunChanges,
|
|
7277
7304
|
runPrAutomation
|
|
7278
7305
|
} from "@rig/runtime/control-plane/native/pr-automation";
|
|
7306
|
+
function looksLikeGitHubToken(value) {
|
|
7307
|
+
const token = value?.trim();
|
|
7308
|
+
if (!token)
|
|
7309
|
+
return false;
|
|
7310
|
+
return /^(gh[opusr]_|github_pat_)/.test(token);
|
|
7311
|
+
}
|
|
7312
|
+
function githubBridgeEnv(token) {
|
|
7313
|
+
const clean = token?.trim();
|
|
7314
|
+
if (!clean)
|
|
7315
|
+
return {};
|
|
7316
|
+
return {
|
|
7317
|
+
RIG_GITHUB_TOKEN: clean,
|
|
7318
|
+
GITHUB_TOKEN: clean,
|
|
7319
|
+
GH_TOKEN: clean
|
|
7320
|
+
};
|
|
7321
|
+
}
|
|
7279
7322
|
function buildPiRigBridgeEnv(input) {
|
|
7323
|
+
const githubToken = input.githubToken?.trim() || (looksLikeGitHubToken(input.authToken) ? input.authToken.trim() : "");
|
|
7280
7324
|
return {
|
|
7281
7325
|
RIG_PROJECT_ROOT: input.projectRoot,
|
|
7282
7326
|
PROJECT_RIG_ROOT: input.projectRoot,
|
|
@@ -7286,7 +7330,7 @@ function buildPiRigBridgeEnv(input) {
|
|
|
7286
7330
|
RIG_RUNTIME_ADAPTER: "pi",
|
|
7287
7331
|
...input.serverUrl ? { RIG_SERVER_URL: input.serverUrl } : {},
|
|
7288
7332
|
...input.authToken ? { RIG_AUTH_TOKEN: input.authToken } : {},
|
|
7289
|
-
...
|
|
7333
|
+
...githubBridgeEnv(githubToken)
|
|
7290
7334
|
};
|
|
7291
7335
|
}
|
|
7292
7336
|
function runGitSync(cwd, args, input) {
|
|
@@ -7928,6 +7972,8 @@ function stringArrayField(record, key) {
|
|
|
7928
7972
|
}
|
|
7929
7973
|
async function executeRigOwnedTaskRun(context, input) {
|
|
7930
7974
|
const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
|
|
7975
|
+
const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
|
|
7976
|
+
const resumeMode = process.env.RIG_RUN_RESUME === "1";
|
|
7931
7977
|
const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
|
|
7932
7978
|
let prompt = buildRunPrompt({
|
|
7933
7979
|
projectRoot: context.projectRoot,
|
|
@@ -7983,14 +8029,14 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
7983
8029
|
taskId: runtimeTaskId,
|
|
7984
8030
|
createdAt: startedAt,
|
|
7985
8031
|
runtimeAdapter: input.runtimeAdapter,
|
|
7986
|
-
status: "created"
|
|
8032
|
+
status: resumeMode ? "preparing" : "created"
|
|
7987
8033
|
});
|
|
7988
8034
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
7989
8035
|
status: "preparing",
|
|
7990
8036
|
startedAt,
|
|
7991
8037
|
completedAt: null,
|
|
7992
8038
|
errorText: null,
|
|
7993
|
-
artifactRoot: null,
|
|
8039
|
+
artifactRoot: resumeMode ? existingRunRecord?.artifactRoot ?? null : null,
|
|
7994
8040
|
runtimeAdapter: input.runtimeAdapter,
|
|
7995
8041
|
runtimeMode: input.runtimeMode,
|
|
7996
8042
|
interactionMode: input.interactionMode,
|
|
@@ -8006,9 +8052,9 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
8006
8052
|
detail: input.taskId ?? input.title ?? runtimeTaskId
|
|
8007
8053
|
});
|
|
8008
8054
|
appendRunLog(context.projectRoot, input.runId, {
|
|
8009
|
-
id: `log:${input.runId}:start`,
|
|
8010
|
-
title: "Rig task run started",
|
|
8011
|
-
detail: input.taskId ?? input.title ?? runtimeTaskId,
|
|
8055
|
+
id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
|
|
8056
|
+
title: resumeMode ? "Rig task run resumed" : "Rig task run started",
|
|
8057
|
+
detail: resumeMode ? `Continuing the same run lifecycle for ${input.taskId ?? input.title ?? runtimeTaskId}.` : input.taskId ?? input.title ?? runtimeTaskId,
|
|
8012
8058
|
tone: "info",
|
|
8013
8059
|
status: "preparing",
|
|
8014
8060
|
createdAt: startedAt
|
|
@@ -8086,11 +8132,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8086
8132
|
let reviewAction;
|
|
8087
8133
|
let verificationStarted = false;
|
|
8088
8134
|
let reviewStarted = false;
|
|
8089
|
-
let latestRuntimeWorkspace = null;
|
|
8090
|
-
let latestSessionDir = null;
|
|
8091
|
-
let latestLogsDir = null;
|
|
8135
|
+
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
8136
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
|
|
8137
|
+
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
8092
8138
|
let latestProviderCommand = null;
|
|
8093
|
-
let latestRuntimeBranch = null;
|
|
8139
|
+
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
8094
8140
|
let snapshotSidecarPromise = null;
|
|
8095
8141
|
let dirtyBaselineApplied = false;
|
|
8096
8142
|
const childEnv = {
|
|
@@ -8108,7 +8154,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8108
8154
|
RIG_RUNTIME_ADAPTER: input.runtimeAdapter,
|
|
8109
8155
|
RIG_SERVER_RUN_ID: input.runId
|
|
8110
8156
|
},
|
|
8111
|
-
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {}
|
|
8157
|
+
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {},
|
|
8158
|
+
...resumeMode ? {
|
|
8159
|
+
RIG_RUN_RESUME: "1",
|
|
8160
|
+
RIG_RUNTIME_ARTIFACT_CLEANUP: "preserve"
|
|
8161
|
+
} : {}
|
|
8112
8162
|
};
|
|
8113
8163
|
Object.assign(childEnv, buildTaskRunReviewEnv(automationConfig));
|
|
8114
8164
|
Object.assign(childEnv, buildDirtyBaselineHandshakeEnv({ projectRoot: context.projectRoot, runId: input.runId, baselineMode: input.baselineMode }));
|
|
@@ -8414,7 +8464,25 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8414
8464
|
let reviewFailureDetail = null;
|
|
8415
8465
|
const stderrLines = [];
|
|
8416
8466
|
const piAcceptedArtifactExitGraceMs = resolvePiAcceptedArtifactExitGraceMs(childEnv);
|
|
8417
|
-
|
|
8467
|
+
if (resumeMode && latestRuntimeWorkspace) {
|
|
8468
|
+
const acceptedArtifactState = readTaskRunAcceptedArtifactState({
|
|
8469
|
+
taskId: input.taskId ?? runtimeTaskId,
|
|
8470
|
+
workspaceDir: latestRuntimeWorkspace
|
|
8471
|
+
});
|
|
8472
|
+
if (acceptedArtifactState.accepted) {
|
|
8473
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
8474
|
+
id: `log:${input.runId}:resume-accepted-artifacts`,
|
|
8475
|
+
title: "Resume found accepted artifacts; continuing closeout",
|
|
8476
|
+
detail: acceptedArtifactState.reason ?? "Accepted task artifacts are present from the previous run process.",
|
|
8477
|
+
tone: "info",
|
|
8478
|
+
status: "validating",
|
|
8479
|
+
createdAt: new Date().toISOString()
|
|
8480
|
+
});
|
|
8481
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: "Resume found accepted artifacts; continuing closeout" });
|
|
8482
|
+
exit = { code: 0, signal: null };
|
|
8483
|
+
}
|
|
8484
|
+
}
|
|
8485
|
+
for (let attempt = 1;!exit && attempt <= maxAttempts; attempt += 1) {
|
|
8418
8486
|
const attemptHostAgentCommand = buildHostAgentCommand(currentPrompt);
|
|
8419
8487
|
const child = spawn2(attemptHostAgentCommand[0], attemptHostAgentCommand.slice(1), {
|
|
8420
8488
|
cwd: context.projectRoot,
|
|
@@ -67,6 +67,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
67
67
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
68
68
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
69
69
|
const next = {
|
|
70
|
+
...existing ?? {},
|
|
70
71
|
runId: input.runId,
|
|
71
72
|
projectRoot,
|
|
72
73
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
|
@@ -126,6 +126,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
126
126
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
127
127
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
128
128
|
const next = {
|
|
129
|
+
...existing ?? {},
|
|
129
130
|
runId: input.runId,
|
|
130
131
|
projectRoot,
|
|
131
132
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
package/dist/src/commands/run.js
CHANGED
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
listOpenEpics,
|
|
65
65
|
resolveDefaultEpic,
|
|
66
66
|
runResume,
|
|
67
|
+
runRestart,
|
|
67
68
|
runStatus,
|
|
68
69
|
runStop,
|
|
69
70
|
startRun,
|
|
@@ -406,6 +407,17 @@ async function attachRunOperatorView(context, input) {
|
|
|
406
407
|
}
|
|
407
408
|
|
|
408
409
|
// packages/cli/src/commands/run.ts
|
|
410
|
+
function normalizeRemoteRunDetails(payload) {
|
|
411
|
+
const run = payload.run;
|
|
412
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
413
|
+
return null;
|
|
414
|
+
return {
|
|
415
|
+
...run,
|
|
416
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
417
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
418
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
409
421
|
function shouldPromptForEpicSelection(context, command, promptEpic, noEpicPrompt) {
|
|
410
422
|
if (noEpicPrompt) {
|
|
411
423
|
return false;
|
|
@@ -544,7 +556,7 @@ async function executeRun(context, args) {
|
|
|
544
556
|
if (!run.value) {
|
|
545
557
|
throw new CliError2("run show requires --run <id>.");
|
|
546
558
|
}
|
|
547
|
-
const record = readAuthorityRun(context.projectRoot, run.value);
|
|
559
|
+
const record = readAuthorityRun(context.projectRoot, run.value) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, run.value).catch(() => ({})));
|
|
548
560
|
if (!record) {
|
|
549
561
|
throw new CliError2(`Run not found: ${run.value}`, 2);
|
|
550
562
|
}
|
|
@@ -725,6 +737,20 @@ async function executeRun(context, args) {
|
|
|
725
737
|
}
|
|
726
738
|
return { ok: true, group: "run", command, details: resumed };
|
|
727
739
|
}
|
|
740
|
+
case "restart": {
|
|
741
|
+
requireNoExtraArgs(rest, "bun run rig run restart");
|
|
742
|
+
if (context.dryRun) {
|
|
743
|
+
if (context.outputMode === "text") {
|
|
744
|
+
console.log("[dry-run] rig run restart");
|
|
745
|
+
}
|
|
746
|
+
return { ok: true, group: "run", command };
|
|
747
|
+
}
|
|
748
|
+
const restarted = await runRestart(context.projectRoot, runtimeContext);
|
|
749
|
+
if (context.outputMode === "text") {
|
|
750
|
+
console.log(`Restarted run: ${restarted.runId}`);
|
|
751
|
+
}
|
|
752
|
+
return { ok: true, group: "run", command, details: restarted };
|
|
753
|
+
}
|
|
728
754
|
case "stop": {
|
|
729
755
|
const runOption = takeOption(rest, "--run");
|
|
730
756
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
@@ -135,6 +135,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
135
135
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
136
136
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
137
137
|
const next = {
|
|
138
|
+
...existing ?? {},
|
|
138
139
|
runId: input.runId,
|
|
139
140
|
projectRoot,
|
|
140
141
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
|
@@ -405,7 +406,24 @@ var PI_CANONICAL_RUN_STAGES = [
|
|
|
405
406
|
function canonicalPiRunStages() {
|
|
406
407
|
return [...PI_CANONICAL_RUN_STAGES];
|
|
407
408
|
}
|
|
409
|
+
function looksLikeGitHubToken(value) {
|
|
410
|
+
const token = value?.trim();
|
|
411
|
+
if (!token)
|
|
412
|
+
return false;
|
|
413
|
+
return /^(gh[opusr]_|github_pat_)/.test(token);
|
|
414
|
+
}
|
|
415
|
+
function githubBridgeEnv(token) {
|
|
416
|
+
const clean = token?.trim();
|
|
417
|
+
if (!clean)
|
|
418
|
+
return {};
|
|
419
|
+
return {
|
|
420
|
+
RIG_GITHUB_TOKEN: clean,
|
|
421
|
+
GITHUB_TOKEN: clean,
|
|
422
|
+
GH_TOKEN: clean
|
|
423
|
+
};
|
|
424
|
+
}
|
|
408
425
|
function buildPiRigBridgeEnv(input) {
|
|
426
|
+
const githubToken = input.githubToken?.trim() || (looksLikeGitHubToken(input.authToken) ? input.authToken.trim() : "");
|
|
409
427
|
return {
|
|
410
428
|
RIG_PROJECT_ROOT: input.projectRoot,
|
|
411
429
|
PROJECT_RIG_ROOT: input.projectRoot,
|
|
@@ -415,7 +433,7 @@ function buildPiRigBridgeEnv(input) {
|
|
|
415
433
|
RIG_RUNTIME_ADAPTER: "pi",
|
|
416
434
|
...input.serverUrl ? { RIG_SERVER_URL: input.serverUrl } : {},
|
|
417
435
|
...input.authToken ? { RIG_AUTH_TOKEN: input.authToken } : {},
|
|
418
|
-
...
|
|
436
|
+
...githubBridgeEnv(githubToken)
|
|
419
437
|
};
|
|
420
438
|
}
|
|
421
439
|
function runGitSync(cwd, args, input) {
|
|
@@ -1064,6 +1082,8 @@ function stringArrayField(record, key) {
|
|
|
1064
1082
|
}
|
|
1065
1083
|
async function executeRigOwnedTaskRun(context, input) {
|
|
1066
1084
|
const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
|
|
1085
|
+
const existingRunRecord = readAuthorityRun3(context.projectRoot, input.runId);
|
|
1086
|
+
const resumeMode = process.env.RIG_RUN_RESUME === "1";
|
|
1067
1087
|
const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
|
|
1068
1088
|
let prompt = buildRunPrompt({
|
|
1069
1089
|
projectRoot: context.projectRoot,
|
|
@@ -1119,14 +1139,14 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
1119
1139
|
taskId: runtimeTaskId,
|
|
1120
1140
|
createdAt: startedAt,
|
|
1121
1141
|
runtimeAdapter: input.runtimeAdapter,
|
|
1122
|
-
status: "created"
|
|
1142
|
+
status: resumeMode ? "preparing" : "created"
|
|
1123
1143
|
});
|
|
1124
1144
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
1125
1145
|
status: "preparing",
|
|
1126
1146
|
startedAt,
|
|
1127
1147
|
completedAt: null,
|
|
1128
1148
|
errorText: null,
|
|
1129
|
-
artifactRoot: null,
|
|
1149
|
+
artifactRoot: resumeMode ? existingRunRecord?.artifactRoot ?? null : null,
|
|
1130
1150
|
runtimeAdapter: input.runtimeAdapter,
|
|
1131
1151
|
runtimeMode: input.runtimeMode,
|
|
1132
1152
|
interactionMode: input.interactionMode,
|
|
@@ -1142,9 +1162,9 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
1142
1162
|
detail: input.taskId ?? input.title ?? runtimeTaskId
|
|
1143
1163
|
});
|
|
1144
1164
|
appendRunLog(context.projectRoot, input.runId, {
|
|
1145
|
-
id: `log:${input.runId}:start`,
|
|
1146
|
-
title: "Rig task run started",
|
|
1147
|
-
detail: input.taskId ?? input.title ?? runtimeTaskId,
|
|
1165
|
+
id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
|
|
1166
|
+
title: resumeMode ? "Rig task run resumed" : "Rig task run started",
|
|
1167
|
+
detail: resumeMode ? `Continuing the same run lifecycle for ${input.taskId ?? input.title ?? runtimeTaskId}.` : input.taskId ?? input.title ?? runtimeTaskId,
|
|
1148
1168
|
tone: "info",
|
|
1149
1169
|
status: "preparing",
|
|
1150
1170
|
createdAt: startedAt
|
|
@@ -1222,11 +1242,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1222
1242
|
let reviewAction;
|
|
1223
1243
|
let verificationStarted = false;
|
|
1224
1244
|
let reviewStarted = false;
|
|
1225
|
-
let latestRuntimeWorkspace = null;
|
|
1226
|
-
let latestSessionDir = null;
|
|
1227
|
-
let latestLogsDir = null;
|
|
1245
|
+
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
1246
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve4(existingRunRecord.sessionPath, "..") : null;
|
|
1247
|
+
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
1228
1248
|
let latestProviderCommand = null;
|
|
1229
|
-
let latestRuntimeBranch = null;
|
|
1249
|
+
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
1230
1250
|
let snapshotSidecarPromise = null;
|
|
1231
1251
|
let dirtyBaselineApplied = false;
|
|
1232
1252
|
const childEnv = {
|
|
@@ -1244,7 +1264,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1244
1264
|
RIG_RUNTIME_ADAPTER: input.runtimeAdapter,
|
|
1245
1265
|
RIG_SERVER_RUN_ID: input.runId
|
|
1246
1266
|
},
|
|
1247
|
-
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {}
|
|
1267
|
+
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {},
|
|
1268
|
+
...resumeMode ? {
|
|
1269
|
+
RIG_RUN_RESUME: "1",
|
|
1270
|
+
RIG_RUNTIME_ARTIFACT_CLEANUP: "preserve"
|
|
1271
|
+
} : {}
|
|
1248
1272
|
};
|
|
1249
1273
|
Object.assign(childEnv, buildTaskRunReviewEnv(automationConfig));
|
|
1250
1274
|
Object.assign(childEnv, buildDirtyBaselineHandshakeEnv({ projectRoot: context.projectRoot, runId: input.runId, baselineMode: input.baselineMode }));
|
|
@@ -1550,7 +1574,25 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1550
1574
|
let reviewFailureDetail = null;
|
|
1551
1575
|
const stderrLines = [];
|
|
1552
1576
|
const piAcceptedArtifactExitGraceMs = resolvePiAcceptedArtifactExitGraceMs(childEnv);
|
|
1553
|
-
|
|
1577
|
+
if (resumeMode && latestRuntimeWorkspace) {
|
|
1578
|
+
const acceptedArtifactState = readTaskRunAcceptedArtifactState({
|
|
1579
|
+
taskId: input.taskId ?? runtimeTaskId,
|
|
1580
|
+
workspaceDir: latestRuntimeWorkspace
|
|
1581
|
+
});
|
|
1582
|
+
if (acceptedArtifactState.accepted) {
|
|
1583
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
1584
|
+
id: `log:${input.runId}:resume-accepted-artifacts`,
|
|
1585
|
+
title: "Resume found accepted artifacts; continuing closeout",
|
|
1586
|
+
detail: acceptedArtifactState.reason ?? "Accepted task artifacts are present from the previous run process.",
|
|
1587
|
+
tone: "info",
|
|
1588
|
+
status: "validating",
|
|
1589
|
+
createdAt: new Date().toISOString()
|
|
1590
|
+
});
|
|
1591
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: "Resume found accepted artifacts; continuing closeout" });
|
|
1592
|
+
exit = { code: 0, signal: null };
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
for (let attempt = 1;!exit && attempt <= maxAttempts; attempt += 1) {
|
|
1554
1596
|
const attemptHostAgentCommand = buildHostAgentCommand(currentPrompt);
|
|
1555
1597
|
const child = spawn(attemptHostAgentCommand[0], attemptHostAgentCommand.slice(1), {
|
|
1556
1598
|
cwd: context.projectRoot,
|
package/dist/src/commands.js
CHANGED
|
@@ -3240,6 +3240,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3240
3240
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
3241
3241
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
3242
3242
|
const next = {
|
|
3243
|
+
...existing ?? {},
|
|
3243
3244
|
runId: input.runId,
|
|
3244
3245
|
projectRoot,
|
|
3245
3246
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
|
@@ -5912,6 +5913,7 @@ import {
|
|
|
5912
5913
|
listOpenEpics,
|
|
5913
5914
|
resolveDefaultEpic,
|
|
5914
5915
|
runResume,
|
|
5916
|
+
runRestart,
|
|
5915
5917
|
runStatus,
|
|
5916
5918
|
runStop,
|
|
5917
5919
|
startRun,
|
|
@@ -6020,6 +6022,17 @@ async function attachRunOperatorView(context, input) {
|
|
|
6020
6022
|
}
|
|
6021
6023
|
|
|
6022
6024
|
// packages/cli/src/commands/run.ts
|
|
6025
|
+
function normalizeRemoteRunDetails(payload) {
|
|
6026
|
+
const run = payload.run;
|
|
6027
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
6028
|
+
return null;
|
|
6029
|
+
return {
|
|
6030
|
+
...run,
|
|
6031
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
6032
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
6033
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
6034
|
+
};
|
|
6035
|
+
}
|
|
6023
6036
|
function shouldPromptForEpicSelection(context, command, promptEpic, noEpicPrompt) {
|
|
6024
6037
|
if (noEpicPrompt) {
|
|
6025
6038
|
return false;
|
|
@@ -6158,7 +6171,7 @@ async function executeRun(context, args) {
|
|
|
6158
6171
|
if (!run.value) {
|
|
6159
6172
|
throw new CliError2("run show requires --run <id>.");
|
|
6160
6173
|
}
|
|
6161
|
-
const record = readAuthorityRun4(context.projectRoot, run.value);
|
|
6174
|
+
const record = readAuthorityRun4(context.projectRoot, run.value) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, run.value).catch(() => ({})));
|
|
6162
6175
|
if (!record) {
|
|
6163
6176
|
throw new CliError2(`Run not found: ${run.value}`, 2);
|
|
6164
6177
|
}
|
|
@@ -6339,6 +6352,20 @@ async function executeRun(context, args) {
|
|
|
6339
6352
|
}
|
|
6340
6353
|
return { ok: true, group: "run", command, details: resumed };
|
|
6341
6354
|
}
|
|
6355
|
+
case "restart": {
|
|
6356
|
+
requireNoExtraArgs(rest, "bun run rig run restart");
|
|
6357
|
+
if (context.dryRun) {
|
|
6358
|
+
if (context.outputMode === "text") {
|
|
6359
|
+
console.log("[dry-run] rig run restart");
|
|
6360
|
+
}
|
|
6361
|
+
return { ok: true, group: "run", command };
|
|
6362
|
+
}
|
|
6363
|
+
const restarted = await runRestart(context.projectRoot, runtimeContext);
|
|
6364
|
+
if (context.outputMode === "text") {
|
|
6365
|
+
console.log(`Restarted run: ${restarted.runId}`);
|
|
6366
|
+
}
|
|
6367
|
+
return { ok: true, group: "run", command, details: restarted };
|
|
6368
|
+
}
|
|
6342
6369
|
case "stop": {
|
|
6343
6370
|
const runOption = takeOption(rest, "--run");
|
|
6344
6371
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
@@ -7070,7 +7097,24 @@ import {
|
|
|
7070
7097
|
commitRunChanges,
|
|
7071
7098
|
runPrAutomation
|
|
7072
7099
|
} from "@rig/runtime/control-plane/native/pr-automation";
|
|
7100
|
+
function looksLikeGitHubToken(value) {
|
|
7101
|
+
const token = value?.trim();
|
|
7102
|
+
if (!token)
|
|
7103
|
+
return false;
|
|
7104
|
+
return /^(gh[opusr]_|github_pat_)/.test(token);
|
|
7105
|
+
}
|
|
7106
|
+
function githubBridgeEnv(token) {
|
|
7107
|
+
const clean = token?.trim();
|
|
7108
|
+
if (!clean)
|
|
7109
|
+
return {};
|
|
7110
|
+
return {
|
|
7111
|
+
RIG_GITHUB_TOKEN: clean,
|
|
7112
|
+
GITHUB_TOKEN: clean,
|
|
7113
|
+
GH_TOKEN: clean
|
|
7114
|
+
};
|
|
7115
|
+
}
|
|
7073
7116
|
function buildPiRigBridgeEnv(input) {
|
|
7117
|
+
const githubToken = input.githubToken?.trim() || (looksLikeGitHubToken(input.authToken) ? input.authToken.trim() : "");
|
|
7074
7118
|
return {
|
|
7075
7119
|
RIG_PROJECT_ROOT: input.projectRoot,
|
|
7076
7120
|
PROJECT_RIG_ROOT: input.projectRoot,
|
|
@@ -7080,7 +7124,7 @@ function buildPiRigBridgeEnv(input) {
|
|
|
7080
7124
|
RIG_RUNTIME_ADAPTER: "pi",
|
|
7081
7125
|
...input.serverUrl ? { RIG_SERVER_URL: input.serverUrl } : {},
|
|
7082
7126
|
...input.authToken ? { RIG_AUTH_TOKEN: input.authToken } : {},
|
|
7083
|
-
...
|
|
7127
|
+
...githubBridgeEnv(githubToken)
|
|
7084
7128
|
};
|
|
7085
7129
|
}
|
|
7086
7130
|
function runGitSync(cwd, args, input) {
|
|
@@ -7722,6 +7766,8 @@ function stringArrayField(record, key) {
|
|
|
7722
7766
|
}
|
|
7723
7767
|
async function executeRigOwnedTaskRun(context, input) {
|
|
7724
7768
|
const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
|
|
7769
|
+
const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
|
|
7770
|
+
const resumeMode = process.env.RIG_RUN_RESUME === "1";
|
|
7725
7771
|
const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
|
|
7726
7772
|
let prompt = buildRunPrompt({
|
|
7727
7773
|
projectRoot: context.projectRoot,
|
|
@@ -7777,14 +7823,14 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
7777
7823
|
taskId: runtimeTaskId,
|
|
7778
7824
|
createdAt: startedAt,
|
|
7779
7825
|
runtimeAdapter: input.runtimeAdapter,
|
|
7780
|
-
status: "created"
|
|
7826
|
+
status: resumeMode ? "preparing" : "created"
|
|
7781
7827
|
});
|
|
7782
7828
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
7783
7829
|
status: "preparing",
|
|
7784
7830
|
startedAt,
|
|
7785
7831
|
completedAt: null,
|
|
7786
7832
|
errorText: null,
|
|
7787
|
-
artifactRoot: null,
|
|
7833
|
+
artifactRoot: resumeMode ? existingRunRecord?.artifactRoot ?? null : null,
|
|
7788
7834
|
runtimeAdapter: input.runtimeAdapter,
|
|
7789
7835
|
runtimeMode: input.runtimeMode,
|
|
7790
7836
|
interactionMode: input.interactionMode,
|
|
@@ -7800,9 +7846,9 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
7800
7846
|
detail: input.taskId ?? input.title ?? runtimeTaskId
|
|
7801
7847
|
});
|
|
7802
7848
|
appendRunLog(context.projectRoot, input.runId, {
|
|
7803
|
-
id: `log:${input.runId}:start`,
|
|
7804
|
-
title: "Rig task run started",
|
|
7805
|
-
detail: input.taskId ?? input.title ?? runtimeTaskId,
|
|
7849
|
+
id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
|
|
7850
|
+
title: resumeMode ? "Rig task run resumed" : "Rig task run started",
|
|
7851
|
+
detail: resumeMode ? `Continuing the same run lifecycle for ${input.taskId ?? input.title ?? runtimeTaskId}.` : input.taskId ?? input.title ?? runtimeTaskId,
|
|
7806
7852
|
tone: "info",
|
|
7807
7853
|
status: "preparing",
|
|
7808
7854
|
createdAt: startedAt
|
|
@@ -7880,11 +7926,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
7880
7926
|
let reviewAction;
|
|
7881
7927
|
let verificationStarted = false;
|
|
7882
7928
|
let reviewStarted = false;
|
|
7883
|
-
let latestRuntimeWorkspace = null;
|
|
7884
|
-
let latestSessionDir = null;
|
|
7885
|
-
let latestLogsDir = null;
|
|
7929
|
+
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
7930
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve21(existingRunRecord.sessionPath, "..") : null;
|
|
7931
|
+
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
7886
7932
|
let latestProviderCommand = null;
|
|
7887
|
-
let latestRuntimeBranch = null;
|
|
7933
|
+
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
7888
7934
|
let snapshotSidecarPromise = null;
|
|
7889
7935
|
let dirtyBaselineApplied = false;
|
|
7890
7936
|
const childEnv = {
|
|
@@ -7902,7 +7948,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
7902
7948
|
RIG_RUNTIME_ADAPTER: input.runtimeAdapter,
|
|
7903
7949
|
RIG_SERVER_RUN_ID: input.runId
|
|
7904
7950
|
},
|
|
7905
|
-
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {}
|
|
7951
|
+
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {},
|
|
7952
|
+
...resumeMode ? {
|
|
7953
|
+
RIG_RUN_RESUME: "1",
|
|
7954
|
+
RIG_RUNTIME_ARTIFACT_CLEANUP: "preserve"
|
|
7955
|
+
} : {}
|
|
7906
7956
|
};
|
|
7907
7957
|
Object.assign(childEnv, buildTaskRunReviewEnv(automationConfig));
|
|
7908
7958
|
Object.assign(childEnv, buildDirtyBaselineHandshakeEnv({ projectRoot: context.projectRoot, runId: input.runId, baselineMode: input.baselineMode }));
|
|
@@ -8208,7 +8258,25 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8208
8258
|
let reviewFailureDetail = null;
|
|
8209
8259
|
const stderrLines = [];
|
|
8210
8260
|
const piAcceptedArtifactExitGraceMs = resolvePiAcceptedArtifactExitGraceMs(childEnv);
|
|
8211
|
-
|
|
8261
|
+
if (resumeMode && latestRuntimeWorkspace) {
|
|
8262
|
+
const acceptedArtifactState = readTaskRunAcceptedArtifactState({
|
|
8263
|
+
taskId: input.taskId ?? runtimeTaskId,
|
|
8264
|
+
workspaceDir: latestRuntimeWorkspace
|
|
8265
|
+
});
|
|
8266
|
+
if (acceptedArtifactState.accepted) {
|
|
8267
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
8268
|
+
id: `log:${input.runId}:resume-accepted-artifacts`,
|
|
8269
|
+
title: "Resume found accepted artifacts; continuing closeout",
|
|
8270
|
+
detail: acceptedArtifactState.reason ?? "Accepted task artifacts are present from the previous run process.",
|
|
8271
|
+
tone: "info",
|
|
8272
|
+
status: "validating",
|
|
8273
|
+
createdAt: new Date().toISOString()
|
|
8274
|
+
});
|
|
8275
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: "Resume found accepted artifacts; continuing closeout" });
|
|
8276
|
+
exit = { code: 0, signal: null };
|
|
8277
|
+
}
|
|
8278
|
+
}
|
|
8279
|
+
for (let attempt = 1;!exit && attempt <= maxAttempts; attempt += 1) {
|
|
8212
8280
|
const attemptHostAgentCommand = buildHostAgentCommand(currentPrompt);
|
|
8213
8281
|
const child = spawn2(attemptHostAgentCommand[0], attemptHostAgentCommand.slice(1), {
|
|
8214
8282
|
cwd: context.projectRoot,
|
package/dist/src/index.js
CHANGED
|
@@ -3442,6 +3442,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3442
3442
|
const runtimeAdapter = normalizeRuntimeAdapter(input.runtimeAdapter ?? existing?.runtimeAdapter ?? "claude-code");
|
|
3443
3443
|
const title = resolveTaskTitleForAuthorityRun(projectRoot, input.taskId) ?? input.taskId;
|
|
3444
3444
|
const next = {
|
|
3445
|
+
...existing ?? {},
|
|
3445
3446
|
runId: input.runId,
|
|
3446
3447
|
projectRoot,
|
|
3447
3448
|
workspaceId: existing?.workspaceId ?? RIG_WORKSPACE_ID,
|
|
@@ -6114,6 +6115,7 @@ import {
|
|
|
6114
6115
|
listOpenEpics,
|
|
6115
6116
|
resolveDefaultEpic,
|
|
6116
6117
|
runResume,
|
|
6118
|
+
runRestart,
|
|
6117
6119
|
runStatus,
|
|
6118
6120
|
runStop,
|
|
6119
6121
|
startRun,
|
|
@@ -6222,6 +6224,17 @@ async function attachRunOperatorView(context, input) {
|
|
|
6222
6224
|
}
|
|
6223
6225
|
|
|
6224
6226
|
// packages/cli/src/commands/run.ts
|
|
6227
|
+
function normalizeRemoteRunDetails(payload) {
|
|
6228
|
+
const run = payload.run;
|
|
6229
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
6230
|
+
return null;
|
|
6231
|
+
return {
|
|
6232
|
+
...run,
|
|
6233
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
6234
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
6235
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
6236
|
+
};
|
|
6237
|
+
}
|
|
6225
6238
|
function shouldPromptForEpicSelection(context, command, promptEpic, noEpicPrompt) {
|
|
6226
6239
|
if (noEpicPrompt) {
|
|
6227
6240
|
return false;
|
|
@@ -6360,7 +6373,7 @@ async function executeRun(context, args) {
|
|
|
6360
6373
|
if (!run.value) {
|
|
6361
6374
|
throw new CliError2("run show requires --run <id>.");
|
|
6362
6375
|
}
|
|
6363
|
-
const record = readAuthorityRun4(context.projectRoot, run.value);
|
|
6376
|
+
const record = readAuthorityRun4(context.projectRoot, run.value) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, run.value).catch(() => ({})));
|
|
6364
6377
|
if (!record) {
|
|
6365
6378
|
throw new CliError2(`Run not found: ${run.value}`, 2);
|
|
6366
6379
|
}
|
|
@@ -6541,6 +6554,20 @@ async function executeRun(context, args) {
|
|
|
6541
6554
|
}
|
|
6542
6555
|
return { ok: true, group: "run", command, details: resumed };
|
|
6543
6556
|
}
|
|
6557
|
+
case "restart": {
|
|
6558
|
+
requireNoExtraArgs(rest, "bun run rig run restart");
|
|
6559
|
+
if (context.dryRun) {
|
|
6560
|
+
if (context.outputMode === "text") {
|
|
6561
|
+
console.log("[dry-run] rig run restart");
|
|
6562
|
+
}
|
|
6563
|
+
return { ok: true, group: "run", command };
|
|
6564
|
+
}
|
|
6565
|
+
const restarted = await runRestart(context.projectRoot, runtimeContext);
|
|
6566
|
+
if (context.outputMode === "text") {
|
|
6567
|
+
console.log(`Restarted run: ${restarted.runId}`);
|
|
6568
|
+
}
|
|
6569
|
+
return { ok: true, group: "run", command, details: restarted };
|
|
6570
|
+
}
|
|
6544
6571
|
case "stop": {
|
|
6545
6572
|
const runOption = takeOption(rest, "--run");
|
|
6546
6573
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
@@ -7272,7 +7299,24 @@ import {
|
|
|
7272
7299
|
commitRunChanges,
|
|
7273
7300
|
runPrAutomation
|
|
7274
7301
|
} from "@rig/runtime/control-plane/native/pr-automation";
|
|
7302
|
+
function looksLikeGitHubToken(value) {
|
|
7303
|
+
const token = value?.trim();
|
|
7304
|
+
if (!token)
|
|
7305
|
+
return false;
|
|
7306
|
+
return /^(gh[opusr]_|github_pat_)/.test(token);
|
|
7307
|
+
}
|
|
7308
|
+
function githubBridgeEnv(token) {
|
|
7309
|
+
const clean = token?.trim();
|
|
7310
|
+
if (!clean)
|
|
7311
|
+
return {};
|
|
7312
|
+
return {
|
|
7313
|
+
RIG_GITHUB_TOKEN: clean,
|
|
7314
|
+
GITHUB_TOKEN: clean,
|
|
7315
|
+
GH_TOKEN: clean
|
|
7316
|
+
};
|
|
7317
|
+
}
|
|
7275
7318
|
function buildPiRigBridgeEnv(input) {
|
|
7319
|
+
const githubToken = input.githubToken?.trim() || (looksLikeGitHubToken(input.authToken) ? input.authToken.trim() : "");
|
|
7276
7320
|
return {
|
|
7277
7321
|
RIG_PROJECT_ROOT: input.projectRoot,
|
|
7278
7322
|
PROJECT_RIG_ROOT: input.projectRoot,
|
|
@@ -7282,7 +7326,7 @@ function buildPiRigBridgeEnv(input) {
|
|
|
7282
7326
|
RIG_RUNTIME_ADAPTER: "pi",
|
|
7283
7327
|
...input.serverUrl ? { RIG_SERVER_URL: input.serverUrl } : {},
|
|
7284
7328
|
...input.authToken ? { RIG_AUTH_TOKEN: input.authToken } : {},
|
|
7285
|
-
...
|
|
7329
|
+
...githubBridgeEnv(githubToken)
|
|
7286
7330
|
};
|
|
7287
7331
|
}
|
|
7288
7332
|
function runGitSync(cwd, args, input) {
|
|
@@ -7924,6 +7968,8 @@ function stringArrayField(record, key) {
|
|
|
7924
7968
|
}
|
|
7925
7969
|
async function executeRigOwnedTaskRun(context, input) {
|
|
7926
7970
|
const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
|
|
7971
|
+
const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
|
|
7972
|
+
const resumeMode = process.env.RIG_RUN_RESUME === "1";
|
|
7927
7973
|
const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
|
|
7928
7974
|
let prompt = buildRunPrompt({
|
|
7929
7975
|
projectRoot: context.projectRoot,
|
|
@@ -7979,14 +8025,14 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
7979
8025
|
taskId: runtimeTaskId,
|
|
7980
8026
|
createdAt: startedAt,
|
|
7981
8027
|
runtimeAdapter: input.runtimeAdapter,
|
|
7982
|
-
status: "created"
|
|
8028
|
+
status: resumeMode ? "preparing" : "created"
|
|
7983
8029
|
});
|
|
7984
8030
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
7985
8031
|
status: "preparing",
|
|
7986
8032
|
startedAt,
|
|
7987
8033
|
completedAt: null,
|
|
7988
8034
|
errorText: null,
|
|
7989
|
-
artifactRoot: null,
|
|
8035
|
+
artifactRoot: resumeMode ? existingRunRecord?.artifactRoot ?? null : null,
|
|
7990
8036
|
runtimeAdapter: input.runtimeAdapter,
|
|
7991
8037
|
runtimeMode: input.runtimeMode,
|
|
7992
8038
|
interactionMode: input.interactionMode,
|
|
@@ -8002,9 +8048,9 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
8002
8048
|
detail: input.taskId ?? input.title ?? runtimeTaskId
|
|
8003
8049
|
});
|
|
8004
8050
|
appendRunLog(context.projectRoot, input.runId, {
|
|
8005
|
-
id: `log:${input.runId}:start`,
|
|
8006
|
-
title: "Rig task run started",
|
|
8007
|
-
detail: input.taskId ?? input.title ?? runtimeTaskId,
|
|
8051
|
+
id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
|
|
8052
|
+
title: resumeMode ? "Rig task run resumed" : "Rig task run started",
|
|
8053
|
+
detail: resumeMode ? `Continuing the same run lifecycle for ${input.taskId ?? input.title ?? runtimeTaskId}.` : input.taskId ?? input.title ?? runtimeTaskId,
|
|
8008
8054
|
tone: "info",
|
|
8009
8055
|
status: "preparing",
|
|
8010
8056
|
createdAt: startedAt
|
|
@@ -8082,11 +8128,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8082
8128
|
let reviewAction;
|
|
8083
8129
|
let verificationStarted = false;
|
|
8084
8130
|
let reviewStarted = false;
|
|
8085
|
-
let latestRuntimeWorkspace = null;
|
|
8086
|
-
let latestSessionDir = null;
|
|
8087
|
-
let latestLogsDir = null;
|
|
8131
|
+
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
8132
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
|
|
8133
|
+
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
8088
8134
|
let latestProviderCommand = null;
|
|
8089
|
-
let latestRuntimeBranch = null;
|
|
8135
|
+
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
8090
8136
|
let snapshotSidecarPromise = null;
|
|
8091
8137
|
let dirtyBaselineApplied = false;
|
|
8092
8138
|
const childEnv = {
|
|
@@ -8104,7 +8150,11 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8104
8150
|
RIG_RUNTIME_ADAPTER: input.runtimeAdapter,
|
|
8105
8151
|
RIG_SERVER_RUN_ID: input.runId
|
|
8106
8152
|
},
|
|
8107
|
-
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {}
|
|
8153
|
+
...sourceTask ? { RIG_SOURCE_TASK_JSON: JSON.stringify(sourceTask) } : {},
|
|
8154
|
+
...resumeMode ? {
|
|
8155
|
+
RIG_RUN_RESUME: "1",
|
|
8156
|
+
RIG_RUNTIME_ARTIFACT_CLEANUP: "preserve"
|
|
8157
|
+
} : {}
|
|
8108
8158
|
};
|
|
8109
8159
|
Object.assign(childEnv, buildTaskRunReviewEnv(automationConfig));
|
|
8110
8160
|
Object.assign(childEnv, buildDirtyBaselineHandshakeEnv({ projectRoot: context.projectRoot, runId: input.runId, baselineMode: input.baselineMode }));
|
|
@@ -8410,7 +8460,25 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
8410
8460
|
let reviewFailureDetail = null;
|
|
8411
8461
|
const stderrLines = [];
|
|
8412
8462
|
const piAcceptedArtifactExitGraceMs = resolvePiAcceptedArtifactExitGraceMs(childEnv);
|
|
8413
|
-
|
|
8463
|
+
if (resumeMode && latestRuntimeWorkspace) {
|
|
8464
|
+
const acceptedArtifactState = readTaskRunAcceptedArtifactState({
|
|
8465
|
+
taskId: input.taskId ?? runtimeTaskId,
|
|
8466
|
+
workspaceDir: latestRuntimeWorkspace
|
|
8467
|
+
});
|
|
8468
|
+
if (acceptedArtifactState.accepted) {
|
|
8469
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
8470
|
+
id: `log:${input.runId}:resume-accepted-artifacts`,
|
|
8471
|
+
title: "Resume found accepted artifacts; continuing closeout",
|
|
8472
|
+
detail: acceptedArtifactState.reason ?? "Accepted task artifacts are present from the previous run process.",
|
|
8473
|
+
tone: "info",
|
|
8474
|
+
status: "validating",
|
|
8475
|
+
createdAt: new Date().toISOString()
|
|
8476
|
+
});
|
|
8477
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: "Resume found accepted artifacts; continuing closeout" });
|
|
8478
|
+
exit = { code: 0, signal: null };
|
|
8479
|
+
}
|
|
8480
|
+
}
|
|
8481
|
+
for (let attempt = 1;!exit && attempt <= maxAttempts; attempt += 1) {
|
|
8414
8482
|
const attemptHostAgentCommand = buildHostAgentCommand(currentPrompt);
|
|
8415
8483
|
const child = spawn2(attemptHostAgentCommand[0], attemptHostAgentCommand.slice(1), {
|
|
8416
8484
|
cwd: context.projectRoot,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/cli",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Rig package",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@clack/prompts": "^1.2.0",
|
|
26
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
27
|
-
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.
|
|
28
|
-
"@rig/client": "npm:@h-rig/client@0.0.6-alpha.
|
|
26
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.4",
|
|
27
|
+
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.4",
|
|
28
|
+
"@rig/client": "npm:@h-rig/client@0.0.6-alpha.4",
|
|
29
29
|
"picocolors": "^1.1.1"
|
|
30
30
|
}
|
|
31
31
|
}
|