@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/bin/rig.js CHANGED
@@ -531,10 +531,10 @@ import { loadPolicy as loadPolicy3 } from "@rig/runtime/control-plane/runtime/gu
531
531
  // packages/cli/src/commands.ts
532
532
  init_runner();
533
533
  import {
534
- existsSync as existsSync16,
534
+ existsSync as existsSync17,
535
535
  readFileSync as readFileSync12
536
536
  } from "fs";
537
- import { resolve as resolve25 } from "path";
537
+ import { resolve as resolve26 } from "path";
538
538
  import { readBuildConfig } from "@rig/runtime/build-time-config";
539
539
 
540
540
  // packages/cli/src/commands/browser.ts
@@ -3621,8 +3621,7 @@ import { resolve as resolve12 } from "path";
3621
3621
  import {
3622
3622
  readAuthorityRun,
3623
3623
  readJsonlFile as readJsonlFile2,
3624
- resolveAuthorityRunDir,
3625
- writeJsonFile as writeJsonFile3
3624
+ writeAuthorityRunRecord
3626
3625
  } from "@rig/runtime/control-plane/authority-files";
3627
3626
  var RIG_WORKSPACE_ID = "rig-local-workspace";
3628
3627
  function normalizeRuntimeAdapter(value) {
@@ -3708,7 +3707,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3708
3707
  } else if ("errorText" in next) {
3709
3708
  delete next.errorText;
3710
3709
  }
3711
- writeJsonFile3(resolve12(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3710
+ writeAuthorityRunRecord(projectRoot, input.runId, next);
3712
3711
  return next;
3713
3712
  }
3714
3713
 
@@ -4272,7 +4271,7 @@ import { resolve as resolve15 } from "path";
4272
4271
  import {
4273
4272
  listAuthorityRuns,
4274
4273
  readJsonlFile as readJsonlFile3,
4275
- resolveAuthorityRunDir as resolveAuthorityRunDir2
4274
+ resolveAuthorityRunDir
4276
4275
  } from "@rig/runtime/control-plane/authority-files";
4277
4276
 
4278
4277
  // packages/cli/src/commands/_cli-format.ts
@@ -4670,7 +4669,7 @@ async function listRemoteInboxRecords(context, kind, filters) {
4670
4669
  function listLocalInboxRecords(context, kind, filters) {
4671
4670
  const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4672
4671
  const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4673
- return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4672
+ return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir(context.projectRoot, entry.runId), fileName)).map((record) => ({
4674
4673
  runId: entry.runId,
4675
4674
  taskId: entry.taskId ?? undefined,
4676
4675
  record
@@ -4718,7 +4717,7 @@ async function executeInbox(context, args) {
4718
4717
  if (isRemoteConnectionSelected(context.projectRoot)) {
4719
4718
  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);
4720
4719
  }
4721
- const approvalsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4720
+ const approvalsPath = resolve15(resolveAuthorityRunDir(context.projectRoot, run.value), "approvals.jsonl");
4722
4721
  const approvals = readJsonlFile3(approvalsPath);
4723
4722
  const resolvedAt = new Date().toISOString();
4724
4723
  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);
@@ -4774,7 +4773,7 @@ async function executeInbox(context, args) {
4774
4773
  const [key, ...restValue] = entry.split("=");
4775
4774
  return [key, restValue.join("=")];
4776
4775
  }));
4777
- const requestsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4776
+ const requestsPath = resolve15(resolveAuthorityRunDir(context.projectRoot, run.value), "user-input.jsonl");
4778
4777
  const requests = readJsonlFile3(requestsPath);
4779
4778
  const resolvedAt = new Date().toISOString();
4780
4779
  const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
@@ -6241,27 +6240,23 @@ init_runner();
6241
6240
  import { readFileSync as readFileSync8 } from "fs";
6242
6241
  import { resolve as resolve20 } from "path";
6243
6242
  import {
6244
- appendJsonlRecord as appendJsonlRecord2,
6245
6243
  appendRunLifecycleEvent,
6244
+ appendRunLogEntry,
6245
+ appendRunTimelineEntry,
6246
+ patchAuthorityRunRecord,
6246
6247
  readAuthorityRun as readAuthorityRun2,
6247
- resolveAuthorityRunDir as resolveAuthorityRunDir3,
6248
- writeJsonFile as writeJsonFile4
6248
+ resolveAuthorityRunDir as resolveAuthorityRunDir2,
6249
+ writeJsonFile as writeJsonFile3
6249
6250
  } from "@rig/runtime/control-plane/authority-files";
6250
6251
  import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
6251
6252
  import { readPriorPrProgressPromptSection } from "@rig/runtime/control-plane/prompt-context";
6252
6253
  import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
6253
6254
  import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
6254
6255
  function patchAuthorityRun(projectRoot, runId, patch) {
6255
- const current = readAuthorityRun2(projectRoot, runId);
6256
- if (!current) {
6256
+ const next = patchAuthorityRunRecord(projectRoot, runId, patch);
6257
+ if (!next) {
6257
6258
  throw new CliError2(`Run not found: ${runId}`, 2);
6258
6259
  }
6259
- const next = {
6260
- ...current,
6261
- ...patch,
6262
- updatedAt: new Date().toISOString()
6263
- };
6264
- writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6265
6260
  return next;
6266
6261
  }
6267
6262
  function touchAuthorityRun(projectRoot, runId) {
@@ -6269,21 +6264,21 @@ function touchAuthorityRun(projectRoot, runId) {
6269
6264
  if (!current) {
6270
6265
  return;
6271
6266
  }
6272
- writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6267
+ writeJsonFile3(resolve20(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), {
6273
6268
  ...current,
6274
6269
  updatedAt: new Date().toISOString()
6275
6270
  });
6276
6271
  }
6277
6272
  function appendRunTimeline(projectRoot, runId, value) {
6278
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6273
+ appendRunTimelineEntry(projectRoot, runId, value);
6279
6274
  touchAuthorityRun(projectRoot, runId);
6280
6275
  }
6281
6276
  function appendRunLog(projectRoot, runId, value) {
6282
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6277
+ appendRunLogEntry(projectRoot, runId, value);
6283
6278
  touchAuthorityRun(projectRoot, runId);
6284
6279
  }
6285
6280
  function appendRunAction(projectRoot, runId, value) {
6286
- appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6281
+ appendRunTimelineEntry(projectRoot, runId, {
6287
6282
  id: value.id,
6288
6283
  type: "action",
6289
6284
  actionType: value.actionType,
@@ -6504,7 +6499,7 @@ import { resolve as resolve21 } from "path";
6504
6499
  import {
6505
6500
  listAuthorityRuns as listAuthorityRuns2,
6506
6501
  readAuthorityRun as readAuthorityRun3,
6507
- resolveAuthorityRunDir as resolveAuthorityRunDir4,
6502
+ resolveAuthorityRunDir as resolveAuthorityRunDir3,
6508
6503
  resolveTaskArtifactDirs
6509
6504
  } from "@rig/runtime/control-plane/authority-files";
6510
6505
  import { changedFilesForTask } from "@rig/runtime/control-plane/native/task-ops";
@@ -6538,7 +6533,7 @@ async function executeInspect(context, args) {
6538
6533
  }
6539
6534
  return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: serverRun.runId, source: "server", entries } };
6540
6535
  }
6541
- const logsPath = resolve21(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6536
+ const logsPath = resolve21(resolveAuthorityRunDir3(context.projectRoot, latestRun.runId), "logs.jsonl");
6542
6537
  if (!existsSync13(logsPath)) {
6543
6538
  throw new CliError2(`No logs found for run ${latestRun.runId}.`);
6544
6539
  }
@@ -7268,7 +7263,7 @@ init__parsers();
7268
7263
  import { createInterface as createInterface2 } from "readline/promises";
7269
7264
  import {
7270
7265
  listAuthorityRuns as listAuthorityRuns3,
7271
- readAuthorityRun as readAuthorityRun4
7266
+ readAuthorityRun as readAuthorityRun5
7272
7267
  } from "@rig/runtime/control-plane/authority-files";
7273
7268
  import {
7274
7269
  cleanupRunState,
@@ -7284,6 +7279,144 @@ import {
7284
7279
  } from "@rig/runtime/control-plane/native/run-ops";
7285
7280
  import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
7286
7281
 
7282
+ // packages/cli/src/commands/_run-replay.ts
7283
+ import { existsSync as existsSync14, readdirSync as readdirSync2 } from "fs";
7284
+ import { join as join2, resolve as resolve22 } from "path";
7285
+ import {
7286
+ readAuthorityRun as readAuthorityRun4,
7287
+ readJsonlFile as readJsonlFile4,
7288
+ runLifecycleLogPath
7289
+ } from "@rig/runtime/control-plane/authority-files";
7290
+ function asRecord(value) {
7291
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7292
+ }
7293
+ function text2(value) {
7294
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
7295
+ }
7296
+ function snippet(value, max = 120) {
7297
+ const raw = text2(value);
7298
+ if (!raw)
7299
+ return null;
7300
+ const flat = raw.replace(/\s+/g, " ");
7301
+ return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;
7302
+ }
7303
+ function summarizeLifecycleEntry(entry) {
7304
+ const type = text2(entry.type) ?? "event";
7305
+ switch (type) {
7306
+ case "status": {
7307
+ const anchor = text2(entry.sessionId);
7308
+ return [
7309
+ `status \u2192 ${text2(entry.status) ?? "(unknown)"}`,
7310
+ snippet(entry.detail) ? `\u2014 ${snippet(entry.detail)}` : null,
7311
+ anchor ? `[session ${anchor}]` : null
7312
+ ].filter(Boolean).join(" ");
7313
+ }
7314
+ case "timeline-entry": {
7315
+ const payload = asRecord(entry.payload) ?? {};
7316
+ const kind = text2(payload.type) ?? "entry";
7317
+ const body = snippet(payload.title) ?? snippet(payload.text) ?? snippet(payload.detail);
7318
+ const state = text2(payload.state);
7319
+ return [`timeline ${kind}`, body ? `\u2014 ${body}` : null, state ? `(${state})` : null].filter(Boolean).join(" ");
7320
+ }
7321
+ case "log-entry": {
7322
+ const payload = asRecord(entry.payload) ?? {};
7323
+ const title = snippet(payload.title) ?? "log";
7324
+ const detail = snippet(payload.detail);
7325
+ return [`log ${title}`, detail ? `\u2014 ${detail}` : null].filter(Boolean).join(" ");
7326
+ }
7327
+ case "record-patch": {
7328
+ const patch = asRecord(entry.patch) ?? {};
7329
+ const keys = Object.keys(patch);
7330
+ const shown = keys.slice(0, 8).join(", ");
7331
+ return `record-patch {${shown}${keys.length > 8 ? `, +${keys.length - 8} more` : ""}}`;
7332
+ }
7333
+ case "timeline":
7334
+ return "timeline updated (signal)";
7335
+ case "log":
7336
+ return `log signal${snippet(entry.title) ? ` \u2014 ${snippet(entry.title)}` : ""}`;
7337
+ case "completed":
7338
+ return "run completed";
7339
+ case "failed":
7340
+ return `run failed${snippet(entry.error) ? ` \u2014 ${snippet(entry.error)}` : ""}`;
7341
+ default:
7342
+ return type;
7343
+ }
7344
+ }
7345
+ function summarizeSessionEntry(entry) {
7346
+ const type = text2(entry.type) ?? "entry";
7347
+ const message2 = asRecord(entry.message);
7348
+ const role = text2(message2?.role);
7349
+ const content = message2?.content;
7350
+ let body = null;
7351
+ if (typeof content === "string") {
7352
+ body = snippet(content);
7353
+ } else if (Array.isArray(content)) {
7354
+ body = snippet(content.map((part) => text2(asRecord(part)?.text) ?? "").filter(Boolean).join(" "));
7355
+ }
7356
+ return [
7357
+ `pi ${type}`,
7358
+ role ? `(${role})` : null,
7359
+ body ? `\u2014 ${body}` : null
7360
+ ].filter(Boolean).join(" ");
7361
+ }
7362
+ function sessionEntryTimestamp(entry) {
7363
+ return text2(entry.timestamp) ?? text2(entry.at) ?? text2(entry.createdAt) ?? null;
7364
+ }
7365
+ function resolveRunSessionFile(record) {
7366
+ const piSession = record?.piSession ?? null;
7367
+ if (!piSession)
7368
+ return null;
7369
+ const recorded = text2(piSession.sessionFile);
7370
+ if (recorded && existsSync14(recorded)) {
7371
+ return recorded;
7372
+ }
7373
+ const cwd = text2(piSession.cwd);
7374
+ const sessionId = text2(piSession.sessionId);
7375
+ if (!cwd || !sessionId)
7376
+ return null;
7377
+ const sessionDir = resolve22(cwd, ".rig", "session");
7378
+ try {
7379
+ const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
7380
+ return match ? join2(sessionDir, match) : null;
7381
+ } catch {
7382
+ return null;
7383
+ }
7384
+ }
7385
+ function buildRunReplay(projectRoot, runId, options = {}) {
7386
+ const logPath = runLifecycleLogPath(projectRoot, runId);
7387
+ const record = readAuthorityRun4(projectRoot, runId);
7388
+ const lifecycleEntries = readJsonlFile4(logPath).map((entry) => asRecord(entry)).filter((entry) => entry !== null);
7389
+ const merged = lifecycleEntries.map((entry) => ({
7390
+ at: text2(entry.at),
7391
+ source: "run",
7392
+ summary: summarizeLifecycleEntry(entry)
7393
+ }));
7394
+ let sessionFile = null;
7395
+ let sessionEntryCount = 0;
7396
+ if (options.withSession) {
7397
+ sessionFile = resolveRunSessionFile(record);
7398
+ if (sessionFile) {
7399
+ let lastSeenAt = null;
7400
+ const sessionLines = readJsonlFile4(sessionFile).map((entry) => asRecord(entry)).filter((entry) => entry !== null).map((entry) => {
7401
+ lastSeenAt = sessionEntryTimestamp(entry) ?? lastSeenAt;
7402
+ return { at: lastSeenAt, source: "session", summary: summarizeSessionEntry(entry) };
7403
+ });
7404
+ sessionEntryCount = sessionLines.length;
7405
+ merged.push(...sessionLines);
7406
+ merged.sort((left, right) => (left.at ?? "").localeCompare(right.at ?? ""));
7407
+ }
7408
+ }
7409
+ const lines = merged.map((line) => `${line.at ?? "(no timestamp) "} ${line.source === "run" ? "run " : "session"} ${line.summary}`);
7410
+ return {
7411
+ runId,
7412
+ logPath,
7413
+ sessionFile,
7414
+ entryCount: lifecycleEntries.length,
7415
+ sessionEntryCount,
7416
+ lines
7417
+ };
7418
+ }
7419
+
7287
7420
  // packages/cli/src/commands/_operator-surface.ts
7288
7421
  import { createInterface } from "readline";
7289
7422
  import { createInterface as createPromptInterface } from "readline/promises";
@@ -7382,22 +7515,22 @@ function createPiRunStreamRenderer(output = process.stdout) {
7382
7515
  for (const [index, entry] of entries.entries()) {
7383
7516
  const id = entryId(entry, `timeline:${index}:${String(entry.cursor ?? "")}`);
7384
7517
  if (entry.type === "assistant_message" && typeof entry.text === "string") {
7385
- const text2 = entry.text;
7518
+ const text3 = entry.text;
7386
7519
  const previousText = assistantTextById.get(id) ?? "";
7387
- if (!previousText && text2.trim()) {
7520
+ if (!previousText && text3.trim()) {
7388
7521
  writeLine("[Pi assistant]");
7389
7522
  }
7390
- if (text2.startsWith(previousText)) {
7391
- const delta = text2.slice(previousText.length);
7523
+ if (text3.startsWith(previousText)) {
7524
+ const delta = text3.slice(previousText.length);
7392
7525
  if (delta)
7393
7526
  output.write(delta);
7394
- } else if (text2.trim() && text2 !== previousText) {
7527
+ } else if (text3.trim() && text3 !== previousText) {
7395
7528
  if (previousText)
7396
7529
  writeLine(`
7397
7530
  [Pi assistant]`);
7398
- output.write(text2);
7531
+ output.write(text3);
7399
7532
  }
7400
- assistantTextById.set(id, text2);
7533
+ assistantTextById.set(id, text3);
7401
7534
  continue;
7402
7535
  }
7403
7536
  if (seenTimeline.has(id))
@@ -7412,15 +7545,15 @@ function createPiRunStreamRenderer(output = process.stdout) {
7412
7545
  continue;
7413
7546
  }
7414
7547
  if (entry.type === "action") {
7415
- const text2 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7416
- if (text2)
7417
- writeLine(`[Rig action] ${text2}`);
7548
+ const text3 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7549
+ if (text3)
7550
+ writeLine(`[Rig action] ${text3}`);
7418
7551
  continue;
7419
7552
  }
7420
7553
  if (entry.type === "user_message") {
7421
- const text2 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7422
- if (text2)
7423
- writeLine(`[Operator] ${text2}`);
7554
+ const text3 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7555
+ if (text3)
7556
+ writeLine(`[Operator] ${text3}`);
7424
7557
  continue;
7425
7558
  }
7426
7559
  const fallback = String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? "").trim();
@@ -7500,7 +7633,7 @@ async function promptForTaskSelection(question) {
7500
7633
  // packages/cli/src/commands/_pi-frontend.ts
7501
7634
  import { mkdtempSync, rmSync as rmSync5 } from "fs";
7502
7635
  import { tmpdir } from "os";
7503
- import { join as join2 } from "path";
7636
+ import { join as join3 } from "path";
7504
7637
  import {
7505
7638
  createAgentSessionFromServices,
7506
7639
  createAgentSessionServices,
@@ -7632,15 +7765,15 @@ class RigRemoteSessionController {
7632
7765
  for (const compaction of this.pendingCompactions.splice(0))
7633
7766
  compaction.reject(new Error("Remote session closed."));
7634
7767
  }
7635
- async sendPrompt(text2, streamingBehavior) {
7636
- await this.transport.sendPrompt(this.context, this.runId, text2, streamingBehavior);
7768
+ async sendPrompt(text3, streamingBehavior) {
7769
+ await this.transport.sendPrompt(this.context, this.runId, text3, streamingBehavior);
7637
7770
  }
7638
- async sendCommand(text2) {
7639
- const result = await this.transport.runCommand(this.context, this.runId, text2);
7771
+ async sendCommand(text3) {
7772
+ const result = await this.transport.runCommand(this.context, this.runId, text3);
7640
7773
  return typeof result.message === "string" ? result.message : "worker command accepted";
7641
7774
  }
7642
- async sendShell(text2) {
7643
- await this.transport.sendShell(this.context, this.runId, text2);
7775
+ async sendShell(text3) {
7776
+ await this.transport.sendShell(this.context, this.runId, text3);
7644
7777
  }
7645
7778
  async abort() {
7646
7779
  await this.transport.abort(this.context, this.runId);
@@ -7792,8 +7925,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7792
7925
  replaceRemoteMessages(messages) {
7793
7926
  this.agent.state.messages = messages;
7794
7927
  }
7795
- async expandLocalInput(text2) {
7796
- let current = text2;
7928
+ async expandLocalInput(text3) {
7929
+ let current = text3;
7797
7930
  const runner = this.extensionRunner;
7798
7931
  if (runner.hasHandlers("input")) {
7799
7932
  const result = await runner.emitInput(current, undefined, "interactive");
@@ -7806,8 +7939,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7806
7939
  current = expandPromptTemplate(current, [...this.promptTemplates]);
7807
7940
  return current;
7808
7941
  }
7809
- async prompt(text2, options) {
7810
- const trimmed = text2.trim();
7942
+ async prompt(text3, options) {
7943
+ const trimmed = text3.trim();
7811
7944
  if (!trimmed)
7812
7945
  return;
7813
7946
  if (trimmed.startsWith("/")) {
@@ -7836,8 +7969,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7836
7969
  options?.preflightResult?.(true);
7837
7970
  await this.remote.sendPrompt(expanded, behavior);
7838
7971
  }
7839
- async steer(text2) {
7840
- const trimmed = text2.trim();
7972
+ async steer(text3) {
7973
+ const trimmed = text3.trim();
7841
7974
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7842
7975
  return;
7843
7976
  const expanded = await this.expandLocalInput(trimmed);
@@ -7845,8 +7978,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7845
7978
  return;
7846
7979
  await this.remote.sendPrompt(expanded, "steer");
7847
7980
  }
7848
- async followUp(text2) {
7849
- const trimmed = text2.trim();
7981
+ async followUp(text3) {
7982
+ const trimmed = text3.trim();
7850
7983
  if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
7851
7984
  return;
7852
7985
  const expanded = await this.expandLocalInput(trimmed);
@@ -7858,8 +7991,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7858
7991
  await this.remote.abort();
7859
7992
  }
7860
7993
  async compact(customInstructions) {
7861
- const pending = new Promise((resolve22, reject) => {
7862
- this.remote.registerPendingCompaction({ resolve: resolve22, reject });
7994
+ const pending = new Promise((resolve23, reject) => {
7995
+ this.remote.registerPendingCompaction({ resolve: resolve23, reject });
7863
7996
  });
7864
7997
  await this.remote.sendCommand(`/compact${customInstructions ? ` ${customInstructions}` : ""}`);
7865
7998
  return pending;
@@ -7928,8 +8061,8 @@ class RigRemoteAgentSession extends PiAgentSession {
7928
8061
  function createRemoteBashOperations(controller, excludeFromContext) {
7929
8062
  return {
7930
8063
  exec(command, _cwd, execOptions) {
7931
- return new Promise((resolve22, reject) => {
7932
- const pending = { onData: execOptions.onData, resolve: resolve22, reject, sawChunk: false };
8064
+ return new Promise((resolve23, reject) => {
8065
+ const pending = { onData: execOptions.onData, resolve: resolve23, reject, sawChunk: false };
7933
8066
  const cleanup = () => {
7934
8067
  execOptions.signal?.removeEventListener("abort", onAbort);
7935
8068
  if (timer)
@@ -8093,8 +8226,8 @@ function createRigWorkerPiBridgeExtension(options) {
8093
8226
  const prefix = busy ? `${SPINNER_FRAMES[frame]} ` : connected ? "\u25CF " : "\u25CB ";
8094
8227
  ctx.ui.setStatus("rig-worker-pi", `${prefix}${statusText}`);
8095
8228
  };
8096
- const setStatus = (ctx, text2, isBusy) => {
8097
- statusText = text2;
8229
+ const setStatus = (ctx, text3, isBusy) => {
8230
+ statusText = text3;
8098
8231
  busy = isBusy;
8099
8232
  renderStatus(ctx);
8100
8233
  };
@@ -8138,7 +8271,7 @@ function createRigWorkerPiBridgeExtension(options) {
8138
8271
  ctx.ui.notify("Initial message sent to the worker Pi daemon.", "info");
8139
8272
  const nativeUi = ctx.ui;
8140
8273
  options.controller.setUiHooks({
8141
- onStatusText: (text2) => setStatus(ctx, text2, !connected),
8274
+ onStatusText: (text3) => setStatus(ctx, text3, !connected),
8142
8275
  onActivity: (label, detail) => {
8143
8276
  const active = label !== "idle" && !/complete|ready/i.test(label);
8144
8277
  setStatus(ctx, [label, detail].filter(Boolean).join(" \u2014 "), active);
@@ -8195,7 +8328,7 @@ function setTemporaryEnv(updates) {
8195
8328
  };
8196
8329
  }
8197
8330
  async function attachRunBundledPiFrontend(context, input) {
8198
- const tempSessionDir = mkdtempSync(join2(tmpdir(), "rig-pi-frontend-sessions-"));
8331
+ const tempSessionDir = mkdtempSync(join3(tmpdir(), "rig-pi-frontend-sessions-"));
8199
8332
  const restoreEnv = setTemporaryEnv({
8200
8333
  PI_CODING_AGENT_SESSION_DIR: tempSessionDir,
8201
8334
  PI_SKIP_VERSION_CHECK: "1",
@@ -8515,7 +8648,7 @@ async function executeRun(context, args) {
8515
8648
  if (!runId) {
8516
8649
  throw new CliError2("run show requires a run id.");
8517
8650
  }
8518
- const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8651
+ const record = readAuthorityRun5(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
8519
8652
  if (!record) {
8520
8653
  throw new CliError2(`Run not found: ${runId}`, 2);
8521
8654
  }
@@ -8553,6 +8686,46 @@ async function executeRun(context, args) {
8553
8686
  }
8554
8687
  return { ok: true, group: "run", command, details: { runId: run.value, events, cursor } };
8555
8688
  }
8689
+ case "replay": {
8690
+ let pending = rest;
8691
+ const run = takeOption(pending, "--run");
8692
+ pending = run.rest;
8693
+ const withSession = takeFlag(pending, "--with-session");
8694
+ pending = withSession.rest;
8695
+ const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
8696
+ const extra = positionalRunId ? pending.slice(1) : pending;
8697
+ requireNoExtraArgs(extra, "rig run replay <id>|--run <id> [--with-session]");
8698
+ const runId = run.value ?? positionalRunId;
8699
+ if (!runId) {
8700
+ throw new CliError2("run replay requires a run id.", 2);
8701
+ }
8702
+ const replay = buildRunReplay(context.projectRoot, runId, { withSession: withSession.value });
8703
+ if (replay.entryCount === 0 && replay.sessionEntryCount === 0) {
8704
+ throw new CliError2(`No run.jsonl lifecycle log found for ${runId} (looked at ${replay.logPath}).`, 2);
8705
+ }
8706
+ if (context.outputMode === "text") {
8707
+ console.log(`Replay of ${runId} (${replay.entryCount} lifecycle entries${withSession.value ? `, ${replay.sessionEntryCount} session entries` : ""}):`);
8708
+ for (const line of replay.lines) {
8709
+ console.log(line);
8710
+ }
8711
+ if (withSession.value && !replay.sessionFile) {
8712
+ console.log("(no Pi session file resolvable from the run record; showing run.jsonl only)");
8713
+ }
8714
+ }
8715
+ return {
8716
+ ok: true,
8717
+ group: "run",
8718
+ command,
8719
+ details: {
8720
+ runId,
8721
+ logPath: replay.logPath,
8722
+ sessionFile: replay.sessionFile,
8723
+ entryCount: replay.entryCount,
8724
+ sessionEntryCount: replay.sessionEntryCount,
8725
+ lines: replay.lines
8726
+ }
8727
+ };
8728
+ }
8556
8729
  case "attach": {
8557
8730
  let pending = rest;
8558
8731
  const runOption = takeOption(pending, "--run");
@@ -8875,7 +9048,7 @@ async function executeServer(context, args, options) {
8875
9048
  init_runner();
8876
9049
  import { readFileSync as readFileSync10 } from "fs";
8877
9050
  import { spawnSync as spawnSync3 } from "child_process";
8878
- import { resolve as resolve22 } from "path";
9051
+ import { resolve as resolve23 } from "path";
8879
9052
  import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8880
9053
  import {
8881
9054
  taskArtifactDir,
@@ -9053,6 +9226,7 @@ var PRIMARY_GROUPS = [
9053
9226
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
9054
9227
  { command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
9055
9228
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
9229
+ { 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." },
9056
9230
  { command: "resume", description: "Resume the most recent interrupted local run." },
9057
9231
  { command: "restart", description: "Restart the most recent local run from a clean runtime." },
9058
9232
  { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
@@ -9640,7 +9814,7 @@ async function executeTask(context, args, options) {
9640
9814
  const fileFlag = takeOption(rest.slice(1), "--file");
9641
9815
  let content;
9642
9816
  if (fileFlag.value) {
9643
- content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
9817
+ content = readFileSync10(resolve23(context.projectRoot, fileFlag.value), "utf-8");
9644
9818
  } else {
9645
9819
  content = await readStdin();
9646
9820
  }
@@ -9874,8 +10048,8 @@ async function executeTask(context, args, options) {
9874
10048
 
9875
10049
  // packages/cli/src/commands/task-run-driver.ts
9876
10050
  init_runner();
9877
- import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9878
- import { resolve as resolve23 } from "path";
10051
+ import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
10052
+ import { resolve as resolve24 } from "path";
9879
10053
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
9880
10054
  import { createInterface as createLineInterface } from "readline";
9881
10055
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -9899,7 +10073,7 @@ import {
9899
10073
  isCodexExecRecord
9900
10074
  } from "@rig/runtime/control-plane/provider/codex-exec-records";
9901
10075
  import { resolvePreferredShellBinary } from "@rig/runtime/control-plane/native/run-ops";
9902
- import { readAuthorityRun as readAuthorityRun5, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
10076
+ import { readAuthorityRun as readAuthorityRun6, readJsonFile as readJsonFile3, resolveTaskArtifactDirs as resolveTaskArtifactDirs2 } from "@rig/runtime/control-plane/authority-files";
9903
10077
  import {
9904
10078
  buildTaskRunLifecycleComment
9905
10079
  } from "@rig/runtime/control-plane/tasks/source-lifecycle";
@@ -9959,12 +10133,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
9959
10133
  return 0;
9960
10134
  let copied = 0;
9961
10135
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
9962
- const sourcePath = resolve23(sourceRoot, relativePath);
9963
- const targetPath = resolve23(targetRoot, relativePath);
10136
+ const sourcePath = resolve24(sourceRoot, relativePath);
10137
+ const targetPath = resolve24(targetRoot, relativePath);
9964
10138
  try {
9965
10139
  if (!statSync2(sourcePath).isFile())
9966
10140
  continue;
9967
- mkdirSync9(resolve23(targetPath, ".."), { recursive: true });
10141
+ mkdirSync9(resolve24(targetPath, ".."), { recursive: true });
9968
10142
  copyFileSync3(sourcePath, targetPath);
9969
10143
  copied += 1;
9970
10144
  } catch {}
@@ -10003,7 +10177,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
10003
10177
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
10004
10178
  return {
10005
10179
  RIG_BASELINE_MODE: "dirty-snapshot",
10006
- RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
10180
+ RIG_DIRTY_BASELINE_READY_FILE: resolve24(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
10007
10181
  };
10008
10182
  }
10009
10183
  function positiveInt(value, fallback) {
@@ -10108,9 +10282,9 @@ function createCommandRunner(binary) {
10108
10282
  const stderrChunks = [];
10109
10283
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
10110
10284
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
10111
- return await new Promise((resolve24) => {
10112
- child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
10113
- child.once("close", (code) => resolve24({
10285
+ return await new Promise((resolve25) => {
10286
+ child.once("error", (error) => resolve25({ exitCode: 1, stderr: error.message }));
10287
+ child.once("close", (code) => resolve25({
10114
10288
  exitCode: code ?? 1,
10115
10289
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
10116
10290
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -10184,7 +10358,7 @@ async function runTaskRunPostValidationLifecycle(input) {
10184
10358
  config,
10185
10359
  sourceTask: input.sourceTask,
10186
10360
  uploadedSnapshot: input.uploadedSnapshot,
10187
- artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
10361
+ artifactRoot: resolve24(input.projectRoot, "artifacts", taskId3),
10188
10362
  command: ghCommand,
10189
10363
  gitCommand,
10190
10364
  steerPi,
@@ -10314,7 +10488,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
10314
10488
  return null;
10315
10489
  }
10316
10490
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
10317
- const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
10491
+ const summary = readJsonFile3(resolve24(artifactDir, "validation-summary.json"), null);
10318
10492
  if (!summary || summary.status !== "fail") {
10319
10493
  continue;
10320
10494
  }
@@ -10395,9 +10569,9 @@ function readTaskRunAcceptedArtifactState(input) {
10395
10569
  if (!input.taskId || !input.workspaceDir) {
10396
10570
  return { accepted: false, reason: null };
10397
10571
  }
10398
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10399
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10400
- const taskResultPath = resolve23(artifactDir, "task-result.json");
10572
+ const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
10573
+ const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
10574
+ const taskResultPath = resolve24(artifactDir, "task-result.json");
10401
10575
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10402
10576
  if (reviewStatus !== "APPROVED") {
10403
10577
  return { accepted: false, reason: null };
@@ -10434,12 +10608,12 @@ function resolveTaskRunRetryContext(input) {
10434
10608
  if (!input.taskId || !input.workspaceDir) {
10435
10609
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
10436
10610
  }
10437
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10438
- const reviewStatePath = resolve23(artifactDir, "review-state.json");
10439
- const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
10440
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10441
- const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10442
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
10611
+ const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
10612
+ const reviewStatePath = resolve24(artifactDir, "review-state.json");
10613
+ const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
10614
+ const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
10615
+ const failedApproachesPath = resolve24(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10616
+ const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
10443
10617
  const reviewState = readJsonFile3(reviewStatePath, null);
10444
10618
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
10445
10619
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -10625,7 +10799,7 @@ function appendToolTimelineFromLog(input) {
10625
10799
  });
10626
10800
  }
10627
10801
  function readTaskRunReviewStatus(reviewStatusPath) {
10628
- if (!existsSync14(reviewStatusPath)) {
10802
+ if (!existsSync15(reviewStatusPath)) {
10629
10803
  return null;
10630
10804
  }
10631
10805
  try {
@@ -10705,7 +10879,7 @@ async function updateTaskSourceAfterDriverRun(projectRoot, runId, taskId3, sourc
10705
10879
  }
10706
10880
  }
10707
10881
  function readRunSourceTaskContract(projectRoot, runId, taskId3) {
10708
- const run = readAuthorityRun5(projectRoot, runId);
10882
+ const run = readAuthorityRun6(projectRoot, runId);
10709
10883
  const raw = run?.sourceTask;
10710
10884
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
10711
10885
  return null;
@@ -10746,8 +10920,10 @@ async function executeRigOwnedTaskRun(context, input) {
10746
10920
  process.stderr.on("error", () => {});
10747
10921
  configureRunEventSink(context.projectRoot);
10748
10922
  const runtimeTaskId = input.taskId?.trim() || `adhoc-${input.runId}`;
10749
- const existingRunRecord = readAuthorityRun5(context.projectRoot, input.runId);
10923
+ const existingRunRecord = readAuthorityRun6(context.projectRoot, input.runId);
10750
10924
  const resumeMode = process.env.RIG_RUN_RESUME === "1";
10925
+ let latestPiSessionId = typeof existingRunRecord?.piSession?.sessionId === "string" && existingRunRecord.piSession.sessionId.trim() ? existingRunRecord.piSession.sessionId : null;
10926
+ const sessionAnchor = () => latestPiSessionId ? { sessionId: latestPiSessionId } : {};
10751
10927
  const resumePreviousStatus = String(existingRunRecord?.status ?? "").toLowerCase();
10752
10928
  const sourceTask = readRunSourceTaskContract(context.projectRoot, input.runId, input.taskId);
10753
10929
  let prompt = buildRunPrompt({
@@ -10820,7 +10996,8 @@ async function executeRigOwnedTaskRun(context, input) {
10820
10996
  type: "status",
10821
10997
  runId: input.runId,
10822
10998
  status: "preparing",
10823
- detail: input.taskId ?? input.title ?? runtimeTaskId
10999
+ detail: input.taskId ?? input.title ?? runtimeTaskId,
11000
+ ...sessionAnchor()
10824
11001
  });
10825
11002
  appendRunLog(context.projectRoot, input.runId, {
10826
11003
  id: `log:${input.runId}:${resumeMode ? "resume" : "start"}`,
@@ -10846,15 +11023,15 @@ async function executeRigOwnedTaskRun(context, input) {
10846
11023
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
10847
11024
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
10848
11025
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
10849
- const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
11026
+ const planningArtifactPath = resolve24("artifacts", runtimeTaskId, "implementation-plan.md");
10850
11027
  const persistedPlanning = {
10851
11028
  ...planningClassification,
10852
11029
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
10853
11030
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
10854
11031
  classifiedAt: new Date().toISOString()
10855
11032
  };
10856
- mkdirSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10857
- writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
11033
+ mkdirSync9(resolve24(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
11034
+ writeFileSync7(resolve24(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10858
11035
  `, "utf8");
10859
11036
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
10860
11037
  prompt = `${prompt}
@@ -10904,7 +11081,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10904
11081
  let verificationStarted = false;
10905
11082
  let reviewStarted = false;
10906
11083
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
10907
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
11084
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve24(existingRunRecord.sessionPath, "..") : null;
10908
11085
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
10909
11086
  let latestProviderCommand = null;
10910
11087
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -10941,7 +11118,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10941
11118
  return;
10942
11119
  verificationStarted = true;
10943
11120
  patchAuthorityRun(context.projectRoot, input.runId, { status: "validating" });
10944
- emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null });
11121
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "validating", detail: detail ?? null, ...sessionAnchor() });
10945
11122
  verificationAction = startRunAction(context.projectRoot, input.runId, {
10946
11123
  actionId: `action:${input.runId}:completion-verification`,
10947
11124
  actionType: "completion-verification",
@@ -10954,7 +11131,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10954
11131
  return;
10955
11132
  reviewStarted = true;
10956
11133
  patchAuthorityRun(context.projectRoot, input.runId, { status: "reviewing" });
10957
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null });
11134
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: detail ?? null, ...sessionAnchor() });
10958
11135
  reviewAction = startRunAction(context.projectRoot, input.runId, {
10959
11136
  actionId: `action:${input.runId}:review-closeout`,
10960
11137
  actionType: "run.review",
@@ -10990,10 +11167,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10990
11167
  patchAuthorityRun(context.projectRoot, input.runId, {
10991
11168
  status: "running",
10992
11169
  worktreePath: latestRuntimeWorkspace,
10993
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
11170
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve24(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10994
11171
  logRoot: latestLogsDir,
10995
- sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
10996
- sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
11172
+ sessionPath: latestSessionDir ? resolve24(latestSessionDir, "session.json") : null,
11173
+ sessionLogPath: latestLogsDir ? resolve24(latestLogsDir, "agent-stdout.log") : null,
10997
11174
  branch: runtimeId
10998
11175
  });
10999
11176
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -11001,7 +11178,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11001
11178
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
11002
11179
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
11003
11180
  if (readyFile) {
11004
- mkdirSync9(resolve23(readyFile, ".."), { recursive: true });
11181
+ mkdirSync9(resolve24(readyFile, ".."), { recursive: true });
11005
11182
  writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
11006
11183
  `, "utf8");
11007
11184
  }
@@ -11044,7 +11221,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11044
11221
  type: "status",
11045
11222
  runId: input.runId,
11046
11223
  status: "running",
11047
- detail: latestRuntimeWorkspace
11224
+ detail: latestRuntimeWorkspace,
11225
+ ...sessionAnchor()
11048
11226
  });
11049
11227
  return true;
11050
11228
  }
@@ -11127,6 +11305,9 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11127
11305
  piSessionPrivate: privateMetadata
11128
11306
  });
11129
11307
  const sessionId = typeof publicMetadata?.sessionId === "string" ? publicMetadata.sessionId : typeof privateMetadata.public === "object" && privateMetadata.public && !Array.isArray(privateMetadata.public) ? String(privateMetadata.public.sessionId ?? "") : "";
11308
+ if (sessionId) {
11309
+ latestPiSessionId = sessionId;
11310
+ }
11130
11311
  appendRunLog(context.projectRoot, input.runId, {
11131
11312
  id: `log:${input.runId}:pi-session-ready`,
11132
11313
  title: "Worker Pi session ready",
@@ -11386,7 +11567,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11386
11567
  let acceptedArtifactObservedAt = null;
11387
11568
  let acceptedArtifactPollTimer = null;
11388
11569
  let acceptedArtifactKillTimer = null;
11389
- const attemptExit = await new Promise((resolve24) => {
11570
+ const attemptExit = await new Promise((resolve25) => {
11390
11571
  let settled = false;
11391
11572
  const settle = (result) => {
11392
11573
  if (settled)
@@ -11394,7 +11575,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11394
11575
  settled = true;
11395
11576
  if (acceptedArtifactPollTimer)
11396
11577
  clearInterval(acceptedArtifactPollTimer);
11397
- resolve24(result);
11578
+ resolve25(result);
11398
11579
  };
11399
11580
  const pollAcceptedArtifacts = () => {
11400
11581
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -11521,7 +11702,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
11521
11702
  type: "status",
11522
11703
  runId: input.runId,
11523
11704
  status: "validating",
11524
- detail: failureDetail
11705
+ detail: failureDetail,
11706
+ ...sessionAnchor()
11525
11707
  });
11526
11708
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Validate failed" });
11527
11709
  emitServerRunEvent({ type: "log", runId: input.runId, title: `Steering Pi to retry validation (attempt ${attempt + 1}/${maxAttempts})` });
@@ -11596,8 +11778,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11596
11778
  }
11597
11779
  if (planningClassification.planningRequired) {
11598
11780
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
11599
- const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
11600
- if (!existsSync14(expectedPlanPath)) {
11781
+ const expectedPlanPath = resolve24(planWorkspace, planningArtifactPath);
11782
+ if (!existsSync15(expectedPlanPath)) {
11601
11783
  const failedAt = new Date().toISOString();
11602
11784
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
11603
11785
  patchAuthorityRun(context.projectRoot, input.runId, {
@@ -11659,7 +11841,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11659
11841
  payload: { runtimeWorkspace: latestRuntimeWorkspace, branch: latestRuntimeBranch }
11660
11842
  });
11661
11843
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Server-owned closeout requested" });
11662
- emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested." });
11844
+ emitServerRunEvent({ type: "status", runId: input.runId, status: "reviewing", detail: "Server-owned closeout requested.", ...sessionAnchor() });
11663
11845
  await context.emitEvent("command.finished", {
11664
11846
  command: [
11665
11847
  "rig",
@@ -11767,9 +11949,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11767
11949
  });
11768
11950
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
11769
11951
  });
11770
- const exitCode = await new Promise((resolve24) => {
11771
- child.once("error", () => resolve24(1));
11772
- child.once("close", (code) => resolve24(code ?? 1));
11952
+ const exitCode = await new Promise((resolve25) => {
11953
+ child.once("error", () => resolve25(1));
11954
+ child.once("close", (code) => resolve25(code ?? 1));
11773
11955
  });
11774
11956
  for (const pendingLog of flushPendingClaudeToolUseLogs({
11775
11957
  runId: input.runId,
@@ -11911,8 +12093,8 @@ async function executeTest(context, args) {
11911
12093
 
11912
12094
  // packages/cli/src/commands/setup.ts
11913
12095
  init_runner();
11914
- import { existsSync as existsSync15, mkdirSync as mkdirSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
11915
- import { resolve as resolve24 } from "path";
12096
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, readdirSync as readdirSync3, writeFileSync as writeFileSync8 } from "fs";
12097
+ import { resolve as resolve25 } from "path";
11916
12098
  import { createPluginHost } from "@rig/core";
11917
12099
  import {
11918
12100
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -11970,8 +12152,8 @@ function runSetupInit(projectRoot) {
11970
12152
  mkdirSync10(stateDir, { recursive: true });
11971
12153
  mkdirSync10(logsDir, { recursive: true });
11972
12154
  mkdirSync10(artifactsDir, { recursive: true });
11973
- const failuresPath = resolve24(stateDir, "failed_approaches.md");
11974
- if (!existsSync15(failuresPath)) {
12155
+ const failuresPath = resolve25(stateDir, "failed_approaches.md");
12156
+ if (!existsSync16(failuresPath)) {
11975
12157
  writeFileSync8(failuresPath, `# Failed Approaches
11976
12158
 
11977
12159
  `, "utf-8");
@@ -11989,19 +12171,19 @@ async function runSetupCheck(projectRoot) {
11989
12171
  }
11990
12172
  async function runSetupPreflight(projectRoot) {
11991
12173
  await runSetupCheck(projectRoot);
11992
- const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11993
- if (existsSync15(validationRoot)) {
11994
- const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
12174
+ const validationRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
12175
+ if (existsSync16(validationRoot)) {
12176
+ const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11995
12177
  for (const validator of validators) {
11996
- const script = resolve24(validationRoot, validator.name, "validate.sh");
11997
- if (existsSync15(script)) {
12178
+ const script = resolve25(validationRoot, validator.name, "validate.sh");
12179
+ if (existsSync16(script)) {
11998
12180
  console.log(`OK: validator script ${script}`);
11999
12181
  }
12000
12182
  }
12001
12183
  }
12002
- const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
12003
- if (existsSync15(hooksRoot)) {
12004
- const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
12184
+ const hooksRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
12185
+ if (existsSync16(hooksRoot)) {
12186
+ const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
12005
12187
  for (const hook of hooks) {
12006
12188
  console.log(`OK: hook ${hook}`);
12007
12189
  }
@@ -12145,7 +12327,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
12145
12327
  ]);
12146
12328
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
12147
12329
  function hasInitializedRigProject(projectRoot) {
12148
- return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
12330
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync17(resolve26(projectRoot, name))) || existsSync17(resolve26(projectRoot, ".rig"));
12149
12331
  }
12150
12332
  function requireInitializedRigProject(context, group) {
12151
12333
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -12198,8 +12380,8 @@ function resolveTopLevelLaunchState(context) {
12198
12380
  let selectedServer = null;
12199
12381
  if (projectInitialized) {
12200
12382
  try {
12201
- const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
12202
- if (existsSync16(statePath)) {
12383
+ const statePath = resolve26(context.projectRoot, ".rig", "state", "connection.json");
12384
+ if (existsSync17(statePath)) {
12203
12385
  const parsed = JSON.parse(readFileSync12(statePath, "utf-8"));
12204
12386
  selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
12205
12387
  }
@@ -12362,8 +12544,8 @@ async function executeGroup(context, group, args) {
12362
12544
  }
12363
12545
  }
12364
12546
  // packages/cli/src/launcher.ts
12365
- import { existsSync as existsSync17 } from "fs";
12366
- import { basename as basename3, resolve as resolve26 } from "path";
12547
+ import { existsSync as existsSync18 } from "fs";
12548
+ import { basename as basename3, resolve as resolve27 } from "path";
12367
12549
  import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
12368
12550
  import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
12369
12551
  function parsePolicyMode(value) {
@@ -12376,7 +12558,7 @@ function parsePolicyMode(value) {
12376
12558
  throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
12377
12559
  }
12378
12560
  function hasRigProjectMarker(candidate) {
12379
- 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"));
12561
+ 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"));
12380
12562
  }
12381
12563
  function resolveProjectRoot({
12382
12564
  envProjectRoot,
@@ -12385,19 +12567,19 @@ function resolveProjectRoot({
12385
12567
  cwd = process.cwd()
12386
12568
  }) {
12387
12569
  if (envProjectRoot) {
12388
- return resolve26(cwd, envProjectRoot);
12570
+ return resolve27(cwd, envProjectRoot);
12389
12571
  }
12390
12572
  const fallbackImportDir = importDir ?? cwd;
12391
12573
  const execName = basename3(execPath).toLowerCase();
12392
- const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve26(execPath, "..", "..")] : [];
12393
- const candidates = [cwd, ...execCandidates, resolve26(fallbackImportDir, "..")];
12574
+ const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve27(execPath, "..", "..")] : [];
12575
+ const candidates = [cwd, ...execCandidates, resolve27(fallbackImportDir, "..")];
12394
12576
  for (const candidate of candidates) {
12395
12577
  const nearest = resolveNearestRigProjectRoot(candidate);
12396
12578
  if (hasRigProjectMarker(nearest)) {
12397
12579
  return nearest;
12398
12580
  }
12399
12581
  }
12400
- return resolve26(cwd);
12582
+ return resolve27(cwd);
12401
12583
  }
12402
12584
  function normalizeCliErrorCode(message2, isCliError) {
12403
12585
  if (message2.startsWith("Invalid --policy-mode value:")) {
@@ -12464,7 +12646,7 @@ async function runRigCli(module, options = {}) {
12464
12646
  runId: context.runId,
12465
12647
  outcome,
12466
12648
  eventsFile: context.eventBus.getEventsFile(),
12467
- policyFile: resolve26(projectRoot, "rig", "policy", "policy.json"),
12649
+ policyFile: resolve27(projectRoot, "rig", "policy", "policy.json"),
12468
12650
  policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
12469
12651
  }, null, 2));
12470
12652
  }