@moxt-ai/mobius 0.0.134 → 0.0.136

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.
Files changed (36) hide show
  1. package/dist/acp/activity.d.ts +1 -0
  2. package/dist/acp/activity.d.ts.map +1 -1
  3. package/dist/acp/activity.js +11 -0
  4. package/dist/acp/activity.js.map +1 -1
  5. package/dist/acp/agent-session.d.ts.map +1 -1
  6. package/dist/acp/agent-session.js +12 -0
  7. package/dist/acp/agent-session.js.map +1 -1
  8. package/dist/acp/codex/agent.d.ts.map +1 -1
  9. package/dist/acp/codex/agent.js +28 -1
  10. package/dist/acp/codex/agent.js.map +1 -1
  11. package/dist/acp/codex/app-server-protocol.d.ts +8 -0
  12. package/dist/acp/codex/app-server-protocol.d.ts.map +1 -1
  13. package/dist/acp/codex/app-server-protocol.js +6 -0
  14. package/dist/acp/codex/app-server-protocol.js.map +1 -1
  15. package/dist/acp/session-failure.d.ts +12 -0
  16. package/dist/acp/session-failure.d.ts.map +1 -0
  17. package/dist/acp/session-failure.js +65 -0
  18. package/dist/acp/session-failure.js.map +1 -0
  19. package/dist/cli.js +353 -228
  20. package/dist/cli.js.map +4 -4
  21. package/dist/daemon-active-turn.d.ts +1 -0
  22. package/dist/daemon-active-turn.d.ts.map +1 -1
  23. package/dist/daemon-active-turn.js +16 -17
  24. package/dist/daemon-active-turn.js.map +1 -1
  25. package/dist/daemon-turn-registry.d.ts +14 -14
  26. package/dist/daemon-turn-registry.d.ts.map +1 -1
  27. package/dist/daemon-turn-registry.js +6 -2
  28. package/dist/daemon-turn-registry.js.map +1 -1
  29. package/dist/index.js +244 -117
  30. package/dist/index.js.map +4 -4
  31. package/dist/run-daemon.d.ts.map +1 -1
  32. package/dist/run-daemon.js +1 -2
  33. package/dist/run-daemon.js.map +1 -1
  34. package/dist/runtime.js +330 -205
  35. package/dist/runtime.js.map +4 -4
  36. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3381,7 +3381,7 @@ var program = new Command();
3381
3381
  // package.json
3382
3382
  var package_default = {
3383
3383
  name: "@moxt-ai/mobius",
3384
- version: "0.0.134",
3384
+ version: "0.0.136",
3385
3385
  description: "Mobius CLI for pairing and running local AI agent services.",
3386
3386
  type: "module",
3387
3387
  bin: {
@@ -3453,8 +3453,8 @@ function hasTrueChildField(value, childKey, fieldKey) {
3453
3453
  if (!isRecord(value)) {
3454
3454
  return false;
3455
3455
  }
3456
- const child = Reflect.get(value, childKey);
3457
- return isRecord(child) && Reflect.get(child, fieldKey) === true;
3456
+ const child2 = Reflect.get(value, childKey);
3457
+ return isRecord(child2) && Reflect.get(child2, fieldKey) === true;
3458
3458
  }
3459
3459
  function unsupportedSessionCapabilities() {
3460
3460
  return Object.freeze({
@@ -3766,17 +3766,17 @@ function mergeProcessTrees(captured, current) {
3766
3766
  }
3767
3767
  return [...processes.values()];
3768
3768
  }
3769
- async function captureProcessTree(child) {
3770
- if (process.platform === "win32" || child.pid === void 0) {
3769
+ async function captureProcessTree(child2) {
3770
+ if (process.platform === "win32" || child2.pid === void 0) {
3771
3771
  return [];
3772
3772
  }
3773
3773
  if (process.platform === "linux") {
3774
3774
  const procfsEntries = readLinuxProcessTableSynchronously();
3775
3775
  if (procfsEntries.length > 0) {
3776
- return selectProcessTree(procfsEntries, child.pid);
3776
+ return selectProcessTree(procfsEntries, child2.pid);
3777
3777
  }
3778
3778
  }
3779
- return selectProcessTree(await readProcessTable(), child.pid);
3779
+ return selectProcessTree(await readProcessTable(), child2.pid);
3780
3780
  }
3781
3781
  function signalCapturedProcessGroups(processes, rootProcessId, signal) {
3782
3782
  const processIds = new Set(processes.map((identity2) => identity2.processId));
@@ -3833,63 +3833,63 @@ async function waitForCapturedProcessesExit(processes, rootProcessId) {
3833
3833
  }
3834
3834
  return processIds.every((processId) => !processExists(processId));
3835
3835
  }
3836
- function terminateProcess(child) {
3837
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
3836
+ function terminateProcess(child2) {
3837
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
3838
3838
  return;
3839
3839
  }
3840
3840
  if (process.platform !== "win32") {
3841
3841
  try {
3842
- process.kill(-child.pid, "SIGTERM");
3842
+ process.kill(-child2.pid, "SIGTERM");
3843
3843
  return;
3844
3844
  } catch {
3845
3845
  }
3846
3846
  }
3847
- child.kill("SIGTERM");
3847
+ child2.kill("SIGTERM");
3848
3848
  }
3849
- function forceTerminateProcess(child) {
3850
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
3849
+ function forceTerminateProcess(child2) {
3850
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
3851
3851
  return;
3852
3852
  }
3853
3853
  if (process.platform !== "win32") {
3854
3854
  try {
3855
- process.kill(-child.pid, "SIGKILL");
3855
+ process.kill(-child2.pid, "SIGKILL");
3856
3856
  return;
3857
3857
  } catch {
3858
3858
  }
3859
3859
  }
3860
- child.kill("SIGKILL");
3860
+ child2.kill("SIGKILL");
3861
3861
  }
3862
- async function stopProcessTree(child, capturedProcesses = []) {
3863
- const childProcessId = child.pid;
3862
+ async function stopProcessTree(child2, capturedProcesses = []) {
3863
+ const childProcessId = child2.pid;
3864
3864
  if (childProcessId === void 0) {
3865
3865
  return;
3866
3866
  }
3867
- const childExited = child.exitCode !== null || child.signalCode !== null;
3868
- const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child));
3867
+ const childExited = child2.exitCode !== null || child2.signalCode !== null;
3868
+ const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child2));
3869
3869
  if (childExited && processes.length === 0) {
3870
3870
  return;
3871
3871
  }
3872
3872
  signalCapturedProcessGroups(processes, childProcessId, GRACEFUL_STOP_SIGNAL);
3873
- terminateProcess(child);
3873
+ terminateProcess(child2);
3874
3874
  const [exitedAfterTermination, descendantsExitedAfterTermination] = await Promise.all([
3875
- waitForProcessExit(child, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
3875
+ waitForProcessExit(child2, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
3876
3876
  waitForCapturedProcessesExit(processes, childProcessId)
3877
3877
  ]);
3878
3878
  if (exitedAfterTermination && descendantsExitedAfterTermination) {
3879
3879
  return;
3880
3880
  }
3881
3881
  signalCapturedProcessGroups(processes, childProcessId, FORCED_STOP_SIGNAL);
3882
- forceTerminateProcess(child);
3882
+ forceTerminateProcess(child2);
3883
3883
  const [exitedAfterForce, descendantsExitedAfterForce] = await Promise.all([
3884
- waitForProcessExit(child, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
3884
+ waitForProcessExit(child2, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
3885
3885
  waitForCapturedProcessesExit(processes, childProcessId)
3886
3886
  ]);
3887
3887
  if (!exitedAfterForce || !descendantsExitedAfterForce) {
3888
3888
  throw new ProcessExecutionError("process_termination_timeout", "The executable process could not be stopped");
3889
3889
  }
3890
3890
  }
3891
- function waitForProcessExit(child, timeoutMilliseconds) {
3892
- if (child.exitCode !== null || child.signalCode !== null) {
3891
+ function waitForProcessExit(child2, timeoutMilliseconds) {
3892
+ if (child2.exitCode !== null || child2.signalCode !== null) {
3893
3893
  return Promise.resolve(true);
3894
3894
  }
3895
3895
  return new Promise((resolveExit) => {
@@ -3900,13 +3900,13 @@ function waitForProcessExit(child, timeoutMilliseconds) {
3900
3900
  }
3901
3901
  settled = true;
3902
3902
  clearTimeout(timeout);
3903
- child.removeListener("exit", handleExit);
3903
+ child2.removeListener("exit", handleExit);
3904
3904
  resolveExit(exited);
3905
3905
  };
3906
3906
  const handleExit = () => finish(true);
3907
3907
  const timeout = setTimeout(() => finish(false), timeoutMilliseconds);
3908
- child.once("exit", handleExit);
3909
- if (child.exitCode !== null || child.signalCode !== null) {
3908
+ child2.once("exit", handleExit);
3909
+ if (child2.exitCode !== null || child2.signalCode !== null) {
3910
3910
  finish(true);
3911
3911
  }
3912
3912
  });
@@ -3914,7 +3914,7 @@ function waitForProcessExit(child, timeoutMilliseconds) {
3914
3914
  async function runBoundedProcess(options) {
3915
3915
  options.signal.throwIfAborted();
3916
3916
  const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
3917
- const child = spawn(options.command, [...options.arguments], {
3917
+ const child2 = spawn(options.command, [...options.arguments], {
3918
3918
  cwd: options.cwd,
3919
3919
  detached: process.platform !== "win32",
3920
3920
  env: { ...options.environment },
@@ -3937,7 +3937,7 @@ async function runBoundedProcess(options) {
3937
3937
  interruptionFailure = failure2;
3938
3938
  const stop = async () => {
3939
3939
  try {
3940
- await stopProcessTree(child);
3940
+ await stopProcessTree(child2);
3941
3941
  } catch (error62) {
3942
3942
  interruptionCleanupFailure = error62 instanceof ProcessExecutionError ? error62 : new ProcessExecutionError(
3943
3943
  "process_termination_failed",
@@ -3976,8 +3976,8 @@ async function runBoundedProcess(options) {
3976
3976
  interrupt(failure2);
3977
3977
  }
3978
3978
  };
3979
- child.stdout?.on("data", collectStdout);
3980
- child.stderr?.on("data", collectStderr);
3979
+ child2.stdout?.on("data", collectStdout);
3980
+ child2.stderr?.on("data", collectStderr);
3981
3981
  const timeout = setTimeout(() => {
3982
3982
  interrupt(new ProcessExecutionError("process_timeout", "The executable probe timed out"));
3983
3983
  }, options.timeoutMilliseconds);
@@ -3992,8 +3992,8 @@ async function runBoundedProcess(options) {
3992
3992
  }
3993
3993
  try {
3994
3994
  const exit = new Promise((resolveExit, rejectExit) => {
3995
- child.once("error", rejectExit);
3996
- child.once("exit", (code) => resolveExit(code ?? 1));
3995
+ child2.once("error", rejectExit);
3996
+ child2.once("exit", (code) => resolveExit(code ?? 1));
3997
3997
  });
3998
3998
  const exitCode = await Promise.race([exit, interrupted.promise.then(() => -1)]);
3999
3999
  if (interruptionCleanupFailure !== null) {
@@ -4016,12 +4016,12 @@ async function runBoundedProcess(options) {
4016
4016
  } finally {
4017
4017
  clearTimeout(timeout);
4018
4018
  options.signal.removeEventListener("abort", abort);
4019
- child.stdout?.removeListener("data", collectStdout);
4020
- child.stderr?.removeListener("data", collectStderr);
4019
+ child2.stdout?.removeListener("data", collectStdout);
4020
+ child2.stderr?.removeListener("data", collectStderr);
4021
4021
  if (stopping) {
4022
4022
  await interrupted.promise;
4023
4023
  } else {
4024
- await stopProcessTree(child);
4024
+ await stopProcessTree(child2);
4025
4025
  }
4026
4026
  }
4027
4027
  }
@@ -4824,6 +4824,74 @@ function acpEndpointTerminationError(termination) {
4824
4824
  }
4825
4825
  }
4826
4826
 
4827
+ // src/acp/value-utils.ts
4828
+ function truncate(value, maximumLength) {
4829
+ return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
4830
+ }
4831
+ function isRecord3(value) {
4832
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4833
+ }
4834
+ function readString(value, fallback = "") {
4835
+ return typeof value === "string" ? value : fallback;
4836
+ }
4837
+
4838
+ // src/acp/session-failure.ts
4839
+ var CATEGORIES = /* @__PURE__ */ new Set([
4840
+ "access",
4841
+ "connection",
4842
+ "limit",
4843
+ "request",
4844
+ "service",
4845
+ "unknown"
4846
+ ]);
4847
+ function isCategory(value) {
4848
+ return typeof value === "string" && CATEGORIES.has(value);
4849
+ }
4850
+ function child(value, key) {
4851
+ return isRecord3(value) ? value[key] : void 0;
4852
+ }
4853
+ function readAcpSessionFailure(value) {
4854
+ const meta3 = child(value, "_meta");
4855
+ const jetbrains = child(meta3, "jetbrains");
4856
+ const air = child(jetbrains, "air");
4857
+ const failure2 = child(air, "sessionFailure");
4858
+ if (!isRecord3(air) || !Number.isInteger(air["version"]) || Number(air["version"]) < 1 || !isRecord3(failure2)) {
4859
+ return null;
4860
+ }
4861
+ const id = failure2["id"];
4862
+ const revision = failure2["revision"];
4863
+ const category = failure2["category"];
4864
+ const severity = failure2["severity"];
4865
+ const title2 = failure2["title"];
4866
+ if (typeof id !== "string" || id.length === 0 || id.length > 512 || !Number.isInteger(revision) || Number(revision) < 1 || !isCategory(category) || severity !== "warning" && severity !== "error" || typeof title2 !== "string" || title2.length === 0) {
4867
+ return null;
4868
+ }
4869
+ return {
4870
+ category,
4871
+ id,
4872
+ revision: Number(revision),
4873
+ severity,
4874
+ title: truncate(title2, 4096)
4875
+ };
4876
+ }
4877
+ function sessionFailureMeta(failure2) {
4878
+ return {
4879
+ jetbrains: {
4880
+ air: {
4881
+ version: 1,
4882
+ sessionFailure: {
4883
+ actions: [],
4884
+ category: failure2.category,
4885
+ id: failure2.id,
4886
+ revision: failure2.revision,
4887
+ severity: failure2.severity,
4888
+ title: failure2.title
4889
+ }
4890
+ }
4891
+ }
4892
+ };
4893
+ }
4894
+
4827
4895
  // src/acp/codex/app-server-client.ts
4828
4896
  import { spawn as spawn2 } from "node:child_process";
4829
4897
 
@@ -9861,9 +9929,9 @@ function isRecursive(inst, stack, resolve9) {
9861
9929
  return PROVEN;
9862
9930
  stack.add(inst);
9863
9931
  let result = NONE;
9864
- const check2 = (child) => {
9865
- if (result !== PROVEN && child?._zod) {
9866
- const answer = isRecursive(child, stack, resolve9);
9932
+ const check2 = (child2) => {
9933
+ if (result !== PROVEN && child2?._zod) {
9934
+ const answer = isRecursive(child2, stack, resolve9);
9867
9935
  if (answer > result)
9868
9936
  result = answer;
9869
9937
  }
@@ -9874,9 +9942,9 @@ function isRecursive(inst, stack, resolve9) {
9874
9942
  const desc2 = Object.getOwnPropertyDescriptor(sh, key);
9875
9943
  if (spread && !desc2.enumerable)
9876
9944
  continue;
9877
- const child = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
9878
- if (child > answer)
9879
- answer = child;
9945
+ const child2 = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
9946
+ if (child2 > answer)
9947
+ answer = child2;
9880
9948
  }
9881
9949
  return answer;
9882
9950
  };
@@ -24616,6 +24684,12 @@ var turnNotificationSchema = external_exports.object({
24616
24684
  threadId: boundedText(256),
24617
24685
  turn: turnSchema
24618
24686
  });
24687
+ var errorNotificationSchema = external_exports.object({
24688
+ error: external_exports.object({ message: boundedText(4096) }),
24689
+ threadId: boundedText(256),
24690
+ turnId: boundedText(256),
24691
+ willRetry: external_exports.boolean()
24692
+ });
24619
24693
  var commandApprovalParamsSchema = external_exports.object({
24620
24694
  command: external_exports.string().nullish(),
24621
24695
  commandActions: external_exports.array(external_exports.unknown()).max(1e3).nullish(),
@@ -24960,7 +25034,7 @@ var CodexAppServerClient = class {
24960
25034
  var TOOL_OUTPUT_CHARACTER_LIMIT = 32768;
24961
25035
  var TITLE_CHARACTER_LIMIT = 500;
24962
25036
  var CODEX_META_KEY = "codex";
24963
- function truncate(value, limit) {
25037
+ function truncate2(value, limit) {
24964
25038
  return value.length <= limit ? value : value.slice(0, limit);
24965
25039
  }
24966
25040
  function boundedParagraphs(values, limit) {
@@ -24976,7 +25050,7 @@ function boundedParagraphs(values, limit) {
24976
25050
  return text2;
24977
25051
  }
24978
25052
  function textContent(text2) {
24979
- const block = { text: truncate(text2, TOOL_OUTPUT_CHARACTER_LIMIT), type: "text" };
25053
+ const block = { text: truncate2(text2, TOOL_OUTPUT_CHARACTER_LIMIT), type: "text" };
24980
25054
  return { content: block, type: "content" };
24981
25055
  }
24982
25056
  function firstLine(value) {
@@ -25015,16 +25089,16 @@ function presentToolItem(item) {
25015
25089
  rawInput: { command: item.command, cwd: item.cwd },
25016
25090
  rawOutput: {
25017
25091
  ...item.exitCode == null ? {} : { exitCode: item.exitCode },
25018
- output: truncate(output2, TOOL_OUTPUT_CHARACTER_LIMIT)
25092
+ output: truncate2(output2, TOOL_OUTPUT_CHARACTER_LIMIT)
25019
25093
  },
25020
25094
  status: commandStatus(item.status),
25021
- title: truncate(firstLine(item.command), TITLE_CHARACTER_LIMIT)
25095
+ title: truncate2(firstLine(item.command), TITLE_CHARACTER_LIMIT)
25022
25096
  };
25023
25097
  }
25024
25098
  if (item.type === "fileChange") {
25025
25099
  const paths = item.changes.map((change) => change.path);
25026
25100
  const content = item.changes.map((change) => ({
25027
- newText: truncate(change.diff, TOOL_OUTPUT_CHARACTER_LIMIT),
25101
+ newText: truncate2(change.diff, TOOL_OUTPUT_CHARACTER_LIMIT),
25028
25102
  path: change.path,
25029
25103
  type: "diff"
25030
25104
  }));
@@ -25035,7 +25109,7 @@ function presentToolItem(item) {
25035
25109
  rawInput: { changes: item.changes.map((change) => change.path) },
25036
25110
  rawOutput: null,
25037
25111
  status: patchStatus(item.status),
25038
- title: truncate(paths.join(", "), TITLE_CHARACTER_LIMIT)
25112
+ title: truncate2(paths.join(", "), TITLE_CHARACTER_LIMIT)
25039
25113
  };
25040
25114
  }
25041
25115
  if (item.type === "mcpToolCall") {
@@ -25054,7 +25128,7 @@ function presentToolItem(item) {
25054
25128
  rawInput: item.arguments ?? null,
25055
25129
  rawOutput: item.error ?? item.result ?? null,
25056
25130
  status: mcpStatus(item.status),
25057
- title: truncate(label, TITLE_CHARACTER_LIMIT)
25131
+ title: truncate2(label, TITLE_CHARACTER_LIMIT)
25058
25132
  };
25059
25133
  }
25060
25134
  if (item.type === "dynamicToolCall") {
@@ -25067,7 +25141,7 @@ function presentToolItem(item) {
25067
25141
  rawInput: item.arguments ?? null,
25068
25142
  rawOutput: item.success === true ? null : item.contentItems ?? null,
25069
25143
  status: mcpStatus(item.status),
25070
- title: truncate(label, TITLE_CHARACTER_LIMIT)
25144
+ title: truncate2(label, TITLE_CHARACTER_LIMIT)
25071
25145
  };
25072
25146
  }
25073
25147
  return null;
@@ -25625,6 +25699,7 @@ var CodexAcpAgent = class {
25625
25699
  #nativeSessionId = "";
25626
25700
  #streamedReasoningItemIds = /* @__PURE__ */ new Set();
25627
25701
  #streamedAgentMessageItemIds = /* @__PURE__ */ new Set();
25702
+ #noticeRevisions = /* @__PURE__ */ new Map();
25628
25703
  #turn = null;
25629
25704
  #nativeTurnId = null;
25630
25705
  #updateTail = Promise.resolve();
@@ -25777,10 +25852,10 @@ var CodexAcpAgent = class {
25777
25852
  if (this.#closePromise === null) {
25778
25853
  this.#appServer.detach();
25779
25854
  this.#closePromise = (async () => {
25780
- const child = this.#appServer.child();
25855
+ const child2 = this.#appServer.child();
25781
25856
  try {
25782
- const captured = await captureProcessTree(child);
25783
- await stopProcessTree(child, captured);
25857
+ const captured = await captureProcessTree(child2);
25858
+ await stopProcessTree(child2, captured);
25784
25859
  } finally {
25785
25860
  this.#connection?.close();
25786
25861
  }
@@ -25870,6 +25945,27 @@ var CodexAcpAgent = class {
25870
25945
  await pending;
25871
25946
  };
25872
25947
  #onNotification = async (method, params) => {
25948
+ if (method === "error") {
25949
+ const decoded = errorNotificationSchema.safeParse(params);
25950
+ if (decoded.success && decoded.data.willRetry && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null && decoded.data.turnId === this.#turn.turn.id) {
25951
+ const id = `codex:${decoded.data.turnId}:error`;
25952
+ const revision = (this.#noticeRevisions.get(id) ?? 0) + 1;
25953
+ this.#noticeRevisions.set(id, revision);
25954
+ await this.#enqueue(async () => {
25955
+ await this.#emit({
25956
+ _meta: sessionFailureMeta({
25957
+ category: "service",
25958
+ id,
25959
+ revision,
25960
+ severity: "warning",
25961
+ title: decoded.data.error.message
25962
+ }),
25963
+ sessionUpdate: "session_info_update"
25964
+ });
25965
+ });
25966
+ }
25967
+ return;
25968
+ }
25873
25969
  if (method === "turn/started") {
25874
25970
  const decoded = turnNotificationSchema.safeParse(params);
25875
25971
  if (decoded.success && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null) {
@@ -26847,7 +26943,7 @@ var ManagedAgentArchiveError = class extends Error {
26847
26943
  this.name = "ManagedAgentArchiveError";
26848
26944
  }
26849
26945
  };
26850
- function isRecord3(value) {
26946
+ function isRecord4(value) {
26851
26947
  return typeof value === "object" && value !== null && !Array.isArray(value);
26852
26948
  }
26853
26949
  function isContainedPath3(root, candidate) {
@@ -26904,7 +27000,7 @@ async function readManifest(path3) {
26904
27000
  );
26905
27001
  }
26906
27002
  const parsed = JSON.parse(await handle.readFile({ encoding: "utf8" }));
26907
- if (!isRecord3(parsed)) {
27003
+ if (!isRecord4(parsed)) {
26908
27004
  throw new ManagedAgentArchiveError(
26909
27005
  "managed_archive_verification_failed",
26910
27006
  "The managed Agent archive manifest is invalid"
@@ -27540,7 +27636,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
27540
27636
  signal.removeEventListener("abort", abort);
27541
27637
  }
27542
27638
  }
27543
- const child = spawn3(agent.adapterPath, [...agent.arguments], {
27639
+ const child2 = spawn3(agent.adapterPath, [...agent.arguments], {
27544
27640
  cwd: defaultWorkspace,
27545
27641
  detached: process.platform !== "win32",
27546
27642
  env: { ...environment, ...agent.environment },
@@ -27549,17 +27645,17 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
27549
27645
  });
27550
27646
  const processExit = new Promise((_resolve, reject) => {
27551
27647
  const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
27552
- child.once("error", reject);
27553
- child.once("exit", rejectExit);
27554
- if (child.exitCode !== null || child.signalCode !== null) {
27648
+ child2.once("error", reject);
27649
+ child2.once("exit", rejectExit);
27650
+ if (child2.exitCode !== null || child2.signalCode !== null) {
27555
27651
  rejectExit();
27556
27652
  }
27557
27653
  });
27558
- const stdin = child.stdin;
27559
- const stdout = child.stdout;
27560
- const stderr = child.stderr;
27654
+ const stdin = child2.stdin;
27655
+ const stdout = child2.stdout;
27656
+ const stderr = child2.stderr;
27561
27657
  if (stdin === null || stdout === null || stderr === null) {
27562
- await stopProcessTree(child);
27658
+ await stopProcessTree(child2);
27563
27659
  throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
27564
27660
  }
27565
27661
  let stderrBytes = 0;
@@ -27611,11 +27707,11 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
27611
27707
  } finally {
27612
27708
  clearTimeout(timeout);
27613
27709
  signal.removeEventListener("abort", abort);
27614
- const capturedProcesses = await captureProcessTree(child);
27710
+ const capturedProcesses = await captureProcessTree(child2);
27615
27711
  connection.close();
27616
27712
  stdin.end();
27617
27713
  stderr.removeListener("data", consumeStderr);
27618
- await stopProcessTree(child, capturedProcesses);
27714
+ await stopProcessTree(child2, capturedProcesses);
27619
27715
  }
27620
27716
  }
27621
27717
 
@@ -28835,7 +28931,7 @@ var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
28835
28931
  var MAX_PROMPT_LENGTH = 1e4;
28836
28932
  var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
28837
28933
  var MAX_EVENT_TEXT_LENGTH = 1e5;
28838
- var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["plan", "progress", "reasoning", "tool"]);
28934
+ var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["notice", "plan", "progress", "reasoning", "tool"]);
28839
28935
  var NARRATION_ACTIVITY_TYPES = /* @__PURE__ */ new Set(["progress", "reasoning"]);
28840
28936
  var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
28841
28937
  var TOOL_KINDS = /* @__PURE__ */ new Set([
@@ -28858,7 +28954,7 @@ var ProtocolMessageError = class extends Error {
28858
28954
  this.name = "ProtocolMessageError";
28859
28955
  }
28860
28956
  };
28861
- function isRecord4(value) {
28957
+ function isRecord5(value) {
28862
28958
  return typeof value === "object" && value !== null && !Array.isArray(value);
28863
28959
  }
28864
28960
  function parseJson2(encoded) {
@@ -28870,7 +28966,7 @@ function parseJson2(encoded) {
28870
28966
  cause: error62
28871
28967
  });
28872
28968
  }
28873
- if (!isRecord4(value)) {
28969
+ if (!isRecord5(value)) {
28874
28970
  throw new ProtocolMessageError("Message must be a JSON object");
28875
28971
  }
28876
28972
  return value;
@@ -28882,7 +28978,7 @@ function assertExactKeys(value, allowedKeys) {
28882
28978
  }
28883
28979
  }
28884
28980
  }
28885
- function readString(value, key, maximumLength) {
28981
+ function readString2(value, key, maximumLength) {
28886
28982
  const field = value[key];
28887
28983
  if (typeof field !== "string" || field.length === 0 || field.length > maximumLength) {
28888
28984
  throw new ProtocolMessageError(`Invalid string field: ${key}`);
@@ -28967,10 +29063,10 @@ function readActivityContent(value) {
28967
29063
  }
28968
29064
  function readActivityDetail(value) {
28969
29065
  const field = value["detail"];
28970
- if (!isRecord4(field)) {
29066
+ if (!isRecord5(field)) {
28971
29067
  throw new ProtocolMessageError("Invalid activity detail field");
28972
29068
  }
28973
- const kind = readString(field, "kind", 32);
29069
+ const kind = readString2(field, "kind", 32);
28974
29070
  if (kind === "available") {
28975
29071
  assertExactKeys(field, ["artifactId", "kind"]);
28976
29072
  return {
@@ -29018,7 +29114,7 @@ function readIdentifier(value, key) {
29018
29114
  }
29019
29115
  }
29020
29116
  function readDirectoryIdentifier(value, key) {
29021
- const field = readString(value, key, 2048);
29117
+ const field = readString2(value, key, 2048);
29022
29118
  if (!DIRECTORY_IDENTIFIER_PATTERN2.test(field)) {
29023
29119
  throw new ProtocolMessageError(`Invalid directory identifier field: ${key}`);
29024
29120
  }
@@ -29030,7 +29126,7 @@ function assertKind(value, expectedKind) {
29030
29126
  }
29031
29127
  }
29032
29128
  function decodeMessageKind(encoded) {
29033
- return readString(parseJson2(encoded), "kind", 64);
29129
+ return readString2(parseJson2(encoded), "kind", 64);
29034
29130
  }
29035
29131
  function decodeSessionPromptCommand(encoded) {
29036
29132
  const value = parseJson2(encoded);
@@ -29178,7 +29274,7 @@ function decodeAgentMessageDeltaEvent(encoded) {
29178
29274
  messageId: value["messageId"] === void 0 ? "" : readText(value, "messageId", 255),
29179
29275
  sequence,
29180
29276
  sessionId: readIdentifier(value, "sessionId"),
29181
- text: readString(value, "text", MAX_EVENT_TEXT_LENGTH)
29277
+ text: readString2(value, "text", MAX_EVENT_TEXT_LENGTH)
29182
29278
  };
29183
29279
  }
29184
29280
  function decodeAgentActivityEvent(encoded) {
@@ -29215,7 +29311,7 @@ function decodeAgentActivityEvent(encoded) {
29215
29311
  sequence: readSequence(value, "sequence"),
29216
29312
  sessionId: readIdentifier(value, "sessionId"),
29217
29313
  status: readAllowedString(value, "status", ACTIVITY_STATUSES),
29218
- title: readString(value, "title", 500),
29314
+ title: readString2(value, "title", 500),
29219
29315
  toolKind: readAllowedString(value, "toolKind", TOOL_KINDS)
29220
29316
  };
29221
29317
  }
@@ -29227,7 +29323,7 @@ function decodeSessionCompletedEvent(encoded) {
29227
29323
  commandId: readIdentifier(value, "commandId"),
29228
29324
  kind: SESSION_COMPLETED_KIND,
29229
29325
  sessionId: readIdentifier(value, "sessionId"),
29230
- stopReason: readString(value, "stopReason", 64)
29326
+ stopReason: readString2(value, "stopReason", 64)
29231
29327
  };
29232
29328
  }
29233
29329
  function decodeSessionFailedEvent(encoded) {
@@ -29238,7 +29334,7 @@ function decodeSessionFailedEvent(encoded) {
29238
29334
  code: readIdentifier(value, "code"),
29239
29335
  commandId: readIdentifier(value, "commandId"),
29240
29336
  kind: SESSION_FAILED_KIND,
29241
- message: readString(value, "message", 500),
29337
+ message: readString2(value, "message", 500),
29242
29338
  sessionId: readIdentifier(value, "sessionId")
29243
29339
  };
29244
29340
  }
@@ -29379,7 +29475,6 @@ var nativeMessagePageSchema = external_exports.discriminatedUnion("status", [
29379
29475
  var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
29380
29476
  var NATIVE_SESSION_RESULT_KIND = "native.session.result";
29381
29477
  var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
29382
- var ACTIVE_TURN_TEXT_LIMIT = 1e6;
29383
29478
  var directoryId = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/);
29384
29479
  var envelope = {
29385
29480
  requestId: identifierStringSchema,
@@ -29398,6 +29493,18 @@ var activeTurnActivitySchema = external_exports.strictObject({
29398
29493
  title: external_exports.string().max(500),
29399
29494
  toolKind: external_exports.string().max(64)
29400
29495
  }).readonly();
29496
+ var activeTurnSnapshotSchema = external_exports.strictObject({
29497
+ activities: external_exports.array(activeTurnActivitySchema).readonly(),
29498
+ commandId: identifierStringSchema,
29499
+ content: external_exports.array(displayContentSchema).readonly(),
29500
+ prompt: external_exports.string().max(1e5),
29501
+ text: external_exports.string(),
29502
+ truncated: external_exports.boolean(),
29503
+ epoch: identifierStringSchema,
29504
+ interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
29505
+ sequence: external_exports.number().int().nonnegative(),
29506
+ state: external_exports.literal("running")
29507
+ }).readonly();
29401
29508
  var identity = {
29402
29509
  ...envelope,
29403
29510
  kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
@@ -29479,21 +29586,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
29479
29586
  images: external_exports.array(promptImageSchema).max(8).readonly()
29480
29587
  }).readonly()
29481
29588
  ).readonly(),
29482
- turn: external_exports.strictObject({
29483
- activities: external_exports.array(activeTurnActivitySchema).max(100).readonly(),
29484
- commandId: identifierStringSchema,
29485
- content: external_exports.array(displayContentSchema).max(100).readonly(),
29486
- prompt: external_exports.string().max(1e5),
29487
- text: external_exports.string().max(ACTIVE_TURN_TEXT_LIMIT),
29488
- truncated: external_exports.boolean(),
29489
- epoch: identifierStringSchema,
29490
- interaction: external_exports.discriminatedUnion("kind", [
29491
- sessionPermissionRequestedEventSchema,
29492
- sessionElicitationRequestedEventSchema
29493
- ]).nullable(),
29494
- sequence: external_exports.number().int().nonnegative(),
29495
- state: external_exports.literal("running")
29496
- }).readonly().nullable()
29589
+ turn: activeTurnSnapshotSchema.nullable()
29497
29590
  }).readonly(),
29498
29591
  external_exports.strictObject({
29499
29592
  ...resultEnvelope,
@@ -29569,6 +29662,13 @@ var committedEventSchema = external_exports.strictObject({
29569
29662
  }).readonly();
29570
29663
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
29571
29664
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
29665
+ var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
29666
+ var sessionTurnUpdatedSchema = external_exports.strictObject({
29667
+ kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
29668
+ sessionId: identifierStringSchema,
29669
+ turn: activeTurnSnapshotSchema
29670
+ }).readonly();
29671
+ var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
29572
29672
  function decode5(encoded, schema) {
29573
29673
  let value;
29574
29674
  try {
@@ -29598,6 +29698,8 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
29598
29698
  function decodeRecordedSessionEvent(encoded) {
29599
29699
  const kind = decodeMessageKind(encoded);
29600
29700
  switch (kind) {
29701
+ case SESSION_TURN_UPDATED_KIND:
29702
+ return decodeSessionTurnUpdatedEvent(encoded);
29601
29703
  case SESSION_QUEUE_CHANGED_KIND:
29602
29704
  return decode5(encoded, sessionQueueChangedSchema);
29603
29705
  case AGENT_ACTIVITY_KIND:
@@ -30063,7 +30165,7 @@ var VerifiedRuntimeConnection = class {
30063
30165
  this.runtimeId = runtimeId;
30064
30166
  }
30065
30167
  };
30066
- function isRecord5(value) {
30168
+ function isRecord6(value) {
30067
30169
  return typeof value === "object" && value !== null && !Array.isArray(value);
30068
30170
  }
30069
30171
  function hasExactKeys(value, expectedKeys) {
@@ -30136,7 +30238,7 @@ function channelIndexFileName(channelId) {
30136
30238
  return `mci_${createHash2("sha256").update(channelId).digest("hex")}.json`;
30137
30239
  }
30138
30240
  function decodeInstallationPointer(value) {
30139
- if (!isRecord5(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
30241
+ if (!isRecord6(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
30140
30242
  throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
30141
30243
  }
30142
30244
  const storedInstallationId = value["installationId"];
@@ -30146,7 +30248,7 @@ function decodeInstallationPointer(value) {
30146
30248
  return { installationId: validateInstallationId(storedInstallationId) };
30147
30249
  }
30148
30250
  function decodeChannelIndex(value) {
30149
- if (!isRecord5(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
30251
+ if (!isRecord6(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
30150
30252
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
30151
30253
  }
30152
30254
  const applicationId = value["applicationId"];
@@ -30196,7 +30298,7 @@ function decodeVerifiedConnection(value) {
30196
30298
  );
30197
30299
  }
30198
30300
  function decodeConnection(value) {
30199
- if (!isRecord5(value)) {
30301
+ if (!isRecord6(value)) {
30200
30302
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
30201
30303
  }
30202
30304
  return decodeVerifiedConnection(value);
@@ -30514,7 +30616,7 @@ var PairingClientError = class extends Error {
30514
30616
  this.name = "PairingClientError";
30515
30617
  }
30516
30618
  };
30517
- function isRecord6(value) {
30619
+ function isRecord7(value) {
30518
30620
  return typeof value === "object" && value !== null && !Array.isArray(value);
30519
30621
  }
30520
30622
  function hasExactKeys2(value, expectedKeys) {
@@ -30637,9 +30739,9 @@ async function readJsonResponse(response) {
30637
30739
  }
30638
30740
  }
30639
30741
  function readRelayError(value) {
30640
- if (isRecord6(value)) {
30742
+ if (isRecord7(value)) {
30641
30743
  const error62 = value["error"];
30642
- if (isRecord6(error62)) {
30744
+ if (isRecord7(error62)) {
30643
30745
  const code = error62["code"];
30644
30746
  const message = error62["message"];
30645
30747
  if (typeof code === "string" && typeof message === "string") {
@@ -30650,7 +30752,7 @@ function readRelayError(value) {
30650
30752
  return new PairingClientError("pairing_failed", "The relay could not pair this machine");
30651
30753
  }
30652
30754
  function decodePairingResponse(value, credentialField, expectedKeys) {
30653
- if (!isRecord6(value) || !hasExactKeys2(value, expectedKeys)) {
30755
+ if (!isRecord7(value) || !hasExactKeys2(value, expectedKeys)) {
30654
30756
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
30655
30757
  }
30656
30758
  const appId = value["appId"];
@@ -31208,10 +31310,10 @@ async function replaceImageMarkers(text2, replace) {
31208
31310
 
31209
31311
  // src/acp/activity-content.ts
31210
31312
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
31211
- function isRecord7(value) {
31313
+ function isRecord8(value) {
31212
31314
  return typeof value === "object" && value !== null && !Array.isArray(value);
31213
31315
  }
31214
- function truncate2(value, maximumLength) {
31316
+ function truncate3(value, maximumLength) {
31215
31317
  if (value.length <= maximumLength) {
31216
31318
  return value;
31217
31319
  }
@@ -31219,13 +31321,13 @@ function truncate2(value, maximumLength) {
31219
31321
  }
31220
31322
  function formatUnknown(value) {
31221
31323
  if (typeof value === "string") {
31222
- return truncate2(value, AGENT_ACTIVITY_DETAIL_LIMIT);
31324
+ return truncate3(value, AGENT_ACTIVITY_DETAIL_LIMIT);
31223
31325
  }
31224
31326
  try {
31225
31327
  const encoded = JSON.stringify(value, null, 2);
31226
- return truncate2(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
31328
+ return truncate3(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
31227
31329
  } catch {
31228
- return truncate2(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
31330
+ return truncate3(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
31229
31331
  }
31230
31332
  }
31231
31333
  function formatUnknownDetail(value) {
@@ -31253,16 +31355,16 @@ function readContentOutputDetail(content) {
31253
31355
  function summarizeDisplayContent(content) {
31254
31356
  return {
31255
31357
  ...content,
31256
- artifactId: truncate2(content.artifactId, 128),
31257
- data: truncate2(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
31258
- mimeType: truncate2(content.mimeType, 255),
31259
- name: truncate2(content.name, 500),
31260
- newText: truncate2(content.newText, AGENT_ACTIVITY_DETAIL_LIMIT),
31261
- oldText: truncate2(content.oldText, AGENT_ACTIVITY_DETAIL_LIMIT),
31262
- path: truncate2(content.path, 2048),
31263
- terminalId: truncate2(content.terminalId, 255),
31264
- text: truncate2(content.text, AGENT_ACTIVITY_DETAIL_LIMIT),
31265
- uri: truncate2(content.uri, 4096)
31358
+ artifactId: truncate3(content.artifactId, 128),
31359
+ data: truncate3(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
31360
+ mimeType: truncate3(content.mimeType, 255),
31361
+ name: truncate3(content.name, 500),
31362
+ newText: truncate3(content.newText, AGENT_ACTIVITY_DETAIL_LIMIT),
31363
+ oldText: truncate3(content.oldText, AGENT_ACTIVITY_DETAIL_LIMIT),
31364
+ path: truncate3(content.path, 2048),
31365
+ terminalId: truncate3(content.terminalId, 255),
31366
+ text: truncate3(content.text, AGENT_ACTIVITY_DETAIL_LIMIT),
31367
+ uri: truncate3(content.uri, 4096)
31266
31368
  };
31267
31369
  }
31268
31370
  function contentFitsRecordingEnvelope(content) {
@@ -31280,8 +31382,8 @@ function captureActivityDetail(content, input2, output2) {
31280
31382
  return {
31281
31383
  capturedBytes: encodedByteLength({
31282
31384
  content: content.slice(0, 100).map(summarizeDisplayContent),
31283
- input: truncate2(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
31284
- output: truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
31385
+ input: truncate3(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
31386
+ output: truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
31285
31387
  }),
31286
31388
  kind: "truncated",
31287
31389
  originalBytes
@@ -31392,16 +31494,16 @@ async function normalizeToolContent(content, prepareContent) {
31392
31494
  return normalized;
31393
31495
  }
31394
31496
  function rawMcpToolContent(rawOutput) {
31395
- if (!isRecord7(rawOutput)) {
31497
+ if (!isRecord8(rawOutput)) {
31396
31498
  return [];
31397
31499
  }
31398
- const result = isRecord7(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
31500
+ const result = isRecord8(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
31399
31501
  const content = result["content"];
31400
31502
  if (!Array.isArray(content)) {
31401
31503
  return [];
31402
31504
  }
31403
31505
  return content.flatMap((item) => {
31404
- if (!isRecord7(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
31506
+ if (!isRecord8(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
31405
31507
  return [];
31406
31508
  }
31407
31509
  const uri = item["uri"];
@@ -31429,7 +31531,7 @@ function normalizeLocations(locations) {
31429
31531
  break;
31430
31532
  }
31431
31533
  const suffix = typeof location.line === "number" ? `:${location.line.toString()}` : "";
31432
- const value = truncate2(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
31534
+ const value = truncate3(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
31433
31535
  if (value.length > 0 && !unique.has(value)) {
31434
31536
  unique.add(value);
31435
31537
  normalized.push(value);
@@ -31451,14 +31553,14 @@ function normalizeToolStatus(status, fallback) {
31451
31553
  }
31452
31554
  function normalizeTitle(title2, fallback) {
31453
31555
  const normalized = title2.trim();
31454
- return truncate2(normalized.length === 0 ? fallback : normalized, 500);
31556
+ return truncate3(normalized.length === 0 ? fallback : normalized, 500);
31455
31557
  }
31456
31558
  function formatPlanEntries(entries) {
31457
31559
  const lines = [];
31458
31560
  for (const entry of entries) {
31459
31561
  lines.push(`[${entry.status}] ${entry.content}`);
31460
31562
  }
31461
- return truncate2(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
31563
+ return truncate3(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
31462
31564
  }
31463
31565
  function planStatus(entries) {
31464
31566
  if (entries.length === 0) {
@@ -31478,7 +31580,7 @@ function contentPhase(content) {
31478
31580
  return "";
31479
31581
  }
31480
31582
  const codex = metadata["codex"];
31481
- if (!isRecord7(codex)) {
31583
+ if (!isRecord8(codex)) {
31482
31584
  return "";
31483
31585
  }
31484
31586
  const phase = codex["phase"];
@@ -31491,19 +31593,6 @@ function isProgressMessage(content) {
31491
31593
  // src/acp/agent-connection.ts
31492
31594
  import { spawn as spawn4 } from "node:child_process";
31493
31595
  import { ndJsonStream as ndJsonStream2, RequestError as RequestError3 } from "@agentclientprotocol/sdk";
31494
-
31495
- // src/acp/value-utils.ts
31496
- function truncate3(value, maximumLength) {
31497
- return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
31498
- }
31499
- function isRecord8(value) {
31500
- return typeof value === "object" && value !== null && !Array.isArray(value);
31501
- }
31502
- function readString2(value, fallback = "") {
31503
- return typeof value === "string" ? value : fallback;
31504
- }
31505
-
31506
- // src/acp/agent-connection.ts
31507
31596
  function readableWebStream(input2) {
31508
31597
  let streamOpen = true;
31509
31598
  return new ReadableStream({
@@ -31595,19 +31684,19 @@ var AgentConnection = class {
31595
31684
  this.connection = createAcpClient(client2).connect(inProcess.app());
31596
31685
  return;
31597
31686
  }
31598
- const child = spawn4(agent.adapterPath, [...agent.arguments], {
31687
+ const child2 = spawn4(agent.adapterPath, [...agent.arguments], {
31599
31688
  cwd,
31600
31689
  detached: process.platform !== "win32",
31601
31690
  env: { ...process.env, ...agent.environment },
31602
31691
  shell: false,
31603
31692
  stdio: ["pipe", "pipe", "pipe"]
31604
31693
  });
31605
- this.#process = { kind: "child", child };
31606
- const stdin = child.stdin;
31607
- const stdout = child.stdout;
31608
- const stderr = child.stderr;
31694
+ this.#process = { kind: "child", child: child2 };
31695
+ const stdin = child2.stdin;
31696
+ const stdout = child2.stdout;
31697
+ const stderr = child2.stderr;
31609
31698
  if (stdin === null || stdout === null || stderr === null) {
31610
- child.kill("SIGKILL");
31699
+ child2.kill("SIGKILL");
31611
31700
  throw new AcpExecutionError("ACP process streams are unavailable");
31612
31701
  }
31613
31702
  stderr.setEncoding("utf8");
@@ -31615,10 +31704,10 @@ var AgentConnection = class {
31615
31704
  process.stderr.write(`[${agent.id}-acp] ${chunk}`);
31616
31705
  });
31617
31706
  this.termination = new Promise((resolve9) => {
31618
- child.once("error", (cause) => {
31707
+ child2.once("error", (cause) => {
31619
31708
  resolve9({ kind: "failed", error: new AcpExecutionError("The ACP process could not run", { cause }) });
31620
31709
  });
31621
- child.once("exit", (code, signal) => {
31710
+ child2.once("exit", (code, signal) => {
31622
31711
  resolve9({
31623
31712
  kind: "failed",
31624
31713
  error: new AcpExecutionError("The ACP process stopped", { cause: { code, signal } })
@@ -31676,7 +31765,7 @@ var AgentConnection = class {
31676
31765
  );
31677
31766
  }
31678
31767
  if (error62 instanceof RequestError3) {
31679
- throw new AcpExecutionError(truncate3(error62.message, 500), { cause: error62 }, "acp_agent_error");
31768
+ throw new AcpExecutionError(truncate(error62.message, 500), { cause: error62 }, "acp_agent_error");
31680
31769
  }
31681
31770
  throw error62;
31682
31771
  }
@@ -31753,6 +31842,7 @@ var AcpActivityTracker = class {
31753
31842
  #activities = /* @__PURE__ */ new Map();
31754
31843
  #identities = /* @__PURE__ */ new Map();
31755
31844
  #narrations = /* @__PURE__ */ new Map();
31845
+ #noticeRevisions = /* @__PURE__ */ new Map();
31756
31846
  #onActivity;
31757
31847
  #onNarration;
31758
31848
  #prepareContent;
@@ -31788,13 +31878,37 @@ var AcpActivityTracker = class {
31788
31878
  await this.#onNarration(new AcpActivityNarration(identity2.id, activityType, identity2.sequence, text2));
31789
31879
  }
31790
31880
  };
31881
+ recordNotice = async (id, revision, severity, text2) => {
31882
+ const key = `notice:${id}`;
31883
+ if ((this.#noticeRevisions.get(key) ?? 0) >= revision) {
31884
+ return;
31885
+ }
31886
+ await this.finishNarrative();
31887
+ this.#noticeRevisions.set(key, revision);
31888
+ const identity2 = this.#identity(key);
31889
+ await this.#record(
31890
+ key,
31891
+ new AcpActivity(
31892
+ identity2.id,
31893
+ "notice",
31894
+ "",
31895
+ [],
31896
+ "",
31897
+ truncate3(text2, AGENT_ACTIVITY_DETAIL_LIMIT),
31898
+ identity2.sequence,
31899
+ severity === "error" ? "failed" : "completed",
31900
+ severity === "error" ? "Agent error" : "Agent warning",
31901
+ ""
31902
+ )
31903
+ );
31904
+ };
31791
31905
  #narrativeSnapshot = (identity2, activityType, output2, status) => new AcpActivity(
31792
31906
  identity2.id,
31793
31907
  activityType,
31794
31908
  "",
31795
31909
  [],
31796
31910
  "",
31797
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31911
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31798
31912
  identity2.sequence,
31799
31913
  status,
31800
31914
  activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -31822,7 +31936,7 @@ var AcpActivityTracker = class {
31822
31936
  "",
31823
31937
  [],
31824
31938
  "",
31825
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31939
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31826
31940
  identity2.sequence,
31827
31941
  "running",
31828
31942
  "Plan",
@@ -31872,7 +31986,7 @@ var AcpActivityTracker = class {
31872
31986
  "tool",
31873
31987
  update.rawInput === void 0 ? "" : formatUnknown(update.rawInput),
31874
31988
  normalizeLocations(update.locations ?? []),
31875
- truncate2(update.name ?? "", 128),
31989
+ truncate3(update.name ?? "", 128),
31876
31990
  output2,
31877
31991
  identity2.sequence,
31878
31992
  normalizeToolStatus(update.status ?? "pending", "pending"),
@@ -31902,7 +32016,7 @@ var AcpActivityTracker = class {
31902
32016
  "tool",
31903
32017
  update.rawInput === void 0 ? previous?.input ?? "" : formatUnknown(update.rawInput),
31904
32018
  update.locations === void 0 || update.locations === null ? previous?.locations ?? [] : normalizeLocations(update.locations),
31905
- update.name === void 0 || update.name === null ? previous?.name ?? "" : truncate2(update.name, 128),
32019
+ update.name === void 0 || update.name === null ? previous?.name ?? "" : truncate3(update.name, 128),
31906
32020
  output2,
31907
32021
  identity2.sequence,
31908
32022
  update.status === void 0 || update.status === null ? previous?.status ?? "pending" : normalizeToolStatus(update.status, previous?.status ?? "pending"),
@@ -31957,7 +32071,7 @@ var AcpActivityTracker = class {
31957
32071
  "",
31958
32072
  [],
31959
32073
  "",
31960
- truncate2(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
32074
+ truncate3(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
31961
32075
  narration.sequence,
31962
32076
  "completed",
31963
32077
  narration.activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -32576,11 +32690,11 @@ function normalizeElicitationOptions(schema) {
32576
32690
  const oneOf = schema["oneOf"];
32577
32691
  if (Array.isArray(oneOf)) {
32578
32692
  for (const option of oneOf) {
32579
- if (isRecord8(option) && typeof option["const"] === "string") {
32693
+ if (isRecord3(option) && typeof option["const"] === "string") {
32580
32694
  normalized.push({
32581
- description: truncate3(readString2(option["description"]), 500),
32582
- label: truncate3(readString2(option["title"], option["const"]), 255),
32583
- value: truncate3(option["const"], 500)
32695
+ description: truncate(readString(option["description"]), 500),
32696
+ label: truncate(readString(option["title"], option["const"]), 255),
32697
+ value: truncate(option["const"], 500)
32584
32698
  });
32585
32699
  }
32586
32700
  }
@@ -32596,7 +32710,7 @@ function normalizeElicitationOptions(schema) {
32596
32710
  return normalized.slice(0, 200);
32597
32711
  }
32598
32712
  const items = schema["items"];
32599
- if (!isRecord8(items)) {
32713
+ if (!isRecord3(items)) {
32600
32714
  return normalized;
32601
32715
  }
32602
32716
  const anyOf = items["anyOf"];
@@ -32609,7 +32723,7 @@ function numericString(value) {
32609
32723
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
32610
32724
  }
32611
32725
  function normalizeElicitationFields(requestedSchema) {
32612
- if (!isRecord8(requestedSchema) || !isRecord8(requestedSchema["properties"])) {
32726
+ if (!isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
32613
32727
  return [];
32614
32728
  }
32615
32729
  const properties = requestedSchema["properties"];
@@ -32619,7 +32733,7 @@ function normalizeElicitationFields(requestedSchema) {
32619
32733
  );
32620
32734
  const normalized = [];
32621
32735
  for (const [name, property] of Object.entries(properties)) {
32622
- if (!isRecord8(property)) {
32736
+ if (!isRecord3(property)) {
32623
32737
  continue;
32624
32738
  }
32625
32739
  const type = elicitationFieldType(property["type"]);
@@ -32629,19 +32743,19 @@ function normalizeElicitationFields(requestedSchema) {
32629
32743
  normalized.push({
32630
32744
  defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
32631
32745
  defaultNumberValue: typeof defaultValue === "number" && Number.isFinite(defaultValue) ? defaultValue : 0,
32632
- defaultStringValue: typeof defaultValue === "string" ? truncate3(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate3(JSON.stringify(defaultValue), 1e4) : "",
32633
- description: truncate3(readString2(property["description"]), 500),
32634
- format: truncate3(readString2(property["format"]), 64),
32746
+ defaultStringValue: typeof defaultValue === "string" ? truncate(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate(JSON.stringify(defaultValue), 1e4) : "",
32747
+ description: truncate(readString(property["description"]), 500),
32748
+ format: truncate(readString(property["format"]), 64),
32635
32749
  hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
32636
32750
  maximum: numericString(property["maximum"]),
32637
32751
  maximumLength: numericString(property["maxLength"] ?? property["maxItems"]),
32638
32752
  minimum: numericString(property["minimum"]),
32639
32753
  minimumLength: numericString(property["minLength"] ?? property["minItems"]),
32640
- name: truncate3(name, 128),
32754
+ name: truncate(name, 128),
32641
32755
  options,
32642
- pattern: truncate3(readString2(property["pattern"]), 500),
32756
+ pattern: truncate(readString(property["pattern"]), 500),
32643
32757
  required: required2.has(name),
32644
- title: truncate3(readString2(property["title"], name), 255),
32758
+ title: truncate(readString(property["title"], name), 255),
32645
32759
  type: normalizedType
32646
32760
  });
32647
32761
  }
@@ -32710,7 +32824,7 @@ function validateElicitationContent(encoded, requestedSchema) {
32710
32824
  "invalid_elicitation_response"
32711
32825
  );
32712
32826
  }
32713
- if (!isRecord8(decoded) || !isRecord8(requestedSchema) || !isRecord8(requestedSchema["properties"])) {
32827
+ if (!isRecord3(decoded) || !isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
32714
32828
  throw new AcpExecutionError(
32715
32829
  "Elicitation response does not match the requested form",
32716
32830
  {},
@@ -32730,7 +32844,7 @@ function validateElicitationContent(encoded, requestedSchema) {
32730
32844
  const validated = {};
32731
32845
  for (const [name, value] of Object.entries(decoded)) {
32732
32846
  const property = properties[name];
32733
- if (!isRecord8(property)) {
32847
+ if (!isRecord3(property)) {
32734
32848
  throw new AcpExecutionError(
32735
32849
  `Elicitation field ${name} was not requested`,
32736
32850
  {},
@@ -32934,8 +33048,8 @@ var AcpSessionInteractions = class {
32934
33048
  const interactionId = `permission-${crypto.randomUUID()}`;
32935
33049
  const options = request.options.slice(0, 20).map((option) => ({
32936
33050
  kind: option.kind,
32937
- name: truncate3(option.name, 255),
32938
- optionId: truncate3(option.optionId, 255)
33051
+ name: truncate(option.name, 255),
33052
+ optionId: truncate(option.optionId, 255)
32939
33053
  }));
32940
33054
  if (options.length === 0) {
32941
33055
  throw new AcpExecutionError(
@@ -32957,9 +33071,9 @@ var AcpSessionInteractions = class {
32957
33071
  kind: SESSION_PERMISSION_REQUESTED_KIND,
32958
33072
  options,
32959
33073
  sessionId: this.#context.sessionId(),
32960
- title: truncate3(request.toolCall.title ?? "Permission required", 500),
32961
- toolCallId: truncate3(request.toolCall.toolCallId, 255),
32962
- toolKind: truncate3(request.toolCall.kind ?? "other", 64)
33074
+ title: truncate(request.toolCall.title ?? "Permission required", 500),
33075
+ toolCallId: truncate(request.toolCall.toolCallId, 255),
33076
+ toolKind: truncate(request.toolCall.kind ?? "other", 64)
32963
33077
  });
32964
33078
  return await pending.completion.promise;
32965
33079
  } finally {
@@ -32988,7 +33102,7 @@ var AcpSessionInteractions = class {
32988
33102
  const schemaValue = Reflect.get(request, "requestedSchema");
32989
33103
  const requestedSchema = request.mode === "form" ? schemaValue : {};
32990
33104
  const elicitationIdValue = Reflect.get(request, "elicitationId");
32991
- const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
33105
+ const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate(elicitationIdValue, 255) : "";
32992
33106
  const pending = new PendingElicitation(interactionId, elicitationId, requestedSchema);
32993
33107
  this.#pendingElicitations.set(interactionId, pending);
32994
33108
  const abort = () => {
@@ -33003,10 +33117,10 @@ var AcpSessionInteractions = class {
33003
33117
  fields: normalizeElicitationFields(requestedSchema),
33004
33118
  interactionId,
33005
33119
  kind: SESSION_ELICITATION_REQUESTED_KIND,
33006
- message: truncate3(request.message, 2e3),
33120
+ message: truncate(request.message, 2e3),
33007
33121
  mode: request.mode,
33008
33122
  sessionId: this.#context.sessionId(),
33009
- url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString2(Reflect.get(request, "url")), 4096) : ""
33123
+ url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate(readString(Reflect.get(request, "url")), 4096) : ""
33010
33124
  });
33011
33125
  return await pending.completion.promise;
33012
33126
  } finally {
@@ -38953,6 +39067,9 @@ var AgentSession = class _AgentSession {
38953
39067
  methods8.agent.initialize,
38954
39068
  {
38955
39069
  clientCapabilities: {
39070
+ _meta: {
39071
+ jetbrains: { air: { capabilities: ["sessionFailure"], version: 1 } }
39072
+ },
38956
39073
  elicitation: { form: {}, url: {} },
38957
39074
  plan: {},
38958
39075
  session: { configOptions: { boolean: {} } }
@@ -38976,8 +39093,8 @@ var AgentSession = class _AgentSession {
38976
39093
  );
38977
39094
  }
38978
39095
  this.#capabilities = normalizeAcpCapabilities(initialized);
38979
- this.#agentName = truncate3(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
38980
- this.#agentVersion = truncate3(
39096
+ this.#agentName = truncate(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
39097
+ this.#agentVersion = truncate(
38981
39098
  this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
38982
39099
  128
38983
39100
  );
@@ -39338,7 +39455,7 @@ var AgentSession = class _AgentSession {
39338
39455
  }
39339
39456
  const prompt = this.buildPrompt(options);
39340
39457
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
39341
- this.#sessionTitle = truncate3(options.prompt, 500);
39458
+ this.#sessionTitle = truncate(options.prompt, 500);
39342
39459
  }
39343
39460
  this.#store.write(
39344
39461
  new AcpStoredSession(
@@ -39386,6 +39503,10 @@ var AgentSession = class _AgentSession {
39386
39503
  "acp_invalid_prompt_response"
39387
39504
  );
39388
39505
  }
39506
+ const failure2 = readAcpSessionFailure(response);
39507
+ if (failure2 !== null) {
39508
+ await running.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
39509
+ }
39389
39510
  if (result.usage != null || result._meta?.quota !== void 0) {
39390
39511
  await this.#getObserver().onUsage({
39391
39512
  _meta: result._meta ?? null,
@@ -39430,7 +39551,7 @@ var AgentSession = class _AgentSession {
39430
39551
  "ACP agent exited during steering",
39431
39552
  options.signal
39432
39553
  );
39433
- if (!isRecord8(response)) {
39554
+ if (!isRecord3(response)) {
39434
39555
  throw new AcpExecutionError(
39435
39556
  "ACP agent returned an invalid steering response",
39436
39557
  {},
@@ -39496,13 +39617,13 @@ var AgentSession = class _AgentSession {
39496
39617
  );
39497
39618
  } else {
39498
39619
  await this.#turn.activities.finishNarrative();
39499
- await this.#turn.onText(update.content.text, truncate3(update.messageId ?? "", 255));
39620
+ await this.#turn.onText(update.content.text, truncate(update.messageId ?? "", 255));
39500
39621
  }
39501
39622
  } else {
39502
39623
  await this.#turn.activities.finishNarrative();
39503
39624
  await this.emitAgentContent(
39504
39625
  normalizeContentBlock(update.content),
39505
- truncate3(update.messageId ?? "", 255)
39626
+ truncate(update.messageId ?? "", 255)
39506
39627
  );
39507
39628
  }
39508
39629
  return;
@@ -39539,9 +39660,9 @@ var AgentSession = class _AgentSession {
39539
39660
  }
39540
39661
  if (update.sessionUpdate === "available_commands_update") {
39541
39662
  const commands = update.availableCommands.slice(0, 500).map((command) => ({
39542
- description: truncate3(command.description, 500),
39543
- inputHint: truncate3(command.input?.hint ?? "", 255),
39544
- name: truncate3(command.name, 128)
39663
+ description: truncate(command.description, 500),
39664
+ inputHint: truncate(command.input?.hint ?? "", 255),
39665
+ name: truncate(command.name, 128)
39545
39666
  })).filter((command) => command.name.length > 0);
39546
39667
  this.#commands = commands;
39547
39668
  await this.#getObserver().onCommands({
@@ -39569,11 +39690,15 @@ var AgentSession = class _AgentSession {
39569
39690
  return;
39570
39691
  }
39571
39692
  if (update.sessionUpdate === "session_info_update") {
39693
+ const failure2 = readAcpSessionFailure(update);
39694
+ if (failure2 !== null && this.#turn.running) {
39695
+ await this.#turn.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
39696
+ }
39572
39697
  if (Object.hasOwn(update, "title")) {
39573
- this.#sessionTitle = truncate3(update.title ?? "", 500);
39698
+ this.#sessionTitle = truncate(update.title ?? "", 500);
39574
39699
  }
39575
39700
  if (Object.hasOwn(update, "updatedAt")) {
39576
- this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
39701
+ this.#sessionUpdatedAt = truncate(update.updatedAt ?? "", 128);
39577
39702
  }
39578
39703
  if (this.#updates.sessionId().length > 0) {
39579
39704
  this.#store.write(
@@ -39599,7 +39724,7 @@ var AgentSession = class _AgentSession {
39599
39724
  if (update.sessionUpdate === "usage_update") {
39600
39725
  await this.#getObserver().onUsage({
39601
39726
  costAmount: update.cost?.amount ?? 0,
39602
- costCurrency: truncate3(update.cost?.currency ?? "", 16),
39727
+ costCurrency: truncate(update.cost?.currency ?? "", 16),
39603
39728
  hasCost: update.cost !== void 0 && update.cost !== null,
39604
39729
  kind: SESSION_USAGE_UPDATED_KIND,
39605
39730
  sessionId: this.#mobiusSessionId,
@@ -41423,16 +41548,16 @@ var WorkspaceDirectoryService = class {
41423
41548
  const children = await readdir3(target, { withFileTypes: true });
41424
41549
  signal.throwIfAborted();
41425
41550
  const entries = [];
41426
- for (const child of children) {
41551
+ for (const child2 of children) {
41427
41552
  if (entries.length === 500) {
41428
41553
  break;
41429
41554
  }
41430
- if (child.isFile() || child.isBlockDevice() || child.isCharacterDevice() || child.isFIFO() || child.isSocket()) {
41555
+ if (child2.isFile() || child2.isBlockDevice() || child2.isCharacterDevice() || child2.isFIFO() || child2.isSocket()) {
41431
41556
  continue;
41432
41557
  }
41433
41558
  try {
41434
- const path3 = await this.resolvePath(join16(target, child.name), signal);
41435
- entries.push({ directoryId: encodePath(path3), name: child.name });
41559
+ const path3 = await this.resolvePath(join16(target, child2.name), signal);
41560
+ entries.push({ directoryId: encodePath(path3), name: child2.name });
41436
41561
  } catch (cause) {
41437
41562
  signal.throwIfAborted();
41438
41563
  if (!(cause instanceof LocalAuthorizationError)) {
@@ -41952,7 +42077,6 @@ var ActiveDaemonTurn = class {
41952
42077
  #text = "";
41953
42078
  #activities = /* @__PURE__ */ new Map();
41954
42079
  #content = /* @__PURE__ */ new Map();
41955
- #truncated = false;
41956
42080
  #sequence = 0;
41957
42081
  #interaction = null;
41958
42082
  #epoch = decodeIdentifier(randomUUID2());
@@ -41995,21 +42119,8 @@ var ActiveDaemonTurn = class {
41995
42119
  effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
41996
42120
  recordEvent = (event) => {
41997
42121
  if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
41998
- this.#sequence += 1;
41999
42122
  this.#text += event.text;
42000
- if (this.#text.length > ACTIVE_TURN_TEXT_LIMIT) {
42001
- this.#text = this.#text.slice(-ACTIVE_TURN_TEXT_LIMIT);
42002
- this.#truncated = true;
42003
- }
42004
- return {
42005
- commandId: this.command.commandId,
42006
- epoch: this.#epoch,
42007
- kind: AGENT_MESSAGE_DELTA_KIND,
42008
- messageId: event.messageId,
42009
- sequence: this.#sequence,
42010
- sessionId: this.command.sessionId,
42011
- text: event.text
42012
- };
42123
+ return this.updated();
42013
42124
  }
42014
42125
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
42015
42126
  return event;
@@ -42050,15 +42161,26 @@ var ActiveDaemonTurn = class {
42050
42161
  } else if ((event.kind === SESSION_PERMISSION_RESOLVED_KIND || event.kind === SESSION_ELICITATION_RESOLVED_KIND) && this.#interaction?.interactionId === event.interactionId) {
42051
42162
  this.#interaction = null;
42052
42163
  }
42164
+ if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
42165
+ return this.updated();
42166
+ }
42053
42167
  return event;
42054
42168
  };
42169
+ updated = () => {
42170
+ this.#sequence += 1;
42171
+ const turn = this.snapshot();
42172
+ if (turn === null) {
42173
+ throw new Error("Only a running turn can publish a snapshot");
42174
+ }
42175
+ return { kind: "session.turn.updated", sessionId: this.command.sessionId, turn };
42176
+ };
42055
42177
  snapshot = () => this.#dispatch.kind === "running" ? {
42056
42178
  activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
42057
42179
  commandId: decodeIdentifier(this.command.commandId),
42058
42180
  content: [...this.#content.values()],
42059
42181
  prompt: this.command.prompt,
42060
42182
  text: this.#text,
42061
- truncated: this.#truncated,
42183
+ truncated: false,
42062
42184
  epoch: this.#epoch,
42063
42185
  interaction: this.#interaction,
42064
42186
  sequence: this.#sequence,
@@ -42127,9 +42249,13 @@ var DaemonTurnRegistry = class {
42127
42249
  turn.finish();
42128
42250
  };
42129
42251
  recordEvent = (event) => {
42130
- for (const turn of this.#turns.values()) {
42131
- turn.recordEvent(event);
42252
+ if ("commandId" in event) {
42253
+ const turn = this.#turns.get(event.commandId);
42254
+ if (turn !== void 0 && turn.command.sessionId === event.sessionId) {
42255
+ return turn.recordEvent(event);
42256
+ }
42132
42257
  }
42258
+ return event;
42133
42259
  };
42134
42260
  executionSnapshot = async (matches) => {
42135
42261
  const matching = [];
@@ -42451,7 +42577,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42451
42577
  );
42452
42578
  }
42453
42579
  signal.throwIfAborted();
42454
- const child = spawn5(agent.agentIdentity.realPath, ["app-server"], {
42580
+ const child2 = spawn5(agent.agentIdentity.realPath, ["app-server"], {
42455
42581
  cwd,
42456
42582
  env: { ...process.env, ...agent.environment },
42457
42583
  detached: process.platform !== "win32",
@@ -42471,7 +42597,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42471
42597
  )
42472
42598
  );
42473
42599
  const send2 = (message) => {
42474
- child.stdin.write(`${JSON.stringify(message)}
42600
+ child2.stdin.write(`${JSON.stringify(message)}
42475
42601
  `);
42476
42602
  };
42477
42603
  const onData = (chunk) => {
@@ -42601,11 +42727,11 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42601
42727
  () => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
42602
42728
  options.detail === "rich" ? 6e4 : 15e3
42603
42729
  );
42604
- child.stdout.setEncoding("utf8");
42605
- child.stdout.on("data", onData);
42606
- child.stdin.on("error", fail);
42607
- child.on("error", fail);
42608
- child.on("exit", onExit);
42730
+ child2.stdout.setEncoding("utf8");
42731
+ child2.stdout.on("data", onData);
42732
+ child2.stdin.on("error", fail);
42733
+ child2.on("error", fail);
42734
+ child2.on("exit", onExit);
42609
42735
  signal.addEventListener("abort", abort, { once: true });
42610
42736
  try {
42611
42737
  if (signal.aborted) {
@@ -42625,13 +42751,13 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42625
42751
  } finally {
42626
42752
  clearTimeout(timeout);
42627
42753
  signal.removeEventListener("abort", abort);
42628
- child.stdout.removeListener("data", onData);
42629
- if (child.pid !== void 0) {
42630
- await stopProcessTree(child);
42754
+ child2.stdout.removeListener("data", onData);
42755
+ if (child2.pid !== void 0) {
42756
+ await stopProcessTree(child2);
42631
42757
  }
42632
- child.stdin.removeListener("error", fail);
42633
- child.removeListener("error", fail);
42634
- child.removeListener("exit", onExit);
42758
+ child2.stdin.removeListener("error", fail);
42759
+ child2.removeListener("error", fail);
42760
+ child2.removeListener("exit", onExit);
42635
42761
  }
42636
42762
  }
42637
42763
  var readCodexHistory = async (agent, cwd, nativeSessionId, signal) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, { detail: "messages" });
@@ -46138,8 +46264,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
46138
46264
  const publisher = new DaemonSessionEventPublisher();
46139
46265
  const activeTurns = new DaemonTurnRegistry(operations);
46140
46266
  const recordSessionEvent = (sessionId, event) => {
46141
- activeTurns.recordEvent(event);
46142
- publisher.publish(sessionId, event);
46267
+ publisher.publish(sessionId, activeTurns.recordEvent(event));
46143
46268
  };
46144
46269
  const agentRuntime = new AgentRuntimeManager(
46145
46270
  new DaemonAcpObserver(recordSessionEvent),
@@ -46737,13 +46862,13 @@ async function sendControlRequest(stateDirectory, command, signal) {
46737
46862
  }
46738
46863
  }
46739
46864
  async function spawnManager() {
46740
- const child = spawn6(process.execPath, [process.argv[1] ?? "", "__manager"], {
46865
+ const child2 = spawn6(process.execPath, [process.argv[1] ?? "", "__manager"], {
46741
46866
  detached: true,
46742
46867
  env: process.env,
46743
46868
  stdio: "ignore"
46744
46869
  });
46745
- child.unref();
46746
- return child;
46870
+ child2.unref();
46871
+ return child2;
46747
46872
  }
46748
46873
  async function launchManager(managerVersion) {
46749
46874
  process.stdout.write(`Starting mobius daemon ${managerVersion}