@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/runtime.js CHANGED
@@ -5042,9 +5042,9 @@ function isRecursive(inst, stack, resolve9) {
5042
5042
  return PROVEN;
5043
5043
  stack.add(inst);
5044
5044
  let result = NONE;
5045
- const check2 = (child) => {
5046
- if (result !== PROVEN && child?._zod) {
5047
- const answer = isRecursive(child, stack, resolve9);
5045
+ const check2 = (child2) => {
5046
+ if (result !== PROVEN && child2?._zod) {
5047
+ const answer = isRecursive(child2, stack, resolve9);
5048
5048
  if (answer > result)
5049
5049
  result = answer;
5050
5050
  }
@@ -5055,9 +5055,9 @@ function isRecursive(inst, stack, resolve9) {
5055
5055
  const desc2 = Object.getOwnPropertyDescriptor(sh, key);
5056
5056
  if (spread && !desc2.enumerable)
5057
5057
  continue;
5058
- const child = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
5059
- if (child > answer)
5060
- answer = child;
5058
+ const child2 = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
5059
+ if (child2 > answer)
5060
+ answer = child2;
5061
5061
  }
5062
5062
  return answer;
5063
5063
  };
@@ -20436,7 +20436,7 @@ var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
20436
20436
  var MAX_PROMPT_LENGTH = 1e4;
20437
20437
  var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
20438
20438
  var MAX_EVENT_TEXT_LENGTH = 1e5;
20439
- var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["plan", "progress", "reasoning", "tool"]);
20439
+ var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["notice", "plan", "progress", "reasoning", "tool"]);
20440
20440
  var NARRATION_ACTIVITY_TYPES = /* @__PURE__ */ new Set(["progress", "reasoning"]);
20441
20441
  var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
20442
20442
  var TOOL_KINDS = /* @__PURE__ */ new Set([
@@ -20980,7 +20980,6 @@ var nativeMessagePageSchema = external_exports.discriminatedUnion("status", [
20980
20980
  var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
20981
20981
  var NATIVE_SESSION_RESULT_KIND = "native.session.result";
20982
20982
  var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
20983
- var ACTIVE_TURN_TEXT_LIMIT = 1e6;
20984
20983
  var directoryId = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/);
20985
20984
  var envelope = {
20986
20985
  requestId: identifierStringSchema,
@@ -20999,6 +20998,18 @@ var activeTurnActivitySchema = external_exports.strictObject({
20999
20998
  title: external_exports.string().max(500),
21000
20999
  toolKind: external_exports.string().max(64)
21001
21000
  }).readonly();
21001
+ var activeTurnSnapshotSchema = external_exports.strictObject({
21002
+ activities: external_exports.array(activeTurnActivitySchema).readonly(),
21003
+ commandId: identifierStringSchema,
21004
+ content: external_exports.array(displayContentSchema).readonly(),
21005
+ prompt: external_exports.string().max(1e5),
21006
+ text: external_exports.string(),
21007
+ truncated: external_exports.boolean(),
21008
+ epoch: identifierStringSchema,
21009
+ interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
21010
+ sequence: external_exports.number().int().nonnegative(),
21011
+ state: external_exports.literal("running")
21012
+ }).readonly();
21002
21013
  var identity = {
21003
21014
  ...envelope,
21004
21015
  kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
@@ -21080,21 +21091,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21080
21091
  images: external_exports.array(promptImageSchema).max(8).readonly()
21081
21092
  }).readonly()
21082
21093
  ).readonly(),
21083
- turn: external_exports.strictObject({
21084
- activities: external_exports.array(activeTurnActivitySchema).max(100).readonly(),
21085
- commandId: identifierStringSchema,
21086
- content: external_exports.array(displayContentSchema).max(100).readonly(),
21087
- prompt: external_exports.string().max(1e5),
21088
- text: external_exports.string().max(ACTIVE_TURN_TEXT_LIMIT),
21089
- truncated: external_exports.boolean(),
21090
- epoch: identifierStringSchema,
21091
- interaction: external_exports.discriminatedUnion("kind", [
21092
- sessionPermissionRequestedEventSchema,
21093
- sessionElicitationRequestedEventSchema
21094
- ]).nullable(),
21095
- sequence: external_exports.number().int().nonnegative(),
21096
- state: external_exports.literal("running")
21097
- }).readonly().nullable()
21094
+ turn: activeTurnSnapshotSchema.nullable()
21098
21095
  }).readonly(),
21099
21096
  external_exports.strictObject({
21100
21097
  ...resultEnvelope,
@@ -21170,6 +21167,13 @@ var committedEventSchema = external_exports.strictObject({
21170
21167
  }).readonly();
21171
21168
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
21172
21169
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
21170
+ var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
21171
+ var sessionTurnUpdatedSchema = external_exports.strictObject({
21172
+ kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
21173
+ sessionId: identifierStringSchema,
21174
+ turn: activeTurnSnapshotSchema
21175
+ }).readonly();
21176
+ var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
21173
21177
  function decode5(encoded, schema) {
21174
21178
  let value;
21175
21179
  try {
@@ -21199,6 +21203,8 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
21199
21203
  function decodeRecordedSessionEvent(encoded) {
21200
21204
  const kind = decodeMessageKind(encoded);
21201
21205
  switch (kind) {
21206
+ case SESSION_TURN_UPDATED_KIND:
21207
+ return decodeSessionTurnUpdatedEvent(encoded);
21202
21208
  case SESSION_QUEUE_CHANGED_KIND:
21203
21209
  return decode5(encoded, sessionQueueChangedSchema);
21204
21210
  case AGENT_ACTIVITY_KIND:
@@ -21546,8 +21552,8 @@ function hasTrueChildField(value, childKey, fieldKey) {
21546
21552
  if (!isRecord2(value)) {
21547
21553
  return false;
21548
21554
  }
21549
- const child = Reflect.get(value, childKey);
21550
- return isRecord2(child) && Reflect.get(child, fieldKey) === true;
21555
+ const child2 = Reflect.get(value, childKey);
21556
+ return isRecord2(child2) && Reflect.get(child2, fieldKey) === true;
21551
21557
  }
21552
21558
  function unsupportedSessionCapabilities() {
21553
21559
  return Object.freeze({
@@ -21859,17 +21865,17 @@ function mergeProcessTrees(captured, current) {
21859
21865
  }
21860
21866
  return [...processes.values()];
21861
21867
  }
21862
- async function captureProcessTree(child) {
21863
- if (process.platform === "win32" || child.pid === void 0) {
21868
+ async function captureProcessTree(child2) {
21869
+ if (process.platform === "win32" || child2.pid === void 0) {
21864
21870
  return [];
21865
21871
  }
21866
21872
  if (process.platform === "linux") {
21867
21873
  const procfsEntries = readLinuxProcessTableSynchronously();
21868
21874
  if (procfsEntries.length > 0) {
21869
- return selectProcessTree(procfsEntries, child.pid);
21875
+ return selectProcessTree(procfsEntries, child2.pid);
21870
21876
  }
21871
21877
  }
21872
- return selectProcessTree(await readProcessTable(), child.pid);
21878
+ return selectProcessTree(await readProcessTable(), child2.pid);
21873
21879
  }
21874
21880
  function signalCapturedProcessGroups(processes, rootProcessId, signal) {
21875
21881
  const processIds = new Set(processes.map((identity2) => identity2.processId));
@@ -21926,63 +21932,63 @@ async function waitForCapturedProcessesExit(processes, rootProcessId) {
21926
21932
  }
21927
21933
  return processIds.every((processId) => !processExists(processId));
21928
21934
  }
21929
- function terminateProcess(child) {
21930
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
21935
+ function terminateProcess(child2) {
21936
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
21931
21937
  return;
21932
21938
  }
21933
21939
  if (process.platform !== "win32") {
21934
21940
  try {
21935
- process.kill(-child.pid, "SIGTERM");
21941
+ process.kill(-child2.pid, "SIGTERM");
21936
21942
  return;
21937
21943
  } catch {
21938
21944
  }
21939
21945
  }
21940
- child.kill("SIGTERM");
21946
+ child2.kill("SIGTERM");
21941
21947
  }
21942
- function forceTerminateProcess(child) {
21943
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
21948
+ function forceTerminateProcess(child2) {
21949
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
21944
21950
  return;
21945
21951
  }
21946
21952
  if (process.platform !== "win32") {
21947
21953
  try {
21948
- process.kill(-child.pid, "SIGKILL");
21954
+ process.kill(-child2.pid, "SIGKILL");
21949
21955
  return;
21950
21956
  } catch {
21951
21957
  }
21952
21958
  }
21953
- child.kill("SIGKILL");
21959
+ child2.kill("SIGKILL");
21954
21960
  }
21955
- async function stopProcessTree(child, capturedProcesses = []) {
21956
- const childProcessId = child.pid;
21961
+ async function stopProcessTree(child2, capturedProcesses = []) {
21962
+ const childProcessId = child2.pid;
21957
21963
  if (childProcessId === void 0) {
21958
21964
  return;
21959
21965
  }
21960
- const childExited = child.exitCode !== null || child.signalCode !== null;
21961
- const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child));
21966
+ const childExited = child2.exitCode !== null || child2.signalCode !== null;
21967
+ const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child2));
21962
21968
  if (childExited && processes.length === 0) {
21963
21969
  return;
21964
21970
  }
21965
21971
  signalCapturedProcessGroups(processes, childProcessId, GRACEFUL_STOP_SIGNAL);
21966
- terminateProcess(child);
21972
+ terminateProcess(child2);
21967
21973
  const [exitedAfterTermination, descendantsExitedAfterTermination] = await Promise.all([
21968
- waitForProcessExit(child, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
21974
+ waitForProcessExit(child2, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
21969
21975
  waitForCapturedProcessesExit(processes, childProcessId)
21970
21976
  ]);
21971
21977
  if (exitedAfterTermination && descendantsExitedAfterTermination) {
21972
21978
  return;
21973
21979
  }
21974
21980
  signalCapturedProcessGroups(processes, childProcessId, FORCED_STOP_SIGNAL);
21975
- forceTerminateProcess(child);
21981
+ forceTerminateProcess(child2);
21976
21982
  const [exitedAfterForce, descendantsExitedAfterForce] = await Promise.all([
21977
- waitForProcessExit(child, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
21983
+ waitForProcessExit(child2, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
21978
21984
  waitForCapturedProcessesExit(processes, childProcessId)
21979
21985
  ]);
21980
21986
  if (!exitedAfterForce || !descendantsExitedAfterForce) {
21981
21987
  throw new ProcessExecutionError("process_termination_timeout", "The executable process could not be stopped");
21982
21988
  }
21983
21989
  }
21984
- function waitForProcessExit(child, timeoutMilliseconds) {
21985
- if (child.exitCode !== null || child.signalCode !== null) {
21990
+ function waitForProcessExit(child2, timeoutMilliseconds) {
21991
+ if (child2.exitCode !== null || child2.signalCode !== null) {
21986
21992
  return Promise.resolve(true);
21987
21993
  }
21988
21994
  return new Promise((resolveExit) => {
@@ -21993,13 +21999,13 @@ function waitForProcessExit(child, timeoutMilliseconds) {
21993
21999
  }
21994
22000
  settled = true;
21995
22001
  clearTimeout(timeout);
21996
- child.removeListener("exit", handleExit);
22002
+ child2.removeListener("exit", handleExit);
21997
22003
  resolveExit(exited);
21998
22004
  };
21999
22005
  const handleExit = () => finish(true);
22000
22006
  const timeout = setTimeout(() => finish(false), timeoutMilliseconds);
22001
- child.once("exit", handleExit);
22002
- if (child.exitCode !== null || child.signalCode !== null) {
22007
+ child2.once("exit", handleExit);
22008
+ if (child2.exitCode !== null || child2.signalCode !== null) {
22003
22009
  finish(true);
22004
22010
  }
22005
22011
  });
@@ -22007,7 +22013,7 @@ function waitForProcessExit(child, timeoutMilliseconds) {
22007
22013
  async function runBoundedProcess(options) {
22008
22014
  options.signal.throwIfAborted();
22009
22015
  const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
22010
- const child = spawn(options.command, [...options.arguments], {
22016
+ const child2 = spawn(options.command, [...options.arguments], {
22011
22017
  cwd: options.cwd,
22012
22018
  detached: process.platform !== "win32",
22013
22019
  env: { ...options.environment },
@@ -22030,7 +22036,7 @@ async function runBoundedProcess(options) {
22030
22036
  interruptionFailure = failure2;
22031
22037
  const stop = async () => {
22032
22038
  try {
22033
- await stopProcessTree(child);
22039
+ await stopProcessTree(child2);
22034
22040
  } catch (error62) {
22035
22041
  interruptionCleanupFailure = error62 instanceof ProcessExecutionError ? error62 : new ProcessExecutionError(
22036
22042
  "process_termination_failed",
@@ -22069,8 +22075,8 @@ async function runBoundedProcess(options) {
22069
22075
  interrupt(failure2);
22070
22076
  }
22071
22077
  };
22072
- child.stdout?.on("data", collectStdout);
22073
- child.stderr?.on("data", collectStderr);
22078
+ child2.stdout?.on("data", collectStdout);
22079
+ child2.stderr?.on("data", collectStderr);
22074
22080
  const timeout = setTimeout(() => {
22075
22081
  interrupt(new ProcessExecutionError("process_timeout", "The executable probe timed out"));
22076
22082
  }, options.timeoutMilliseconds);
@@ -22085,8 +22091,8 @@ async function runBoundedProcess(options) {
22085
22091
  }
22086
22092
  try {
22087
22093
  const exit = new Promise((resolveExit, rejectExit) => {
22088
- child.once("error", rejectExit);
22089
- child.once("exit", (code) => resolveExit(code ?? 1));
22094
+ child2.once("error", rejectExit);
22095
+ child2.once("exit", (code) => resolveExit(code ?? 1));
22090
22096
  });
22091
22097
  const exitCode = await Promise.race([exit, interrupted.promise.then(() => -1)]);
22092
22098
  if (interruptionCleanupFailure !== null) {
@@ -22109,12 +22115,12 @@ async function runBoundedProcess(options) {
22109
22115
  } finally {
22110
22116
  clearTimeout(timeout);
22111
22117
  options.signal.removeEventListener("abort", abort);
22112
- child.stdout?.removeListener("data", collectStdout);
22113
- child.stderr?.removeListener("data", collectStderr);
22118
+ child2.stdout?.removeListener("data", collectStdout);
22119
+ child2.stderr?.removeListener("data", collectStderr);
22114
22120
  if (stopping) {
22115
22121
  await interrupted.promise;
22116
22122
  } else {
22117
- await stopProcessTree(child);
22123
+ await stopProcessTree(child2);
22118
22124
  }
22119
22125
  }
22120
22126
  }
@@ -22852,6 +22858,74 @@ function acpEndpointTerminationError(termination) {
22852
22858
  }
22853
22859
  }
22854
22860
 
22861
+ // src/acp/value-utils.ts
22862
+ function truncate(value, maximumLength) {
22863
+ return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
22864
+ }
22865
+ function isRecord4(value) {
22866
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22867
+ }
22868
+ function readString2(value, fallback = "") {
22869
+ return typeof value === "string" ? value : fallback;
22870
+ }
22871
+
22872
+ // src/acp/session-failure.ts
22873
+ var CATEGORIES = /* @__PURE__ */ new Set([
22874
+ "access",
22875
+ "connection",
22876
+ "limit",
22877
+ "request",
22878
+ "service",
22879
+ "unknown"
22880
+ ]);
22881
+ function isCategory(value) {
22882
+ return typeof value === "string" && CATEGORIES.has(value);
22883
+ }
22884
+ function child(value, key) {
22885
+ return isRecord4(value) ? value[key] : void 0;
22886
+ }
22887
+ function readAcpSessionFailure(value) {
22888
+ const meta3 = child(value, "_meta");
22889
+ const jetbrains = child(meta3, "jetbrains");
22890
+ const air = child(jetbrains, "air");
22891
+ const failure2 = child(air, "sessionFailure");
22892
+ if (!isRecord4(air) || !Number.isInteger(air["version"]) || Number(air["version"]) < 1 || !isRecord4(failure2)) {
22893
+ return null;
22894
+ }
22895
+ const id = failure2["id"];
22896
+ const revision = failure2["revision"];
22897
+ const category = failure2["category"];
22898
+ const severity = failure2["severity"];
22899
+ const title2 = failure2["title"];
22900
+ 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) {
22901
+ return null;
22902
+ }
22903
+ return {
22904
+ category,
22905
+ id,
22906
+ revision: Number(revision),
22907
+ severity,
22908
+ title: truncate(title2, 4096)
22909
+ };
22910
+ }
22911
+ function sessionFailureMeta(failure2) {
22912
+ return {
22913
+ jetbrains: {
22914
+ air: {
22915
+ version: 1,
22916
+ sessionFailure: {
22917
+ actions: [],
22918
+ category: failure2.category,
22919
+ id: failure2.id,
22920
+ revision: failure2.revision,
22921
+ severity: failure2.severity,
22922
+ title: failure2.title
22923
+ }
22924
+ }
22925
+ }
22926
+ };
22927
+ }
22928
+
22855
22929
  // src/acp/codex/app-server-client.ts
22856
22930
  import { spawn as spawn2 } from "node:child_process";
22857
22931
 
@@ -22976,6 +23050,12 @@ var turnNotificationSchema = external_exports.object({
22976
23050
  threadId: boundedText(256),
22977
23051
  turn: turnSchema
22978
23052
  });
23053
+ var errorNotificationSchema = external_exports.object({
23054
+ error: external_exports.object({ message: boundedText(4096) }),
23055
+ threadId: boundedText(256),
23056
+ turnId: boundedText(256),
23057
+ willRetry: external_exports.boolean()
23058
+ });
22979
23059
  var commandApprovalParamsSchema = external_exports.object({
22980
23060
  command: external_exports.string().nullish(),
22981
23061
  commandActions: external_exports.array(external_exports.unknown()).max(1e3).nullish(),
@@ -23320,7 +23400,7 @@ var CodexAppServerClient = class {
23320
23400
  var TOOL_OUTPUT_CHARACTER_LIMIT = 32768;
23321
23401
  var TITLE_CHARACTER_LIMIT = 500;
23322
23402
  var CODEX_META_KEY = "codex";
23323
- function truncate(value, limit) {
23403
+ function truncate2(value, limit) {
23324
23404
  return value.length <= limit ? value : value.slice(0, limit);
23325
23405
  }
23326
23406
  function boundedParagraphs(values, limit) {
@@ -23336,7 +23416,7 @@ function boundedParagraphs(values, limit) {
23336
23416
  return text2;
23337
23417
  }
23338
23418
  function textContent(text2) {
23339
- const block = { text: truncate(text2, TOOL_OUTPUT_CHARACTER_LIMIT), type: "text" };
23419
+ const block = { text: truncate2(text2, TOOL_OUTPUT_CHARACTER_LIMIT), type: "text" };
23340
23420
  return { content: block, type: "content" };
23341
23421
  }
23342
23422
  function firstLine(value) {
@@ -23375,16 +23455,16 @@ function presentToolItem(item) {
23375
23455
  rawInput: { command: item.command, cwd: item.cwd },
23376
23456
  rawOutput: {
23377
23457
  ...item.exitCode == null ? {} : { exitCode: item.exitCode },
23378
- output: truncate(output2, TOOL_OUTPUT_CHARACTER_LIMIT)
23458
+ output: truncate2(output2, TOOL_OUTPUT_CHARACTER_LIMIT)
23379
23459
  },
23380
23460
  status: commandStatus(item.status),
23381
- title: truncate(firstLine(item.command), TITLE_CHARACTER_LIMIT)
23461
+ title: truncate2(firstLine(item.command), TITLE_CHARACTER_LIMIT)
23382
23462
  };
23383
23463
  }
23384
23464
  if (item.type === "fileChange") {
23385
23465
  const paths = item.changes.map((change) => change.path);
23386
23466
  const content = item.changes.map((change) => ({
23387
- newText: truncate(change.diff, TOOL_OUTPUT_CHARACTER_LIMIT),
23467
+ newText: truncate2(change.diff, TOOL_OUTPUT_CHARACTER_LIMIT),
23388
23468
  path: change.path,
23389
23469
  type: "diff"
23390
23470
  }));
@@ -23395,7 +23475,7 @@ function presentToolItem(item) {
23395
23475
  rawInput: { changes: item.changes.map((change) => change.path) },
23396
23476
  rawOutput: null,
23397
23477
  status: patchStatus(item.status),
23398
- title: truncate(paths.join(", "), TITLE_CHARACTER_LIMIT)
23478
+ title: truncate2(paths.join(", "), TITLE_CHARACTER_LIMIT)
23399
23479
  };
23400
23480
  }
23401
23481
  if (item.type === "mcpToolCall") {
@@ -23414,7 +23494,7 @@ function presentToolItem(item) {
23414
23494
  rawInput: item.arguments ?? null,
23415
23495
  rawOutput: item.error ?? item.result ?? null,
23416
23496
  status: mcpStatus(item.status),
23417
- title: truncate(label, TITLE_CHARACTER_LIMIT)
23497
+ title: truncate2(label, TITLE_CHARACTER_LIMIT)
23418
23498
  };
23419
23499
  }
23420
23500
  if (item.type === "dynamicToolCall") {
@@ -23427,7 +23507,7 @@ function presentToolItem(item) {
23427
23507
  rawInput: item.arguments ?? null,
23428
23508
  rawOutput: item.success === true ? null : item.contentItems ?? null,
23429
23509
  status: mcpStatus(item.status),
23430
- title: truncate(label, TITLE_CHARACTER_LIMIT)
23510
+ title: truncate2(label, TITLE_CHARACTER_LIMIT)
23431
23511
  };
23432
23512
  }
23433
23513
  return null;
@@ -23985,6 +24065,7 @@ var CodexAcpAgent = class {
23985
24065
  #nativeSessionId = "";
23986
24066
  #streamedReasoningItemIds = /* @__PURE__ */ new Set();
23987
24067
  #streamedAgentMessageItemIds = /* @__PURE__ */ new Set();
24068
+ #noticeRevisions = /* @__PURE__ */ new Map();
23988
24069
  #turn = null;
23989
24070
  #nativeTurnId = null;
23990
24071
  #updateTail = Promise.resolve();
@@ -24137,10 +24218,10 @@ var CodexAcpAgent = class {
24137
24218
  if (this.#closePromise === null) {
24138
24219
  this.#appServer.detach();
24139
24220
  this.#closePromise = (async () => {
24140
- const child = this.#appServer.child();
24221
+ const child2 = this.#appServer.child();
24141
24222
  try {
24142
- const captured = await captureProcessTree(child);
24143
- await stopProcessTree(child, captured);
24223
+ const captured = await captureProcessTree(child2);
24224
+ await stopProcessTree(child2, captured);
24144
24225
  } finally {
24145
24226
  this.#connection?.close();
24146
24227
  }
@@ -24230,6 +24311,27 @@ var CodexAcpAgent = class {
24230
24311
  await pending;
24231
24312
  };
24232
24313
  #onNotification = async (method, params) => {
24314
+ if (method === "error") {
24315
+ const decoded = errorNotificationSchema.safeParse(params);
24316
+ if (decoded.success && decoded.data.willRetry && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null && decoded.data.turnId === this.#turn.turn.id) {
24317
+ const id = `codex:${decoded.data.turnId}:error`;
24318
+ const revision = (this.#noticeRevisions.get(id) ?? 0) + 1;
24319
+ this.#noticeRevisions.set(id, revision);
24320
+ await this.#enqueue(async () => {
24321
+ await this.#emit({
24322
+ _meta: sessionFailureMeta({
24323
+ category: "service",
24324
+ id,
24325
+ revision,
24326
+ severity: "warning",
24327
+ title: decoded.data.error.message
24328
+ }),
24329
+ sessionUpdate: "session_info_update"
24330
+ });
24331
+ });
24332
+ }
24333
+ return;
24334
+ }
24233
24335
  if (method === "turn/started") {
24234
24336
  const decoded = turnNotificationSchema.safeParse(params);
24235
24337
  if (decoded.success && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null) {
@@ -25207,7 +25309,7 @@ var ManagedAgentArchiveError = class extends Error {
25207
25309
  this.name = "ManagedAgentArchiveError";
25208
25310
  }
25209
25311
  };
25210
- function isRecord4(value) {
25312
+ function isRecord5(value) {
25211
25313
  return typeof value === "object" && value !== null && !Array.isArray(value);
25212
25314
  }
25213
25315
  function isContainedPath3(root, candidate) {
@@ -25264,7 +25366,7 @@ async function readManifest(path2) {
25264
25366
  );
25265
25367
  }
25266
25368
  const parsed = JSON.parse(await handle.readFile({ encoding: "utf8" }));
25267
- if (!isRecord4(parsed)) {
25369
+ if (!isRecord5(parsed)) {
25268
25370
  throw new ManagedAgentArchiveError(
25269
25371
  "managed_archive_verification_failed",
25270
25372
  "The managed Agent archive manifest is invalid"
@@ -25900,7 +26002,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
25900
26002
  signal.removeEventListener("abort", abort);
25901
26003
  }
25902
26004
  }
25903
- const child = spawn3(agent.adapterPath, [...agent.arguments], {
26005
+ const child2 = spawn3(agent.adapterPath, [...agent.arguments], {
25904
26006
  cwd: defaultWorkspace,
25905
26007
  detached: process.platform !== "win32",
25906
26008
  env: { ...environment, ...agent.environment },
@@ -25909,17 +26011,17 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
25909
26011
  });
25910
26012
  const processExit = new Promise((_resolve, reject) => {
25911
26013
  const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
25912
- child.once("error", reject);
25913
- child.once("exit", rejectExit);
25914
- if (child.exitCode !== null || child.signalCode !== null) {
26014
+ child2.once("error", reject);
26015
+ child2.once("exit", rejectExit);
26016
+ if (child2.exitCode !== null || child2.signalCode !== null) {
25915
26017
  rejectExit();
25916
26018
  }
25917
26019
  });
25918
- const stdin = child.stdin;
25919
- const stdout = child.stdout;
25920
- const stderr = child.stderr;
26020
+ const stdin = child2.stdin;
26021
+ const stdout = child2.stdout;
26022
+ const stderr = child2.stderr;
25921
26023
  if (stdin === null || stdout === null || stderr === null) {
25922
- await stopProcessTree(child);
26024
+ await stopProcessTree(child2);
25923
26025
  throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
25924
26026
  }
25925
26027
  let stderrBytes = 0;
@@ -25971,11 +26073,11 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
25971
26073
  } finally {
25972
26074
  clearTimeout(timeout);
25973
26075
  signal.removeEventListener("abort", abort);
25974
- const capturedProcesses = await captureProcessTree(child);
26076
+ const capturedProcesses = await captureProcessTree(child2);
25975
26077
  connection.close();
25976
26078
  stdin.end();
25977
26079
  stderr.removeListener("data", consumeStderr);
25978
- await stopProcessTree(child, capturedProcesses);
26080
+ await stopProcessTree(child2, capturedProcesses);
25979
26081
  }
25980
26082
  }
25981
26083
 
@@ -26889,10 +26991,10 @@ async function replaceImageMarkers(text2, replace) {
26889
26991
 
26890
26992
  // src/acp/activity-content.ts
26891
26993
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
26892
- function isRecord5(value) {
26994
+ function isRecord6(value) {
26893
26995
  return typeof value === "object" && value !== null && !Array.isArray(value);
26894
26996
  }
26895
- function truncate2(value, maximumLength) {
26997
+ function truncate3(value, maximumLength) {
26896
26998
  if (value.length <= maximumLength) {
26897
26999
  return value;
26898
27000
  }
@@ -26900,13 +27002,13 @@ function truncate2(value, maximumLength) {
26900
27002
  }
26901
27003
  function formatUnknown(value) {
26902
27004
  if (typeof value === "string") {
26903
- return truncate2(value, AGENT_ACTIVITY_DETAIL_LIMIT);
27005
+ return truncate3(value, AGENT_ACTIVITY_DETAIL_LIMIT);
26904
27006
  }
26905
27007
  try {
26906
27008
  const encoded = JSON.stringify(value, null, 2);
26907
- return truncate2(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
27009
+ return truncate3(encoded ?? "", AGENT_ACTIVITY_DETAIL_LIMIT);
26908
27010
  } catch {
26909
- return truncate2(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
27011
+ return truncate3(String(value), AGENT_ACTIVITY_DETAIL_LIMIT);
26910
27012
  }
26911
27013
  }
26912
27014
  function formatUnknownDetail(value) {
@@ -26934,16 +27036,16 @@ function readContentOutputDetail(content) {
26934
27036
  function summarizeDisplayContent(content) {
26935
27037
  return {
26936
27038
  ...content,
26937
- artifactId: truncate2(content.artifactId, 128),
26938
- data: truncate2(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
26939
- mimeType: truncate2(content.mimeType, 255),
26940
- name: truncate2(content.name, 500),
26941
- newText: truncate2(content.newText, AGENT_ACTIVITY_DETAIL_LIMIT),
26942
- oldText: truncate2(content.oldText, AGENT_ACTIVITY_DETAIL_LIMIT),
26943
- path: truncate2(content.path, 2048),
26944
- terminalId: truncate2(content.terminalId, 255),
26945
- text: truncate2(content.text, AGENT_ACTIVITY_DETAIL_LIMIT),
26946
- uri: truncate2(content.uri, 4096)
27039
+ artifactId: truncate3(content.artifactId, 128),
27040
+ data: truncate3(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
27041
+ mimeType: truncate3(content.mimeType, 255),
27042
+ name: truncate3(content.name, 500),
27043
+ newText: truncate3(content.newText, AGENT_ACTIVITY_DETAIL_LIMIT),
27044
+ oldText: truncate3(content.oldText, AGENT_ACTIVITY_DETAIL_LIMIT),
27045
+ path: truncate3(content.path, 2048),
27046
+ terminalId: truncate3(content.terminalId, 255),
27047
+ text: truncate3(content.text, AGENT_ACTIVITY_DETAIL_LIMIT),
27048
+ uri: truncate3(content.uri, 4096)
26947
27049
  };
26948
27050
  }
26949
27051
  function contentFitsRecordingEnvelope(content) {
@@ -26961,8 +27063,8 @@ function captureActivityDetail(content, input2, output2) {
26961
27063
  return {
26962
27064
  capturedBytes: encodedByteLength({
26963
27065
  content: content.slice(0, 100).map(summarizeDisplayContent),
26964
- input: truncate2(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
26965
- output: truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
27066
+ input: truncate3(input2, AGENT_ACTIVITY_DETAIL_LIMIT),
27067
+ output: truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT)
26966
27068
  }),
26967
27069
  kind: "truncated",
26968
27070
  originalBytes
@@ -27073,16 +27175,16 @@ async function normalizeToolContent(content, prepareContent) {
27073
27175
  return normalized;
27074
27176
  }
27075
27177
  function rawMcpToolContent(rawOutput) {
27076
- if (!isRecord5(rawOutput)) {
27178
+ if (!isRecord6(rawOutput)) {
27077
27179
  return [];
27078
27180
  }
27079
- const result = isRecord5(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
27181
+ const result = isRecord6(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
27080
27182
  const content = result["content"];
27081
27183
  if (!Array.isArray(content)) {
27082
27184
  return [];
27083
27185
  }
27084
27186
  return content.flatMap((item) => {
27085
- if (!isRecord5(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
27187
+ if (!isRecord6(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
27086
27188
  return [];
27087
27189
  }
27088
27190
  const uri = item["uri"];
@@ -27110,7 +27212,7 @@ function normalizeLocations(locations) {
27110
27212
  break;
27111
27213
  }
27112
27214
  const suffix = typeof location.line === "number" ? `:${location.line.toString()}` : "";
27113
- const value = truncate2(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
27215
+ const value = truncate3(`${location.path}${suffix}`, AGENT_ACTIVITY_LOCATION_LENGTH_LIMIT);
27114
27216
  if (value.length > 0 && !unique.has(value)) {
27115
27217
  unique.add(value);
27116
27218
  normalized.push(value);
@@ -27132,14 +27234,14 @@ function normalizeToolStatus(status, fallback) {
27132
27234
  }
27133
27235
  function normalizeTitle(title2, fallback) {
27134
27236
  const normalized = title2.trim();
27135
- return truncate2(normalized.length === 0 ? fallback : normalized, 500);
27237
+ return truncate3(normalized.length === 0 ? fallback : normalized, 500);
27136
27238
  }
27137
27239
  function formatPlanEntries(entries) {
27138
27240
  const lines = [];
27139
27241
  for (const entry of entries) {
27140
27242
  lines.push(`[${entry.status}] ${entry.content}`);
27141
27243
  }
27142
- return truncate2(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
27244
+ return truncate3(lines.join("\n"), AGENT_ACTIVITY_DETAIL_LIMIT);
27143
27245
  }
27144
27246
  function planStatus(entries) {
27145
27247
  if (entries.length === 0) {
@@ -27159,7 +27261,7 @@ function contentPhase(content) {
27159
27261
  return "";
27160
27262
  }
27161
27263
  const codex = metadata["codex"];
27162
- if (!isRecord5(codex)) {
27264
+ if (!isRecord6(codex)) {
27163
27265
  return "";
27164
27266
  }
27165
27267
  const phase = codex["phase"];
@@ -27172,19 +27274,6 @@ function isProgressMessage(content) {
27172
27274
  // src/acp/agent-connection.ts
27173
27275
  import { spawn as spawn4 } from "node:child_process";
27174
27276
  import { ndJsonStream as ndJsonStream2, RequestError as RequestError3 } from "@agentclientprotocol/sdk";
27175
-
27176
- // src/acp/value-utils.ts
27177
- function truncate3(value, maximumLength) {
27178
- return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
27179
- }
27180
- function isRecord6(value) {
27181
- return typeof value === "object" && value !== null && !Array.isArray(value);
27182
- }
27183
- function readString2(value, fallback = "") {
27184
- return typeof value === "string" ? value : fallback;
27185
- }
27186
-
27187
- // src/acp/agent-connection.ts
27188
27277
  function readableWebStream(input2) {
27189
27278
  let streamOpen = true;
27190
27279
  return new ReadableStream({
@@ -27276,19 +27365,19 @@ var AgentConnection = class {
27276
27365
  this.connection = createAcpClient(client2).connect(inProcess.app());
27277
27366
  return;
27278
27367
  }
27279
- const child = spawn4(agent.adapterPath, [...agent.arguments], {
27368
+ const child2 = spawn4(agent.adapterPath, [...agent.arguments], {
27280
27369
  cwd,
27281
27370
  detached: process.platform !== "win32",
27282
27371
  env: { ...process.env, ...agent.environment },
27283
27372
  shell: false,
27284
27373
  stdio: ["pipe", "pipe", "pipe"]
27285
27374
  });
27286
- this.#process = { kind: "child", child };
27287
- const stdin = child.stdin;
27288
- const stdout = child.stdout;
27289
- const stderr = child.stderr;
27375
+ this.#process = { kind: "child", child: child2 };
27376
+ const stdin = child2.stdin;
27377
+ const stdout = child2.stdout;
27378
+ const stderr = child2.stderr;
27290
27379
  if (stdin === null || stdout === null || stderr === null) {
27291
- child.kill("SIGKILL");
27380
+ child2.kill("SIGKILL");
27292
27381
  throw new AcpExecutionError("ACP process streams are unavailable");
27293
27382
  }
27294
27383
  stderr.setEncoding("utf8");
@@ -27296,10 +27385,10 @@ var AgentConnection = class {
27296
27385
  process.stderr.write(`[${agent.id}-acp] ${chunk}`);
27297
27386
  });
27298
27387
  this.termination = new Promise((resolve9) => {
27299
- child.once("error", (cause) => {
27388
+ child2.once("error", (cause) => {
27300
27389
  resolve9({ kind: "failed", error: new AcpExecutionError("The ACP process could not run", { cause }) });
27301
27390
  });
27302
- child.once("exit", (code, signal) => {
27391
+ child2.once("exit", (code, signal) => {
27303
27392
  resolve9({
27304
27393
  kind: "failed",
27305
27394
  error: new AcpExecutionError("The ACP process stopped", { cause: { code, signal } })
@@ -27357,7 +27446,7 @@ var AgentConnection = class {
27357
27446
  );
27358
27447
  }
27359
27448
  if (error62 instanceof RequestError3) {
27360
- throw new AcpExecutionError(truncate3(error62.message, 500), { cause: error62 }, "acp_agent_error");
27449
+ throw new AcpExecutionError(truncate(error62.message, 500), { cause: error62 }, "acp_agent_error");
27361
27450
  }
27362
27451
  throw error62;
27363
27452
  }
@@ -27434,6 +27523,7 @@ var AcpActivityTracker = class {
27434
27523
  #activities = /* @__PURE__ */ new Map();
27435
27524
  #identities = /* @__PURE__ */ new Map();
27436
27525
  #narrations = /* @__PURE__ */ new Map();
27526
+ #noticeRevisions = /* @__PURE__ */ new Map();
27437
27527
  #onActivity;
27438
27528
  #onNarration;
27439
27529
  #prepareContent;
@@ -27469,13 +27559,37 @@ var AcpActivityTracker = class {
27469
27559
  await this.#onNarration(new AcpActivityNarration(identity2.id, activityType, identity2.sequence, text2));
27470
27560
  }
27471
27561
  };
27562
+ recordNotice = async (id, revision, severity, text2) => {
27563
+ const key = `notice:${id}`;
27564
+ if ((this.#noticeRevisions.get(key) ?? 0) >= revision) {
27565
+ return;
27566
+ }
27567
+ await this.finishNarrative();
27568
+ this.#noticeRevisions.set(key, revision);
27569
+ const identity2 = this.#identity(key);
27570
+ await this.#record(
27571
+ key,
27572
+ new AcpActivity(
27573
+ identity2.id,
27574
+ "notice",
27575
+ "",
27576
+ [],
27577
+ "",
27578
+ truncate3(text2, AGENT_ACTIVITY_DETAIL_LIMIT),
27579
+ identity2.sequence,
27580
+ severity === "error" ? "failed" : "completed",
27581
+ severity === "error" ? "Agent error" : "Agent warning",
27582
+ ""
27583
+ )
27584
+ );
27585
+ };
27472
27586
  #narrativeSnapshot = (identity2, activityType, output2, status) => new AcpActivity(
27473
27587
  identity2.id,
27474
27588
  activityType,
27475
27589
  "",
27476
27590
  [],
27477
27591
  "",
27478
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
27592
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
27479
27593
  identity2.sequence,
27480
27594
  status,
27481
27595
  activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -27503,7 +27617,7 @@ var AcpActivityTracker = class {
27503
27617
  "",
27504
27618
  [],
27505
27619
  "",
27506
- truncate2(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
27620
+ truncate3(output2, AGENT_ACTIVITY_DETAIL_LIMIT),
27507
27621
  identity2.sequence,
27508
27622
  "running",
27509
27623
  "Plan",
@@ -27553,7 +27667,7 @@ var AcpActivityTracker = class {
27553
27667
  "tool",
27554
27668
  update.rawInput === void 0 ? "" : formatUnknown(update.rawInput),
27555
27669
  normalizeLocations(update.locations ?? []),
27556
- truncate2(update.name ?? "", 128),
27670
+ truncate3(update.name ?? "", 128),
27557
27671
  output2,
27558
27672
  identity2.sequence,
27559
27673
  normalizeToolStatus(update.status ?? "pending", "pending"),
@@ -27583,7 +27697,7 @@ var AcpActivityTracker = class {
27583
27697
  "tool",
27584
27698
  update.rawInput === void 0 ? previous?.input ?? "" : formatUnknown(update.rawInput),
27585
27699
  update.locations === void 0 || update.locations === null ? previous?.locations ?? [] : normalizeLocations(update.locations),
27586
- update.name === void 0 || update.name === null ? previous?.name ?? "" : truncate2(update.name, 128),
27700
+ update.name === void 0 || update.name === null ? previous?.name ?? "" : truncate3(update.name, 128),
27587
27701
  output2,
27588
27702
  identity2.sequence,
27589
27703
  update.status === void 0 || update.status === null ? previous?.status ?? "pending" : normalizeToolStatus(update.status, previous?.status ?? "pending"),
@@ -27638,7 +27752,7 @@ var AcpActivityTracker = class {
27638
27752
  "",
27639
27753
  [],
27640
27754
  "",
27641
- truncate2(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
27755
+ truncate3(narration.output, AGENT_ACTIVITY_DETAIL_LIMIT),
27642
27756
  narration.sequence,
27643
27757
  "completed",
27644
27758
  narration.activityType === "reasoning" ? "Reasoning" : "Progress update",
@@ -28257,11 +28371,11 @@ function normalizeElicitationOptions(schema) {
28257
28371
  const oneOf = schema["oneOf"];
28258
28372
  if (Array.isArray(oneOf)) {
28259
28373
  for (const option of oneOf) {
28260
- if (isRecord6(option) && typeof option["const"] === "string") {
28374
+ if (isRecord4(option) && typeof option["const"] === "string") {
28261
28375
  normalized.push({
28262
- description: truncate3(readString2(option["description"]), 500),
28263
- label: truncate3(readString2(option["title"], option["const"]), 255),
28264
- value: truncate3(option["const"], 500)
28376
+ description: truncate(readString2(option["description"]), 500),
28377
+ label: truncate(readString2(option["title"], option["const"]), 255),
28378
+ value: truncate(option["const"], 500)
28265
28379
  });
28266
28380
  }
28267
28381
  }
@@ -28277,7 +28391,7 @@ function normalizeElicitationOptions(schema) {
28277
28391
  return normalized.slice(0, 200);
28278
28392
  }
28279
28393
  const items = schema["items"];
28280
- if (!isRecord6(items)) {
28394
+ if (!isRecord4(items)) {
28281
28395
  return normalized;
28282
28396
  }
28283
28397
  const anyOf = items["anyOf"];
@@ -28290,7 +28404,7 @@ function numericString(value) {
28290
28404
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
28291
28405
  }
28292
28406
  function normalizeElicitationFields(requestedSchema) {
28293
- if (!isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
28407
+ if (!isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
28294
28408
  return [];
28295
28409
  }
28296
28410
  const properties = requestedSchema["properties"];
@@ -28300,7 +28414,7 @@ function normalizeElicitationFields(requestedSchema) {
28300
28414
  );
28301
28415
  const normalized = [];
28302
28416
  for (const [name, property] of Object.entries(properties)) {
28303
- if (!isRecord6(property)) {
28417
+ if (!isRecord4(property)) {
28304
28418
  continue;
28305
28419
  }
28306
28420
  const type = elicitationFieldType(property["type"]);
@@ -28310,19 +28424,19 @@ function normalizeElicitationFields(requestedSchema) {
28310
28424
  normalized.push({
28311
28425
  defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
28312
28426
  defaultNumberValue: typeof defaultValue === "number" && Number.isFinite(defaultValue) ? defaultValue : 0,
28313
- defaultStringValue: typeof defaultValue === "string" ? truncate3(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate3(JSON.stringify(defaultValue), 1e4) : "",
28314
- description: truncate3(readString2(property["description"]), 500),
28315
- format: truncate3(readString2(property["format"]), 64),
28427
+ defaultStringValue: typeof defaultValue === "string" ? truncate(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate(JSON.stringify(defaultValue), 1e4) : "",
28428
+ description: truncate(readString2(property["description"]), 500),
28429
+ format: truncate(readString2(property["format"]), 64),
28316
28430
  hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
28317
28431
  maximum: numericString(property["maximum"]),
28318
28432
  maximumLength: numericString(property["maxLength"] ?? property["maxItems"]),
28319
28433
  minimum: numericString(property["minimum"]),
28320
28434
  minimumLength: numericString(property["minLength"] ?? property["minItems"]),
28321
- name: truncate3(name, 128),
28435
+ name: truncate(name, 128),
28322
28436
  options,
28323
- pattern: truncate3(readString2(property["pattern"]), 500),
28437
+ pattern: truncate(readString2(property["pattern"]), 500),
28324
28438
  required: required2.has(name),
28325
- title: truncate3(readString2(property["title"], name), 255),
28439
+ title: truncate(readString2(property["title"], name), 255),
28326
28440
  type: normalizedType
28327
28441
  });
28328
28442
  }
@@ -28391,7 +28505,7 @@ function validateElicitationContent(encoded, requestedSchema) {
28391
28505
  "invalid_elicitation_response"
28392
28506
  );
28393
28507
  }
28394
- if (!isRecord6(decoded) || !isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
28508
+ if (!isRecord4(decoded) || !isRecord4(requestedSchema) || !isRecord4(requestedSchema["properties"])) {
28395
28509
  throw new AcpExecutionError(
28396
28510
  "Elicitation response does not match the requested form",
28397
28511
  {},
@@ -28411,7 +28525,7 @@ function validateElicitationContent(encoded, requestedSchema) {
28411
28525
  const validated = {};
28412
28526
  for (const [name, value] of Object.entries(decoded)) {
28413
28527
  const property = properties[name];
28414
- if (!isRecord6(property)) {
28528
+ if (!isRecord4(property)) {
28415
28529
  throw new AcpExecutionError(
28416
28530
  `Elicitation field ${name} was not requested`,
28417
28531
  {},
@@ -28615,8 +28729,8 @@ var AcpSessionInteractions = class {
28615
28729
  const interactionId = `permission-${crypto.randomUUID()}`;
28616
28730
  const options = request.options.slice(0, 20).map((option) => ({
28617
28731
  kind: option.kind,
28618
- name: truncate3(option.name, 255),
28619
- optionId: truncate3(option.optionId, 255)
28732
+ name: truncate(option.name, 255),
28733
+ optionId: truncate(option.optionId, 255)
28620
28734
  }));
28621
28735
  if (options.length === 0) {
28622
28736
  throw new AcpExecutionError(
@@ -28638,9 +28752,9 @@ var AcpSessionInteractions = class {
28638
28752
  kind: SESSION_PERMISSION_REQUESTED_KIND,
28639
28753
  options,
28640
28754
  sessionId: this.#context.sessionId(),
28641
- title: truncate3(request.toolCall.title ?? "Permission required", 500),
28642
- toolCallId: truncate3(request.toolCall.toolCallId, 255),
28643
- toolKind: truncate3(request.toolCall.kind ?? "other", 64)
28755
+ title: truncate(request.toolCall.title ?? "Permission required", 500),
28756
+ toolCallId: truncate(request.toolCall.toolCallId, 255),
28757
+ toolKind: truncate(request.toolCall.kind ?? "other", 64)
28644
28758
  });
28645
28759
  return await pending.completion.promise;
28646
28760
  } finally {
@@ -28669,7 +28783,7 @@ var AcpSessionInteractions = class {
28669
28783
  const schemaValue = Reflect.get(request, "requestedSchema");
28670
28784
  const requestedSchema = request.mode === "form" ? schemaValue : {};
28671
28785
  const elicitationIdValue = Reflect.get(request, "elicitationId");
28672
- const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
28786
+ const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate(elicitationIdValue, 255) : "";
28673
28787
  const pending = new PendingElicitation(interactionId, elicitationId, requestedSchema);
28674
28788
  this.#pendingElicitations.set(interactionId, pending);
28675
28789
  const abort = () => {
@@ -28684,10 +28798,10 @@ var AcpSessionInteractions = class {
28684
28798
  fields: normalizeElicitationFields(requestedSchema),
28685
28799
  interactionId,
28686
28800
  kind: SESSION_ELICITATION_REQUESTED_KIND,
28687
- message: truncate3(request.message, 2e3),
28801
+ message: truncate(request.message, 2e3),
28688
28802
  mode: request.mode,
28689
28803
  sessionId: this.#context.sessionId(),
28690
- url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString2(Reflect.get(request, "url")), 4096) : ""
28804
+ url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate(readString2(Reflect.get(request, "url")), 4096) : ""
28691
28805
  });
28692
28806
  return await pending.completion.promise;
28693
28807
  } finally {
@@ -34634,6 +34748,9 @@ var AgentSession = class _AgentSession {
34634
34748
  methods8.agent.initialize,
34635
34749
  {
34636
34750
  clientCapabilities: {
34751
+ _meta: {
34752
+ jetbrains: { air: { capabilities: ["sessionFailure"], version: 1 } }
34753
+ },
34637
34754
  elicitation: { form: {}, url: {} },
34638
34755
  plan: {},
34639
34756
  session: { configOptions: { boolean: {} } }
@@ -34657,8 +34774,8 @@ var AgentSession = class _AgentSession {
34657
34774
  );
34658
34775
  }
34659
34776
  this.#capabilities = normalizeAcpCapabilities(initialized);
34660
- this.#agentName = truncate3(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
34661
- this.#agentVersion = truncate3(
34777
+ this.#agentName = truncate(initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId, 255);
34778
+ this.#agentVersion = truncate(
34662
34779
  this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
34663
34780
  128
34664
34781
  );
@@ -35019,7 +35136,7 @@ var AgentSession = class _AgentSession {
35019
35136
  }
35020
35137
  const prompt = this.buildPrompt(options);
35021
35138
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
35022
- this.#sessionTitle = truncate3(options.prompt, 500);
35139
+ this.#sessionTitle = truncate(options.prompt, 500);
35023
35140
  }
35024
35141
  this.#store.write(
35025
35142
  new AcpStoredSession(
@@ -35067,6 +35184,10 @@ var AgentSession = class _AgentSession {
35067
35184
  "acp_invalid_prompt_response"
35068
35185
  );
35069
35186
  }
35187
+ const failure2 = readAcpSessionFailure(response);
35188
+ if (failure2 !== null) {
35189
+ await running.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
35190
+ }
35070
35191
  if (result.usage != null || result._meta?.quota !== void 0) {
35071
35192
  await this.#getObserver().onUsage({
35072
35193
  _meta: result._meta ?? null,
@@ -35111,7 +35232,7 @@ var AgentSession = class _AgentSession {
35111
35232
  "ACP agent exited during steering",
35112
35233
  options.signal
35113
35234
  );
35114
- if (!isRecord6(response)) {
35235
+ if (!isRecord4(response)) {
35115
35236
  throw new AcpExecutionError(
35116
35237
  "ACP agent returned an invalid steering response",
35117
35238
  {},
@@ -35177,13 +35298,13 @@ var AgentSession = class _AgentSession {
35177
35298
  );
35178
35299
  } else {
35179
35300
  await this.#turn.activities.finishNarrative();
35180
- await this.#turn.onText(update.content.text, truncate3(update.messageId ?? "", 255));
35301
+ await this.#turn.onText(update.content.text, truncate(update.messageId ?? "", 255));
35181
35302
  }
35182
35303
  } else {
35183
35304
  await this.#turn.activities.finishNarrative();
35184
35305
  await this.emitAgentContent(
35185
35306
  normalizeContentBlock(update.content),
35186
- truncate3(update.messageId ?? "", 255)
35307
+ truncate(update.messageId ?? "", 255)
35187
35308
  );
35188
35309
  }
35189
35310
  return;
@@ -35220,9 +35341,9 @@ var AgentSession = class _AgentSession {
35220
35341
  }
35221
35342
  if (update.sessionUpdate === "available_commands_update") {
35222
35343
  const commands = update.availableCommands.slice(0, 500).map((command) => ({
35223
- description: truncate3(command.description, 500),
35224
- inputHint: truncate3(command.input?.hint ?? "", 255),
35225
- name: truncate3(command.name, 128)
35344
+ description: truncate(command.description, 500),
35345
+ inputHint: truncate(command.input?.hint ?? "", 255),
35346
+ name: truncate(command.name, 128)
35226
35347
  })).filter((command) => command.name.length > 0);
35227
35348
  this.#commands = commands;
35228
35349
  await this.#getObserver().onCommands({
@@ -35250,11 +35371,15 @@ var AgentSession = class _AgentSession {
35250
35371
  return;
35251
35372
  }
35252
35373
  if (update.sessionUpdate === "session_info_update") {
35374
+ const failure2 = readAcpSessionFailure(update);
35375
+ if (failure2 !== null && this.#turn.running) {
35376
+ await this.#turn.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
35377
+ }
35253
35378
  if (Object.hasOwn(update, "title")) {
35254
- this.#sessionTitle = truncate3(update.title ?? "", 500);
35379
+ this.#sessionTitle = truncate(update.title ?? "", 500);
35255
35380
  }
35256
35381
  if (Object.hasOwn(update, "updatedAt")) {
35257
- this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
35382
+ this.#sessionUpdatedAt = truncate(update.updatedAt ?? "", 128);
35258
35383
  }
35259
35384
  if (this.#updates.sessionId().length > 0) {
35260
35385
  this.#store.write(
@@ -35280,7 +35405,7 @@ var AgentSession = class _AgentSession {
35280
35405
  if (update.sessionUpdate === "usage_update") {
35281
35406
  await this.#getObserver().onUsage({
35282
35407
  costAmount: update.cost?.amount ?? 0,
35283
- costCurrency: truncate3(update.cost?.currency ?? "", 16),
35408
+ costCurrency: truncate(update.cost?.currency ?? "", 16),
35284
35409
  hasCost: update.cost !== void 0 && update.cost !== null,
35285
35410
  kind: SESSION_USAGE_UPDATED_KIND,
35286
35411
  sessionId: this.#mobiusSessionId,
@@ -37104,16 +37229,16 @@ var WorkspaceDirectoryService = class {
37104
37229
  const children = await readdir2(target, { withFileTypes: true });
37105
37230
  signal.throwIfAborted();
37106
37231
  const entries = [];
37107
- for (const child of children) {
37232
+ for (const child2 of children) {
37108
37233
  if (entries.length === 500) {
37109
37234
  break;
37110
37235
  }
37111
- if (child.isFile() || child.isBlockDevice() || child.isCharacterDevice() || child.isFIFO() || child.isSocket()) {
37236
+ if (child2.isFile() || child2.isBlockDevice() || child2.isCharacterDevice() || child2.isFIFO() || child2.isSocket()) {
37112
37237
  continue;
37113
37238
  }
37114
37239
  try {
37115
- const path2 = await this.resolvePath(join15(target, child.name), signal);
37116
- entries.push({ directoryId: encodePath(path2), name: child.name });
37240
+ const path2 = await this.resolvePath(join15(target, child2.name), signal);
37241
+ entries.push({ directoryId: encodePath(path2), name: child2.name });
37117
37242
  } catch (cause) {
37118
37243
  signal.throwIfAborted();
37119
37244
  if (!(cause instanceof LocalAuthorizationError)) {
@@ -37633,7 +37758,6 @@ var ActiveDaemonTurn = class {
37633
37758
  #text = "";
37634
37759
  #activities = /* @__PURE__ */ new Map();
37635
37760
  #content = /* @__PURE__ */ new Map();
37636
- #truncated = false;
37637
37761
  #sequence = 0;
37638
37762
  #interaction = null;
37639
37763
  #epoch = decodeIdentifier(randomUUID());
@@ -37676,21 +37800,8 @@ var ActiveDaemonTurn = class {
37676
37800
  effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
37677
37801
  recordEvent = (event) => {
37678
37802
  if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
37679
- this.#sequence += 1;
37680
37803
  this.#text += event.text;
37681
- if (this.#text.length > ACTIVE_TURN_TEXT_LIMIT) {
37682
- this.#text = this.#text.slice(-ACTIVE_TURN_TEXT_LIMIT);
37683
- this.#truncated = true;
37684
- }
37685
- return {
37686
- commandId: this.command.commandId,
37687
- epoch: this.#epoch,
37688
- kind: AGENT_MESSAGE_DELTA_KIND,
37689
- messageId: event.messageId,
37690
- sequence: this.#sequence,
37691
- sessionId: this.command.sessionId,
37692
- text: event.text
37693
- };
37804
+ return this.updated();
37694
37805
  }
37695
37806
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
37696
37807
  return event;
@@ -37731,15 +37842,26 @@ var ActiveDaemonTurn = class {
37731
37842
  } else if ((event.kind === SESSION_PERMISSION_RESOLVED_KIND || event.kind === SESSION_ELICITATION_RESOLVED_KIND) && this.#interaction?.interactionId === event.interactionId) {
37732
37843
  this.#interaction = null;
37733
37844
  }
37845
+ if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
37846
+ return this.updated();
37847
+ }
37734
37848
  return event;
37735
37849
  };
37850
+ updated = () => {
37851
+ this.#sequence += 1;
37852
+ const turn = this.snapshot();
37853
+ if (turn === null) {
37854
+ throw new Error("Only a running turn can publish a snapshot");
37855
+ }
37856
+ return { kind: "session.turn.updated", sessionId: this.command.sessionId, turn };
37857
+ };
37736
37858
  snapshot = () => this.#dispatch.kind === "running" ? {
37737
37859
  activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
37738
37860
  commandId: decodeIdentifier(this.command.commandId),
37739
37861
  content: [...this.#content.values()],
37740
37862
  prompt: this.command.prompt,
37741
37863
  text: this.#text,
37742
- truncated: this.#truncated,
37864
+ truncated: false,
37743
37865
  epoch: this.#epoch,
37744
37866
  interaction: this.#interaction,
37745
37867
  sequence: this.#sequence,
@@ -37808,9 +37930,13 @@ var DaemonTurnRegistry = class {
37808
37930
  turn.finish();
37809
37931
  };
37810
37932
  recordEvent = (event) => {
37811
- for (const turn of this.#turns.values()) {
37812
- turn.recordEvent(event);
37933
+ if ("commandId" in event) {
37934
+ const turn = this.#turns.get(event.commandId);
37935
+ if (turn !== void 0 && turn.command.sessionId === event.sessionId) {
37936
+ return turn.recordEvent(event);
37937
+ }
37813
37938
  }
37939
+ return event;
37814
37940
  };
37815
37941
  executionSnapshot = async (matches) => {
37816
37942
  const matching = [];
@@ -38132,7 +38258,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
38132
38258
  );
38133
38259
  }
38134
38260
  signal.throwIfAborted();
38135
- const child = spawn5(agent.agentIdentity.realPath, ["app-server"], {
38261
+ const child2 = spawn5(agent.agentIdentity.realPath, ["app-server"], {
38136
38262
  cwd,
38137
38263
  env: { ...process.env, ...agent.environment },
38138
38264
  detached: process.platform !== "win32",
@@ -38152,7 +38278,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
38152
38278
  )
38153
38279
  );
38154
38280
  const send2 = (message) => {
38155
- child.stdin.write(`${JSON.stringify(message)}
38281
+ child2.stdin.write(`${JSON.stringify(message)}
38156
38282
  `);
38157
38283
  };
38158
38284
  const onData = (chunk) => {
@@ -38282,11 +38408,11 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
38282
38408
  () => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
38283
38409
  options.detail === "rich" ? 6e4 : 15e3
38284
38410
  );
38285
- child.stdout.setEncoding("utf8");
38286
- child.stdout.on("data", onData);
38287
- child.stdin.on("error", fail);
38288
- child.on("error", fail);
38289
- child.on("exit", onExit);
38411
+ child2.stdout.setEncoding("utf8");
38412
+ child2.stdout.on("data", onData);
38413
+ child2.stdin.on("error", fail);
38414
+ child2.on("error", fail);
38415
+ child2.on("exit", onExit);
38290
38416
  signal.addEventListener("abort", abort, { once: true });
38291
38417
  try {
38292
38418
  if (signal.aborted) {
@@ -38306,13 +38432,13 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
38306
38432
  } finally {
38307
38433
  clearTimeout(timeout);
38308
38434
  signal.removeEventListener("abort", abort);
38309
- child.stdout.removeListener("data", onData);
38310
- if (child.pid !== void 0) {
38311
- await stopProcessTree(child);
38435
+ child2.stdout.removeListener("data", onData);
38436
+ if (child2.pid !== void 0) {
38437
+ await stopProcessTree(child2);
38312
38438
  }
38313
- child.stdin.removeListener("error", fail);
38314
- child.removeListener("error", fail);
38315
- child.removeListener("exit", onExit);
38439
+ child2.stdin.removeListener("error", fail);
38440
+ child2.removeListener("error", fail);
38441
+ child2.removeListener("exit", onExit);
38316
38442
  }
38317
38443
  }
38318
38444
  var readCodexHistory = async (agent, cwd, nativeSessionId, signal) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, { detail: "messages" });
@@ -41819,8 +41945,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
41819
41945
  const publisher = new DaemonSessionEventPublisher();
41820
41946
  const activeTurns = new DaemonTurnRegistry(operations);
41821
41947
  const recordSessionEvent = (sessionId, event) => {
41822
- activeTurns.recordEvent(event);
41823
- publisher.publish(sessionId, event);
41948
+ publisher.publish(sessionId, activeTurns.recordEvent(event));
41824
41949
  };
41825
41950
  const agentRuntime = new AgentRuntimeManager(
41826
41951
  new DaemonAcpObserver(recordSessionEvent),