@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/index.js CHANGED
@@ -5068,9 +5068,9 @@ function isRecursive(inst, stack, resolve9) {
5068
5068
  return PROVEN;
5069
5069
  stack.add(inst);
5070
5070
  let result = NONE;
5071
- const check2 = (child) => {
5072
- if (result !== PROVEN && child?._zod) {
5073
- const answer = isRecursive(child, stack, resolve9);
5071
+ const check2 = (child2) => {
5072
+ if (result !== PROVEN && child2?._zod) {
5073
+ const answer = isRecursive(child2, stack, resolve9);
5074
5074
  if (answer > result)
5075
5075
  result = answer;
5076
5076
  }
@@ -5081,9 +5081,9 @@ function isRecursive(inst, stack, resolve9) {
5081
5081
  const desc2 = Object.getOwnPropertyDescriptor(sh, key);
5082
5082
  if (spread && !desc2.enumerable)
5083
5083
  continue;
5084
- const child = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
5085
- if (child > answer)
5086
- answer = child;
5084
+ const child2 = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve9) : NONE;
5085
+ if (child2 > answer)
5086
+ answer = child2;
5087
5087
  }
5088
5088
  return answer;
5089
5089
  };
@@ -20462,7 +20462,7 @@ var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
20462
20462
  var MAX_PROMPT_LENGTH = 1e4;
20463
20463
  var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
20464
20464
  var MAX_EVENT_TEXT_LENGTH = 1e5;
20465
- var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["plan", "progress", "reasoning", "tool"]);
20465
+ var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["notice", "plan", "progress", "reasoning", "tool"]);
20466
20466
  var NARRATION_ACTIVITY_TYPES = /* @__PURE__ */ new Set(["progress", "reasoning"]);
20467
20467
  var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
20468
20468
  var TOOL_KINDS = /* @__PURE__ */ new Set([
@@ -21006,7 +21006,6 @@ var nativeMessagePageSchema = external_exports.discriminatedUnion("status", [
21006
21006
  var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
21007
21007
  var NATIVE_SESSION_RESULT_KIND = "native.session.result";
21008
21008
  var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
21009
- var ACTIVE_TURN_TEXT_LIMIT = 1e6;
21010
21009
  var directoryId = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/);
21011
21010
  var envelope = {
21012
21011
  requestId: identifierStringSchema,
@@ -21025,6 +21024,18 @@ var activeTurnActivitySchema = external_exports.strictObject({
21025
21024
  title: external_exports.string().max(500),
21026
21025
  toolKind: external_exports.string().max(64)
21027
21026
  }).readonly();
21027
+ var activeTurnSnapshotSchema = external_exports.strictObject({
21028
+ activities: external_exports.array(activeTurnActivitySchema).readonly(),
21029
+ commandId: identifierStringSchema,
21030
+ content: external_exports.array(displayContentSchema).readonly(),
21031
+ prompt: external_exports.string().max(1e5),
21032
+ text: external_exports.string(),
21033
+ truncated: external_exports.boolean(),
21034
+ epoch: identifierStringSchema,
21035
+ interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
21036
+ sequence: external_exports.number().int().nonnegative(),
21037
+ state: external_exports.literal("running")
21038
+ }).readonly();
21028
21039
  var identity = {
21029
21040
  ...envelope,
21030
21041
  kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
@@ -21106,21 +21117,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21106
21117
  images: external_exports.array(promptImageSchema).max(8).readonly()
21107
21118
  }).readonly()
21108
21119
  ).readonly(),
21109
- turn: external_exports.strictObject({
21110
- activities: external_exports.array(activeTurnActivitySchema).max(100).readonly(),
21111
- commandId: identifierStringSchema,
21112
- content: external_exports.array(displayContentSchema).max(100).readonly(),
21113
- prompt: external_exports.string().max(1e5),
21114
- text: external_exports.string().max(ACTIVE_TURN_TEXT_LIMIT),
21115
- truncated: external_exports.boolean(),
21116
- epoch: identifierStringSchema,
21117
- interaction: external_exports.discriminatedUnion("kind", [
21118
- sessionPermissionRequestedEventSchema,
21119
- sessionElicitationRequestedEventSchema
21120
- ]).nullable(),
21121
- sequence: external_exports.number().int().nonnegative(),
21122
- state: external_exports.literal("running")
21123
- }).readonly().nullable()
21120
+ turn: activeTurnSnapshotSchema.nullable()
21124
21121
  }).readonly(),
21125
21122
  external_exports.strictObject({
21126
21123
  ...resultEnvelope,
@@ -21196,6 +21193,13 @@ var committedEventSchema = external_exports.strictObject({
21196
21193
  }).readonly();
21197
21194
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
21198
21195
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
21196
+ var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
21197
+ var sessionTurnUpdatedSchema = external_exports.strictObject({
21198
+ kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
21199
+ sessionId: identifierStringSchema,
21200
+ turn: activeTurnSnapshotSchema
21201
+ }).readonly();
21202
+ var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
21199
21203
  function decode5(encoded, schema) {
21200
21204
  let value;
21201
21205
  try {
@@ -21225,6 +21229,8 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
21225
21229
  function decodeRecordedSessionEvent(encoded) {
21226
21230
  const kind = decodeMessageKind(encoded);
21227
21231
  switch (kind) {
21232
+ case SESSION_TURN_UPDATED_KIND:
21233
+ return decodeSessionTurnUpdatedEvent(encoded);
21228
21234
  case SESSION_QUEUE_CHANGED_KIND:
21229
21235
  return decode5(encoded, sessionQueueChangedSchema);
21230
21236
  case AGENT_ACTIVITY_KIND:
@@ -21572,8 +21578,8 @@ function hasTrueChildField(value, childKey, fieldKey) {
21572
21578
  if (!isRecord2(value)) {
21573
21579
  return false;
21574
21580
  }
21575
- const child = Reflect.get(value, childKey);
21576
- return isRecord2(child) && Reflect.get(child, fieldKey) === true;
21581
+ const child2 = Reflect.get(value, childKey);
21582
+ return isRecord2(child2) && Reflect.get(child2, fieldKey) === true;
21577
21583
  }
21578
21584
  function unsupportedSessionCapabilities() {
21579
21585
  return Object.freeze({
@@ -21885,17 +21891,17 @@ function mergeProcessTrees(captured, current) {
21885
21891
  }
21886
21892
  return [...processes.values()];
21887
21893
  }
21888
- async function captureProcessTree(child) {
21889
- if (process.platform === "win32" || child.pid === void 0) {
21894
+ async function captureProcessTree(child2) {
21895
+ if (process.platform === "win32" || child2.pid === void 0) {
21890
21896
  return [];
21891
21897
  }
21892
21898
  if (process.platform === "linux") {
21893
21899
  const procfsEntries = readLinuxProcessTableSynchronously();
21894
21900
  if (procfsEntries.length > 0) {
21895
- return selectProcessTree(procfsEntries, child.pid);
21901
+ return selectProcessTree(procfsEntries, child2.pid);
21896
21902
  }
21897
21903
  }
21898
- return selectProcessTree(await readProcessTable(), child.pid);
21904
+ return selectProcessTree(await readProcessTable(), child2.pid);
21899
21905
  }
21900
21906
  function signalCapturedProcessGroups(processes, rootProcessId, signal) {
21901
21907
  const processIds = new Set(processes.map((identity2) => identity2.processId));
@@ -21952,63 +21958,63 @@ async function waitForCapturedProcessesExit(processes, rootProcessId) {
21952
21958
  }
21953
21959
  return processIds.every((processId) => !processExists(processId));
21954
21960
  }
21955
- function terminateProcess(child) {
21956
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
21961
+ function terminateProcess(child2) {
21962
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
21957
21963
  return;
21958
21964
  }
21959
21965
  if (process.platform !== "win32") {
21960
21966
  try {
21961
- process.kill(-child.pid, "SIGTERM");
21967
+ process.kill(-child2.pid, "SIGTERM");
21962
21968
  return;
21963
21969
  } catch {
21964
21970
  }
21965
21971
  }
21966
- child.kill("SIGTERM");
21972
+ child2.kill("SIGTERM");
21967
21973
  }
21968
- function forceTerminateProcess(child) {
21969
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
21974
+ function forceTerminateProcess(child2) {
21975
+ if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
21970
21976
  return;
21971
21977
  }
21972
21978
  if (process.platform !== "win32") {
21973
21979
  try {
21974
- process.kill(-child.pid, "SIGKILL");
21980
+ process.kill(-child2.pid, "SIGKILL");
21975
21981
  return;
21976
21982
  } catch {
21977
21983
  }
21978
21984
  }
21979
- child.kill("SIGKILL");
21985
+ child2.kill("SIGKILL");
21980
21986
  }
21981
- async function stopProcessTree(child, capturedProcesses = []) {
21982
- const childProcessId = child.pid;
21987
+ async function stopProcessTree(child2, capturedProcesses = []) {
21988
+ const childProcessId = child2.pid;
21983
21989
  if (childProcessId === void 0) {
21984
21990
  return;
21985
21991
  }
21986
- const childExited = child.exitCode !== null || child.signalCode !== null;
21987
- const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child));
21992
+ const childExited = child2.exitCode !== null || child2.signalCode !== null;
21993
+ const processes = mergeProcessTrees(capturedProcesses, await captureProcessTree(child2));
21988
21994
  if (childExited && processes.length === 0) {
21989
21995
  return;
21990
21996
  }
21991
21997
  signalCapturedProcessGroups(processes, childProcessId, GRACEFUL_STOP_SIGNAL);
21992
- terminateProcess(child);
21998
+ terminateProcess(child2);
21993
21999
  const [exitedAfterTermination, descendantsExitedAfterTermination] = await Promise.all([
21994
- waitForProcessExit(child, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
22000
+ waitForProcessExit(child2, PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS),
21995
22001
  waitForCapturedProcessesExit(processes, childProcessId)
21996
22002
  ]);
21997
22003
  if (exitedAfterTermination && descendantsExitedAfterTermination) {
21998
22004
  return;
21999
22005
  }
22000
22006
  signalCapturedProcessGroups(processes, childProcessId, FORCED_STOP_SIGNAL);
22001
- forceTerminateProcess(child);
22007
+ forceTerminateProcess(child2);
22002
22008
  const [exitedAfterForce, descendantsExitedAfterForce] = await Promise.all([
22003
- waitForProcessExit(child, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
22009
+ waitForProcessExit(child2, PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS),
22004
22010
  waitForCapturedProcessesExit(processes, childProcessId)
22005
22011
  ]);
22006
22012
  if (!exitedAfterForce || !descendantsExitedAfterForce) {
22007
22013
  throw new ProcessExecutionError("process_termination_timeout", "The executable process could not be stopped");
22008
22014
  }
22009
22015
  }
22010
- function waitForProcessExit(child, timeoutMilliseconds) {
22011
- if (child.exitCode !== null || child.signalCode !== null) {
22016
+ function waitForProcessExit(child2, timeoutMilliseconds) {
22017
+ if (child2.exitCode !== null || child2.signalCode !== null) {
22012
22018
  return Promise.resolve(true);
22013
22019
  }
22014
22020
  return new Promise((resolveExit) => {
@@ -22019,13 +22025,13 @@ function waitForProcessExit(child, timeoutMilliseconds) {
22019
22025
  }
22020
22026
  settled = true;
22021
22027
  clearTimeout(timeout);
22022
- child.removeListener("exit", handleExit);
22028
+ child2.removeListener("exit", handleExit);
22023
22029
  resolveExit(exited);
22024
22030
  };
22025
22031
  const handleExit = () => finish(true);
22026
22032
  const timeout = setTimeout(() => finish(false), timeoutMilliseconds);
22027
- child.once("exit", handleExit);
22028
- if (child.exitCode !== null || child.signalCode !== null) {
22033
+ child2.once("exit", handleExit);
22034
+ if (child2.exitCode !== null || child2.signalCode !== null) {
22029
22035
  finish(true);
22030
22036
  }
22031
22037
  });
@@ -22033,7 +22039,7 @@ function waitForProcessExit(child, timeoutMilliseconds) {
22033
22039
  async function runBoundedProcess(options) {
22034
22040
  options.signal.throwIfAborted();
22035
22041
  const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
22036
- const child = spawn(options.command, [...options.arguments], {
22042
+ const child2 = spawn(options.command, [...options.arguments], {
22037
22043
  cwd: options.cwd,
22038
22044
  detached: process.platform !== "win32",
22039
22045
  env: { ...options.environment },
@@ -22056,7 +22062,7 @@ async function runBoundedProcess(options) {
22056
22062
  interruptionFailure = failure2;
22057
22063
  const stop = async () => {
22058
22064
  try {
22059
- await stopProcessTree(child);
22065
+ await stopProcessTree(child2);
22060
22066
  } catch (error62) {
22061
22067
  interruptionCleanupFailure = error62 instanceof ProcessExecutionError ? error62 : new ProcessExecutionError(
22062
22068
  "process_termination_failed",
@@ -22095,8 +22101,8 @@ async function runBoundedProcess(options) {
22095
22101
  interrupt(failure2);
22096
22102
  }
22097
22103
  };
22098
- child.stdout?.on("data", collectStdout);
22099
- child.stderr?.on("data", collectStderr);
22104
+ child2.stdout?.on("data", collectStdout);
22105
+ child2.stderr?.on("data", collectStderr);
22100
22106
  const timeout = setTimeout(() => {
22101
22107
  interrupt(new ProcessExecutionError("process_timeout", "The executable probe timed out"));
22102
22108
  }, options.timeoutMilliseconds);
@@ -22111,8 +22117,8 @@ async function runBoundedProcess(options) {
22111
22117
  }
22112
22118
  try {
22113
22119
  const exit = new Promise((resolveExit, rejectExit) => {
22114
- child.once("error", rejectExit);
22115
- child.once("exit", (code) => resolveExit(code ?? 1));
22120
+ child2.once("error", rejectExit);
22121
+ child2.once("exit", (code) => resolveExit(code ?? 1));
22116
22122
  });
22117
22123
  const exitCode = await Promise.race([exit, interrupted.promise.then(() => -1)]);
22118
22124
  if (interruptionCleanupFailure !== null) {
@@ -22135,12 +22141,12 @@ async function runBoundedProcess(options) {
22135
22141
  } finally {
22136
22142
  clearTimeout(timeout);
22137
22143
  options.signal.removeEventListener("abort", abort);
22138
- child.stdout?.removeListener("data", collectStdout);
22139
- child.stderr?.removeListener("data", collectStderr);
22144
+ child2.stdout?.removeListener("data", collectStdout);
22145
+ child2.stderr?.removeListener("data", collectStderr);
22140
22146
  if (stopping) {
22141
22147
  await interrupted.promise;
22142
22148
  } else {
22143
- await stopProcessTree(child);
22149
+ await stopProcessTree(child2);
22144
22150
  }
22145
22151
  }
22146
22152
  }
@@ -23184,19 +23190,19 @@ var AgentConnection = class {
23184
23190
  this.connection = createAcpClient(client2).connect(inProcess.app());
23185
23191
  return;
23186
23192
  }
23187
- const child = spawn2(agent.adapterPath, [...agent.arguments], {
23193
+ const child2 = spawn2(agent.adapterPath, [...agent.arguments], {
23188
23194
  cwd,
23189
23195
  detached: process.platform !== "win32",
23190
23196
  env: { ...process.env, ...agent.environment },
23191
23197
  shell: false,
23192
23198
  stdio: ["pipe", "pipe", "pipe"]
23193
23199
  });
23194
- this.#process = { kind: "child", child };
23195
- const stdin = child.stdin;
23196
- const stdout = child.stdout;
23197
- const stderr = child.stderr;
23200
+ this.#process = { kind: "child", child: child2 };
23201
+ const stdin = child2.stdin;
23202
+ const stdout = child2.stdout;
23203
+ const stderr = child2.stderr;
23198
23204
  if (stdin === null || stdout === null || stderr === null) {
23199
- child.kill("SIGKILL");
23205
+ child2.kill("SIGKILL");
23200
23206
  throw new AcpExecutionError("ACP process streams are unavailable");
23201
23207
  }
23202
23208
  stderr.setEncoding("utf8");
@@ -23204,10 +23210,10 @@ var AgentConnection = class {
23204
23210
  process.stderr.write(`[${agent.id}-acp] ${chunk}`);
23205
23211
  });
23206
23212
  this.termination = new Promise((resolve9) => {
23207
- child.once("error", (cause) => {
23213
+ child2.once("error", (cause) => {
23208
23214
  resolve9({ kind: "failed", error: new AcpExecutionError("The ACP process could not run", { cause }) });
23209
23215
  });
23210
- child.once("exit", (code, signal) => {
23216
+ child2.once("exit", (code, signal) => {
23211
23217
  resolve9({
23212
23218
  kind: "failed",
23213
23219
  error: new AcpExecutionError("The ACP process stopped", { cause: { code, signal } })
@@ -23342,6 +23348,7 @@ var AcpActivityTracker = class {
23342
23348
  #activities = /* @__PURE__ */ new Map();
23343
23349
  #identities = /* @__PURE__ */ new Map();
23344
23350
  #narrations = /* @__PURE__ */ new Map();
23351
+ #noticeRevisions = /* @__PURE__ */ new Map();
23345
23352
  #onActivity;
23346
23353
  #onNarration;
23347
23354
  #prepareContent;
@@ -23377,6 +23384,30 @@ var AcpActivityTracker = class {
23377
23384
  await this.#onNarration(new AcpActivityNarration(identity2.id, activityType, identity2.sequence, text2));
23378
23385
  }
23379
23386
  };
23387
+ recordNotice = async (id, revision, severity, text2) => {
23388
+ const key = `notice:${id}`;
23389
+ if ((this.#noticeRevisions.get(key) ?? 0) >= revision) {
23390
+ return;
23391
+ }
23392
+ await this.finishNarrative();
23393
+ this.#noticeRevisions.set(key, revision);
23394
+ const identity2 = this.#identity(key);
23395
+ await this.#record(
23396
+ key,
23397
+ new AcpActivity(
23398
+ identity2.id,
23399
+ "notice",
23400
+ "",
23401
+ [],
23402
+ "",
23403
+ truncate(text2, AGENT_ACTIVITY_DETAIL_LIMIT),
23404
+ identity2.sequence,
23405
+ severity === "error" ? "failed" : "completed",
23406
+ severity === "error" ? "Agent error" : "Agent warning",
23407
+ ""
23408
+ )
23409
+ );
23410
+ };
23380
23411
  #narrativeSnapshot = (identity2, activityType, output2, status) => new AcpActivity(
23381
23412
  identity2.id,
23382
23413
  activityType,
@@ -23939,6 +23970,63 @@ var AcpAgentSettingsSnapshot = class {
23939
23970
  }
23940
23971
  };
23941
23972
 
23973
+ // src/acp/session-failure.ts
23974
+ var CATEGORIES = /* @__PURE__ */ new Set([
23975
+ "access",
23976
+ "connection",
23977
+ "limit",
23978
+ "request",
23979
+ "service",
23980
+ "unknown"
23981
+ ]);
23982
+ function isCategory(value) {
23983
+ return typeof value === "string" && CATEGORIES.has(value);
23984
+ }
23985
+ function child(value, key) {
23986
+ return isRecord4(value) ? value[key] : void 0;
23987
+ }
23988
+ function readAcpSessionFailure(value) {
23989
+ const meta3 = child(value, "_meta");
23990
+ const jetbrains = child(meta3, "jetbrains");
23991
+ const air = child(jetbrains, "air");
23992
+ const failure2 = child(air, "sessionFailure");
23993
+ if (!isRecord4(air) || !Number.isInteger(air["version"]) || Number(air["version"]) < 1 || !isRecord4(failure2)) {
23994
+ return null;
23995
+ }
23996
+ const id = failure2["id"];
23997
+ const revision = failure2["revision"];
23998
+ const category = failure2["category"];
23999
+ const severity = failure2["severity"];
24000
+ const title2 = failure2["title"];
24001
+ 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) {
24002
+ return null;
24003
+ }
24004
+ return {
24005
+ category,
24006
+ id,
24007
+ revision: Number(revision),
24008
+ severity,
24009
+ title: truncate2(title2, 4096)
24010
+ };
24011
+ }
24012
+ function sessionFailureMeta(failure2) {
24013
+ return {
24014
+ jetbrains: {
24015
+ air: {
24016
+ version: 1,
24017
+ sessionFailure: {
24018
+ actions: [],
24019
+ category: failure2.category,
24020
+ id: failure2.id,
24021
+ revision: failure2.revision,
24022
+ severity: failure2.severity,
24023
+ title: failure2.title
24024
+ }
24025
+ }
24026
+ }
24027
+ };
24028
+ }
24029
+
23942
24030
  // src/acp/session-history.ts
23943
24031
  var HISTORY_ACTIVITY_FIELD_LIMIT = 1e5;
23944
24032
  var HISTORY_ACTIVITY_LIMIT = 100;
@@ -30542,6 +30630,9 @@ var AgentSession = class _AgentSession {
30542
30630
  methods3.agent.initialize,
30543
30631
  {
30544
30632
  clientCapabilities: {
30633
+ _meta: {
30634
+ jetbrains: { air: { capabilities: ["sessionFailure"], version: 1 } }
30635
+ },
30545
30636
  elicitation: { form: {}, url: {} },
30546
30637
  plan: {},
30547
30638
  session: { configOptions: { boolean: {} } }
@@ -30975,6 +31066,10 @@ var AgentSession = class _AgentSession {
30975
31066
  "acp_invalid_prompt_response"
30976
31067
  );
30977
31068
  }
31069
+ const failure2 = readAcpSessionFailure(response);
31070
+ if (failure2 !== null) {
31071
+ await running.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
31072
+ }
30978
31073
  if (result.usage != null || result._meta?.quota !== void 0) {
30979
31074
  await this.#getObserver().onUsage({
30980
31075
  _meta: result._meta ?? null,
@@ -31158,6 +31253,10 @@ var AgentSession = class _AgentSession {
31158
31253
  return;
31159
31254
  }
31160
31255
  if (update.sessionUpdate === "session_info_update") {
31256
+ const failure2 = readAcpSessionFailure(update);
31257
+ if (failure2 !== null && this.#turn.running) {
31258
+ await this.#turn.activities.recordNotice(failure2.id, failure2.revision, failure2.severity, failure2.title);
31259
+ }
31161
31260
  if (Object.hasOwn(update, "title")) {
31162
31261
  this.#sessionTitle = truncate2(update.title ?? "", 500);
31163
31262
  }
@@ -33043,6 +33142,12 @@ var turnNotificationSchema = external_exports.object({
33043
33142
  threadId: boundedText(256),
33044
33143
  turn: turnSchema
33045
33144
  });
33145
+ var errorNotificationSchema = external_exports.object({
33146
+ error: external_exports.object({ message: boundedText(4096) }),
33147
+ threadId: boundedText(256),
33148
+ turnId: boundedText(256),
33149
+ willRetry: external_exports.boolean()
33150
+ });
33046
33151
  var commandApprovalParamsSchema = external_exports.object({
33047
33152
  command: external_exports.string().nullish(),
33048
33153
  commandActions: external_exports.array(external_exports.unknown()).max(1e3).nullish(),
@@ -34052,6 +34157,7 @@ var CodexAcpAgent = class {
34052
34157
  #nativeSessionId = "";
34053
34158
  #streamedReasoningItemIds = /* @__PURE__ */ new Set();
34054
34159
  #streamedAgentMessageItemIds = /* @__PURE__ */ new Set();
34160
+ #noticeRevisions = /* @__PURE__ */ new Map();
34055
34161
  #turn = null;
34056
34162
  #nativeTurnId = null;
34057
34163
  #updateTail = Promise.resolve();
@@ -34204,10 +34310,10 @@ var CodexAcpAgent = class {
34204
34310
  if (this.#closePromise === null) {
34205
34311
  this.#appServer.detach();
34206
34312
  this.#closePromise = (async () => {
34207
- const child = this.#appServer.child();
34313
+ const child2 = this.#appServer.child();
34208
34314
  try {
34209
- const captured = await captureProcessTree(child);
34210
- await stopProcessTree(child, captured);
34315
+ const captured = await captureProcessTree(child2);
34316
+ await stopProcessTree(child2, captured);
34211
34317
  } finally {
34212
34318
  this.#connection?.close();
34213
34319
  }
@@ -34297,6 +34403,27 @@ var CodexAcpAgent = class {
34297
34403
  await pending;
34298
34404
  };
34299
34405
  #onNotification = async (method, params) => {
34406
+ if (method === "error") {
34407
+ const decoded = errorNotificationSchema.safeParse(params);
34408
+ if (decoded.success && decoded.data.willRetry && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null && decoded.data.turnId === this.#turn.turn.id) {
34409
+ const id = `codex:${decoded.data.turnId}:error`;
34410
+ const revision = (this.#noticeRevisions.get(id) ?? 0) + 1;
34411
+ this.#noticeRevisions.set(id, revision);
34412
+ await this.#enqueue(async () => {
34413
+ await this.#emit({
34414
+ _meta: sessionFailureMeta({
34415
+ category: "service",
34416
+ id,
34417
+ revision,
34418
+ severity: "warning",
34419
+ title: decoded.data.error.message
34420
+ }),
34421
+ sessionUpdate: "session_info_update"
34422
+ });
34423
+ });
34424
+ }
34425
+ return;
34426
+ }
34300
34427
  if (method === "turn/started") {
34301
34428
  const decoded = turnNotificationSchema.safeParse(params);
34302
34429
  if (decoded.success && decoded.data.threadId === this.#nativeSessionId && this.#turn !== null) {
@@ -35927,7 +36054,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
35927
36054
  signal.removeEventListener("abort", abort);
35928
36055
  }
35929
36056
  }
35930
- const child = spawn4(agent.adapterPath, [...agent.arguments], {
36057
+ const child2 = spawn4(agent.adapterPath, [...agent.arguments], {
35931
36058
  cwd: defaultWorkspace,
35932
36059
  detached: process.platform !== "win32",
35933
36060
  env: { ...environment, ...agent.environment },
@@ -35936,17 +36063,17 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
35936
36063
  });
35937
36064
  const processExit = new Promise((_resolve, reject) => {
35938
36065
  const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
35939
- child.once("error", reject);
35940
- child.once("exit", rejectExit);
35941
- if (child.exitCode !== null || child.signalCode !== null) {
36066
+ child2.once("error", reject);
36067
+ child2.once("exit", rejectExit);
36068
+ if (child2.exitCode !== null || child2.signalCode !== null) {
35942
36069
  rejectExit();
35943
36070
  }
35944
36071
  });
35945
- const stdin = child.stdin;
35946
- const stdout = child.stdout;
35947
- const stderr = child.stderr;
36072
+ const stdin = child2.stdin;
36073
+ const stdout = child2.stdout;
36074
+ const stderr = child2.stderr;
35948
36075
  if (stdin === null || stdout === null || stderr === null) {
35949
- await stopProcessTree(child);
36076
+ await stopProcessTree(child2);
35950
36077
  throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
35951
36078
  }
35952
36079
  let stderrBytes = 0;
@@ -35998,11 +36125,11 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
35998
36125
  } finally {
35999
36126
  clearTimeout(timeout);
36000
36127
  signal.removeEventListener("abort", abort);
36001
- const capturedProcesses = await captureProcessTree(child);
36128
+ const capturedProcesses = await captureProcessTree(child2);
36002
36129
  connection.close();
36003
36130
  stdin.end();
36004
36131
  stderr.removeListener("data", consumeStderr);
36005
- await stopProcessTree(child, capturedProcesses);
36132
+ await stopProcessTree(child2, capturedProcesses);
36006
36133
  }
36007
36134
  }
36008
36135
 
@@ -37980,16 +38107,16 @@ var WorkspaceDirectoryService = class {
37980
38107
  const children = await readdir3(target, { withFileTypes: true });
37981
38108
  signal.throwIfAborted();
37982
38109
  const entries = [];
37983
- for (const child of children) {
38110
+ for (const child2 of children) {
37984
38111
  if (entries.length === 500) {
37985
38112
  break;
37986
38113
  }
37987
- if (child.isFile() || child.isBlockDevice() || child.isCharacterDevice() || child.isFIFO() || child.isSocket()) {
38114
+ if (child2.isFile() || child2.isBlockDevice() || child2.isCharacterDevice() || child2.isFIFO() || child2.isSocket()) {
37988
38115
  continue;
37989
38116
  }
37990
38117
  try {
37991
- const path2 = await this.resolvePath(join16(target, child.name), signal);
37992
- entries.push({ directoryId: encodePath(path2), name: child.name });
38118
+ const path2 = await this.resolvePath(join16(target, child2.name), signal);
38119
+ entries.push({ directoryId: encodePath(path2), name: child2.name });
37993
38120
  } catch (cause) {
37994
38121
  signal.throwIfAborted();
37995
38122
  if (!(cause instanceof LocalAuthorizationError)) {
@@ -38509,7 +38636,6 @@ var ActiveDaemonTurn = class {
38509
38636
  #text = "";
38510
38637
  #activities = /* @__PURE__ */ new Map();
38511
38638
  #content = /* @__PURE__ */ new Map();
38512
- #truncated = false;
38513
38639
  #sequence = 0;
38514
38640
  #interaction = null;
38515
38641
  #epoch = decodeIdentifier(randomUUID2());
@@ -38552,21 +38678,8 @@ var ActiveDaemonTurn = class {
38552
38678
  effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
38553
38679
  recordEvent = (event) => {
38554
38680
  if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
38555
- this.#sequence += 1;
38556
38681
  this.#text += event.text;
38557
- if (this.#text.length > ACTIVE_TURN_TEXT_LIMIT) {
38558
- this.#text = this.#text.slice(-ACTIVE_TURN_TEXT_LIMIT);
38559
- this.#truncated = true;
38560
- }
38561
- return {
38562
- commandId: this.command.commandId,
38563
- epoch: this.#epoch,
38564
- kind: AGENT_MESSAGE_DELTA_KIND,
38565
- messageId: event.messageId,
38566
- sequence: this.#sequence,
38567
- sessionId: this.command.sessionId,
38568
- text: event.text
38569
- };
38682
+ return this.updated();
38570
38683
  }
38571
38684
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
38572
38685
  return event;
@@ -38607,15 +38720,26 @@ var ActiveDaemonTurn = class {
38607
38720
  } else if ((event.kind === SESSION_PERMISSION_RESOLVED_KIND || event.kind === SESSION_ELICITATION_RESOLVED_KIND) && this.#interaction?.interactionId === event.interactionId) {
38608
38721
  this.#interaction = null;
38609
38722
  }
38723
+ if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
38724
+ return this.updated();
38725
+ }
38610
38726
  return event;
38611
38727
  };
38728
+ updated = () => {
38729
+ this.#sequence += 1;
38730
+ const turn = this.snapshot();
38731
+ if (turn === null) {
38732
+ throw new Error("Only a running turn can publish a snapshot");
38733
+ }
38734
+ return { kind: "session.turn.updated", sessionId: this.command.sessionId, turn };
38735
+ };
38612
38736
  snapshot = () => this.#dispatch.kind === "running" ? {
38613
38737
  activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
38614
38738
  commandId: decodeIdentifier(this.command.commandId),
38615
38739
  content: [...this.#content.values()],
38616
38740
  prompt: this.command.prompt,
38617
38741
  text: this.#text,
38618
- truncated: this.#truncated,
38742
+ truncated: false,
38619
38743
  epoch: this.#epoch,
38620
38744
  interaction: this.#interaction,
38621
38745
  sequence: this.#sequence,
@@ -38684,9 +38808,13 @@ var DaemonTurnRegistry = class {
38684
38808
  turn.finish();
38685
38809
  };
38686
38810
  recordEvent = (event) => {
38687
- for (const turn of this.#turns.values()) {
38688
- turn.recordEvent(event);
38811
+ if ("commandId" in event) {
38812
+ const turn = this.#turns.get(event.commandId);
38813
+ if (turn !== void 0 && turn.command.sessionId === event.sessionId) {
38814
+ return turn.recordEvent(event);
38815
+ }
38689
38816
  }
38817
+ return event;
38690
38818
  };
38691
38819
  executionSnapshot = async (matches) => {
38692
38820
  const matching = [];
@@ -39008,7 +39136,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
39008
39136
  );
39009
39137
  }
39010
39138
  signal.throwIfAborted();
39011
- const child = spawn5(agent.agentIdentity.realPath, ["app-server"], {
39139
+ const child2 = spawn5(agent.agentIdentity.realPath, ["app-server"], {
39012
39140
  cwd,
39013
39141
  env: { ...process.env, ...agent.environment },
39014
39142
  detached: process.platform !== "win32",
@@ -39028,7 +39156,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
39028
39156
  )
39029
39157
  );
39030
39158
  const send2 = (message) => {
39031
- child.stdin.write(`${JSON.stringify(message)}
39159
+ child2.stdin.write(`${JSON.stringify(message)}
39032
39160
  `);
39033
39161
  };
39034
39162
  const onData = (chunk) => {
@@ -39158,11 +39286,11 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
39158
39286
  () => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
39159
39287
  options.detail === "rich" ? 6e4 : 15e3
39160
39288
  );
39161
- child.stdout.setEncoding("utf8");
39162
- child.stdout.on("data", onData);
39163
- child.stdin.on("error", fail);
39164
- child.on("error", fail);
39165
- child.on("exit", onExit);
39289
+ child2.stdout.setEncoding("utf8");
39290
+ child2.stdout.on("data", onData);
39291
+ child2.stdin.on("error", fail);
39292
+ child2.on("error", fail);
39293
+ child2.on("exit", onExit);
39166
39294
  signal.addEventListener("abort", abort, { once: true });
39167
39295
  try {
39168
39296
  if (signal.aborted) {
@@ -39182,13 +39310,13 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
39182
39310
  } finally {
39183
39311
  clearTimeout(timeout);
39184
39312
  signal.removeEventListener("abort", abort);
39185
- child.stdout.removeListener("data", onData);
39186
- if (child.pid !== void 0) {
39187
- await stopProcessTree(child);
39313
+ child2.stdout.removeListener("data", onData);
39314
+ if (child2.pid !== void 0) {
39315
+ await stopProcessTree(child2);
39188
39316
  }
39189
- child.stdin.removeListener("error", fail);
39190
- child.removeListener("error", fail);
39191
- child.removeListener("exit", onExit);
39317
+ child2.stdin.removeListener("error", fail);
39318
+ child2.removeListener("error", fail);
39319
+ child2.removeListener("exit", onExit);
39192
39320
  }
39193
39321
  }
39194
39322
  var readCodexHistory = async (agent, cwd, nativeSessionId, signal) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, { detail: "messages" });
@@ -42675,8 +42803,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
42675
42803
  const publisher = new DaemonSessionEventPublisher();
42676
42804
  const activeTurns = new DaemonTurnRegistry(operations);
42677
42805
  const recordSessionEvent = (sessionId, event) => {
42678
- activeTurns.recordEvent(event);
42679
- publisher.publish(sessionId, event);
42806
+ publisher.publish(sessionId, activeTurns.recordEvent(event));
42680
42807
  };
42681
42808
  const agentRuntime = new AgentRuntimeManager(
42682
42809
  new DaemonAcpObserver(recordSessionEvent),