@moxt-ai/mobius 0.0.133 → 0.0.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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.133",
3384
+ version: "0.0.135",
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
  }
@@ -30063,7 +30159,7 @@ var VerifiedRuntimeConnection = class {
30063
30159
  this.runtimeId = runtimeId;
30064
30160
  }
30065
30161
  };
30066
- function isRecord5(value) {
30162
+ function isRecord6(value) {
30067
30163
  return typeof value === "object" && value !== null && !Array.isArray(value);
30068
30164
  }
30069
30165
  function hasExactKeys(value, expectedKeys) {
@@ -30136,7 +30232,7 @@ function channelIndexFileName(channelId) {
30136
30232
  return `mci_${createHash2("sha256").update(channelId).digest("hex")}.json`;
30137
30233
  }
30138
30234
  function decodeInstallationPointer(value) {
30139
- if (!isRecord5(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
30235
+ if (!isRecord6(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
30140
30236
  throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
30141
30237
  }
30142
30238
  const storedInstallationId = value["installationId"];
@@ -30146,7 +30242,7 @@ function decodeInstallationPointer(value) {
30146
30242
  return { installationId: validateInstallationId(storedInstallationId) };
30147
30243
  }
30148
30244
  function decodeChannelIndex(value) {
30149
- if (!isRecord5(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
30245
+ if (!isRecord6(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
30150
30246
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
30151
30247
  }
30152
30248
  const applicationId = value["applicationId"];
@@ -30196,7 +30292,7 @@ function decodeVerifiedConnection(value) {
30196
30292
  );
30197
30293
  }
30198
30294
  function decodeConnection(value) {
30199
- if (!isRecord5(value)) {
30295
+ if (!isRecord6(value)) {
30200
30296
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
30201
30297
  }
30202
30298
  return decodeVerifiedConnection(value);
@@ -30514,7 +30610,7 @@ var PairingClientError = class extends Error {
30514
30610
  this.name = "PairingClientError";
30515
30611
  }
30516
30612
  };
30517
- function isRecord6(value) {
30613
+ function isRecord7(value) {
30518
30614
  return typeof value === "object" && value !== null && !Array.isArray(value);
30519
30615
  }
30520
30616
  function hasExactKeys2(value, expectedKeys) {
@@ -30637,9 +30733,9 @@ async function readJsonResponse(response) {
30637
30733
  }
30638
30734
  }
30639
30735
  function readRelayError(value) {
30640
- if (isRecord6(value)) {
30736
+ if (isRecord7(value)) {
30641
30737
  const error62 = value["error"];
30642
- if (isRecord6(error62)) {
30738
+ if (isRecord7(error62)) {
30643
30739
  const code = error62["code"];
30644
30740
  const message = error62["message"];
30645
30741
  if (typeof code === "string" && typeof message === "string") {
@@ -30650,7 +30746,7 @@ function readRelayError(value) {
30650
30746
  return new PairingClientError("pairing_failed", "The relay could not pair this machine");
30651
30747
  }
30652
30748
  function decodePairingResponse(value, credentialField, expectedKeys) {
30653
- if (!isRecord6(value) || !hasExactKeys2(value, expectedKeys)) {
30749
+ if (!isRecord7(value) || !hasExactKeys2(value, expectedKeys)) {
30654
30750
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
30655
30751
  }
30656
30752
  const appId = value["appId"];
@@ -31208,10 +31304,10 @@ async function replaceImageMarkers(text2, replace) {
31208
31304
 
31209
31305
  // src/acp/activity-content.ts
31210
31306
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
31211
- function isRecord7(value) {
31307
+ function isRecord8(value) {
31212
31308
  return typeof value === "object" && value !== null && !Array.isArray(value);
31213
31309
  }
31214
- function truncate2(value, maximumLength) {
31310
+ function truncate3(value, maximumLength) {
31215
31311
  if (value.length <= maximumLength) {
31216
31312
  return value;
31217
31313
  }
@@ -31219,13 +31315,13 @@ function truncate2(value, maximumLength) {
31219
31315
  }
31220
31316
  function formatUnknown(value) {
31221
31317
  if (typeof value === "string") {
31222
- return truncate2(value, AGENT_ACTIVITY_DETAIL_LIMIT);
31318
+ return truncate3(value, AGENT_ACTIVITY_DETAIL_LIMIT);
31223
31319
  }
31224
31320
  try {
31225
31321
  const encoded = JSON.stringify(value, null, 2);
31226
- return truncate2(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
31322
+ return truncate3(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
31227
31323
  } catch {
31228
- return truncate2(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
31324
+ return truncate3(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
31229
31325
  }
31230
31326
  }
31231
31327
  function formatUnknownDetail(value) {
@@ -31253,16 +31349,16 @@ function readContentOutputDetail(content) {
31253
31349
  function summarizeDisplayContent(content) {
31254
31350
  return {
31255
31351
  ...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)
31352
+ artifactId: truncate3(content.artifactId, 128),
31353
+ data: truncate3(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
31354
+ mimeType: truncate3(content.mimeType, 255),
31355
+ name: truncate3(content.name, 500),
31356
+ newText: truncate3(content.newText, AGENT_ACTIVITY_DETAIL_LIMIT),
31357
+ oldText: truncate3(content.oldText, AGENT_ACTIVITY_DETAIL_LIMIT),
31358
+ path: truncate3(content.path, 2048),
31359
+ terminalId: truncate3(content.terminalId, 255),
31360
+ text: truncate3(content.text, AGENT_ACTIVITY_DETAIL_LIMIT),
31361
+ uri: truncate3(content.uri, 4096)
31266
31362
  };
31267
31363
  }
31268
31364
  function contentFitsRecordingEnvelope(content) {
@@ -31280,8 +31376,8 @@ function captureActivityDetail(content, input2, output2) {
31280
31376
  return {
31281
31377
  capturedBytes: encodedByteLength({
31282
31378
  content: content.slice(0, 100).map(summarizeDisplayContent),
31283
- input: truncate2(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
31284
- output: truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
31379
+ input: truncate3(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
31380
+ output: truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
31285
31381
  }),
31286
31382
  kind: "truncated",
31287
31383
  originalBytes
@@ -31392,16 +31488,16 @@ async function normalizeToolContent(content, prepareContent) {
31392
31488
  return normalized;
31393
31489
  }
31394
31490
  function rawMcpToolContent(rawOutput) {
31395
- if (!isRecord7(rawOutput)) {
31491
+ if (!isRecord8(rawOutput)) {
31396
31492
  return [];
31397
31493
  }
31398
- const result = isRecord7(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
31494
+ const result = isRecord8(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
31399
31495
  const content = result["content"];
31400
31496
  if (!Array.isArray(content)) {
31401
31497
  return [];
31402
31498
  }
31403
31499
  return content.flatMap((item) => {
31404
- if (!isRecord7(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
31500
+ if (!isRecord8(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
31405
31501
  return [];
31406
31502
  }
31407
31503
  const uri = item["uri"];
@@ -31429,7 +31525,7 @@ function normalizeLocations(locations) {
31429
31525
  break;
31430
31526
  }
31431
31527
  const suffix = typeof location.line === "number" ? `:${location.line.toString()}` : "";
31432
- const value = truncate2(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
31528
+ const value = truncate3(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
31433
31529
  if (value.length > 0 && !unique.has(value)) {
31434
31530
  unique.add(value);
31435
31531
  normalized.push(value);
@@ -31451,14 +31547,14 @@ function normalizeToolStatus(status, fallback) {
31451
31547
  }
31452
31548
  function normalizeTitle(title2, fallback) {
31453
31549
  const normalized = title2.trim();
31454
- return truncate2(normalized.length === 0 ? fallback : normalized, 500);
31550
+ return truncate3(normalized.length === 0 ? fallback : normalized, 500);
31455
31551
  }
31456
31552
  function formatPlanEntries(entries) {
31457
31553
  const lines = [];
31458
31554
  for (const entry of entries) {
31459
31555
  lines.push(`[${entry.status}] ${entry.content}`);
31460
31556
  }
31461
- return truncate2(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
31557
+ return truncate3(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
31462
31558
  }
31463
31559
  function planStatus(entries) {
31464
31560
  if (entries.length === 0) {
@@ -31478,7 +31574,7 @@ function contentPhase(content) {
31478
31574
  return "";
31479
31575
  }
31480
31576
  const codex = metadata["codex"];
31481
- if (!isRecord7(codex)) {
31577
+ if (!isRecord8(codex)) {
31482
31578
  return "";
31483
31579
  }
31484
31580
  const phase = codex["phase"];
@@ -31491,19 +31587,6 @@ function isProgressMessage(content) {
31491
31587
  // src/acp/agent-connection.ts
31492
31588
  import { spawn as spawn4 } from "node:child_process";
31493
31589
  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
31590
  function readableWebStream(input2) {
31508
31591
  let streamOpen = true;
31509
31592
  return new ReadableStream({
@@ -31595,19 +31678,19 @@ var AgentConnection = class {
31595
31678
  this.connection = createAcpClient(client2).connect(inProcess.app());
31596
31679
  return;
31597
31680
  }
31598
- const child = spawn4(agent.adapterPath, [...agent.arguments], {
31681
+ const child2 = spawn4(agent.adapterPath, [...agent.arguments], {
31599
31682
  cwd,
31600
31683
  detached: process.platform !== "win32",
31601
31684
  env: { ...process.env, ...agent.environment },
31602
31685
  shell: false,
31603
31686
  stdio: ["pipe", "pipe", "pipe"]
31604
31687
  });
31605
- this.#process = { kind: "child", child };
31606
- const stdin = child.stdin;
31607
- const stdout = child.stdout;
31608
- const stderr = child.stderr;
31688
+ this.#process = { kind: "child", child: child2 };
31689
+ const stdin = child2.stdin;
31690
+ const stdout = child2.stdout;
31691
+ const stderr = child2.stderr;
31609
31692
  if (stdin === null || stdout === null || stderr === null) {
31610
- child.kill("SIGKILL");
31693
+ child2.kill("SIGKILL");
31611
31694
  throw new AcpExecutionError("ACP process streams are unavailable");
31612
31695
  }
31613
31696
  stderr.setEncoding("utf8");
@@ -31615,10 +31698,10 @@ var AgentConnection = class {
31615
31698
  process.stderr.write(`[${agent.id}-acp] ${chunk}`);
31616
31699
  });
31617
31700
  this.termination = new Promise((resolve9) => {
31618
- child.once("error", (cause) => {
31701
+ child2.once("error", (cause) => {
31619
31702
  resolve9({ kind: "failed", error: new AcpExecutionError("The ACP process could not run", { cause }) });
31620
31703
  });
31621
- child.once("exit", (code, signal) => {
31704
+ child2.once("exit", (code, signal) => {
31622
31705
  resolve9({
31623
31706
  kind: "failed",
31624
31707
  error: new AcpExecutionError("The ACP process stopped", { cause: { code, signal } })
@@ -31676,7 +31759,7 @@ var AgentConnection = class {
31676
31759
  );
31677
31760
  }
31678
31761
  if (error62 instanceof RequestError3) {
31679
- throw new AcpExecutionError(truncate3(error62.message, 500), { cause: error62 }, "acp_agent_error");
31762
+ throw new AcpExecutionError(truncate(error62.message, 500), { cause: error62 }, "acp_agent_error");
31680
31763
  }
31681
31764
  throw error62;
31682
31765
  }
@@ -31753,6 +31836,7 @@ var AcpActivityTracker = class {
31753
31836
  #activities = /* @__PURE__ */ new Map();
31754
31837
  #identities = /* @__PURE__ */ new Map();
31755
31838
  #narrations = /* @__PURE__ */ new Map();
31839
+ #noticeRevisions = /* @__PURE__ */ new Map();
31756
31840
  #onActivity;
31757
31841
  #onNarration;
31758
31842
  #prepareContent;
@@ -31788,13 +31872,37 @@ var AcpActivityTracker = class {
31788
31872
  await this.#onNarration(new AcpActivityNarration(identity2.id, activityType, identity2.sequence, text2));
31789
31873
  }
31790
31874
  };
31875
+ recordNotice = async (id, revision, severity, text2) => {
31876
+ const key = `notice:${id}`;
31877
+ if ((this.#noticeRevisions.get(key) ?? 0) >= revision) {
31878
+ return;
31879
+ }
31880
+ await this.finishNarrative();
31881
+ this.#noticeRevisions.set(key, revision);
31882
+ const identity2 = this.#identity(key);
31883
+ await this.#record(
31884
+ key,
31885
+ new AcpActivity(
31886
+ identity2.id,
31887
+ "notice",
31888
+ "",
31889
+ [],
31890
+ "",
31891
+ truncate3(text2, AGENT_ACTIVITY_DETAIL_LIMIT),
31892
+ identity2.sequence,
31893
+ severity === "error" ? "failed" : "completed",
31894
+ severity === "error" ? "Agent error" : "Agent warning",
31895
+ ""
31896
+ )
31897
+ );
31898
+ };
31791
31899
  #narrativeSnapshot = (identity2, activityType, output2, status) => new AcpActivity(
31792
31900
  identity2.id,
31793
31901
  activityType,
31794
31902
  "",
31795
31903
  [],
31796
31904
  "",
31797
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31905
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31798
31906
  identity2.sequence,
31799
31907
  status,
31800
31908
  activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -31822,7 +31930,7 @@ var AcpActivityTracker = class {
31822
31930
  "",
31823
31931
  [],
31824
31932
  "",
31825
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31933
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
31826
31934
  identity2.sequence,
31827
31935
  "running",
31828
31936
  "Plan",
@@ -31872,7 +31980,7 @@ var AcpActivityTracker = class {
31872
31980
  "tool",
31873
31981
  update.rawInput === void 0 ? "" : formatUnknown(update.rawInput),
31874
31982
  normalizeLocations(update.locations ?? []),
31875
- truncate2(update.name ?? "", 128),
31983
+ truncate3(update.name ?? "", 128),
31876
31984
  output2,
31877
31985
  identity2.sequence,
31878
31986
  normalizeToolStatus(update.status ?? "pending", "pending"),
@@ -31902,7 +32010,7 @@ var AcpActivityTracker = class {
31902
32010
  "tool",
31903
32011
  update.rawInput === void 0 ? previous?.input ?? "" : formatUnknown(update.rawInput),
31904
32012
  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),
32013
+ update.name === void 0 || update.name === null ? previous?.name ?? "" : truncate3(update.name, 128),
31906
32014
  output2,
31907
32015
  identity2.sequence,
31908
32016
  update.status === void 0 || update.status === null ? previous?.status ?? "pending" : normalizeToolStatus(update.status, previous?.status ?? "pending"),
@@ -31957,7 +32065,7 @@ var AcpActivityTracker = class {
31957
32065
  "",
31958
32066
  [],
31959
32067
  "",
31960
- truncate2(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
32068
+ truncate3(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
31961
32069
  narration.sequence,
31962
32070
  "completed",
31963
32071
  narration.activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -32576,11 +32684,11 @@ function normalizeElicitationOptions(schema) {
32576
32684
  const oneOf = schema["oneOf"];
32577
32685
  if (Array.isArray(oneOf)) {
32578
32686
  for (const option of oneOf) {
32579
- if (isRecord8(option) && typeof option["const"] === "string") {
32687
+ if (isRecord3(option) && typeof option["const"] === "string") {
32580
32688
  normalized.push({
32581
- description: truncate3(readString2(option["description"]), 500),
32582
- label: truncate3(readString2(option["title"], option["const"]), 255),
32583
- value: truncate3(option["const"], 500)
32689
+ description: truncate(readString(option["description"]), 500),
32690
+ label: truncate(readString(option["title"], option["const"]), 255),
32691
+ value: truncate(option["const"], 500)
32584
32692
  });
32585
32693
  }
32586
32694
  }
@@ -32596,7 +32704,7 @@ function normalizeElicitationOptions(schema) {
32596
32704
  return normalized.slice(0, 200);
32597
32705
  }
32598
32706
  const items = schema["items"];
32599
- if (!isRecord8(items)) {
32707
+ if (!isRecord3(items)) {
32600
32708
  return normalized;
32601
32709
  }
32602
32710
  const anyOf = items["anyOf"];
@@ -32609,7 +32717,7 @@ function numericString(value) {
32609
32717
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
32610
32718
  }
32611
32719
  function normalizeElicitationFields(requestedSchema) {
32612
- if (!isRecord8(requestedSchema) || !isRecord8(requestedSchema["properties"])) {
32720
+ if (!isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
32613
32721
  return [];
32614
32722
  }
32615
32723
  const properties = requestedSchema["properties"];
@@ -32619,7 +32727,7 @@ function normalizeElicitationFields(requestedSchema) {
32619
32727
  );
32620
32728
  const normalized = [];
32621
32729
  for (const [name, property] of Object.entries(properties)) {
32622
- if (!isRecord8(property)) {
32730
+ if (!isRecord3(property)) {
32623
32731
  continue;
32624
32732
  }
32625
32733
  const type = elicitationFieldType(property["type"]);
@@ -32629,19 +32737,19 @@ function normalizeElicitationFields(requestedSchema) {
32629
32737
  normalized.push({
32630
32738
  defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
32631
32739
  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),
32740
+ defaultStringValue: typeof defaultValue === "string" ? truncate(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate(JSON.stringify(defaultValue), 1e4) : "",
32741
+ description: truncate(readString(property["description"]), 500),
32742
+ format: truncate(readString(property["format"]), 64),
32635
32743
  hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
32636
32744
  maximum: numericString(property["maximum"]),
32637
32745
  maximumLength: numericString(property["maxLength"] ?? property["maxItems"]),
32638
32746
  minimum: numericString(property["minimum"]),
32639
32747
  minimumLength: numericString(property["minLength"] ?? property["minItems"]),
32640
- name: truncate3(name, 128),
32748
+ name: truncate(name, 128),
32641
32749
  options,
32642
- pattern: truncate3(readString2(property["pattern"]), 500),
32750
+ pattern: truncate(readString(property["pattern"]), 500),
32643
32751
  required: required2.has(name),
32644
- title: truncate3(readString2(property["title"], name), 255),
32752
+ title: truncate(readString(property["title"], name), 255),
32645
32753
  type: normalizedType
32646
32754
  });
32647
32755
  }
@@ -32710,7 +32818,7 @@ function validateElicitationContent(encoded, requestedSchema) {
32710
32818
  "invalid_elicitation_response"
32711
32819
  );
32712
32820
  }
32713
- if (!isRecord8(decoded) || !isRecord8(requestedSchema) || !isRecord8(requestedSchema["properties"])) {
32821
+ if (!isRecord3(decoded) || !isRecord3(requestedSchema) || !isRecord3(requestedSchema["properties"])) {
32714
32822
  throw new AcpExecutionError(
32715
32823
  "Elicitation response does not match the requested form",
32716
32824
  {},
@@ -32730,7 +32838,7 @@ function validateElicitationContent(encoded, requestedSchema) {
32730
32838
  const validated = {};
32731
32839
  for (const [name, value] of Object.entries(decoded)) {
32732
32840
  const property = properties[name];
32733
- if (!isRecord8(property)) {
32841
+ if (!isRecord3(property)) {
32734
32842
  throw new AcpExecutionError(
32735
32843
  `Elicitation field ${name} was not requested`,
32736
32844
  {},
@@ -32934,8 +33042,8 @@ var AcpSessionInteractions = class {
32934
33042
  const interactionId = `permission-${crypto.randomUUID()}`;
32935
33043
  const options = request.options.slice(0, 20).map((option) => ({
32936
33044
  kind: option.kind,
32937
- name: truncate3(option.name, 255),
32938
- optionId: truncate3(option.optionId, 255)
33045
+ name: truncate(option.name, 255),
33046
+ optionId: truncate(option.optionId, 255)
32939
33047
  }));
32940
33048
  if (options.length === 0) {
32941
33049
  throw new AcpExecutionError(
@@ -32957,9 +33065,9 @@ var AcpSessionInteractions = class {
32957
33065
  kind: SESSION_PERMISSION_REQUESTED_KIND,
32958
33066
  options,
32959
33067
  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)
33068
+ title: truncate(request.toolCall.title ?? "Permission required", 500),
33069
+ toolCallId: truncate(request.toolCall.toolCallId, 255),
33070
+ toolKind: truncate(request.toolCall.kind ?? "other", 64)
32963
33071
  });
32964
33072
  return await pending.completion.promise;
32965
33073
  } finally {
@@ -32988,7 +33096,7 @@ var AcpSessionInteractions = class {
32988
33096
  const schemaValue = Reflect.get(request, "requestedSchema");
32989
33097
  const requestedSchema = request.mode === "form" ? schemaValue : {};
32990
33098
  const elicitationIdValue = Reflect.get(request, "elicitationId");
32991
- const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
33099
+ const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate(elicitationIdValue, 255) : "";
32992
33100
  const pending = new PendingElicitation(interactionId, elicitationId, requestedSchema);
32993
33101
  this.#pendingElicitations.set(interactionId, pending);
32994
33102
  const abort = () => {
@@ -33003,10 +33111,10 @@ var AcpSessionInteractions = class {
33003
33111
  fields: normalizeElicitationFields(requestedSchema),
33004
33112
  interactionId,
33005
33113
  kind: SESSION_ELICITATION_REQUESTED_KIND,
33006
- message: truncate3(request.message, 2e3),
33114
+ message: truncate(request.message, 2e3),
33007
33115
  mode: request.mode,
33008
33116
  sessionId: this.#context.sessionId(),
33009
- url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString2(Reflect.get(request, "url")), 4096) : ""
33117
+ url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate(readString(Reflect.get(request, "url")), 4096) : ""
33010
33118
  });
33011
33119
  return await pending.completion.promise;
33012
33120
  } finally {
@@ -38953,6 +39061,9 @@ var AgentSession = class _AgentSession {
38953
39061
  methods8.agent.initialize,
38954
39062
  {
38955
39063
  clientCapabilities: {
39064
+ _meta: {
39065
+ jetbrains: { air: { capabilities: ["sessionFailure"], version: 1 } }
39066
+ },
38956
39067
  elicitation: { form: {}, url: {} },
38957
39068
  plan: {},
38958
39069
  session: { configOptions: { boolean: {} } }
@@ -38976,8 +39087,8 @@ var AgentSession = class _AgentSession {
38976
39087
  );
38977
39088
  }
38978
39089
  this.#capabilities = normalizeAcpCapabilities(initialized);
38979
- this.#agentName = truncate3(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
38980
- this.#agentVersion = truncate3(
39090
+ this.#agentName = truncate(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
39091
+ this.#agentVersion = truncate(
38981
39092
  this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
38982
39093
  128
38983
39094
  );
@@ -39338,7 +39449,7 @@ var AgentSession = class _AgentSession {
39338
39449
  }
39339
39450
  const prompt = this.buildPrompt(options);
39340
39451
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
39341
- this.#sessionTitle = truncate3(options.prompt, 500);
39452
+ this.#sessionTitle = truncate(options.prompt, 500);
39342
39453
  }
39343
39454
  this.#store.write(
39344
39455
  new AcpStoredSession(
@@ -39386,6 +39497,10 @@ var AgentSession = class _AgentSession {
39386
39497
  "acp_invalid_prompt_response"
39387
39498
  );
39388
39499
  }
39500
+ const failure2 = readAcpSessionFailure(response);
39501
+ if (failure2 !== null) {
39502
+ await running.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
39503
+ }
39389
39504
  if (result.usage != null || result._meta?.quota !== void 0) {
39390
39505
  await this.#getObserver().onUsage({
39391
39506
  _meta: result._meta ?? null,
@@ -39430,7 +39545,7 @@ var AgentSession = class _AgentSession {
39430
39545
  "ACP agent exited during steering",
39431
39546
  options.signal
39432
39547
  );
39433
- if (!isRecord8(response)) {
39548
+ if (!isRecord3(response)) {
39434
39549
  throw new AcpExecutionError(
39435
39550
  "ACP agent returned an invalid steering response",
39436
39551
  {},
@@ -39496,13 +39611,13 @@ var AgentSession = class _AgentSession {
39496
39611
  );
39497
39612
  } else {
39498
39613
  await this.#turn.activities.finishNarrative();
39499
- await this.#turn.onText(update.content.text, truncate3(update.messageId ?? "", 255));
39614
+ await this.#turn.onText(update.content.text, truncate(update.messageId ?? "", 255));
39500
39615
  }
39501
39616
  } else {
39502
39617
  await this.#turn.activities.finishNarrative();
39503
39618
  await this.emitAgentContent(
39504
39619
  normalizeContentBlock(update.content),
39505
- truncate3(update.messageId ?? "", 255)
39620
+ truncate(update.messageId ?? "", 255)
39506
39621
  );
39507
39622
  }
39508
39623
  return;
@@ -39539,9 +39654,9 @@ var AgentSession = class _AgentSession {
39539
39654
  }
39540
39655
  if (update.sessionUpdate === "available_commands_update") {
39541
39656
  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)
39657
+ description: truncate(command.description, 500),
39658
+ inputHint: truncate(command.input?.hint ?? "", 255),
39659
+ name: truncate(command.name, 128)
39545
39660
  })).filter((command) => command.name.length > 0);
39546
39661
  this.#commands = commands;
39547
39662
  await this.#getObserver().onCommands({
@@ -39569,11 +39684,15 @@ var AgentSession = class _AgentSession {
39569
39684
  return;
39570
39685
  }
39571
39686
  if (update.sessionUpdate === "session_info_update") {
39687
+ const failure2 = readAcpSessionFailure(update);
39688
+ if (failure2 !== null && this.#turn.running) {
39689
+ await this.#turn.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
39690
+ }
39572
39691
  if (Object.hasOwn(update, "title")) {
39573
- this.#sessionTitle = truncate3(update.title ?? "", 500);
39692
+ this.#sessionTitle = truncate(update.title ?? "", 500);
39574
39693
  }
39575
39694
  if (Object.hasOwn(update, "updatedAt")) {
39576
- this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
39695
+ this.#sessionUpdatedAt = truncate(update.updatedAt ?? "", 128);
39577
39696
  }
39578
39697
  if (this.#updates.sessionId().length > 0) {
39579
39698
  this.#store.write(
@@ -39599,7 +39718,7 @@ var AgentSession = class _AgentSession {
39599
39718
  if (update.sessionUpdate === "usage_update") {
39600
39719
  await this.#getObserver().onUsage({
39601
39720
  costAmount: update.cost?.amount ?? 0,
39602
- costCurrency: truncate3(update.cost?.currency ?? "", 16),
39721
+ costCurrency: truncate(update.cost?.currency ?? "", 16),
39603
39722
  hasCost: update.cost !== void 0 && update.cost !== null,
39604
39723
  kind: SESSION_USAGE_UPDATED_KIND,
39605
39724
  sessionId: this.#mobiusSessionId,
@@ -40156,7 +40275,7 @@ var AgentRuntimeManager = class {
40156
40275
  } finally {
40157
40276
  if (retained && this.#sessionIdentity === "native") {
40158
40277
  const stored = this.#store.read(sessionId);
40159
- if (stored instanceof FoundAcpStoredSession && isNativeChatSessionId(stored.session.agentId, sessionId)) {
40278
+ if (stored instanceof FoundAcpStoredSession && stored.session.nativeSessionId === sessionId && isNativeChatSessionId(stored.session.agentId, sessionId)) {
40160
40279
  this.#store.remove(sessionId);
40161
40280
  }
40162
40281
  }
@@ -41423,16 +41542,16 @@ var WorkspaceDirectoryService = class {
41423
41542
  const children = await readdir3(target, { withFileTypes: true });
41424
41543
  signal.throwIfAborted();
41425
41544
  const entries = [];
41426
- for (const child of children) {
41545
+ for (const child2 of children) {
41427
41546
  if (entries.length === 500) {
41428
41547
  break;
41429
41548
  }
41430
- if (child.isFile() || child.isBlockDevice() || child.isCharacterDevice() || child.isFIFO() || child.isSocket()) {
41549
+ if (child2.isFile() || child2.isBlockDevice() || child2.isCharacterDevice() || child2.isFIFO() || child2.isSocket()) {
41431
41550
  continue;
41432
41551
  }
41433
41552
  try {
41434
- const path3 = await this.resolvePath(join16(target, child.name), signal);
41435
- entries.push({ directoryId: encodePath(path3), name: child.name });
41553
+ const path3 = await this.resolvePath(join16(target, child2.name), signal);
41554
+ entries.push({ directoryId: encodePath(path3), name: child2.name });
41436
41555
  } catch (cause) {
41437
41556
  signal.throwIfAborted();
41438
41557
  if (!(cause instanceof LocalAuthorizationError)) {
@@ -42451,7 +42570,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42451
42570
  );
42452
42571
  }
42453
42572
  signal.throwIfAborted();
42454
- const child = spawn5(agent.agentIdentity.realPath, ["app-server"], {
42573
+ const child2 = spawn5(agent.agentIdentity.realPath, ["app-server"], {
42455
42574
  cwd,
42456
42575
  env: { ...process.env, ...agent.environment },
42457
42576
  detached: process.platform !== "win32",
@@ -42471,7 +42590,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42471
42590
  )
42472
42591
  );
42473
42592
  const send2 = (message) => {
42474
- child.stdin.write(`${JSON.stringify(message)}
42593
+ child2.stdin.write(`${JSON.stringify(message)}
42475
42594
  `);
42476
42595
  };
42477
42596
  const onData = (chunk) => {
@@ -42601,11 +42720,11 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42601
42720
  () => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
42602
42721
  options.detail === "rich" ? 6e4 : 15e3
42603
42722
  );
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);
42723
+ child2.stdout.setEncoding("utf8");
42724
+ child2.stdout.on("data", onData);
42725
+ child2.stdin.on("error", fail);
42726
+ child2.on("error", fail);
42727
+ child2.on("exit", onExit);
42609
42728
  signal.addEventListener("abort", abort, { once: true });
42610
42729
  try {
42611
42730
  if (signal.aborted) {
@@ -42625,13 +42744,13 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
42625
42744
  } finally {
42626
42745
  clearTimeout(timeout);
42627
42746
  signal.removeEventListener("abort", abort);
42628
- child.stdout.removeListener("data", onData);
42629
- if (child.pid !== void 0) {
42630
- await stopProcessTree(child);
42747
+ child2.stdout.removeListener("data", onData);
42748
+ if (child2.pid !== void 0) {
42749
+ await stopProcessTree(child2);
42631
42750
  }
42632
- child.stdin.removeListener("error", fail);
42633
- child.removeListener("error", fail);
42634
- child.removeListener("exit", onExit);
42751
+ child2.stdin.removeListener("error", fail);
42752
+ child2.removeListener("error", fail);
42753
+ child2.removeListener("exit", onExit);
42635
42754
  }
42636
42755
  }
42637
42756
  var readCodexHistory = async (agent, cwd, nativeSessionId, signal) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, { detail: "messages" });
@@ -46737,13 +46856,13 @@ async function sendControlRequest(stateDirectory, command, signal) {
46737
46856
  }
46738
46857
  }
46739
46858
  async function spawnManager() {
46740
- const child = spawn6(process.execPath, [process.argv[1] ?? "", "__manager"], {
46859
+ const child2 = spawn6(process.execPath, [process.argv[1] ?? "", "__manager"], {
46741
46860
  detached: true,
46742
46861
  env: process.env,
46743
46862
  stdio: "ignore"
46744
46863
  });
46745
- child.unref();
46746
- return child;
46864
+ child2.unref();
46865
+ return child2;
46747
46866
  }
46748
46867
  async function launchManager(managerVersion) {
46749
46868
  process.stdout.write(`Starting mobius daemon ${managerVersion}