@cydm/pie 1.0.36 → 1.0.38

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.
@@ -8,10 +8,10 @@ import {
8
8
  createSharedWebSearchTool,
9
9
  interpretShellExit,
10
10
  requestInteraction
11
- } from "./chunk-MGZHZSHB.js";
11
+ } from "./chunk-2PLCSYFF.js";
12
12
  import {
13
13
  Type
14
- } from "./chunk-64XJIKVK.js";
14
+ } from "./chunk-2WHIT2UB.js";
15
15
 
16
16
  // src/config.ts
17
17
  import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  EventStream,
4
4
  streamSimple,
5
5
  validateToolArguments
6
- } from "./chunk-64XJIKVK.js";
6
+ } from "./chunk-2WHIT2UB.js";
7
7
 
8
8
  // ../../packages/agent-core/src/agent-loop.ts
9
9
  function createLoopErrorMessage(error, config, signal) {
@@ -3,8 +3,8 @@ import {
3
3
  Agent,
4
4
  agentLoop,
5
5
  agentLoopContinue
6
- } from "./chunk-4B42ZU4B.js";
7
- import "./chunk-64XJIKVK.js";
6
+ } from "./chunk-NTFKTUOW.js";
7
+ import "./chunk-2WHIT2UB.js";
8
8
  import "./chunk-TG2EQLX2.js";
9
9
  export {
10
10
  Agent,
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  EventStream
4
- } from "./chunk-64XJIKVK.js";
4
+ } from "./chunk-2WHIT2UB.js";
5
5
  import "./chunk-TG2EQLX2.js";
6
6
 
7
7
  // src/app/test-stream.ts
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  getThemesDir,
20
20
  migrateConfigFromAgentDir,
21
21
  truncateHeadTail
22
- } from "./chunks/chunk-QXTAEPLR.js";
22
+ } from "./chunks/chunk-IKIEQTVJ.js";
23
23
  import {
24
24
  AGENTS_CONTEXT_FILE_NAME,
25
25
  AgentSessionController,
@@ -69,8 +69,8 @@ import {
69
69
  setExtensionEnabledInSettings,
70
70
  shouldPreserveExecutionStateForUserText,
71
71
  supersedeExecutionState
72
- } from "./chunks/chunk-MGZHZSHB.js";
73
- import "./chunks/chunk-4B42ZU4B.js";
72
+ } from "./chunks/chunk-2PLCSYFF.js";
73
+ import "./chunks/chunk-NTFKTUOW.js";
74
74
  import {
75
75
  Deref,
76
76
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -105,7 +105,7 @@ import {
105
105
  setLogger,
106
106
  sortToolModelCandidatesByCapability,
107
107
  type_exports
108
- } from "./chunks/chunk-64XJIKVK.js";
108
+ } from "./chunks/chunk-2WHIT2UB.js";
109
109
  import {
110
110
  resolveCliProjectRoot
111
111
  } from "./chunks/chunk-NTYHFBUA.js";
@@ -44905,6 +44905,7 @@ function validateCompat(value, label) {
44905
44905
  if (value === void 0) return;
44906
44906
  if (!isPlainRecord(value)) throw new Error(`${label} is invalid`);
44907
44907
  assertOnlyKeys(value, [
44908
+ "forcedReasoningEffort",
44908
44909
  "supportsStore",
44909
44910
  "supportsDeveloperRole",
44910
44911
  "supportsReasoningEffort",
@@ -44916,6 +44917,9 @@ function validateCompat(value, label) {
44916
44917
  "supportsStrictMode",
44917
44918
  "cacheCapability"
44918
44919
  ], label);
44920
+ if (value.forcedReasoningEffort !== void 0 && value.forcedReasoningEffort !== "none") {
44921
+ throw new Error(`${label}.forcedReasoningEffort must be "none"`);
44922
+ }
44919
44923
  for (const field of [
44920
44924
  "supportsStore",
44921
44925
  "supportsDeveloperRole",
@@ -46565,6 +46569,165 @@ function parseModelsCommandArgs(args) {
46565
46569
 
46566
46570
  // src/commands/sessions.ts
46567
46571
  import fs6 from "node:fs";
46572
+
46573
+ // src/session-control.ts
46574
+ var SessionControlError = class extends Error {
46575
+ constructor(code, message, recoverable = sessionControlErrorRecoverable(code)) {
46576
+ super(message);
46577
+ this.code = code;
46578
+ this.recoverable = recoverable;
46579
+ this.name = "SessionControlError";
46580
+ }
46581
+ code;
46582
+ recoverable;
46583
+ };
46584
+ function sessionControlErrorRecoverable(code) {
46585
+ return code !== "session_unrecoverable" && code !== "session_mismatch";
46586
+ }
46587
+ async function loadRequiredSession(store, sessionId) {
46588
+ const exists = await store.exists(sessionId);
46589
+ const data = await store.load(sessionId);
46590
+ if (data) return data;
46591
+ throw new SessionControlError(
46592
+ exists ? "session_unrecoverable" : "session_not_found",
46593
+ exists ? `Session could not be recovered: ${sessionId}` : `Session not found: ${sessionId}`
46594
+ );
46595
+ }
46596
+ async function rewindStoredSession(params) {
46597
+ const data = await loadRequiredSession(params.store, params.sessionId);
46598
+ if (!data.entries.some((entry) => entry.id === params.entryId)) {
46599
+ throw new SessionControlError("checkpoint_not_found", `Entry not found: ${params.entryId}`);
46600
+ }
46601
+ try {
46602
+ await params.store.save(params.sessionId, data.entries, {
46603
+ ...data.metadata,
46604
+ activeEntryId: params.entryId,
46605
+ updatedAt: params.now ?? Date.now()
46606
+ });
46607
+ const metadata = await params.store.getMetadata(params.sessionId);
46608
+ if (!metadata) {
46609
+ throw new SessionControlError("session_unrecoverable", `Session could not be recovered after rewind: ${params.sessionId}`, false);
46610
+ }
46611
+ return {
46612
+ sessionId: params.sessionId,
46613
+ entryId: params.entryId,
46614
+ checkpointId: params.entryId,
46615
+ activeEntryId: params.entryId,
46616
+ headEntryId: params.entryId,
46617
+ metadata
46618
+ };
46619
+ } catch (error) {
46620
+ if (error instanceof SessionControlError) throw error;
46621
+ throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
46622
+ }
46623
+ }
46624
+ async function forkStoredSession(params) {
46625
+ try {
46626
+ const existingTarget = await maybeLoadExistingForkTarget(params);
46627
+ if (existingTarget) return existingTarget;
46628
+ const source = await loadRequiredSession(params.store, params.sourceSessionId);
46629
+ const pathEntries = pathToEntry(source, params.sourceEntryId);
46630
+ if (pathEntries.length === 0 || pathEntries[pathEntries.length - 1]?.id !== params.sourceEntryId) {
46631
+ throw new SessionControlError("checkpoint_not_found", `Entry not found: ${params.sourceEntryId}`);
46632
+ }
46633
+ const now = params.now ?? Date.now();
46634
+ const idMap = /* @__PURE__ */ new Map();
46635
+ for (const entry of pathEntries) idMap.set(entry.id, generateEntryId());
46636
+ const forkedEntries = pathEntries.map((entry) => {
46637
+ const nextId = idMap.get(entry.id);
46638
+ if (!nextId) throw new SessionControlError("session_io_error", `Failed to map entry: ${entry.id}`);
46639
+ const parentId = entry.parentId ? idMap.get(entry.parentId) ?? null : null;
46640
+ return {
46641
+ ...cloneJson(entry),
46642
+ id: nextId,
46643
+ parentId,
46644
+ timestamp: entry.timestamp
46645
+ };
46646
+ });
46647
+ const activeEntryId = idMap.get(params.sourceEntryId);
46648
+ if (!activeEntryId) {
46649
+ throw new SessionControlError("session_io_error", `Failed to map active entry: ${params.sourceEntryId}`);
46650
+ }
46651
+ await params.store.save(params.targetSessionId, forkedEntries, {
46652
+ name: params.name,
46653
+ createdAt: now,
46654
+ updatedAt: now,
46655
+ activeEntryId,
46656
+ cwd: params.cwd ?? source.metadata.cwd,
46657
+ sourceSessionId: params.sourceSessionId,
46658
+ sourceEntryId: params.sourceEntryId,
46659
+ sourceActiveEntryId: source.metadata.activeEntryId ?? void 0,
46660
+ forkBaseEntryId: activeEntryId,
46661
+ ...params.requestId ? { sessionControlRequestId: params.requestId } : {}
46662
+ });
46663
+ const metadata = await params.store.getMetadata(params.targetSessionId);
46664
+ if (!metadata) {
46665
+ throw new SessionControlError("session_unrecoverable", `Session could not be recovered after fork: ${params.targetSessionId}`, false);
46666
+ }
46667
+ return buildForkResult({
46668
+ metadata,
46669
+ sourceSessionId: params.sourceSessionId,
46670
+ sourceEntryId: params.sourceEntryId,
46671
+ sourceActiveEntryId: source.metadata.activeEntryId ?? null
46672
+ });
46673
+ } catch (error) {
46674
+ if (error instanceof SessionControlError) throw error;
46675
+ throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
46676
+ }
46677
+ }
46678
+ async function maybeLoadExistingForkTarget(params) {
46679
+ if (!await params.store.exists(params.targetSessionId)) return null;
46680
+ const target = await params.store.load(params.targetSessionId);
46681
+ if (!target) {
46682
+ throw new SessionControlError("session_unrecoverable", `Session could not be recovered: ${params.targetSessionId}`, false);
46683
+ }
46684
+ const metadata = target.metadata;
46685
+ if (params.requestId && metadata.sessionControlRequestId === params.requestId && metadata.sourceSessionId === params.sourceSessionId && metadata.sourceEntryId === params.sourceEntryId && typeof metadata.forkBaseEntryId === "string" && metadata.activeEntryId === metadata.forkBaseEntryId) {
46686
+ return buildForkResult({
46687
+ metadata,
46688
+ sourceSessionId: params.sourceSessionId,
46689
+ sourceEntryId: params.sourceEntryId,
46690
+ sourceActiveEntryId: typeof metadata.sourceActiveEntryId === "string" ? metadata.sourceActiveEntryId : null
46691
+ });
46692
+ }
46693
+ throw new SessionControlError("target_exists", `Target session already exists: ${params.targetSessionId}`);
46694
+ }
46695
+ function buildForkResult(params) {
46696
+ const targetActiveEntryId = params.metadata.activeEntryId;
46697
+ if (!targetActiveEntryId) {
46698
+ throw new SessionControlError("session_unrecoverable", `Fork target has no active entry: ${params.metadata.id}`, false);
46699
+ }
46700
+ const forkBaseEntryId = typeof params.metadata.forkBaseEntryId === "string" ? params.metadata.forkBaseEntryId : targetActiveEntryId;
46701
+ return {
46702
+ sourceSessionId: params.sourceSessionId,
46703
+ sourceEntryId: params.sourceEntryId,
46704
+ sourceCheckpointId: params.sourceEntryId,
46705
+ targetSessionId: params.metadata.id,
46706
+ targetActiveEntryId,
46707
+ targetHeadEntryId: targetActiveEntryId,
46708
+ headEntryId: targetActiveEntryId,
46709
+ sourceActiveEntryId: params.sourceActiveEntryId,
46710
+ forkBaseEntryId,
46711
+ metadata: params.metadata
46712
+ };
46713
+ }
46714
+ function pathToEntry(data, entryId) {
46715
+ const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
46716
+ const path31 = [];
46717
+ let current = entryId;
46718
+ while (current) {
46719
+ const entry = byId.get(current);
46720
+ if (!entry) return [];
46721
+ path31.unshift(entry);
46722
+ current = entry.parentId;
46723
+ }
46724
+ return path31;
46725
+ }
46726
+ function cloneJson(value) {
46727
+ return JSON.parse(JSON.stringify(value));
46728
+ }
46729
+
46730
+ // src/commands/sessions.ts
46568
46731
  async function runSessionsCommand(args) {
46569
46732
  const command = args[0] || "help";
46570
46733
  const rest = args.slice(1);
@@ -46691,17 +46854,12 @@ async function rewindSession(args) {
46691
46854
  const entryId = stringFlag(args, "--to");
46692
46855
  if (!sessionId || !entryId) throw new Error("Usage: pie sessions rewind <sessionId> --to <entryId> [--json]");
46693
46856
  const store = new FileSessionStore(getSessionsDir());
46694
- const data = await store.load(sessionId);
46695
- if (!data) throw new Error(`Session not found: ${sessionId}`);
46696
- if (!data.entries.some((entry) => entry.id === entryId)) throw new Error(`Entry not found: ${entryId}`);
46697
- await store.save(sessionId, data.entries, { ...data.metadata, activeEntryId: entryId, updatedAt: Date.now() });
46698
- const updated = await store.getMetadata(sessionId);
46699
- if (!updated) throw new Error(`Session not found after rewind: ${sessionId}`);
46857
+ const result = await rewindStoredSession({ store, sessionId, entryId });
46700
46858
  const response = {
46701
46859
  ok: true,
46702
- session: sessionSummary(updated),
46703
- activeEntryId: entryId,
46704
- currentHead: entryId
46860
+ session: sessionSummary(result.metadata),
46861
+ activeEntryId: result.activeEntryId,
46862
+ currentHead: result.headEntryId
46705
46863
  };
46706
46864
  if (json) {
46707
46865
  console.log(JSON.stringify(response, null, 2));
@@ -46720,50 +46878,23 @@ async function forkSession(args) {
46720
46878
  throw new Error("Usage: pie sessions fork <sessionId> --from <entryId> --target <newSessionId> --name <name> [--cwd <path>] [--json]");
46721
46879
  }
46722
46880
  const store = new FileSessionStore(getSessionsDir());
46723
- const source = await store.load(sourceSessionId);
46724
- if (!source) throw new Error(`Session not found: ${sourceSessionId}`);
46725
- if (await store.exists(targetSessionId)) throw new Error(`Target session already exists: ${targetSessionId}`);
46726
- const pathEntries = pathToEntry(source, sourceEntryId);
46727
- if (pathEntries.length === 0 || pathEntries[pathEntries.length - 1]?.id !== sourceEntryId) {
46728
- throw new Error(`Entry not found: ${sourceEntryId}`);
46729
- }
46730
- const now = Date.now();
46731
- const idMap = /* @__PURE__ */ new Map();
46732
- for (const entry of pathEntries) idMap.set(entry.id, generateEntryId());
46733
- const forkedEntries = pathEntries.map((entry) => {
46734
- const nextId = idMap.get(entry.id);
46735
- if (!nextId) throw new Error(`Failed to map entry: ${entry.id}`);
46736
- const parentId = entry.parentId ? idMap.get(entry.parentId) ?? null : null;
46737
- return {
46738
- ...cloneJson(entry),
46739
- id: nextId,
46740
- parentId,
46741
- timestamp: entry.timestamp
46742
- };
46743
- });
46744
- const activeEntryId = idMap.get(sourceEntryId) ?? null;
46745
- await store.save(targetSessionId, forkedEntries, {
46746
- name,
46747
- createdAt: now,
46748
- updatedAt: now,
46749
- activeEntryId,
46750
- cwd: cwd ?? source.metadata.cwd,
46881
+ const result = await forkStoredSession({
46882
+ store,
46751
46883
  sourceSessionId,
46752
46884
  sourceEntryId,
46753
- sourceActiveEntryId: source.metadata.activeEntryId ?? void 0,
46754
- forkBaseEntryId: activeEntryId ?? void 0
46885
+ targetSessionId,
46886
+ name,
46887
+ cwd
46755
46888
  });
46756
- const updated = await store.getMetadata(targetSessionId);
46757
- if (!updated) throw new Error(`Session not found after fork: ${targetSessionId}`);
46758
46889
  const response = {
46759
46890
  ok: true,
46760
- session: sessionSummary(updated),
46891
+ session: sessionSummary(result.metadata),
46761
46892
  sourceSessionId,
46762
46893
  sourceEntryId,
46763
- sourceActiveEntryId: source.metadata.activeEntryId,
46764
- forkBaseEntryId: activeEntryId,
46765
- activeEntryId,
46766
- currentHead: activeEntryId
46894
+ sourceActiveEntryId: result.sourceActiveEntryId,
46895
+ forkBaseEntryId: result.forkBaseEntryId,
46896
+ activeEntryId: result.targetActiveEntryId,
46897
+ currentHead: result.targetHeadEntryId
46767
46898
  };
46768
46899
  if (json) {
46769
46900
  console.log(JSON.stringify(response, null, 2));
@@ -46856,7 +46987,7 @@ function activeTranscriptEvents(entries) {
46856
46987
  role,
46857
46988
  turnId,
46858
46989
  content: textFromMessage(entry.message),
46859
- message: entry.message ? cloneJson(entry.message) : void 0
46990
+ message: entry.message ? cloneJson2(entry.message) : void 0
46860
46991
  };
46861
46992
  });
46862
46993
  }
@@ -46879,18 +47010,6 @@ function activePathEntries(data) {
46879
47010
  if (!activeEntryId) return [];
46880
47011
  return pathToEntry(data, activeEntryId);
46881
47012
  }
46882
- function pathToEntry(data, entryId) {
46883
- const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
46884
- const path31 = [];
46885
- let current = entryId;
46886
- while (current) {
46887
- const entry = byId.get(current);
46888
- if (!entry) return [];
46889
- path31.unshift(entry);
46890
- current = entry.parentId;
46891
- }
46892
- return path31;
46893
- }
46894
47013
  function resolveBeforeCursor(events, cursor) {
46895
47014
  if (!cursor) return events.length;
46896
47015
  const numeric = Number(cursor);
@@ -46900,7 +47019,7 @@ function resolveBeforeCursor(events, cursor) {
46900
47019
  const index = events.findIndex((event) => event.entryId === cursor || event.checkpointId === cursor);
46901
47020
  return index >= 0 ? index : events.length;
46902
47021
  }
46903
- function cloneJson(value) {
47022
+ function cloneJson2(value) {
46904
47023
  return JSON.parse(JSON.stringify(value));
46905
47024
  }
46906
47025
  function listCursorQueryKey(input) {
@@ -59939,7 +60058,14 @@ var ExecutionStateManager = class {
59939
60058
  return this.store.clear();
59940
60059
  }
59941
60060
  restoreFromMetadata(raw) {
59942
- return this.store.replace(restoreExecutionState(raw));
60061
+ const restored = restoreExecutionState(raw);
60062
+ if (restored.mode === "todo" && restored.lifecycle === "active" && restored.awaitingContinuation) {
60063
+ return this.store.replace(pauseExecutionState({
60064
+ ...restored,
60065
+ awaitingContinuation: false
60066
+ }, "Previous todo turn was interrupted while a tool was running. Send 'continue' to resume the remaining items."));
60067
+ }
60068
+ return this.store.replace(restored);
59943
60069
  }
59944
60070
  getReminder() {
59945
60071
  return buildExecutionReminder(this.store.read());
@@ -67872,6 +67998,14 @@ function scheduleContinuationTimeout(host) {
67872
67998
  });
67873
67999
  return;
67874
68000
  }
68001
+ if (host.agent.state.isStreaming || host.isProcessing || host.submitLock || host.pendingTools.size > 0) {
68002
+ host.logDebug("continuation_timeout:active_work", {
68003
+ isStreaming: host.agent.state.isStreaming,
68004
+ isProcessing: host.isProcessing,
68005
+ pendingTools: host.pendingTools.size
68006
+ });
68007
+ return;
68008
+ }
67875
68009
  const outcome = host.executionState.markAwaitingContinuationStalled();
67876
68010
  host.logDebug("continuation_timeout:expired", {
67877
68011
  currentStepId: state.currentStepId,
@@ -67886,20 +68020,6 @@ function scheduleContinuationTimeout(host) {
67886
68020
  appendWarningSummary(host, outcome.terminalSummary);
67887
68021
  }
67888
68022
  }
67889
- if (host.agent.state.isStreaming || host.submitLock || host.isProcessing) {
67890
- host.logDebug("continuation_timeout:force_reset", {
67891
- isStreaming: host.agent.state.isStreaming,
67892
- submitLock: host.submitLock,
67893
- isProcessing: host.isProcessing
67894
- });
67895
- host.agent.resetProcessingState();
67896
- host.isProcessing = false;
67897
- host.setSubmitLock(false);
67898
- host.streamingComponent = void 0;
67899
- host.pendingTools.clear();
67900
- host.footer.setState({ status: "ready" });
67901
- host.safeRequestRender();
67902
- }
67903
68023
  host.agentSessionController?.requestQueueDispatch();
67904
68024
  }, timeoutMs);
67905
68025
  }
@@ -68230,7 +68350,7 @@ function buildRuntimeModeContext(state) {
68230
68350
  const lines = [
68231
68351
  RUNTIME_MODE_CONTEXT_MARKER,
68232
68352
  "Current runtime mode:",
68233
- `- Plan mode: ${state.planMode === "planning" ? "active (analysis/read-only planning)" : "off"}.`,
68353
+ `- Plan mode: ${state.planMode === "planning" ? "active (workspace read-only; plan_scratch permits session-local temporary drafts)" : "off"}.`,
68234
68354
  `- YOLO mode: ${state.yoloMode ? "on (filesystem sandbox directory restrictions are disabled)" : "off (workspace/protected-path restrictions apply)"}.`,
68235
68355
  `- Filesystem scope: ${state.filesystemScope === "all" ? "all local paths may be passed directly to file tools when permitted" : "workspace paths and configured safe roots only"}.`
68236
68356
  ];
@@ -68238,7 +68358,7 @@ function buildRuntimeModeContext(state) {
68238
68358
  const transitionText = {
68239
68359
  entered_yolo: "YOLO mode was just enabled for this turn.",
68240
68360
  exited_yolo: "YOLO mode was just disabled; do not assume previous absolute-path access still applies.",
68241
- entered_plan: "Plan mode was just enabled; analyze and plan without making changes.",
68361
+ entered_plan: "Plan mode was just enabled; analyze and plan without changing the workspace. Use plan_scratch for temporary drafts.",
68242
68362
  exited_plan: "Plan mode was just disabled; execution tools may be used when the task requires them."
68243
68363
  };
68244
68364
  lines.push(`- Transition: ${transitionText[state.pendingTransition]}`);
@@ -69240,7 +69360,10 @@ var InteractiveMode = class {
69240
69360
  async syncSessionScopedState(messages) {
69241
69361
  const activeSession = this.sessionManager.getActiveSession();
69242
69362
  const sessionMessages = messages ?? this.sessionManager.getMessages();
69243
- this.executionState.restoreFromMetadata(activeSession?.metadata?.executionState);
69363
+ const restoredExecutionState = this.executionState.restoreFromMetadata(activeSession?.metadata?.executionState);
69364
+ if (restoredExecutionState.lifecycle === "paused" && activeSession?.metadata?.executionState?.awaitingContinuation) {
69365
+ this.persistExecutionState();
69366
+ }
69244
69367
  if (this.executionState.clearIfSupersededByUserMessage(sessionMessages)) {
69245
69368
  this.persistExecutionState();
69246
69369
  }
@@ -69257,7 +69380,7 @@ var InteractiveMode = class {
69257
69380
  if (savedLevel) {
69258
69381
  this.thinkingLevel = savedLevel;
69259
69382
  }
69260
- const { Agent } = await import("./chunks/src-27UD2ZBZ.js");
69383
+ const { Agent } = await import("./chunks/src-PBRYPFUI.js");
69261
69384
  const activeSession = this.sessionManager.getActiveSession();
69262
69385
  this.agent = new Agent({
69263
69386
  initialState: {
@@ -69978,7 +70101,7 @@ async function runPrintMode(params) {
69978
70101
  `);
69979
70102
  console.log("Assistant: ");
69980
70103
  }
69981
- const { Agent: AgentClass } = await import("./chunks/src-27UD2ZBZ.js");
70104
+ const { Agent: AgentClass } = await import("./chunks/src-PBRYPFUI.js");
69982
70105
  let agent;
69983
70106
  const printModeExtensions = await loadPrintModeExtensions({
69984
70107
  cwd: runtime.cwd,
@@ -70224,6 +70347,26 @@ function parseInput(line) {
70224
70347
  reason: typeof parsed.reason === "string" ? parsed.reason : void 0
70225
70348
  };
70226
70349
  }
70350
+ if (parsed.type === "session.rewind") {
70351
+ return {
70352
+ type: "session.rewind",
70353
+ sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
70354
+ requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
70355
+ entryId: typeof parsed.entryId === "string" ? parsed.entryId : void 0,
70356
+ checkpointId: typeof parsed.checkpointId === "string" ? parsed.checkpointId : void 0
70357
+ };
70358
+ }
70359
+ if (parsed.type === "session.fork") {
70360
+ return {
70361
+ type: "session.fork",
70362
+ sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
70363
+ requestId: typeof parsed.requestId === "string" ? parsed.requestId : void 0,
70364
+ fromEntryId: typeof parsed.fromEntryId === "string" ? parsed.fromEntryId : void 0,
70365
+ targetSessionId: typeof parsed.targetSessionId === "string" ? parsed.targetSessionId : void 0,
70366
+ name: typeof parsed.name === "string" ? parsed.name : void 0,
70367
+ cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0
70368
+ };
70369
+ }
70227
70370
  if ((parsed.type === "turn.request" || parsed.type === "turn.input") && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
70228
70371
  const streamingBehavior = parsed.streamingBehavior;
70229
70372
  if (streamingBehavior !== void 0 && streamingBehavior !== "steer" && streamingBehavior !== "followUp") {
@@ -70386,6 +70529,7 @@ async function runJsonEventsMode(params) {
70386
70529
  let thinkingLevel = "off";
70387
70530
  let defaultRuntime;
70388
70531
  let defaultModelState;
70532
+ const completedSessionControlRequests = /* @__PURE__ */ new Map();
70389
70533
  const noProgressTimeoutMs = Number(process.env.PIE_JSON_EVENTS_NO_PROGRESS_MS || 6e5);
70390
70534
  const mockResponseDelayMs = Number(process.env.PIE_TEST_MOCK_RESPONSE_DELAY_MS || 0);
70391
70535
  writeEvent({ type: "agent.ready", sessionId });
@@ -70534,6 +70678,148 @@ async function runJsonEventsMode(params) {
70534
70678
  }
70535
70679
  return error instanceof Error ? error.message : String(error);
70536
70680
  }
70681
+ function sessionControlStore() {
70682
+ return new FileSessionStore(runtime?.paths.sessionsDir ?? getSessionsDir());
70683
+ }
70684
+ function invalidSessionControl(message) {
70685
+ return new SessionControlError("invalid_request", message);
70686
+ }
70687
+ function requireSessionControlString(value, field) {
70688
+ const normalized = value?.trim();
70689
+ if (!normalized) {
70690
+ throw invalidSessionControl(`${field} is required`);
70691
+ }
70692
+ return normalized;
70693
+ }
70694
+ function requireSessionControlBase(message) {
70695
+ const requestedSessionId = requireSessionControlString(message.sessionId, "sessionId");
70696
+ const requestId = requireSessionControlString(message.requestId, "requestId");
70697
+ if (requestedSessionId !== sessionId) {
70698
+ throw new SessionControlError("session_mismatch", sessionMismatchError(requestedSessionId), false);
70699
+ }
70700
+ if (activeTurn && !activeTurn.finalized) {
70701
+ throw new SessionControlError("session_busy", `Cannot ${message.type.slice("session.".length)} session while a turn is active`);
70702
+ }
70703
+ return { sessionId: requestedSessionId, requestId };
70704
+ }
70705
+ function resolveRewindEntryId(message) {
70706
+ const entryId = message.entryId?.trim();
70707
+ const checkpointId = message.checkpointId?.trim();
70708
+ if (entryId && checkpointId && entryId !== checkpointId) {
70709
+ throw invalidSessionControl("entryId and checkpointId must match when both are provided");
70710
+ }
70711
+ const resolved = entryId || checkpointId;
70712
+ if (!resolved) {
70713
+ throw invalidSessionControl("entryId or checkpointId is required");
70714
+ }
70715
+ return resolved;
70716
+ }
70717
+ function writeSessionControlFailure(message, operation, error) {
70718
+ const detail = error instanceof SessionControlError ? error : new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
70719
+ writeEvent({
70720
+ type: "session.failed",
70721
+ sessionId: message.sessionId || sessionId,
70722
+ requestId: message.requestId,
70723
+ operation,
70724
+ error: detail.message,
70725
+ code: detail.code,
70726
+ recoverable: detail.recoverable
70727
+ });
70728
+ }
70729
+ async function saveRuntimeSessionForControl() {
70730
+ if (!runtime?.sessionManager.getActiveSession()) return;
70731
+ try {
70732
+ await runtime.sessionManager.save();
70733
+ } catch (error) {
70734
+ throw new SessionControlError("session_io_error", error instanceof Error ? error.message : String(error));
70735
+ }
70736
+ }
70737
+ async function syncRuntimeAfterRewind(controlSessionId) {
70738
+ if (params.mockResponse !== void 0) return;
70739
+ if (runtime?.sessionManager.getActiveSessionId() !== controlSessionId) return;
70740
+ const loaded = await runtime.sessionManager.loadSession(controlSessionId, { warnIfMissing: false });
70741
+ if (!loaded) {
70742
+ const exists = await runtime.sessionManager.hasSession(controlSessionId);
70743
+ throw new SessionControlError(
70744
+ exists ? "session_unrecoverable" : "session_not_found",
70745
+ exists ? `Session could not be recovered: ${controlSessionId}` : `Session not found: ${controlSessionId}`,
70746
+ !exists
70747
+ );
70748
+ }
70749
+ controller?.syncFromActiveSession();
70750
+ }
70751
+ async function handleSessionRewind(message) {
70752
+ try {
70753
+ const { sessionId: controlSessionId, requestId } = requireSessionControlBase(message);
70754
+ const cached = completedSessionControlRequests.get(requestId);
70755
+ if (cached) {
70756
+ writeEvent(cached);
70757
+ return;
70758
+ }
70759
+ const entryId = resolveRewindEntryId(message);
70760
+ await saveRuntimeSessionForControl();
70761
+ const result = await rewindStoredSession({
70762
+ store: sessionControlStore(),
70763
+ sessionId: controlSessionId,
70764
+ entryId
70765
+ });
70766
+ await syncRuntimeAfterRewind(controlSessionId);
70767
+ mockActiveEntryId = result.headEntryId;
70768
+ const event = {
70769
+ type: "session.rewound",
70770
+ sessionId: controlSessionId,
70771
+ requestId,
70772
+ entryId: result.entryId,
70773
+ checkpointId: result.checkpointId,
70774
+ headEntryId: result.headEntryId,
70775
+ activeEntryId: result.activeEntryId
70776
+ };
70777
+ completedSessionControlRequests.set(requestId, event);
70778
+ writeEvent(event);
70779
+ } catch (error) {
70780
+ writeSessionControlFailure(message, "rewind", error);
70781
+ }
70782
+ }
70783
+ async function handleSessionFork(message) {
70784
+ try {
70785
+ const { sessionId: controlSessionId, requestId } = requireSessionControlBase(message);
70786
+ const sourceEntryId = requireSessionControlString(message.fromEntryId, "fromEntryId");
70787
+ const targetSessionId = requireSessionControlString(message.targetSessionId, "targetSessionId");
70788
+ const name = requireSessionControlString(message.name, "name");
70789
+ const forkCwd = message.cwd?.trim() || void 0;
70790
+ const cached = completedSessionControlRequests.get(requestId);
70791
+ if (cached) {
70792
+ writeEvent(cached);
70793
+ return;
70794
+ }
70795
+ await saveRuntimeSessionForControl();
70796
+ const result = await forkStoredSession({
70797
+ store: sessionControlStore(),
70798
+ sourceSessionId: controlSessionId,
70799
+ sourceEntryId,
70800
+ targetSessionId,
70801
+ name,
70802
+ cwd: forkCwd,
70803
+ requestId
70804
+ });
70805
+ const event = {
70806
+ type: "session.forked",
70807
+ sessionId: controlSessionId,
70808
+ requestId,
70809
+ sourceSessionId: result.sourceSessionId,
70810
+ sourceEntryId: result.sourceEntryId,
70811
+ sourceCheckpointId: result.sourceCheckpointId,
70812
+ targetSessionId: result.targetSessionId,
70813
+ targetHeadEntryId: result.targetHeadEntryId,
70814
+ targetActiveEntryId: result.targetActiveEntryId,
70815
+ headEntryId: result.headEntryId
70816
+ };
70817
+ completedSessionControlRequests.set(requestId, event);
70818
+ writeEvent(event);
70819
+ } catch (error) {
70820
+ writeSessionControlFailure(message, "fork", error);
70821
+ }
70822
+ }
70537
70823
  function finalize(kind, detail) {
70538
70824
  const turn = activeTurn;
70539
70825
  if (!turn || turn.finalized) return;
@@ -70765,7 +71051,7 @@ async function runJsonEventsMode(params) {
70765
71051
  if (runtime.initialModel.unconfigured || controller) {
70766
71052
  return;
70767
71053
  }
70768
- const { Agent: AgentClass } = await import("./chunks/src-27UD2ZBZ.js");
71054
+ const { Agent: AgentClass } = await import("./chunks/src-PBRYPFUI.js");
70769
71055
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
70770
71056
  const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
70771
71057
  recordCliCompositionStep(runtime.compositionTrace, {
@@ -71169,6 +71455,14 @@ async function runJsonEventsMode(params) {
71169
71455
  await interrupt(message);
71170
71456
  continue;
71171
71457
  }
71458
+ if (message.type === "session.rewind") {
71459
+ await handleSessionRewind(message);
71460
+ continue;
71461
+ }
71462
+ if (message.type === "session.fork") {
71463
+ await handleSessionFork(message);
71464
+ continue;
71465
+ }
71172
71466
  const shouldTrackTurn = !activeTurn || activeTurn.finalized;
71173
71467
  const turnPromise = runTurn(message).catch((error) => {
71174
71468
  writeEvent({
@@ -71389,7 +71683,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
71389
71683
  }
71390
71684
  async function createCliTestStreamFnFromEnv() {
71391
71685
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
71392
- return (await import("./chunks/test-stream-L4PUYWQQ.js")).createTestStreamFnFromSequenceEnv();
71686
+ return (await import("./chunks/test-stream-EO6L26M5.js")).createTestStreamFnFromSequenceEnv();
71393
71687
  }
71394
71688
  async function startChat(initialPrompt, testCommand) {
71395
71689
  const rawOutput = process.argv.includes("--raw-output");