@h-rig/cli 0.0.6-alpha.60 → 0.0.6-alpha.62

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.
@@ -337,10 +337,10 @@ var init_plugin = __esm(() => {
337
337
  // packages/cli/src/commands.ts
338
338
  init_runner();
339
339
  import {
340
- existsSync as existsSync15,
340
+ existsSync as existsSync16,
341
341
  readFileSync as readFileSync12
342
342
  } from "fs";
343
- import { resolve as resolve24 } from "path";
343
+ import { resolve as resolve25 } from "path";
344
344
  import { readBuildConfig } from "@rig/runtime/build-time-config";
345
345
 
346
346
  // packages/cli/src/commands/browser.ts
@@ -3427,8 +3427,7 @@ import { resolve as resolve11 } from "path";
3427
3427
  import {
3428
3428
  readAuthorityRun,
3429
3429
  readJsonlFile as readJsonlFile2,
3430
- resolveAuthorityRunDir,
3431
- writeJsonFile as writeJsonFile3
3430
+ writeAuthorityRunRecord
3432
3431
  } from "@rig/runtime/control-plane/authority-files";
3433
3432
  var RIG_WORKSPACE_ID = "rig-local-workspace";
3434
3433
  function normalizeRuntimeAdapter(value) {
@@ -3514,7 +3513,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3514
3513
  } else if ("errorText" in next) {
3515
3514
  delete next.errorText;
3516
3515
  }
3517
- writeJsonFile3(resolve11(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3516
+ writeAuthorityRunRecord(projectRoot, input.runId, next);
3518
3517
  return next;
3519
3518
  }
3520
3519
 
@@ -4078,7 +4077,7 @@ import { resolve as resolve14 } from "path";
4078
4077
  import {
4079
4078
  listAuthorityRuns,
4080
4079
  readJsonlFile as readJsonlFile3,
4081
- resolveAuthorityRunDir as resolveAuthorityRunDir2
4080
+ resolveAuthorityRunDir
4082
4081
  } from "@rig/runtime/control-plane/authority-files";
4083
4082
 
4084
4083
  // packages/cli/src/commands/_cli-format.ts
@@ -4476,7 +4475,7 @@ async function listRemoteInboxRecords(context, kind, filters) {
4476
4475
  function listLocalInboxRecords(context, kind, filters) {
4477
4476
  const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4478
4477
  const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4479
- return runs.flatMap((entry) => readJsonlFile3(resolve14(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4478
+ return runs.flatMap((entry) => readJsonlFile3(resolve14(resolveAuthorityRunDir(context.projectRoot, entry.runId), fileName)).map((record) => ({
4480
4479
  runId: entry.runId,
4481
4480
  taskId: entry.taskId ?? undefined,
4482
4481
  record
@@ -4524,7 +4523,7 @@ async function executeInbox(context, args) {
4524
4523
  if (isRemoteConnectionSelected(context.projectRoot)) {
4525
4524
  throw new CliError2("Remote approval resolution is not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
4526
4525
  }
4527
- const approvalsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4526
+ const approvalsPath = resolve14(resolveAuthorityRunDir(context.projectRoot, run.value), "approvals.jsonl");
4528
4527
  const approvals = readJsonlFile3(approvalsPath);
4529
4528
  const resolvedAt = new Date().toISOString();
4530
4529
  const next = approvals.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", decision: decision.value, note: note4.value ?? null, resolvedAt } : entry);
@@ -4580,7 +4579,7 @@ async function executeInbox(context, args) {
4580
4579
  const [key, ...restValue] = entry.split("=");
4581
4580
  return [key, restValue.join("=")];
4582
4581
  }));
4583
- const requestsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4582
+ const requestsPath = resolve14(resolveAuthorityRunDir(context.projectRoot, run.value), "user-input.jsonl");
4584
4583
  const requests = readJsonlFile3(requestsPath);
4585
4584
  const resolvedAt = new Date().toISOString();
4586
4585
  const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
@@ -6047,27 +6046,23 @@ init_runner();
6047
6046
  import { readFileSync as readFileSync8 } from "fs";
6048
6047
  import { resolve as resolve19 } from "path";
6049
6048
  import {
6050
- appendJsonlRecord as appendJsonlRecord2,
6051
6049
  appendRunLifecycleEvent,
6050
+ appendRunLogEntry,
6051
+ appendRunTimelineEntry,
6052
+ patchAuthorityRunRecord,
6052
6053
  readAuthorityRun as readAuthorityRun2,
6053
- resolveAuthorityRunDir as resolveAuthorityRunDir3,
6054
- writeJsonFile as writeJsonFile4
6054
+ resolveAuthorityRunDir as resolveAuthorityRunDir2,
6055
+ writeJsonFile as writeJsonFile3
6055
6056
  } from "@rig/runtime/control-plane/authority-files";
6056
6057
  import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
6057
6058
  import { readPriorPrProgressPromptSection } from "@rig/runtime/control-plane/prompt-context";
6058
6059
  import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
6059
6060
  import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
6060
6061
  function patchAuthorityRun(projectRoot, runId, patch) {
6061
- const current = readAuthorityRun2(projectRoot, runId);
6062
- if (!current) {
6062
+ const next = patchAuthorityRunRecord(projectRoot, runId, patch);
6063
+ if (!next) {
6063
6064
  throw new CliError2(`Run not found: ${runId}`, 2);
6064
6065
  }
6065
- const next = {
6066
- ...current,
6067
- ...patch,
6068
- updatedAt: new Date().toISOString()
6069
- };
6070
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6071
6066
  return next;
6072
6067
  }
6073
6068
  function touchAuthorityRun(projectRoot, runId) {
@@ -6075,21 +6070,21 @@ function touchAuthorityRun(projectRoot, runId) {
6075
6070
  if (!current) {
6076
6071
  return;
6077
6072
  }
6078
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6073
+ writeJsonFile3(resolve19(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), {
6079
6074
  ...current,
6080
6075
  updatedAt: new Date().toISOString()
6081
6076
  });
6082
6077
  }
6083
6078
  function appendRunTimeline(projectRoot, runId, value) {
6084
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6079
+ appendRunTimelineEntry(projectRoot, runId, value);
6085
6080
  touchAuthorityRun(projectRoot, runId);
6086
6081
  }
6087
6082
  function appendRunLog(projectRoot, runId, value) {
6088
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6083
+ appendRunLogEntry(projectRoot, runId, value);
6089
6084
  touchAuthorityRun(projectRoot, runId);
6090
6085
  }
6091
6086
  function appendRunAction(projectRoot, runId, value) {
6092
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6087
+ appendRunTimelineEntry(projectRoot, runId, {
6093
6088
  id: value.id,
6094
6089
  type: "action",
6095
6090
  actionType: value.actionType,
@@ -6310,7 +6305,7 @@ import { resolve as resolve20 } from "path";
6310
6305
  import {
6311
6306
  listAuthorityRuns as listAuthorityRuns2,
6312
6307
  readAuthorityRun as readAuthorityRun3,
6313
- resolveAuthorityRunDir as resolveAuthorityRunDir4,
6308
+ resolveAuthorityRunDir as resolveAuthorityRunDir3,
6314
6309
  resolveTaskArtifactDirs
6315
6310
  } from "@rig/runtime/control-plane/authority-files";
6316
6311
  import { changedFilesForTask } from "@rig/runtime/control-plane/native/task-ops";
@@ -6344,7 +6339,7 @@ async function executeInspect(context, args) {
6344
6339
  }
6345
6340
  return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: serverRun.runId, source: "server", entries } };
6346
6341
  }
6347
- const logsPath = resolve20(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6342
+ const logsPath = resolve20(resolveAuthorityRunDir3(context.projectRoot, latestRun.runId), "logs.jsonl");
6348
6343
  if (!existsSync12(logsPath)) {
6349
6344
  throw new CliError2(`No logs found for run ${latestRun.runId}.`);
6350
6345
  }
@@ -7074,7 +7069,7 @@ init__parsers();
7074
7069
  import { createInterface as createInterface2 } from "readline/promises";
7075
7070
  import {
7076
7071
  listAuthorityRuns as listAuthorityRuns3,
7077
- readAuthorityRun as readAuthorityRun4
7072
+ readAuthorityRun as readAuthorityRun5
7078
7073
  } from "@rig/runtime/control-plane/authority-files";
7079
7074
  import {
7080
7075
  cleanupRunState,
@@ -7090,6 +7085,144 @@ import {
7090
7085
  } from "@rig/runtime/control-plane/native/run-ops";
7091
7086
  import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
7092
7087
 
7088
+ // packages/cli/src/commands/_run-replay.ts
7089
+ import { existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
7090
+ import { join as join2, resolve as resolve21 } from "path";
7091
+ import {
7092
+ readAuthorityRun as readAuthorityRun4,
7093
+ readJsonlFile as readJsonlFile4,
7094
+ runLifecycleLogPath
7095
+ } from "@rig/runtime/control-plane/authority-files";
7096
+ function asRecord(value) {
7097
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7098
+ }
7099
+ function text2(value) {
7100
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
7101
+ }
7102
+ function snippet(value, max = 120) {
7103
+ const raw = text2(value);
7104
+ if (!raw)
7105
+ return null;
7106
+ const flat = raw.replace(/\s+/g, " ");
7107
+ return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;
7108
+ }
7109
+ function summarizeLifecycleEntry(entry) {
7110
+ const type = text2(entry.type) ?? "event";
7111
+ switch (type) {
7112
+ case "status": {
7113
+ const anchor = text2(entry.sessionId);
7114
+ return [
7115
+ `status \u2192 ${text2(entry.status) ?? "(unknown)"}`,
7116
+ snippet(entry.detail) ? `\u2014 ${snippet(entry.detail)}` : null,
7117
+ anchor ? `[session ${anchor}]` : null
7118
+ ].filter(Boolean).join(" ");
7119
+ }
7120
+ case "timeline-entry": {
7121
+ const payload = asRecord(entry.payload) ?? {};
7122
+ const kind = text2(payload.type) ?? "entry";
7123
+ const body = snippet(payload.title) ?? snippet(payload.text) ?? snippet(payload.detail);
7124
+ const state = text2(payload.state);
7125
+ return [`timeline ${kind}`, body ? `\u2014 ${body}` : null, state ? `(${state})` : null].filter(Boolean).join(" ");
7126
+ }
7127
+ case "log-entry": {
7128
+ const payload = asRecord(entry.payload) ?? {};
7129
+ const title = snippet(payload.title) ?? "log";
7130
+ const detail = snippet(payload.detail);
7131
+ return [`log ${title}`, detail ? `\u2014 ${detail}` : null].filter(Boolean).join(" ");
7132
+ }
7133
+ case "record-patch": {
7134
+ const patch = asRecord(entry.patch) ?? {};
7135
+ const keys = Object.keys(patch);
7136
+ const shown = keys.slice(0, 8).join(", ");
7137
+ return `record-patch {${shown}${keys.length > 8 ? `, +${keys.length - 8} more` : ""}}`;
7138
+ }
7139
+ case "timeline":
7140
+ return "timeline updated (signal)";
7141
+ case "log":
7142
+ return `log signal${snippet(entry.title) ? ` \u2014 ${snippet(entry.title)}` : ""}`;
7143
+ case "completed":
7144
+ return "run completed";
7145
+ case "failed":
7146
+ return `run failed${snippet(entry.error) ? ` \u2014 ${snippet(entry.error)}` : ""}`;
7147
+ default:
7148
+ return type;
7149
+ }
7150
+ }
7151
+ function summarizeSessionEntry(entry) {
7152
+ const type = text2(entry.type) ?? "entry";
7153
+ const message2 = asRecord(entry.message);
7154
+ const role = text2(message2?.role);
7155
+ const content = message2?.content;
7156
+ let body = null;
7157
+ if (typeof content === "string") {
7158
+ body = snippet(content);
7159
+ } else if (Array.isArray(content)) {
7160
+ body = snippet(content.map((part) => text2(asRecord(part)?.text) ?? "").filter(Boolean).join(" "));
7161
+ }
7162
+ return [
7163
+ `pi ${type}`,
7164
+ role ? `(${role})` : null,
7165
+ body ? `\u2014 ${body}` : null
7166
+ ].filter(Boolean).join(" ");
7167
+ }
7168
+ function sessionEntryTimestamp(entry) {
7169
+ return text2(entry.timestamp) ?? text2(entry.at) ?? text2(entry.createdAt) ?? null;
7170
+ }
7171
+ function resolveRunSessionFile(record) {
7172
+ const piSession = record?.piSession ?? null;
7173
+ if (!piSession)
7174
+ return null;
7175
+ const recorded = text2(piSession.sessionFile);
7176
+ if (recorded && existsSync13(recorded)) {
7177
+ return recorded;
7178
+ }
7179
+ const cwd = text2(piSession.cwd);
7180
+ const sessionId = text2(piSession.sessionId);
7181
+ if (!cwd || !sessionId)
7182
+ return null;
7183
+ const sessionDir = resolve21(cwd, ".rig", "session");
7184
+ try {
7185
+ const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
7186
+ return match ? join2(sessionDir, match) : null;
7187
+ } catch {
7188
+ return null;
7189
+ }
7190
+ }
7191
+ function buildRunReplay(projectRoot, runId, options = {}) {
7192
+ const logPath = runLifecycleLogPath(projectRoot, runId);
7193
+ const record = readAuthorityRun4(projectRoot, runId);
7194
+ const lifecycleEntries = readJsonlFile4(logPath).map((entry) => asRecord(entry)).filter((entry) => entry !== null);
7195
+ const merged = lifecycleEntries.map((entry) => ({
7196
+ at: text2(entry.at),
7197
+ source: "run",
7198
+ summary: summarizeLifecycleEntry(entry)
7199
+ }));
7200
+ let sessionFile = null;
7201
+ let sessionEntryCount = 0;
7202
+ if (options.withSession) {
7203
+ sessionFile = resolveRunSessionFile(record);
7204
+ if (sessionFile) {
7205
+ let lastSeenAt = null;
7206
+ const sessionLines = readJsonlFile4(sessionFile).map((entry) => asRecord(entry)).filter((entry) => entry !== null).map((entry) => {
7207
+ lastSeenAt = sessionEntryTimestamp(entry) ?? lastSeenAt;
7208
+ return { at: lastSeenAt, source: "session", summary: summarizeSessionEntry(entry) };
7209
+ });
7210
+ sessionEntryCount = sessionLines.length;
7211
+ merged.push(...sessionLines);
7212
+ merged.sort((left, right) => (left.at ?? "").localeCompare(right.at ?? ""));
7213
+ }
7214
+ }
7215
+ const lines = merged.map((line) => `${line.at ?? "(no timestamp) "} ${line.source === "run" ? "run " : "session"} ${line.summary}`);
7216
+ return {
7217
+ runId,
7218
+ logPath,
7219
+ sessionFile,
7220
+ entryCount: lifecycleEntries.length,
7221
+ sessionEntryCount,
7222
+ lines
7223
+ };
7224
+ }
7225
+
7093
7226
  // packages/cli/src/commands/_operator-surface.ts
7094
7227
  import { createInterface } from "readline";
7095
7228
  import { createInterface as createPromptInterface } from "readline/promises";
@@ -7188,22 +7321,22 @@ function createPiRunStreamRenderer(output = process.stdout) {
7188
7321
  for (const [index, entry] of entries.entries()) {
7189
7322
  const id = entryId(entry, `timeline:${index}:${String(entry.cursor ?? "")}`);
7190
7323
  if (entry.type === "assistant_message" && typeof entry.text === "string") {
7191
- const text2 = entry.text;
7324
+ const text3 = entry.text;
7192
7325
  const previousText = assistantTextById.get(id) ?? "";
7193
- if (!previousText && text2.trim()) {
7326
+ if (!previousText && text3.trim()) {
7194
7327
  writeLine("[Pi assistant]");
7195
7328
  }
7196
- if (text2.startsWith(previousText)) {
7197
- const delta = text2.slice(previousText.length);
7329
+ if (text3.startsWith(previousText)) {
7330
+ const delta = text3.slice(previousText.length);
7198
7331
  if (delta)
7199
7332
  output.write(delta);
7200
- } else if (text2.trim() && text2 !== previousText) {
7333
+ } else if (text3.trim() && text3 !== previousText) {
7201
7334
  if (previousText)
7202
7335
  writeLine(`
7203
7336
  [Pi assistant]`);
7204
- output.write(text2);
7337
+ output.write(text3);
7205
7338
  }
7206
- assistantTextById.set(id, text2);
7339
+ assistantTextById.set(id, text3);
7207
7340
  continue;
7208
7341
  }
7209
7342
  if (seenTimeline.has(id))
@@ -7218,15 +7351,15 @@ function createPiRunStreamRenderer(output = process.stdout) {
7218
7351
  continue;
7219
7352
  }
7220
7353
  if (entry.type === "action") {
7221
- const text2 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7222
- if (text2)
7223
- writeLine(`[Rig action] ${text2}`);
7354
+ const text3 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7355
+ if (text3)
7356
+ writeLine(`[Rig action] ${text3}`);
7224
7357
  continue;
7225
7358
  }
7226
7359
  if (entry.type === "user_message") {
7227
- const text2 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7228
- if (text2)
7229
- writeLine(`[Operator] ${text2}`);
7360
+ const text3 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7361
+ if (text3)
7362
+ writeLine(`[Operator] ${text3}`);
7230
7363
  continue;
7231
7364
  }
7232
7365
  const fallback = String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? "").trim();
@@ -7306,7 +7439,7 @@ async function promptForTaskSelection(question) {
7306
7439
  // packages/cli/src/commands/_pi-frontend.ts
7307
7440
  import { mkdtempSync, rmSync as rmSync5 } from "fs";
7308
7441
  import { tmpdir } from "os";
7309
- import { join as join2 } from "path";
7442
+ import { join as join3 } from "path";
7310
7443
  import {
7311
7444
  createAgentSessionFromServices,
7312
7445
  createAgentSessionServices,
@@ -7438,15 +7571,15 @@ class RigRemoteSessionController {
7438
7571
  for (const compaction of this.pendingCompactions.splice(0))
7439
7572
  compaction.reject(new Error("Remote session closed."));
7440
7573
  }
7441
- async sendPrompt(text2, streamingBehavior) {
7442
- await this.transport.sendPrompt(this.context, this.runId, text2, streamingBehavior);
7574
+ async sendPrompt(text3, streamingBehavior) {
7575
+ await this.transport.sendPrompt(this.context, this.runId, text3, streamingBehavior);
7443
7576
  }
7444
- async sendCommand(text2) {
7445
- const result = await this.transport.runCommand(this.context, this.runId, text2);
7577
+ async sendCommand(text3) {
7578
+ const result = await this.transport.runCommand(this.context, this.runId, text3);
7446
7579
  return typeof result.message === "string" ? result.message : "worker command accepted";
7447
7580
  }
7448
- async sendShell(text2) {
7449
- await this.transport.sendShell(this.context, this.runId, text2);
7581
+ async sendShell(text3) {
7582
+ await this.transport.sendShell(this.context, this.runId, text3);
7450
7583
  }
7451
7584
  async abort() {
7452
7585
  await this.transport.abort(this.context, this.runId);
@@ -7598,8 +7731,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7598
7731
  replaceRemoteMessages(messages) {
7599
7732
  this.agent.state.messages = messages;
7600
7733
  }
7601
- async expandLocalInput(text2) {
7602
- let current = text2;
7734
+ async expandLocalInput(text3) {
7735
+ let current = text3;
7603
7736
  const runner = this.extensionRunner;
7604
7737
  if (runner.hasHandlers("input")) {
7605
7738
  const result = await runner.emitInput(current, undefined, "interactive");
@@ -7612,8 +7745,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7612
7745
  current = expandPromptTemplate(current, [...this.promptTemplates]);
7613
7746
  return current;
7614
7747
  }
7615
- async prompt(text2, options) {
7616
- const trimmed = text2.trim();
7748
+ async prompt(text3, options) {
7749
+ const trimmed = text3.trim();
7617
7750
  if (!trimmed)
7618
7751
  return;
7619
7752
  if (trimmed.startsWith("/")) {
@@ -7642,8 +7775,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7642
7775
  options?.preflightResult?.(true);
7643
7776
  await this.remote.sendPrompt(expanded, behavior);
7644
7777
  }
7645
- async steer(text2) {
7646
- const trimmed = text2.trim();
7778
+ async steer(text3) {
7779
+ const trimmed = text3.trim();
7647
7780
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7648
7781
  return;
7649
7782
  const expanded = await this.expandLocalInput(trimmed);
@@ -7651,8 +7784,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7651
7784
  return;
7652
7785
  await this.remote.sendPrompt(expanded, "steer");
7653
7786
  }
7654
- async followUp(text2) {
7655
- const trimmed = text2.trim();
7787
+ async followUp(text3) {
7788
+ const trimmed = text3.trim();
7656
7789
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7657
7790
  return;
7658
7791
  const expanded = await this.expandLocalInput(trimmed);
@@ -7664,8 +7797,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7664
7797
  await this.remote.abort();
7665
7798
  }
7666
7799
  async compact(customInstructions) {
7667
- const pending = new Promise((resolve21, reject) => {
7668
- this.remote.registerPendingCompaction({ resolve: resolve21, reject });
7800
+ const pending = new Promise((resolve22, reject) => {
7801
+ this.remote.registerPendingCompaction({ resolve: resolve22, reject });
7669
7802
  });
7670
7803
  await this.remote.sendCommand(`/compact${customInstructions ? ` ${customInstructions}` : ""}`);
7671
7804
  return pending;
@@ -7734,8 +7867,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7734
7867
  function createRemoteBashOperations(controller, excludeFromContext) {
7735
7868
  return {
7736
7869
  exec(command, _cwd, execOptions) {
7737
- return new Promise((resolve21, reject) => {
7738
- const pending = { onData: execOptions.onData, resolve: resolve21, reject, sawChunk: false };
7870
+ return new Promise((resolve22, reject) => {
7871
+ const pending = { onData: execOptions.onData, resolve: resolve22, reject, sawChunk: false };
7739
7872
  const cleanup = () => {
7740
7873
  execOptions.signal?.removeEventListener("abort", onAbort);
7741
7874
  if (timer)
@@ -7899,8 +8032,8 @@ function createRigWorkerPiBridgeExtension(options) {
7899
8032
  const prefix = busy ? `${SPINNER_FRAMES[frame]} ` : connected ? "\u25CF " : "\u25CB ";
7900
8033
  ctx.ui.setStatus("rig-worker-pi", `${prefix}${statusText}`);
7901
8034
  };
7902
- const setStatus = (ctx, text2, isBusy) => {
7903
- statusText = text2;
8035
+ const setStatus = (ctx, text3, isBusy) => {
8036
+ statusText = text3;
7904
8037
  busy = isBusy;
7905
8038
  renderStatus(ctx);
7906
8039
  };
@@ -7944,7 +8077,7 @@ function createRigWorkerPiBridgeExtension(options) {
7944
8077
  ctx.ui.notify("Initial message sent to the worker Pi daemon.", "info");
7945
8078
  const nativeUi = ctx.ui;
7946
8079
  options.controller.setUiHooks({
7947
- onStatusText: (text2) => setStatus(ctx, text2, !connected),
8080
+ onStatusText: (text3) => setStatus(ctx, text3, !connected),
7948
8081
  onActivity: (label, detail) => {
7949
8082
  const active = label !== "idle" && !/complete|ready/i.test(label);
7950
8083
  setStatus(ctx, [label, detail].filter(Boolean).join(" \u2014 "), active);
@@ -8001,7 +8134,7 @@ function setTemporaryEnv(updates) {
8001
8134
  };
8002
8135
  }
8003
8136
  async function attachRunBundledPiFrontend(context, input) {
8004
- const tempSessionDir = mkdtempSync(join2(tmpdir(), "rig-pi-frontend-sessions-"));
8137
+ const tempSessionDir = mkdtempSync(join3(tmpdir(), "rig-pi-frontend-sessions-"));
8005
8138
  const restoreEnv = setTemporaryEnv({
8006
8139
  PI_CODING_AGENT_SESSION_DIR: tempSessionDir,
8007
8140
  PI_SKIP_VERSION_CHECK: "1",
@@ -8321,7 +8454,7 @@ async function executeRun(context, args) {
8321
8454
  if (!runId) {
8322
8455
  throw new CliError2("run show requires a run id.");
8323
8456
  }
8324
- const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8457
+ const record = readAuthorityRun5(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8325
8458
  if (!record) {
8326
8459
  throw new CliError2(`Run not found: ${runId}`, 2);
8327
8460
  }
@@ -8359,6 +8492,46 @@ async function executeRun(context, args) {
8359
8492
  }
8360
8493
  return { ok: true, group: "run", command, details: { runId: run.value, events, cursor } };
8361
8494
  }
8495
+ case "replay": {
8496
+ let pending = rest;
8497
+ const run = takeOption(pending, "--run");
8498
+ pending = run.rest;
8499
+ const withSession = takeFlag(pending, "--with-session");
8500
+ pending = withSession.rest;
8501
+ const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
8502
+ const extra = positionalRunId ? pending.slice(1) : pending;
8503
+ requireNoExtraArgs(extra, "rig run replay <id>|--run <id> [--with-session]");
8504
+ const runId = run.value ?? positionalRunId;
8505
+ if (!runId) {
8506
+ throw new CliError2("run replay requires a run id.", 2);
8507
+ }
8508
+ const replay = buildRunReplay(context.projectRoot, runId, { withSession: withSession.value });
8509
+ if (replay.entryCount === 0 && replay.sessionEntryCount === 0) {
8510
+ throw new CliError2(`No run.jsonl lifecycle log found for ${runId} (looked at ${replay.logPath}).`, 2);
8511
+ }
8512
+ if (context.outputMode === "text") {
8513
+ console.log(`Replay of ${runId} (${replay.entryCount} lifecycle entries${withSession.value ? `, ${replay.sessionEntryCount} session entries` : ""}):`);
8514
+ for (const line of replay.lines) {
8515
+ console.log(line);
8516
+ }
8517
+ if (withSession.value && !replay.sessionFile) {
8518
+ console.log("(no Pi session file resolvable from the run record; showing run.jsonl only)");
8519
+ }
8520
+ }
8521
+ return {
8522
+ ok: true,
8523
+ group: "run",
8524
+ command,
8525
+ details: {
8526
+ runId,
8527
+ logPath: replay.logPath,
8528
+ sessionFile: replay.sessionFile,
8529
+ entryCount: replay.entryCount,
8530
+ sessionEntryCount: replay.sessionEntryCount,
8531
+ lines: replay.lines
8532
+ }
8533
+ };
8534
+ }
8362
8535
  case "attach": {
8363
8536
  let pending = rest;
8364
8537
  const runOption = takeOption(pending, "--run");
@@ -8681,7 +8854,7 @@ async function executeServer(context, args, options) {
8681
8854
  init_runner();
8682
8855
  import { readFileSync as readFileSync10 } from "fs";
8683
8856
  import { spawnSync as spawnSync3 } from "child_process";
8684
- import { resolve as resolve21 } from "path";
8857
+ import { resolve as resolve22 } from "path";
8685
8858
  import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8686
8859
  import {
8687
8860
  taskArtifactDir,
@@ -8859,6 +9032,7 @@ var PRIMARY_GROUPS = [
8859
9032
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
8860
9033
  { command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
8861
9034
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
9035
+ { command: "replay <run-id>|--run <id> [--with-session]", description: "Print the run's consolidated run.jsonl as a merged timeline; --with-session interleaves the Pi session log." },
8862
9036
  { command: "resume", description: "Resume the most recent interrupted local run." },
8863
9037
  { command: "restart", description: "Restart the most recent local run from a clean runtime." },
8864
9038
  { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
@@ -9446,7 +9620,7 @@ async function executeTask(context, args, options) {
9446
9620
  const fileFlag = takeOption(rest.slice(1), "--file");
9447
9621
  let content;
9448
9622
  if (fileFlag.value) {
9449
- content = readFileSync10(resolve21(context.projectRoot, fileFlag.value), "utf-8");
9623
+ content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
9450
9624
  } else {
9451
9625
  content = await readStdin();
9452
9626
  }
@@ -9680,8 +9854,8 @@ async function executeTask(context, args, options) {
9680
9854
 
9681
9855
  // packages/cli/src/commands/task-run-driver.ts
9682
9856
  init_runner();
9683
- import { copyFileSync as copyFileSync3, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9684
- import { resolve as resolve22 } from "path";
9857
+ import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9858
+ import { resolve as resolve23 } from "path";
9685
9859
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
9686
9860
  import { createInterface as createLineInterface } from "readline";
9687
9861
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -9705,7 +9879,7 @@ import {
9705
9879
  isCodexExecRecord
9706
9880
  } from "@rig/runtime/control-plane/provider/codex-exec-records";
9707
9881
  import { resolvePreferredShellBinary } from "@rig/runtime/control-plane/native/run-ops";
9708
- import { readAuthorityRun as readAuthorityRun5, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
9882
+ import { readAuthorityRun as readAuthorityRun6, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
9709
9883
  import {
9710
9884
  buildTaskRunLifecycleComment
9711
9885
  } from "@rig/runtime/control-plane/tasks/source-lifecycle";
@@ -9765,12 +9939,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
9765
9939
  return 0;
9766
9940
  let copied = 0;
9767
9941
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
9768
- const sourcePath = resolve22(sourceRoot, relativePath);
9769
- const targetPath = resolve22(targetRoot, relativePath);
9942
+ const sourcePath = resolve23(sourceRoot, relativePath);
9943
+ const targetPath = resolve23(targetRoot, relativePath);
9770
9944
  try {
9771
9945
  if (!statSync2(sourcePath).isFile())
9772
9946
  continue;
9773
- mkdirSync8(resolve22(targetPath, ".."), { recursive: true });
9947
+ mkdirSync8(resolve23(targetPath, ".."), { recursive: true });
9774
9948
  copyFileSync3(sourcePath, targetPath);
9775
9949
  copied += 1;
9776
9950
  } catch {}
@@ -9809,7 +9983,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
9809
9983
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
9810
9984
  return {
9811
9985
  RIG_BASELINE_MODE: "dirty-snapshot",
9812
- RIG_DIRTY_BASELINE_READY_FILE: resolve22(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9986
+ RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9813
9987
  };
9814
9988
  }
9815
9989
  function positiveInt(value, fallback) {
@@ -9914,9 +10088,9 @@ function createCommandRunner(binary) {
9914
10088
  const stderrChunks = [];
9915
10089
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9916
10090
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9917
- return await new Promise((resolve23) => {
9918
- child.once("error", (error) => resolve23({ exitCode: 1, stderr: error.message }));
9919
- child.once("close", (code) => resolve23({
10091
+ return await new Promise((resolve24) => {
10092
+ child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
10093
+ child.once("close", (code) => resolve24({
9920
10094
  exitCode: code ?? 1,
9921
10095
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
9922
10096
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -9990,7 +10164,7 @@ async function runTaskRunPostValidationLifecycle(input) {
9990
10164
  config,
9991
10165
  sourceTask: input.sourceTask,
9992
10166
  uploadedSnapshot: input.uploadedSnapshot,
9993
- artifactRoot: resolve22(input.projectRoot, "artifacts", taskId3),
10167
+ artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
9994
10168
  command: ghCommand,
9995
10169
  gitCommand,
9996
10170
  steerPi,
@@ -10120,7 +10294,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
10120
10294
  return null;
10121
10295
  }
10122
10296
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
10123
- const summary = readJsonFile3(resolve22(artifactDir, "validation-summary.json"), null);
10297
+ const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
10124
10298
  if (!summary || summary.status !== "fail") {
10125
10299
  continue;
10126
10300
  }
@@ -10201,9 +10375,9 @@ function readTaskRunAcceptedArtifactState(input) {
10201
10375
  if (!input.taskId || !input.workspaceDir) {
10202
10376
  return { accepted: false, reason: null };
10203
10377
  }
10204
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
10205
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
10206
- const taskResultPath = resolve22(artifactDir, "task-result.json");
10378
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10379
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10380
+ const taskResultPath = resolve23(artifactDir, "task-result.json");
10207
10381
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10208
10382
  if (reviewStatus !== "APPROVED") {
10209
10383
  return { accepted: false, reason: null };
@@ -10240,12 +10414,12 @@ function resolveTaskRunRetryContext(input) {
10240
10414
  if (!input.taskId || !input.workspaceDir) {
10241
10415
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
10242
10416
  }
10243
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
10244
- const reviewStatePath = resolve22(artifactDir, "review-state.json");
10245
- const reviewFeedbackPath = resolve22(artifactDir, "review-feedback.md");
10246
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
10247
- const failedApproachesPath = resolve22(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10248
- const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
10417
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10418
+ const reviewStatePath = resolve23(artifactDir, "review-state.json");
10419
+ const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
10420
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10421
+ const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10422
+ const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
10249
10423
  const reviewState = readJsonFile3(reviewStatePath, null);
10250
10424
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10251
10425
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -10431,7 +10605,7 @@ function appendToolTimelineFromLog(input) {
10431
10605
  });
10432
10606
  }
10433
10607
  function readTaskRunReviewStatus(reviewStatusPath) {
10434
- if (!existsSync13(reviewStatusPath)) {
10608
+ if (!existsSync14(reviewStatusPath)) {
10435
10609
  return null;
10436
10610
  }
10437
10611
  try {
@@ -10511,7 +10685,7 @@ async function updateTaskSourceAfterDriverRun(projectRoot, runId, taskId3, sourc
10511
10685
  }
10512
10686
  }
10513
10687
  function readRunSourceTaskContract(projectRoot, runId, taskId3) {
10514
- const run = readAuthorityRun5(projectRoot, runId);
10688
+ const run = readAuthorityRun6(projectRoot, runId);
10515
10689
  const raw = run?.sourceTask;
10516
10690
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
10517
10691
  return null;
@@ -10552,8 +10726,10 @@ async function executeRigOwnedTaskRun(context, input) {
10552
10726
  process.stderr.on("error", () => {});
10553
10727
  configureRunEventSink(context.projectRoot);
10554
10728
  const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
10555
- const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
10729
+ const existingRunRecord = readAuthorityRun6(context.projectRoot, input.runId);
10556
10730
  const resumeMode = process.env.RIG_RUN_RESUME === "1";
10731
+ let latestPiSessionId = typeof existingRunRecord?.piSession?.sessionId === "string" && existingRunRecord.piSession.sessionId.trim() ? existingRunRecord.piSession.sessionId : null;
10732
+ const sessionAnchor = () => latestPiSessionId ? { sessionId: latestPiSessionId } : {};
10557
10733
  const resumePreviousStatus = String(existingRunRecord?.status ?? "").toLowerCase();
10558
10734
  const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
10559
10735
  let prompt = buildRunPrompt({
@@ -10626,7 +10802,8 @@ async function executeRigOwnedTaskRun(context, input) {
10626
10802
  type: "status",
10627
10803
  runId: input.runId,
10628
10804
  status: "preparing",
10629
- detail: input.taskId ?? input.title ?? runtimeTaskId
10805
+ detail: input.taskId ?? input.title ?? runtimeTaskId,
10806
+ ...sessionAnchor()
10630
10807
  });
10631
10808
  appendRunLog(context.projectRoot, input.runId, {
10632
10809
  id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
@@ -10652,15 +10829,15 @@ async function executeRigOwnedTaskRun(context, input) {
10652
10829
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
10653
10830
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
10654
10831
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
10655
- const planningArtifactPath = resolve22("artifacts", runtimeTaskId, "implementation-plan.md");
10832
+ const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
10656
10833
  const persistedPlanning = {
10657
10834
  ...planningClassification,
10658
10835
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
10659
10836
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
10660
10837
  classifiedAt: new Date().toISOString()
10661
10838
  };
10662
- mkdirSync8(resolve22(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10663
- writeFileSync7(resolve22(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10839
+ mkdirSync8(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10840
+ writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10664
10841
  `, "utf8");
10665
10842
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
10666
10843
  prompt = `${prompt}
@@ -10710,7 +10887,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10710
10887
  let verificationStarted = false;
10711
10888
  let reviewStarted = false;
10712
10889
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
10713
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
10890
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
10714
10891
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
10715
10892
  let latestProviderCommand = null;
10716
10893
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -10747,7 +10924,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10747
10924
  return;
10748
10925
  verificationStarted = true;
10749
10926
  patchAuthorityRun(context.projectRoot, input.runId, { status: "validating" });
10750
- emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null });
10927
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null, ...sessionAnchor() });
10751
10928
  verificationAction = startRunAction(context.projectRoot, input.runId, {
10752
10929
  actionId: `action:${input.runId}:completion-verification`,
10753
10930
  actionType: "completion-verification",
@@ -10760,7 +10937,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10760
10937
  return;
10761
10938
  reviewStarted = true;
10762
10939
  patchAuthorityRun(context.projectRoot, input.runId, { status: "reviewing" });
10763
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null });
10940
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null, ...sessionAnchor() });
10764
10941
  reviewAction = startRunAction(context.projectRoot, input.runId, {
10765
10942
  actionId: `action:${input.runId}:review-closeout`,
10766
10943
  actionType: "run.review",
@@ -10796,10 +10973,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10796
10973
  patchAuthorityRun(context.projectRoot, input.runId, {
10797
10974
  status: "running",
10798
10975
  worktreePath: latestRuntimeWorkspace,
10799
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve22(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10976
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10800
10977
  logRoot: latestLogsDir,
10801
- sessionPath: latestSessionDir ? resolve22(latestSessionDir, "session.json") : null,
10802
- sessionLogPath: latestLogsDir ? resolve22(latestLogsDir, "agent-stdout.log") : null,
10978
+ sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
10979
+ sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
10803
10980
  branch: runtimeId
10804
10981
  });
10805
10982
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -10807,7 +10984,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10807
10984
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
10808
10985
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
10809
10986
  if (readyFile) {
10810
- mkdirSync8(resolve22(readyFile, ".."), { recursive: true });
10987
+ mkdirSync8(resolve23(readyFile, ".."), { recursive: true });
10811
10988
  writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
10812
10989
  `, "utf8");
10813
10990
  }
@@ -10850,7 +11027,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10850
11027
  type: "status",
10851
11028
  runId: input.runId,
10852
11029
  status: "running",
10853
- detail: latestRuntimeWorkspace
11030
+ detail: latestRuntimeWorkspace,
11031
+ ...sessionAnchor()
10854
11032
  });
10855
11033
  return true;
10856
11034
  }
@@ -10933,6 +11111,9 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10933
11111
  piSessionPrivate: privateMetadata
10934
11112
  });
10935
11113
  const sessionId = typeof publicMetadata?.sessionId === "string" ? publicMetadata.sessionId : typeof privateMetadata.public === "object" && privateMetadata.public && !Array.isArray(privateMetadata.public) ? String(privateMetadata.public.sessionId ?? "") : "";
11114
+ if (sessionId) {
11115
+ latestPiSessionId = sessionId;
11116
+ }
10936
11117
  appendRunLog(context.projectRoot, input.runId, {
10937
11118
  id: `log:${input.runId}:pi-session-ready`,
10938
11119
  title: "Worker Pi session ready",
@@ -11192,7 +11373,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11192
11373
  let acceptedArtifactObservedAt = null;
11193
11374
  let acceptedArtifactPollTimer = null;
11194
11375
  let acceptedArtifactKillTimer = null;
11195
- const attemptExit = await new Promise((resolve23) => {
11376
+ const attemptExit = await new Promise((resolve24) => {
11196
11377
  let settled = false;
11197
11378
  const settle = (result) => {
11198
11379
  if (settled)
@@ -11200,7 +11381,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11200
11381
  settled = true;
11201
11382
  if (acceptedArtifactPollTimer)
11202
11383
  clearInterval(acceptedArtifactPollTimer);
11203
- resolve23(result);
11384
+ resolve24(result);
11204
11385
  };
11205
11386
  const pollAcceptedArtifacts = () => {
11206
11387
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -11327,7 +11508,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11327
11508
  type: "status",
11328
11509
  runId: input.runId,
11329
11510
  status: "validating",
11330
- detail: failureDetail
11511
+ detail: failureDetail,
11512
+ ...sessionAnchor()
11331
11513
  });
11332
11514
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Validate failed" });
11333
11515
  emitServerRunEvent({ type: "log", runId: input.runId, title: `Steering Pi to retry validation (attempt ${attempt + 1}/${maxAttempts})` });
@@ -11402,8 +11584,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11402
11584
  }
11403
11585
  if (planningClassification.planningRequired) {
11404
11586
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
11405
- const expectedPlanPath = resolve22(planWorkspace, planningArtifactPath);
11406
- if (!existsSync13(expectedPlanPath)) {
11587
+ const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
11588
+ if (!existsSync14(expectedPlanPath)) {
11407
11589
  const failedAt = new Date().toISOString();
11408
11590
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
11409
11591
  patchAuthorityRun(context.projectRoot, input.runId, {
@@ -11465,7 +11647,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11465
11647
  payload: { runtimeWorkspace: latestRuntimeWorkspace, branch: latestRuntimeBranch }
11466
11648
  });
11467
11649
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Server-owned closeout requested" });
11468
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested." });
11650
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested.", ...sessionAnchor() });
11469
11651
  await context.emitEvent("command.finished", {
11470
11652
  command: [
11471
11653
  "rig",
@@ -11573,9 +11755,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11573
11755
  });
11574
11756
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
11575
11757
  });
11576
- const exitCode = await new Promise((resolve23) => {
11577
- child.once("error", () => resolve23(1));
11578
- child.once("close", (code) => resolve23(code ?? 1));
11758
+ const exitCode = await new Promise((resolve24) => {
11759
+ child.once("error", () => resolve24(1));
11760
+ child.once("close", (code) => resolve24(code ?? 1));
11579
11761
  });
11580
11762
  for (const pendingLog of flushPendingClaudeToolUseLogs({
11581
11763
  runId: input.runId,
@@ -11717,8 +11899,8 @@ async function executeTest(context, args) {
11717
11899
 
11718
11900
  // packages/cli/src/commands/setup.ts
11719
11901
  init_runner();
11720
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
11721
- import { resolve as resolve23 } from "path";
11902
+ import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync3, writeFileSync as writeFileSync8 } from "fs";
11903
+ import { resolve as resolve24 } from "path";
11722
11904
  import { createPluginHost } from "@rig/core";
11723
11905
  import {
11724
11906
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -11776,8 +11958,8 @@ function runSetupInit(projectRoot) {
11776
11958
  mkdirSync9(stateDir, { recursive: true });
11777
11959
  mkdirSync9(logsDir, { recursive: true });
11778
11960
  mkdirSync9(artifactsDir, { recursive: true });
11779
- const failuresPath = resolve23(stateDir, "failed_approaches.md");
11780
- if (!existsSync14(failuresPath)) {
11961
+ const failuresPath = resolve24(stateDir, "failed_approaches.md");
11962
+ if (!existsSync15(failuresPath)) {
11781
11963
  writeFileSync8(failuresPath, `# Failed Approaches
11782
11964
 
11783
11965
  `, "utf-8");
@@ -11795,19 +11977,19 @@ async function runSetupCheck(projectRoot) {
11795
11977
  }
11796
11978
  async function runSetupPreflight(projectRoot) {
11797
11979
  await runSetupCheck(projectRoot);
11798
- const validationRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11799
- if (existsSync14(validationRoot)) {
11800
- const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11980
+ const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11981
+ if (existsSync15(validationRoot)) {
11982
+ const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11801
11983
  for (const validator of validators) {
11802
- const script = resolve23(validationRoot, validator.name, "validate.sh");
11803
- if (existsSync14(script)) {
11984
+ const script = resolve24(validationRoot, validator.name, "validate.sh");
11985
+ if (existsSync15(script)) {
11804
11986
  console.log(`OK: validator script ${script}`);
11805
11987
  }
11806
11988
  }
11807
11989
  }
11808
- const hooksRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11809
- if (existsSync14(hooksRoot)) {
11810
- const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
11990
+ const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11991
+ if (existsSync15(hooksRoot)) {
11992
+ const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
11811
11993
  for (const hook of hooks) {
11812
11994
  console.log(`OK: hook ${hook}`);
11813
11995
  }
@@ -11951,7 +12133,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
11951
12133
  ]);
11952
12134
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
11953
12135
  function hasInitializedRigProject(projectRoot) {
11954
- return RIG_CONFIG_FILENAMES.some((name) => existsSync15(resolve24(projectRoot, name))) || existsSync15(resolve24(projectRoot, ".rig"));
12136
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
11955
12137
  }
11956
12138
  function requireInitializedRigProject(context, group) {
11957
12139
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -12004,8 +12186,8 @@ function resolveTopLevelLaunchState(context) {
12004
12186
  let selectedServer = null;
12005
12187
  if (projectInitialized) {
12006
12188
  try {
12007
- const statePath = resolve24(context.projectRoot, ".rig", "state", "connection.json");
12008
- if (existsSync15(statePath)) {
12189
+ const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
12190
+ if (existsSync16(statePath)) {
12009
12191
  const parsed = JSON.parse(readFileSync12(statePath, "utf-8"));
12010
12192
  selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
12011
12193
  }