@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.
package/dist/src/index.js CHANGED
@@ -527,10 +527,10 @@ var init_plugin = __esm(() => {
527
527
  // packages/cli/src/commands.ts
528
528
  init_runner();
529
529
  import {
530
- existsSync as existsSync16,
530
+ existsSync as existsSync17,
531
531
  readFileSync as readFileSync12
532
532
  } from "fs";
533
- import { resolve as resolve25 } from "path";
533
+ import { resolve as resolve26 } from "path";
534
534
  import { readBuildConfig } from "@rig/runtime/build-time-config";
535
535
 
536
536
  // packages/cli/src/commands/browser.ts
@@ -3617,8 +3617,7 @@ import { resolve as resolve12 } from "path";
3617
3617
  import {
3618
3618
  readAuthorityRun,
3619
3619
  readJsonlFile as readJsonlFile2,
3620
- resolveAuthorityRunDir,
3621
- writeJsonFile as writeJsonFile3
3620
+ writeAuthorityRunRecord
3622
3621
  } from "@rig/runtime/control-plane/authority-files";
3623
3622
  var RIG_WORKSPACE_ID = "rig-local-workspace";
3624
3623
  function normalizeRuntimeAdapter(value) {
@@ -3704,7 +3703,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3704
3703
  } else if ("errorText" in next) {
3705
3704
  delete next.errorText;
3706
3705
  }
3707
- writeJsonFile3(resolve12(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3706
+ writeAuthorityRunRecord(projectRoot, input.runId, next);
3708
3707
  return next;
3709
3708
  }
3710
3709
 
@@ -4268,7 +4267,7 @@ import { resolve as resolve15 } from "path";
4268
4267
  import {
4269
4268
  listAuthorityRuns,
4270
4269
  readJsonlFile as readJsonlFile3,
4271
- resolveAuthorityRunDir as resolveAuthorityRunDir2
4270
+ resolveAuthorityRunDir
4272
4271
  } from "@rig/runtime/control-plane/authority-files";
4273
4272
 
4274
4273
  // packages/cli/src/commands/_cli-format.ts
@@ -4666,7 +4665,7 @@ async function listRemoteInboxRecords(context, kind, filters) {
4666
4665
  function listLocalInboxRecords(context, kind, filters) {
4667
4666
  const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4668
4667
  const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4669
- return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4668
+ return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir(context.projectRoot, entry.runId), fileName)).map((record) => ({
4670
4669
  runId: entry.runId,
4671
4670
  taskId: entry.taskId ?? undefined,
4672
4671
  record
@@ -4714,7 +4713,7 @@ async function executeInbox(context, args) {
4714
4713
  if (isRemoteConnectionSelected(context.projectRoot)) {
4715
4714
  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);
4716
4715
  }
4717
- const approvalsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4716
+ const approvalsPath = resolve15(resolveAuthorityRunDir(context.projectRoot, run.value), "approvals.jsonl");
4718
4717
  const approvals = readJsonlFile3(approvalsPath);
4719
4718
  const resolvedAt = new Date().toISOString();
4720
4719
  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);
@@ -4770,7 +4769,7 @@ async function executeInbox(context, args) {
4770
4769
  const [key, ...restValue] = entry.split("=");
4771
4770
  return [key, restValue.join("=")];
4772
4771
  }));
4773
- const requestsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4772
+ const requestsPath = resolve15(resolveAuthorityRunDir(context.projectRoot, run.value), "user-input.jsonl");
4774
4773
  const requests = readJsonlFile3(requestsPath);
4775
4774
  const resolvedAt = new Date().toISOString();
4776
4775
  const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
@@ -6237,27 +6236,23 @@ init_runner();
6237
6236
  import { readFileSync as readFileSync8 } from "fs";
6238
6237
  import { resolve as resolve20 } from "path";
6239
6238
  import {
6240
- appendJsonlRecord as appendJsonlRecord2,
6241
6239
  appendRunLifecycleEvent,
6240
+ appendRunLogEntry,
6241
+ appendRunTimelineEntry,
6242
+ patchAuthorityRunRecord,
6242
6243
  readAuthorityRun as readAuthorityRun2,
6243
- resolveAuthorityRunDir as resolveAuthorityRunDir3,
6244
- writeJsonFile as writeJsonFile4
6244
+ resolveAuthorityRunDir as resolveAuthorityRunDir2,
6245
+ writeJsonFile as writeJsonFile3
6245
6246
  } from "@rig/runtime/control-plane/authority-files";
6246
6247
  import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
6247
6248
  import { readPriorPrProgressPromptSection } from "@rig/runtime/control-plane/prompt-context";
6248
6249
  import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
6249
6250
  import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
6250
6251
  function patchAuthorityRun(projectRoot, runId, patch) {
6251
- const current = readAuthorityRun2(projectRoot, runId);
6252
- if (!current) {
6252
+ const next = patchAuthorityRunRecord(projectRoot, runId, patch);
6253
+ if (!next) {
6253
6254
  throw new CliError2(`Run not found: ${runId}`, 2);
6254
6255
  }
6255
- const next = {
6256
- ...current,
6257
- ...patch,
6258
- updatedAt: new Date().toISOString()
6259
- };
6260
- writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6261
6256
  return next;
6262
6257
  }
6263
6258
  function touchAuthorityRun(projectRoot, runId) {
@@ -6265,21 +6260,21 @@ function touchAuthorityRun(projectRoot, runId) {
6265
6260
  if (!current) {
6266
6261
  return;
6267
6262
  }
6268
- writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6263
+ writeJsonFile3(resolve20(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), {
6269
6264
  ...current,
6270
6265
  updatedAt: new Date().toISOString()
6271
6266
  });
6272
6267
  }
6273
6268
  function appendRunTimeline(projectRoot, runId, value) {
6274
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6269
+ appendRunTimelineEntry(projectRoot, runId, value);
6275
6270
  touchAuthorityRun(projectRoot, runId);
6276
6271
  }
6277
6272
  function appendRunLog(projectRoot, runId, value) {
6278
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6273
+ appendRunLogEntry(projectRoot, runId, value);
6279
6274
  touchAuthorityRun(projectRoot, runId);
6280
6275
  }
6281
6276
  function appendRunAction(projectRoot, runId, value) {
6282
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6277
+ appendRunTimelineEntry(projectRoot, runId, {
6283
6278
  id: value.id,
6284
6279
  type: "action",
6285
6280
  actionType: value.actionType,
@@ -6500,7 +6495,7 @@ import { resolve as resolve21 } from "path";
6500
6495
  import {
6501
6496
  listAuthorityRuns as listAuthorityRuns2,
6502
6497
  readAuthorityRun as readAuthorityRun3,
6503
- resolveAuthorityRunDir as resolveAuthorityRunDir4,
6498
+ resolveAuthorityRunDir as resolveAuthorityRunDir3,
6504
6499
  resolveTaskArtifactDirs
6505
6500
  } from "@rig/runtime/control-plane/authority-files";
6506
6501
  import { changedFilesForTask } from "@rig/runtime/control-plane/native/task-ops";
@@ -6534,7 +6529,7 @@ async function executeInspect(context, args) {
6534
6529
  }
6535
6530
  return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: serverRun.runId, source: "server", entries } };
6536
6531
  }
6537
- const logsPath = resolve21(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6532
+ const logsPath = resolve21(resolveAuthorityRunDir3(context.projectRoot, latestRun.runId), "logs.jsonl");
6538
6533
  if (!existsSync13(logsPath)) {
6539
6534
  throw new CliError2(`No logs found for run ${latestRun.runId}.`);
6540
6535
  }
@@ -7264,7 +7259,7 @@ init__parsers();
7264
7259
  import { createInterface as createInterface2 } from "readline/promises";
7265
7260
  import {
7266
7261
  listAuthorityRuns as listAuthorityRuns3,
7267
- readAuthorityRun as readAuthorityRun4
7262
+ readAuthorityRun as readAuthorityRun5
7268
7263
  } from "@rig/runtime/control-plane/authority-files";
7269
7264
  import {
7270
7265
  cleanupRunState,
@@ -7280,6 +7275,144 @@ import {
7280
7275
  } from "@rig/runtime/control-plane/native/run-ops";
7281
7276
  import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
7282
7277
 
7278
+ // packages/cli/src/commands/_run-replay.ts
7279
+ import { existsSync as existsSync14, readdirSync as readdirSync2 } from "fs";
7280
+ import { join as join2, resolve as resolve22 } from "path";
7281
+ import {
7282
+ readAuthorityRun as readAuthorityRun4,
7283
+ readJsonlFile as readJsonlFile4,
7284
+ runLifecycleLogPath
7285
+ } from "@rig/runtime/control-plane/authority-files";
7286
+ function asRecord(value) {
7287
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7288
+ }
7289
+ function text2(value) {
7290
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
7291
+ }
7292
+ function snippet(value, max = 120) {
7293
+ const raw = text2(value);
7294
+ if (!raw)
7295
+ return null;
7296
+ const flat = raw.replace(/\s+/g, " ");
7297
+ return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;
7298
+ }
7299
+ function summarizeLifecycleEntry(entry) {
7300
+ const type = text2(entry.type) ?? "event";
7301
+ switch (type) {
7302
+ case "status": {
7303
+ const anchor = text2(entry.sessionId);
7304
+ return [
7305
+ `status \u2192 ${text2(entry.status) ?? "(unknown)"}`,
7306
+ snippet(entry.detail) ? `\u2014 ${snippet(entry.detail)}` : null,
7307
+ anchor ? `[session ${anchor}]` : null
7308
+ ].filter(Boolean).join(" ");
7309
+ }
7310
+ case "timeline-entry": {
7311
+ const payload = asRecord(entry.payload) ?? {};
7312
+ const kind = text2(payload.type) ?? "entry";
7313
+ const body = snippet(payload.title) ?? snippet(payload.text) ?? snippet(payload.detail);
7314
+ const state = text2(payload.state);
7315
+ return [`timeline ${kind}`, body ? `\u2014 ${body}` : null, state ? `(${state})` : null].filter(Boolean).join(" ");
7316
+ }
7317
+ case "log-entry": {
7318
+ const payload = asRecord(entry.payload) ?? {};
7319
+ const title = snippet(payload.title) ?? "log";
7320
+ const detail = snippet(payload.detail);
7321
+ return [`log ${title}`, detail ? `\u2014 ${detail}` : null].filter(Boolean).join(" ");
7322
+ }
7323
+ case "record-patch": {
7324
+ const patch = asRecord(entry.patch) ?? {};
7325
+ const keys = Object.keys(patch);
7326
+ const shown = keys.slice(0, 8).join(", ");
7327
+ return `record-patch {${shown}${keys.length > 8 ? `, +${keys.length - 8} more` : ""}}`;
7328
+ }
7329
+ case "timeline":
7330
+ return "timeline updated (signal)";
7331
+ case "log":
7332
+ return `log signal${snippet(entry.title) ? ` \u2014 ${snippet(entry.title)}` : ""}`;
7333
+ case "completed":
7334
+ return "run completed";
7335
+ case "failed":
7336
+ return `run failed${snippet(entry.error) ? ` \u2014 ${snippet(entry.error)}` : ""}`;
7337
+ default:
7338
+ return type;
7339
+ }
7340
+ }
7341
+ function summarizeSessionEntry(entry) {
7342
+ const type = text2(entry.type) ?? "entry";
7343
+ const message2 = asRecord(entry.message);
7344
+ const role = text2(message2?.role);
7345
+ const content = message2?.content;
7346
+ let body = null;
7347
+ if (typeof content === "string") {
7348
+ body = snippet(content);
7349
+ } else if (Array.isArray(content)) {
7350
+ body = snippet(content.map((part) => text2(asRecord(part)?.text) ?? "").filter(Boolean).join(" "));
7351
+ }
7352
+ return [
7353
+ `pi ${type}`,
7354
+ role ? `(${role})` : null,
7355
+ body ? `\u2014 ${body}` : null
7356
+ ].filter(Boolean).join(" ");
7357
+ }
7358
+ function sessionEntryTimestamp(entry) {
7359
+ return text2(entry.timestamp) ?? text2(entry.at) ?? text2(entry.createdAt) ?? null;
7360
+ }
7361
+ function resolveRunSessionFile(record) {
7362
+ const piSession = record?.piSession ?? null;
7363
+ if (!piSession)
7364
+ return null;
7365
+ const recorded = text2(piSession.sessionFile);
7366
+ if (recorded && existsSync14(recorded)) {
7367
+ return recorded;
7368
+ }
7369
+ const cwd = text2(piSession.cwd);
7370
+ const sessionId = text2(piSession.sessionId);
7371
+ if (!cwd || !sessionId)
7372
+ return null;
7373
+ const sessionDir = resolve22(cwd, ".rig", "session");
7374
+ try {
7375
+ const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
7376
+ return match ? join2(sessionDir, match) : null;
7377
+ } catch {
7378
+ return null;
7379
+ }
7380
+ }
7381
+ function buildRunReplay(projectRoot, runId, options = {}) {
7382
+ const logPath = runLifecycleLogPath(projectRoot, runId);
7383
+ const record = readAuthorityRun4(projectRoot, runId);
7384
+ const lifecycleEntries = readJsonlFile4(logPath).map((entry) => asRecord(entry)).filter((entry) => entry !== null);
7385
+ const merged = lifecycleEntries.map((entry) => ({
7386
+ at: text2(entry.at),
7387
+ source: "run",
7388
+ summary: summarizeLifecycleEntry(entry)
7389
+ }));
7390
+ let sessionFile = null;
7391
+ let sessionEntryCount = 0;
7392
+ if (options.withSession) {
7393
+ sessionFile = resolveRunSessionFile(record);
7394
+ if (sessionFile) {
7395
+ let lastSeenAt = null;
7396
+ const sessionLines = readJsonlFile4(sessionFile).map((entry) => asRecord(entry)).filter((entry) => entry !== null).map((entry) => {
7397
+ lastSeenAt = sessionEntryTimestamp(entry) ?? lastSeenAt;
7398
+ return { at: lastSeenAt, source: "session", summary: summarizeSessionEntry(entry) };
7399
+ });
7400
+ sessionEntryCount = sessionLines.length;
7401
+ merged.push(...sessionLines);
7402
+ merged.sort((left, right) => (left.at ?? "").localeCompare(right.at ?? ""));
7403
+ }
7404
+ }
7405
+ const lines = merged.map((line) => `${line.at ?? "(no timestamp) "} ${line.source === "run" ? "run " : "session"} ${line.summary}`);
7406
+ return {
7407
+ runId,
7408
+ logPath,
7409
+ sessionFile,
7410
+ entryCount: lifecycleEntries.length,
7411
+ sessionEntryCount,
7412
+ lines
7413
+ };
7414
+ }
7415
+
7283
7416
  // packages/cli/src/commands/_operator-surface.ts
7284
7417
  import { createInterface } from "readline";
7285
7418
  import { createInterface as createPromptInterface } from "readline/promises";
@@ -7378,22 +7511,22 @@ function createPiRunStreamRenderer(output = process.stdout) {
7378
7511
  for (const [index, entry] of entries.entries()) {
7379
7512
  const id = entryId(entry, `timeline:${index}:${String(entry.cursor ?? "")}`);
7380
7513
  if (entry.type === "assistant_message" && typeof entry.text === "string") {
7381
- const text2 = entry.text;
7514
+ const text3 = entry.text;
7382
7515
  const previousText = assistantTextById.get(id) ?? "";
7383
- if (!previousText && text2.trim()) {
7516
+ if (!previousText && text3.trim()) {
7384
7517
  writeLine("[Pi assistant]");
7385
7518
  }
7386
- if (text2.startsWith(previousText)) {
7387
- const delta = text2.slice(previousText.length);
7519
+ if (text3.startsWith(previousText)) {
7520
+ const delta = text3.slice(previousText.length);
7388
7521
  if (delta)
7389
7522
  output.write(delta);
7390
- } else if (text2.trim() && text2 !== previousText) {
7523
+ } else if (text3.trim() && text3 !== previousText) {
7391
7524
  if (previousText)
7392
7525
  writeLine(`
7393
7526
  [Pi assistant]`);
7394
- output.write(text2);
7527
+ output.write(text3);
7395
7528
  }
7396
- assistantTextById.set(id, text2);
7529
+ assistantTextById.set(id, text3);
7397
7530
  continue;
7398
7531
  }
7399
7532
  if (seenTimeline.has(id))
@@ -7408,15 +7541,15 @@ function createPiRunStreamRenderer(output = process.stdout) {
7408
7541
  continue;
7409
7542
  }
7410
7543
  if (entry.type === "action") {
7411
- const text2 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7412
- if (text2)
7413
- writeLine(`[Rig action] ${text2}`);
7544
+ const text3 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7545
+ if (text3)
7546
+ writeLine(`[Rig action] ${text3}`);
7414
7547
  continue;
7415
7548
  }
7416
7549
  if (entry.type === "user_message") {
7417
- const text2 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7418
- if (text2)
7419
- writeLine(`[Operator] ${text2}`);
7550
+ const text3 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7551
+ if (text3)
7552
+ writeLine(`[Operator] ${text3}`);
7420
7553
  continue;
7421
7554
  }
7422
7555
  const fallback = String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? "").trim();
@@ -7496,7 +7629,7 @@ async function promptForTaskSelection(question) {
7496
7629
  // packages/cli/src/commands/_pi-frontend.ts
7497
7630
  import { mkdtempSync, rmSync as rmSync5 } from "fs";
7498
7631
  import { tmpdir } from "os";
7499
- import { join as join2 } from "path";
7632
+ import { join as join3 } from "path";
7500
7633
  import {
7501
7634
  createAgentSessionFromServices,
7502
7635
  createAgentSessionServices,
@@ -7628,15 +7761,15 @@ class RigRemoteSessionController {
7628
7761
  for (const compaction of this.pendingCompactions.splice(0))
7629
7762
  compaction.reject(new Error("Remote session closed."));
7630
7763
  }
7631
- async sendPrompt(text2, streamingBehavior) {
7632
- await this.transport.sendPrompt(this.context, this.runId, text2, streamingBehavior);
7764
+ async sendPrompt(text3, streamingBehavior) {
7765
+ await this.transport.sendPrompt(this.context, this.runId, text3, streamingBehavior);
7633
7766
  }
7634
- async sendCommand(text2) {
7635
- const result = await this.transport.runCommand(this.context, this.runId, text2);
7767
+ async sendCommand(text3) {
7768
+ const result = await this.transport.runCommand(this.context, this.runId, text3);
7636
7769
  return typeof result.message === "string" ? result.message : "worker command accepted";
7637
7770
  }
7638
- async sendShell(text2) {
7639
- await this.transport.sendShell(this.context, this.runId, text2);
7771
+ async sendShell(text3) {
7772
+ await this.transport.sendShell(this.context, this.runId, text3);
7640
7773
  }
7641
7774
  async abort() {
7642
7775
  await this.transport.abort(this.context, this.runId);
@@ -7788,8 +7921,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7788
7921
  replaceRemoteMessages(messages) {
7789
7922
  this.agent.state.messages = messages;
7790
7923
  }
7791
- async expandLocalInput(text2) {
7792
- let current = text2;
7924
+ async expandLocalInput(text3) {
7925
+ let current = text3;
7793
7926
  const runner = this.extensionRunner;
7794
7927
  if (runner.hasHandlers("input")) {
7795
7928
  const result = await runner.emitInput(current, undefined, "interactive");
@@ -7802,8 +7935,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7802
7935
  current = expandPromptTemplate(current, [...this.promptTemplates]);
7803
7936
  return current;
7804
7937
  }
7805
- async prompt(text2, options) {
7806
- const trimmed = text2.trim();
7938
+ async prompt(text3, options) {
7939
+ const trimmed = text3.trim();
7807
7940
  if (!trimmed)
7808
7941
  return;
7809
7942
  if (trimmed.startsWith("/")) {
@@ -7832,8 +7965,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7832
7965
  options?.preflightResult?.(true);
7833
7966
  await this.remote.sendPrompt(expanded, behavior);
7834
7967
  }
7835
- async steer(text2) {
7836
- const trimmed = text2.trim();
7968
+ async steer(text3) {
7969
+ const trimmed = text3.trim();
7837
7970
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7838
7971
  return;
7839
7972
  const expanded = await this.expandLocalInput(trimmed);
@@ -7841,8 +7974,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7841
7974
  return;
7842
7975
  await this.remote.sendPrompt(expanded, "steer");
7843
7976
  }
7844
- async followUp(text2) {
7845
- const trimmed = text2.trim();
7977
+ async followUp(text3) {
7978
+ const trimmed = text3.trim();
7846
7979
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7847
7980
  return;
7848
7981
  const expanded = await this.expandLocalInput(trimmed);
@@ -7854,8 +7987,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7854
7987
  await this.remote.abort();
7855
7988
  }
7856
7989
  async compact(customInstructions) {
7857
- const pending = new Promise((resolve22, reject) => {
7858
- this.remote.registerPendingCompaction({ resolve: resolve22, reject });
7990
+ const pending = new Promise((resolve23, reject) => {
7991
+ this.remote.registerPendingCompaction({ resolve: resolve23, reject });
7859
7992
  });
7860
7993
  await this.remote.sendCommand(`/compact${customInstructions ? ` ${customInstructions}` : ""}`);
7861
7994
  return pending;
@@ -7924,8 +8057,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7924
8057
  function createRemoteBashOperations(controller, excludeFromContext) {
7925
8058
  return {
7926
8059
  exec(command, _cwd, execOptions) {
7927
- return new Promise((resolve22, reject) => {
7928
- const pending = { onData: execOptions.onData, resolve: resolve22, reject, sawChunk: false };
8060
+ return new Promise((resolve23, reject) => {
8061
+ const pending = { onData: execOptions.onData, resolve: resolve23, reject, sawChunk: false };
7929
8062
  const cleanup = () => {
7930
8063
  execOptions.signal?.removeEventListener("abort", onAbort);
7931
8064
  if (timer)
@@ -8089,8 +8222,8 @@ function createRigWorkerPiBridgeExtension(options) {
8089
8222
  const prefix = busy ? `${SPINNER_FRAMES[frame]} ` : connected ? "\u25CF " : "\u25CB ";
8090
8223
  ctx.ui.setStatus("rig-worker-pi", `${prefix}${statusText}`);
8091
8224
  };
8092
- const setStatus = (ctx, text2, isBusy) => {
8093
- statusText = text2;
8225
+ const setStatus = (ctx, text3, isBusy) => {
8226
+ statusText = text3;
8094
8227
  busy = isBusy;
8095
8228
  renderStatus(ctx);
8096
8229
  };
@@ -8134,7 +8267,7 @@ function createRigWorkerPiBridgeExtension(options) {
8134
8267
  ctx.ui.notify("Initial message sent to the worker Pi daemon.", "info");
8135
8268
  const nativeUi = ctx.ui;
8136
8269
  options.controller.setUiHooks({
8137
- onStatusText: (text2) => setStatus(ctx, text2, !connected),
8270
+ onStatusText: (text3) => setStatus(ctx, text3, !connected),
8138
8271
  onActivity: (label, detail) => {
8139
8272
  const active = label !== "idle" && !/complete|ready/i.test(label);
8140
8273
  setStatus(ctx, [label, detail].filter(Boolean).join(" \u2014 "), active);
@@ -8191,7 +8324,7 @@ function setTemporaryEnv(updates) {
8191
8324
  };
8192
8325
  }
8193
8326
  async function attachRunBundledPiFrontend(context, input) {
8194
- const tempSessionDir = mkdtempSync(join2(tmpdir(), "rig-pi-frontend-sessions-"));
8327
+ const tempSessionDir = mkdtempSync(join3(tmpdir(), "rig-pi-frontend-sessions-"));
8195
8328
  const restoreEnv = setTemporaryEnv({
8196
8329
  PI_CODING_AGENT_SESSION_DIR: tempSessionDir,
8197
8330
  PI_SKIP_VERSION_CHECK: "1",
@@ -8511,7 +8644,7 @@ async function executeRun(context, args) {
8511
8644
  if (!runId) {
8512
8645
  throw new CliError2("run show requires a run id.");
8513
8646
  }
8514
- const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8647
+ const record = readAuthorityRun5(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8515
8648
  if (!record) {
8516
8649
  throw new CliError2(`Run not found: ${runId}`, 2);
8517
8650
  }
@@ -8549,6 +8682,46 @@ async function executeRun(context, args) {
8549
8682
  }
8550
8683
  return { ok: true, group: "run", command, details: { runId: run.value, events, cursor } };
8551
8684
  }
8685
+ case "replay": {
8686
+ let pending = rest;
8687
+ const run = takeOption(pending, "--run");
8688
+ pending = run.rest;
8689
+ const withSession = takeFlag(pending, "--with-session");
8690
+ pending = withSession.rest;
8691
+ const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
8692
+ const extra = positionalRunId ? pending.slice(1) : pending;
8693
+ requireNoExtraArgs(extra, "rig run replay <id>|--run <id> [--with-session]");
8694
+ const runId = run.value ?? positionalRunId;
8695
+ if (!runId) {
8696
+ throw new CliError2("run replay requires a run id.", 2);
8697
+ }
8698
+ const replay = buildRunReplay(context.projectRoot, runId, { withSession: withSession.value });
8699
+ if (replay.entryCount === 0 && replay.sessionEntryCount === 0) {
8700
+ throw new CliError2(`No run.jsonl lifecycle log found for ${runId} (looked at ${replay.logPath}).`, 2);
8701
+ }
8702
+ if (context.outputMode === "text") {
8703
+ console.log(`Replay of ${runId} (${replay.entryCount} lifecycle entries${withSession.value ? `, ${replay.sessionEntryCount} session entries` : ""}):`);
8704
+ for (const line of replay.lines) {
8705
+ console.log(line);
8706
+ }
8707
+ if (withSession.value && !replay.sessionFile) {
8708
+ console.log("(no Pi session file resolvable from the run record; showing run.jsonl only)");
8709
+ }
8710
+ }
8711
+ return {
8712
+ ok: true,
8713
+ group: "run",
8714
+ command,
8715
+ details: {
8716
+ runId,
8717
+ logPath: replay.logPath,
8718
+ sessionFile: replay.sessionFile,
8719
+ entryCount: replay.entryCount,
8720
+ sessionEntryCount: replay.sessionEntryCount,
8721
+ lines: replay.lines
8722
+ }
8723
+ };
8724
+ }
8552
8725
  case "attach": {
8553
8726
  let pending = rest;
8554
8727
  const runOption = takeOption(pending, "--run");
@@ -8871,7 +9044,7 @@ async function executeServer(context, args, options) {
8871
9044
  init_runner();
8872
9045
  import { readFileSync as readFileSync10 } from "fs";
8873
9046
  import { spawnSync as spawnSync3 } from "child_process";
8874
- import { resolve as resolve22 } from "path";
9047
+ import { resolve as resolve23 } from "path";
8875
9048
  import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8876
9049
  import {
8877
9050
  taskArtifactDir,
@@ -9049,6 +9222,7 @@ var PRIMARY_GROUPS = [
9049
9222
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
9050
9223
  { command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
9051
9224
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
9225
+ { 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." },
9052
9226
  { command: "resume", description: "Resume the most recent interrupted local run." },
9053
9227
  { command: "restart", description: "Restart the most recent local run from a clean runtime." },
9054
9228
  { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
@@ -9636,7 +9810,7 @@ async function executeTask(context, args, options) {
9636
9810
  const fileFlag = takeOption(rest.slice(1), "--file");
9637
9811
  let content;
9638
9812
  if (fileFlag.value) {
9639
- content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
9813
+ content = readFileSync10(resolve23(context.projectRoot, fileFlag.value), "utf-8");
9640
9814
  } else {
9641
9815
  content = await readStdin();
9642
9816
  }
@@ -9870,8 +10044,8 @@ async function executeTask(context, args, options) {
9870
10044
 
9871
10045
  // packages/cli/src/commands/task-run-driver.ts
9872
10046
  init_runner();
9873
- import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9874
- import { resolve as resolve23 } from "path";
10047
+ import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
10048
+ import { resolve as resolve24 } from "path";
9875
10049
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
9876
10050
  import { createInterface as createLineInterface } from "readline";
9877
10051
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -9895,7 +10069,7 @@ import {
9895
10069
  isCodexExecRecord
9896
10070
  } from "@rig/runtime/control-plane/provider/codex-exec-records";
9897
10071
  import { resolvePreferredShellBinary } from "@rig/runtime/control-plane/native/run-ops";
9898
- import { readAuthorityRun as readAuthorityRun5, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
10072
+ import { readAuthorityRun as readAuthorityRun6, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
9899
10073
  import {
9900
10074
  buildTaskRunLifecycleComment
9901
10075
  } from "@rig/runtime/control-plane/tasks/source-lifecycle";
@@ -9955,12 +10129,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
9955
10129
  return 0;
9956
10130
  let copied = 0;
9957
10131
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
9958
- const sourcePath = resolve23(sourceRoot, relativePath);
9959
- const targetPath = resolve23(targetRoot, relativePath);
10132
+ const sourcePath = resolve24(sourceRoot, relativePath);
10133
+ const targetPath = resolve24(targetRoot, relativePath);
9960
10134
  try {
9961
10135
  if (!statSync2(sourcePath).isFile())
9962
10136
  continue;
9963
- mkdirSync9(resolve23(targetPath, ".."), { recursive: true });
10137
+ mkdirSync9(resolve24(targetPath, ".."), { recursive: true });
9964
10138
  copyFileSync3(sourcePath, targetPath);
9965
10139
  copied += 1;
9966
10140
  } catch {}
@@ -9999,7 +10173,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
9999
10173
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
10000
10174
  return {
10001
10175
  RIG_BASELINE_MODE: "dirty-snapshot",
10002
- RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
10176
+ RIG_DIRTY_BASELINE_READY_FILE: resolve24(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
10003
10177
  };
10004
10178
  }
10005
10179
  function positiveInt(value, fallback) {
@@ -10104,9 +10278,9 @@ function createCommandRunner(binary) {
10104
10278
  const stderrChunks = [];
10105
10279
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
10106
10280
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
10107
- return await new Promise((resolve24) => {
10108
- child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
10109
- child.once("close", (code) => resolve24({
10281
+ return await new Promise((resolve25) => {
10282
+ child.once("error", (error) => resolve25({ exitCode: 1, stderr: error.message }));
10283
+ child.once("close", (code) => resolve25({
10110
10284
  exitCode: code ?? 1,
10111
10285
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
10112
10286
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -10180,7 +10354,7 @@ async function runTaskRunPostValidationLifecycle(input) {
10180
10354
  config,
10181
10355
  sourceTask: input.sourceTask,
10182
10356
  uploadedSnapshot: input.uploadedSnapshot,
10183
- artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
10357
+ artifactRoot: resolve24(input.projectRoot, "artifacts", taskId3),
10184
10358
  command: ghCommand,
10185
10359
  gitCommand,
10186
10360
  steerPi,
@@ -10310,7 +10484,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
10310
10484
  return null;
10311
10485
  }
10312
10486
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
10313
- const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
10487
+ const summary = readJsonFile3(resolve24(artifactDir, "validation-summary.json"), null);
10314
10488
  if (!summary || summary.status !== "fail") {
10315
10489
  continue;
10316
10490
  }
@@ -10391,9 +10565,9 @@ function readTaskRunAcceptedArtifactState(input) {
10391
10565
  if (!input.taskId || !input.workspaceDir) {
10392
10566
  return { accepted: false, reason: null };
10393
10567
  }
10394
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10395
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10396
- const taskResultPath = resolve23(artifactDir, "task-result.json");
10568
+ const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
10569
+ const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
10570
+ const taskResultPath = resolve24(artifactDir, "task-result.json");
10397
10571
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10398
10572
  if (reviewStatus !== "APPROVED") {
10399
10573
  return { accepted: false, reason: null };
@@ -10430,12 +10604,12 @@ function resolveTaskRunRetryContext(input) {
10430
10604
  if (!input.taskId || !input.workspaceDir) {
10431
10605
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
10432
10606
  }
10433
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10434
- const reviewStatePath = resolve23(artifactDir, "review-state.json");
10435
- const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
10436
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10437
- const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10438
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
10607
+ const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
10608
+ const reviewStatePath = resolve24(artifactDir, "review-state.json");
10609
+ const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
10610
+ const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
10611
+ const failedApproachesPath = resolve24(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10612
+ const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
10439
10613
  const reviewState = readJsonFile3(reviewStatePath, null);
10440
10614
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10441
10615
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -10621,7 +10795,7 @@ function appendToolTimelineFromLog(input) {
10621
10795
  });
10622
10796
  }
10623
10797
  function readTaskRunReviewStatus(reviewStatusPath) {
10624
- if (!existsSync14(reviewStatusPath)) {
10798
+ if (!existsSync15(reviewStatusPath)) {
10625
10799
  return null;
10626
10800
  }
10627
10801
  try {
@@ -10701,7 +10875,7 @@ async function updateTaskSourceAfterDriverRun(projectRoot, runId, taskId3, sourc
10701
10875
  }
10702
10876
  }
10703
10877
  function readRunSourceTaskContract(projectRoot, runId, taskId3) {
10704
- const run = readAuthorityRun5(projectRoot, runId);
10878
+ const run = readAuthorityRun6(projectRoot, runId);
10705
10879
  const raw = run?.sourceTask;
10706
10880
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
10707
10881
  return null;
@@ -10742,8 +10916,10 @@ async function executeRigOwnedTaskRun(context, input) {
10742
10916
  process.stderr.on("error", () => {});
10743
10917
  configureRunEventSink(context.projectRoot);
10744
10918
  const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
10745
- const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
10919
+ const existingRunRecord = readAuthorityRun6(context.projectRoot, input.runId);
10746
10920
  const resumeMode = process.env.RIG_RUN_RESUME === "1";
10921
+ let latestPiSessionId = typeof existingRunRecord?.piSession?.sessionId === "string" && existingRunRecord.piSession.sessionId.trim() ? existingRunRecord.piSession.sessionId : null;
10922
+ const sessionAnchor = () => latestPiSessionId ? { sessionId: latestPiSessionId } : {};
10747
10923
  const resumePreviousStatus = String(existingRunRecord?.status ?? "").toLowerCase();
10748
10924
  const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
10749
10925
  let prompt = buildRunPrompt({
@@ -10816,7 +10992,8 @@ async function executeRigOwnedTaskRun(context, input) {
10816
10992
  type: "status",
10817
10993
  runId: input.runId,
10818
10994
  status: "preparing",
10819
- detail: input.taskId ?? input.title ?? runtimeTaskId
10995
+ detail: input.taskId ?? input.title ?? runtimeTaskId,
10996
+ ...sessionAnchor()
10820
10997
  });
10821
10998
  appendRunLog(context.projectRoot, input.runId, {
10822
10999
  id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
@@ -10842,15 +11019,15 @@ async function executeRigOwnedTaskRun(context, input) {
10842
11019
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
10843
11020
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
10844
11021
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
10845
- const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
11022
+ const planningArtifactPath = resolve24("artifacts", runtimeTaskId, "implementation-plan.md");
10846
11023
  const persistedPlanning = {
10847
11024
  ...planningClassification,
10848
11025
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
10849
11026
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
10850
11027
  classifiedAt: new Date().toISOString()
10851
11028
  };
10852
- mkdirSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10853
- writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
11029
+ mkdirSync9(resolve24(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
11030
+ writeFileSync7(resolve24(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10854
11031
  `, "utf8");
10855
11032
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
10856
11033
  prompt = `${prompt}
@@ -10900,7 +11077,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10900
11077
  let verificationStarted = false;
10901
11078
  let reviewStarted = false;
10902
11079
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
10903
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
11080
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve24(existingRunRecord.sessionPath, "..") : null;
10904
11081
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
10905
11082
  let latestProviderCommand = null;
10906
11083
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -10937,7 +11114,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10937
11114
  return;
10938
11115
  verificationStarted = true;
10939
11116
  patchAuthorityRun(context.projectRoot, input.runId, { status: "validating" });
10940
- emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null });
11117
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null, ...sessionAnchor() });
10941
11118
  verificationAction = startRunAction(context.projectRoot, input.runId, {
10942
11119
  actionId: `action:${input.runId}:completion-verification`,
10943
11120
  actionType: "completion-verification",
@@ -10950,7 +11127,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10950
11127
  return;
10951
11128
  reviewStarted = true;
10952
11129
  patchAuthorityRun(context.projectRoot, input.runId, { status: "reviewing" });
10953
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null });
11130
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null, ...sessionAnchor() });
10954
11131
  reviewAction = startRunAction(context.projectRoot, input.runId, {
10955
11132
  actionId: `action:${input.runId}:review-closeout`,
10956
11133
  actionType: "run.review",
@@ -10986,10 +11163,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10986
11163
  patchAuthorityRun(context.projectRoot, input.runId, {
10987
11164
  status: "running",
10988
11165
  worktreePath: latestRuntimeWorkspace,
10989
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
11166
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve24(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10990
11167
  logRoot: latestLogsDir,
10991
- sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
10992
- sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
11168
+ sessionPath: latestSessionDir ? resolve24(latestSessionDir, "session.json") : null,
11169
+ sessionLogPath: latestLogsDir ? resolve24(latestLogsDir, "agent-stdout.log") : null,
10993
11170
  branch: runtimeId
10994
11171
  });
10995
11172
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -10997,7 +11174,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10997
11174
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
10998
11175
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
10999
11176
  if (readyFile) {
11000
- mkdirSync9(resolve23(readyFile, ".."), { recursive: true });
11177
+ mkdirSync9(resolve24(readyFile, ".."), { recursive: true });
11001
11178
  writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
11002
11179
  `, "utf8");
11003
11180
  }
@@ -11040,7 +11217,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11040
11217
  type: "status",
11041
11218
  runId: input.runId,
11042
11219
  status: "running",
11043
- detail: latestRuntimeWorkspace
11220
+ detail: latestRuntimeWorkspace,
11221
+ ...sessionAnchor()
11044
11222
  });
11045
11223
  return true;
11046
11224
  }
@@ -11123,6 +11301,9 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11123
11301
  piSessionPrivate: privateMetadata
11124
11302
  });
11125
11303
  const sessionId = typeof publicMetadata?.sessionId === "string" ? publicMetadata.sessionId : typeof privateMetadata.public === "object" && privateMetadata.public && !Array.isArray(privateMetadata.public) ? String(privateMetadata.public.sessionId ?? "") : "";
11304
+ if (sessionId) {
11305
+ latestPiSessionId = sessionId;
11306
+ }
11126
11307
  appendRunLog(context.projectRoot, input.runId, {
11127
11308
  id: `log:${input.runId}:pi-session-ready`,
11128
11309
  title: "Worker Pi session ready",
@@ -11382,7 +11563,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11382
11563
  let acceptedArtifactObservedAt = null;
11383
11564
  let acceptedArtifactPollTimer = null;
11384
11565
  let acceptedArtifactKillTimer = null;
11385
- const attemptExit = await new Promise((resolve24) => {
11566
+ const attemptExit = await new Promise((resolve25) => {
11386
11567
  let settled = false;
11387
11568
  const settle = (result) => {
11388
11569
  if (settled)
@@ -11390,7 +11571,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11390
11571
  settled = true;
11391
11572
  if (acceptedArtifactPollTimer)
11392
11573
  clearInterval(acceptedArtifactPollTimer);
11393
- resolve24(result);
11574
+ resolve25(result);
11394
11575
  };
11395
11576
  const pollAcceptedArtifacts = () => {
11396
11577
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -11517,7 +11698,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11517
11698
  type: "status",
11518
11699
  runId: input.runId,
11519
11700
  status: "validating",
11520
- detail: failureDetail
11701
+ detail: failureDetail,
11702
+ ...sessionAnchor()
11521
11703
  });
11522
11704
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Validate failed" });
11523
11705
  emitServerRunEvent({ type: "log", runId: input.runId, title: `Steering Pi to retry validation (attempt ${attempt + 1}/${maxAttempts})` });
@@ -11592,8 +11774,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11592
11774
  }
11593
11775
  if (planningClassification.planningRequired) {
11594
11776
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
11595
- const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
11596
- if (!existsSync14(expectedPlanPath)) {
11777
+ const expectedPlanPath = resolve24(planWorkspace, planningArtifactPath);
11778
+ if (!existsSync15(expectedPlanPath)) {
11597
11779
  const failedAt = new Date().toISOString();
11598
11780
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
11599
11781
  patchAuthorityRun(context.projectRoot, input.runId, {
@@ -11655,7 +11837,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11655
11837
  payload: { runtimeWorkspace: latestRuntimeWorkspace, branch: latestRuntimeBranch }
11656
11838
  });
11657
11839
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Server-owned closeout requested" });
11658
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested." });
11840
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested.", ...sessionAnchor() });
11659
11841
  await context.emitEvent("command.finished", {
11660
11842
  command: [
11661
11843
  "rig",
@@ -11763,9 +11945,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11763
11945
  });
11764
11946
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
11765
11947
  });
11766
- const exitCode = await new Promise((resolve24) => {
11767
- child.once("error", () => resolve24(1));
11768
- child.once("close", (code) => resolve24(code ?? 1));
11948
+ const exitCode = await new Promise((resolve25) => {
11949
+ child.once("error", () => resolve25(1));
11950
+ child.once("close", (code) => resolve25(code ?? 1));
11769
11951
  });
11770
11952
  for (const pendingLog of flushPendingClaudeToolUseLogs({
11771
11953
  runId: input.runId,
@@ -11907,8 +12089,8 @@ async function executeTest(context, args) {
11907
12089
 
11908
12090
  // packages/cli/src/commands/setup.ts
11909
12091
  init_runner();
11910
- import { existsSync as existsSync15, mkdirSync as mkdirSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
11911
- import { resolve as resolve24 } from "path";
12092
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, readdirSync as readdirSync3, writeFileSync as writeFileSync8 } from "fs";
12093
+ import { resolve as resolve25 } from "path";
11912
12094
  import { createPluginHost } from "@rig/core";
11913
12095
  import {
11914
12096
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -11966,8 +12148,8 @@ function runSetupInit(projectRoot) {
11966
12148
  mkdirSync10(stateDir, { recursive: true });
11967
12149
  mkdirSync10(logsDir, { recursive: true });
11968
12150
  mkdirSync10(artifactsDir, { recursive: true });
11969
- const failuresPath = resolve24(stateDir, "failed_approaches.md");
11970
- if (!existsSync15(failuresPath)) {
12151
+ const failuresPath = resolve25(stateDir, "failed_approaches.md");
12152
+ if (!existsSync16(failuresPath)) {
11971
12153
  writeFileSync8(failuresPath, `# Failed Approaches
11972
12154
 
11973
12155
  `, "utf-8");
@@ -11985,19 +12167,19 @@ async function runSetupCheck(projectRoot) {
11985
12167
  }
11986
12168
  async function runSetupPreflight(projectRoot) {
11987
12169
  await runSetupCheck(projectRoot);
11988
- const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11989
- if (existsSync15(validationRoot)) {
11990
- const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
12170
+ const validationRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
12171
+ if (existsSync16(validationRoot)) {
12172
+ const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11991
12173
  for (const validator of validators) {
11992
- const script = resolve24(validationRoot, validator.name, "validate.sh");
11993
- if (existsSync15(script)) {
12174
+ const script = resolve25(validationRoot, validator.name, "validate.sh");
12175
+ if (existsSync16(script)) {
11994
12176
  console.log(`OK: validator script ${script}`);
11995
12177
  }
11996
12178
  }
11997
12179
  }
11998
- const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11999
- if (existsSync15(hooksRoot)) {
12000
- const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
12180
+ const hooksRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
12181
+ if (existsSync16(hooksRoot)) {
12182
+ const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
12001
12183
  for (const hook of hooks) {
12002
12184
  console.log(`OK: hook ${hook}`);
12003
12185
  }
@@ -12141,7 +12323,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
12141
12323
  ]);
12142
12324
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
12143
12325
  function hasInitializedRigProject(projectRoot) {
12144
- return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
12326
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync17(resolve26(projectRoot, name))) || existsSync17(resolve26(projectRoot, ".rig"));
12145
12327
  }
12146
12328
  function requireInitializedRigProject(context, group) {
12147
12329
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -12194,8 +12376,8 @@ function resolveTopLevelLaunchState(context) {
12194
12376
  let selectedServer = null;
12195
12377
  if (projectInitialized) {
12196
12378
  try {
12197
- const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
12198
- if (existsSync16(statePath)) {
12379
+ const statePath = resolve26(context.projectRoot, ".rig", "state", "connection.json");
12380
+ if (existsSync17(statePath)) {
12199
12381
  const parsed = JSON.parse(readFileSync12(statePath, "utf-8"));
12200
12382
  selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
12201
12383
  }
@@ -12375,8 +12557,8 @@ var __testOnly = {
12375
12557
  validateRequiredBugPromptValue
12376
12558
  };
12377
12559
  // packages/cli/src/launcher.ts
12378
- import { existsSync as existsSync17 } from "fs";
12379
- import { basename as basename3, resolve as resolve26 } from "path";
12560
+ import { existsSync as existsSync18 } from "fs";
12561
+ import { basename as basename3, resolve as resolve27 } from "path";
12380
12562
  import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
12381
12563
  import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
12382
12564
  function parsePolicyMode(value) {
@@ -12389,7 +12571,7 @@ function parsePolicyMode(value) {
12389
12571
  throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
12390
12572
  }
12391
12573
  function hasRigProjectMarker(candidate) {
12392
- return existsSync17(resolve26(candidate, RIG_DEFINITION_DIRNAME)) || existsSync17(resolve26(candidate, RIG_STATE_DIRNAME)) || existsSync17(resolve26(candidate, "rig.config.ts")) || existsSync17(resolve26(candidate, "rig.config.json")) || existsSync17(resolve26(candidate, ".git"));
12574
+ return existsSync18(resolve27(candidate, RIG_DEFINITION_DIRNAME)) || existsSync18(resolve27(candidate, RIG_STATE_DIRNAME)) || existsSync18(resolve27(candidate, "rig.config.ts")) || existsSync18(resolve27(candidate, "rig.config.json")) || existsSync18(resolve27(candidate, ".git"));
12393
12575
  }
12394
12576
  function resolveProjectRoot({
12395
12577
  envProjectRoot,
@@ -12398,19 +12580,19 @@ function resolveProjectRoot({
12398
12580
  cwd = process.cwd()
12399
12581
  }) {
12400
12582
  if (envProjectRoot) {
12401
- return resolve26(cwd, envProjectRoot);
12583
+ return resolve27(cwd, envProjectRoot);
12402
12584
  }
12403
12585
  const fallbackImportDir = importDir ?? cwd;
12404
12586
  const execName = basename3(execPath).toLowerCase();
12405
- const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve26(execPath, "..", "..")] : [];
12406
- const candidates = [cwd, ...execCandidates, resolve26(fallbackImportDir, "..")];
12587
+ const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve27(execPath, "..", "..")] : [];
12588
+ const candidates = [cwd, ...execCandidates, resolve27(fallbackImportDir, "..")];
12407
12589
  for (const candidate of candidates) {
12408
12590
  const nearest = resolveNearestRigProjectRoot(candidate);
12409
12591
  if (hasRigProjectMarker(nearest)) {
12410
12592
  return nearest;
12411
12593
  }
12412
12594
  }
12413
- return resolve26(cwd);
12595
+ return resolve27(cwd);
12414
12596
  }
12415
12597
  function normalizeCliErrorCode(message2, isCliError) {
12416
12598
  if (message2.startsWith("Invalid --policy-mode value:")) {
@@ -12477,7 +12659,7 @@ async function runRigCli(module, options = {}) {
12477
12659
  runId: context.runId,
12478
12660
  outcome,
12479
12661
  eventsFile: context.eventBus.getEventsFile(),
12480
- policyFile: resolve26(projectRoot, "rig", "policy", "policy.json"),
12662
+ policyFile: resolve27(projectRoot, "rig", "policy", "policy.json"),
12481
12663
  policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
12482
12664
  }, null, 2));
12483
12665
  }