@moxt-ai/mobius 0.0.146 → 0.0.149

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 (42) hide show
  1. package/dist/agent-catalog/agent-diagnostics.d.ts +1 -1
  2. package/dist/agent-catalog/agent-diagnostics.d.ts.map +1 -1
  3. package/dist/agent-catalog/agent-diagnostics.js +31 -8
  4. package/dist/agent-catalog/agent-diagnostics.js.map +1 -1
  5. package/dist/agent-catalog/agent-discovery.d.ts +15 -1
  6. package/dist/agent-catalog/agent-discovery.d.ts.map +1 -1
  7. package/dist/agent-catalog/agent-discovery.js +34 -1
  8. package/dist/agent-catalog/agent-discovery.js.map +1 -1
  9. package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
  10. package/dist/agent-catalog/discover-agent.js +3 -2
  11. package/dist/agent-catalog/discover-agent.js.map +1 -1
  12. package/dist/agent-catalog/discover-local-agents.d.ts +1 -0
  13. package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
  14. package/dist/agent-catalog/discover-local-agents.js +8 -3
  15. package/dist/agent-catalog/discover-local-agents.js.map +1 -1
  16. package/dist/cli.js +370 -177
  17. package/dist/cli.js.map +3 -3
  18. package/dist/daemon-active-turn.d.ts +15 -2
  19. package/dist/daemon-active-turn.d.ts.map +1 -1
  20. package/dist/daemon-active-turn.js +63 -25
  21. package/dist/daemon-active-turn.js.map +1 -1
  22. package/dist/daemon-command-handler.js +3 -3
  23. package/dist/daemon-history-commands.d.ts +4 -7
  24. package/dist/daemon-history-commands.d.ts.map +1 -1
  25. package/dist/daemon-history-commands.js.map +1 -1
  26. package/dist/daemon-prompt-executor.d.ts +1 -1
  27. package/dist/daemon-prompt-executor.d.ts.map +1 -1
  28. package/dist/daemon-prompt-executor.js +1 -3
  29. package/dist/daemon-prompt-executor.js.map +1 -1
  30. package/dist/daemon-turn-registry.d.ts +5 -43
  31. package/dist/daemon-turn-registry.d.ts.map +1 -1
  32. package/dist/daemon-turn-registry.js +40 -1
  33. package/dist/daemon-turn-registry.js.map +1 -1
  34. package/dist/index.js +325 -167
  35. package/dist/index.js.map +3 -3
  36. package/dist/native-sessions/live-history-page.d.ts +4 -7
  37. package/dist/native-sessions/live-history-page.d.ts.map +1 -1
  38. package/dist/native-sessions/live-history-page.js +163 -107
  39. package/dist/native-sessions/live-history-page.js.map +1 -1
  40. package/dist/runtime.js +325 -167
  41. package/dist/runtime.js.map +3 -3
  42. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3381,7 +3381,7 @@ var program = new Command();
3381
3381
  // package.json
3382
3382
  var package_default = {
3383
3383
  name: "@moxt-ai/mobius",
3384
- version: "0.0.146",
3384
+ version: "0.0.149",
3385
3385
  description: "Mobius CLI for pairing and running local AI agent services.",
3386
3386
  type: "module",
3387
3387
  bin: {
@@ -4227,6 +4227,17 @@ var AgentProbeFailed = class extends UnavailableAgent {
4227
4227
  this.message = message;
4228
4228
  }
4229
4229
  };
4230
+ var UnsupportedAgentVersion = class extends UnavailableInstalledAgent {
4231
+ code = "agent_version_unsupported";
4232
+ message;
4233
+ minimumSupportedVersion;
4234
+ status = "unsupported_version";
4235
+ constructor(specification, agent, minimumSupportedVersion) {
4236
+ super(specification, agent);
4237
+ this.minimumSupportedVersion = minimumSupportedVersion;
4238
+ this.message = `Agent version ${agent.agentVersion} is below the minimum supported version ${minimumSupportedVersion}`;
4239
+ }
4240
+ };
4230
4241
  var IntegrationProbeFailed = class extends UnavailableInstalledAgent {
4231
4242
  code;
4232
4243
  message;
@@ -4254,12 +4265,25 @@ var AuthenticationRequiredAgent = class extends UnavailableInstalledAgent {
4254
4265
  super(specification, agent);
4255
4266
  }
4256
4267
  };
4268
+ var AgentDiscoveryResult = class {
4269
+ detectionMilliseconds;
4270
+ discovery;
4271
+ constructor(discovery, detectionMilliseconds) {
4272
+ if (!Number.isFinite(detectionMilliseconds) || detectionMilliseconds < 0) {
4273
+ throw new Error("The Agent detection duration is invalid");
4274
+ }
4275
+ this.detectionMilliseconds = Math.round(detectionMilliseconds * 1e3) / 1e3;
4276
+ this.discovery = discovery;
4277
+ }
4278
+ };
4257
4279
  var LocalAgentInventory = class {
4258
4280
  available;
4259
4281
  discoveries;
4260
4282
  installable;
4283
+ results;
4261
4284
  unavailable;
4262
- constructor(discoveries) {
4285
+ constructor(results) {
4286
+ const discoveries = results.map((result) => result.discovery);
4263
4287
  const available = [];
4264
4288
  const unavailable = [];
4265
4289
  for (const discovery of discoveries) {
@@ -4278,8 +4302,17 @@ var LocalAgentInventory = class {
4278
4302
  (discovery) => discovery instanceof UnavailableInstalledAgent ? discovery.agent : new MissingAgentDefinition(discovery.specification.id, discovery.specification.label)
4279
4303
  )
4280
4304
  );
4305
+ this.results = Object.freeze([...results]);
4281
4306
  this.unavailable = Object.freeze(unavailable);
4282
4307
  }
4308
+ detectionMillisecondsFor = (discovery) => {
4309
+ for (const result of this.results) {
4310
+ if (result.discovery === discovery) {
4311
+ return result.detectionMilliseconds;
4312
+ }
4313
+ }
4314
+ throw new Error("The Agent discovery result is unavailable");
4315
+ };
4283
4316
  readyAgents = () => this.available.map((discovery) => discovery.agent);
4284
4317
  };
4285
4318
 
@@ -4313,19 +4346,48 @@ var UnavailableAgentDiagnostic = class {
4313
4346
  this.status = discovery.status;
4314
4347
  }
4315
4348
  };
4349
+ var UnsupportedAgentVersionDiagnostic = class extends UnavailableAgentDiagnostic {
4350
+ agentVersion;
4351
+ minimumSupportedVersion;
4352
+ constructor(discovery) {
4353
+ super(discovery);
4354
+ this.agentVersion = discovery.agent.agentVersion;
4355
+ this.minimumSupportedVersion = discovery.minimumSupportedVersion;
4356
+ }
4357
+ };
4358
+ function withDetectionTime(diagnostic, detectionMilliseconds, verbose) {
4359
+ return verbose ? { ...diagnostic, detectionMilliseconds } : diagnostic;
4360
+ }
4361
+ function unavailableDiagnostic(discovery) {
4362
+ return discovery instanceof UnsupportedAgentVersion ? new UnsupportedAgentVersionDiagnostic(discovery) : new UnavailableAgentDiagnostic(discovery);
4363
+ }
4316
4364
  var AgentDiagnostics = class {
4317
4365
  available;
4318
4366
  unavailable;
4319
- constructor(inventory) {
4320
- this.available = inventory.available.map((discovery) => new AvailableAgentDiagnostic(discovery));
4321
- this.unavailable = inventory.unavailable.map((discovery) => new UnavailableAgentDiagnostic(discovery));
4367
+ constructor(inventory, verbose) {
4368
+ this.available = inventory.available.map(
4369
+ (discovery) => withDetectionTime(
4370
+ new AvailableAgentDiagnostic(discovery),
4371
+ inventory.detectionMillisecondsFor(discovery),
4372
+ verbose
4373
+ )
4374
+ );
4375
+ this.unavailable = inventory.unavailable.map(
4376
+ (discovery) => withDetectionTime(unavailableDiagnostic(discovery), inventory.detectionMillisecondsFor(discovery), verbose)
4377
+ );
4322
4378
  }
4323
4379
  };
4324
4380
  function humanLine(label, status, detail) {
4325
4381
  return `${label.padEnd(13)} ${status.padEnd(17)} ${detail}`.trimEnd();
4326
4382
  }
4327
- function formatAgentDiagnostics(inventory, json2) {
4328
- const diagnostics = new AgentDiagnostics(inventory);
4383
+ function detectionSuffix(diagnostic) {
4384
+ if (!("detectionMilliseconds" in diagnostic) || typeof diagnostic.detectionMilliseconds !== "number") {
4385
+ return "";
4386
+ }
4387
+ return ` detection=${Math.round(diagnostic.detectionMilliseconds).toString()}ms`;
4388
+ }
4389
+ function formatAgentDiagnostics(inventory, json2, verbose = false) {
4390
+ const diagnostics = new AgentDiagnostics(inventory, verbose);
4329
4391
  if (json2) {
4330
4392
  return `${JSON.stringify(diagnostics, null, 2)}
4331
4393
  `;
@@ -4333,11 +4395,17 @@ function formatAgentDiagnostics(inventory, json2) {
4333
4395
  const lines = [];
4334
4396
  for (const available of diagnostics.available) {
4335
4397
  lines.push(
4336
- humanLine(available.label, available.status, `${available.agentVersion} ${available.adapterVersion}`)
4398
+ humanLine(
4399
+ available.label,
4400
+ available.status,
4401
+ `${available.agentVersion} ${available.adapterVersion}${detectionSuffix(available)}`
4402
+ )
4337
4403
  );
4338
4404
  }
4339
4405
  for (const unavailable of diagnostics.unavailable) {
4340
- lines.push(humanLine(unavailable.label, unavailable.status, unavailable.message));
4406
+ lines.push(
4407
+ humanLine(unavailable.label, unavailable.status, `${unavailable.message}${detectionSuffix(unavailable)}`)
4408
+ );
4341
4409
  if (unavailable.recoveryCommand.length > 0) {
4342
4410
  lines.push(
4343
4411
  unavailable.code === "authentication_required" ? ` Authenticate locally: ${unavailable.recoveryCommand}` : ` Install adapter: ${unavailable.recoveryCommand}`
@@ -28077,15 +28145,20 @@ async function discoverAgent(specification, context) {
28077
28145
  );
28078
28146
  continue;
28079
28147
  }
28080
- if (!supportedVersion) {
28081
- continue;
28082
- }
28083
28148
  const installedAgent = new AgentIntegrationDefinition(
28084
28149
  specification.id,
28085
28150
  specification.label,
28086
28151
  agent.identity.requestedPath,
28087
28152
  agentVersion
28088
28153
  );
28154
+ if (!supportedVersion) {
28155
+ lastFailure = new UnsupportedAgentVersion(
28156
+ specification,
28157
+ installedAgent,
28158
+ specification.minimumSupportedAgentVersion
28159
+ );
28160
+ continue;
28161
+ }
28089
28162
  if (adapters.length === 0 && !(specification instanceof InProcessAcpAgentDefinition2)) {
28090
28163
  return new MissingAdapter(specification, installedAgent);
28091
28164
  }
@@ -28179,10 +28252,15 @@ async function discoverAgent(specification, context) {
28179
28252
  // src/agent-catalog/discover-local-agents.ts
28180
28253
  async function discoverLocalAgentInventory(options) {
28181
28254
  const specifications = options.specifications ?? supportedLocalAgentSpecifications();
28182
- const discoveries = await Promise.all(
28183
- specifications.map(async (specification) => await discoverAgent(specification, options))
28255
+ const monotonicTimeMilliseconds = options.monotonicTimeMilliseconds ?? (() => performance.now());
28256
+ const results = await Promise.all(
28257
+ specifications.map(async (specification) => {
28258
+ const startedAt = monotonicTimeMilliseconds();
28259
+ const discovery = await discoverAgent(specification, options);
28260
+ return new AgentDiscoveryResult(discovery, monotonicTimeMilliseconds() - startedAt);
28261
+ })
28184
28262
  );
28185
- return new LocalAgentInventory(discoveries);
28263
+ return new LocalAgentInventory(results);
28186
28264
  }
28187
28265
 
28188
28266
  // src/config.ts
@@ -29546,18 +29624,21 @@ var activeTurnMessageSchema = external_exports.discriminatedUnion("role", [
29546
29624
  activeTurnAssistantMessageSchema
29547
29625
  ]);
29548
29626
  var activeTurnSnapshotSchema = external_exports.strictObject({
29549
- activities: external_exports.array(activeTurnActivitySchema).readonly(),
29550
29627
  commandId: identifierStringSchema,
29551
- content: external_exports.array(displayContentSchema).readonly(),
29552
- prompt: external_exports.string().max(1e5),
29553
- text: external_exports.string(),
29554
- truncated: external_exports.boolean(),
29555
29628
  epoch: identifierStringSchema,
29629
+ hasOlder: external_exports.boolean(),
29556
29630
  interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
29557
29631
  messages: external_exports.array(activeTurnMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
29558
29632
  sequence: external_exports.number().int().nonnegative(),
29559
- state: external_exports.literal("running")
29560
- }).readonly();
29633
+ state: external_exports.literal("running"),
29634
+ truncated: external_exports.boolean()
29635
+ }).readonly().refine(
29636
+ (snapshot) => snapshot.messages.reduce(
29637
+ (total, message) => total + message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0),
29638
+ 0
29639
+ ) <= SESSION_HISTORY_CHARACTER_LIMIT,
29640
+ "Active Turn snapshot content is too large"
29641
+ );
29561
29642
  var identity = {
29562
29643
  ...envelope,
29563
29644
  kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
@@ -29701,27 +29782,14 @@ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSch
29701
29782
 
29702
29783
  // ../protocol/src/session-events.ts
29703
29784
  var SESSION_EVENT_KIND = "session.event";
29704
- var SESSION_EVENT_COMMITTED_KIND = "session.event.committed";
29705
29785
  var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
29706
29786
  var eventEnvelopeSchema = external_exports.strictObject({
29707
29787
  kind: external_exports.literal(SESSION_EVENT_KIND),
29708
29788
  payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
29709
29789
  sessionId: identifierStringSchema
29710
29790
  }).readonly();
29711
- var committedEventSchema = external_exports.strictObject({
29712
- kind: external_exports.literal(SESSION_EVENT_COMMITTED_KIND),
29713
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
29714
- sessionId: identifierStringSchema
29715
- }).readonly();
29716
29791
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
29717
29792
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
29718
- var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
29719
- var sessionTurnUpdatedSchema = external_exports.strictObject({
29720
- kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
29721
- sessionId: identifierStringSchema,
29722
- turn: activeTurnSnapshotSchema
29723
- }).readonly();
29724
- var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
29725
29793
  function decode5(encoded, schema) {
29726
29794
  let value;
29727
29795
  try {
@@ -29751,8 +29819,6 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
29751
29819
  function decodeRecordedSessionEvent(encoded) {
29752
29820
  const kind = decodeMessageKind(encoded);
29753
29821
  switch (kind) {
29754
- case SESSION_TURN_UPDATED_KIND:
29755
- return decodeSessionTurnUpdatedEvent(encoded);
29756
29822
  case SESSION_QUEUE_CHANGED_KIND:
29757
29823
  return decode5(encoded, sessionQueueChangedSchema);
29758
29824
  case AGENT_ACTIVITY_KIND:
@@ -42129,6 +42195,28 @@ var DaemonInstallationObserver = class {
42129
42195
 
42130
42196
  // src/daemon-active-turn.ts
42131
42197
  import { randomUUID as randomUUID2 } from "node:crypto";
42198
+ function activeMessageCharacters(message) {
42199
+ return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
42200
+ }
42201
+ var ACTIVE_TURN_TEXT_CHUNK_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / 2);
42202
+ function boundedRecoveryMessages(messages) {
42203
+ const selected = [];
42204
+ let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT;
42205
+ for (let index = messages.length - 1; index >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index -= 1) {
42206
+ const message = messages[index];
42207
+ if (message === void 0) {
42208
+ break;
42209
+ }
42210
+ const characters = activeMessageCharacters(message);
42211
+ if (characters <= remainingCharacters) {
42212
+ selected.unshift(message);
42213
+ remainingCharacters -= characters;
42214
+ continue;
42215
+ }
42216
+ break;
42217
+ }
42218
+ return { hasOlder: selected.length !== messages.length, messages: selected };
42219
+ }
42132
42220
  var ActiveDaemonTurn = class {
42133
42221
  attemptId;
42134
42222
  command;
@@ -42136,9 +42224,7 @@ var ActiveDaemonTurn = class {
42136
42224
  #finished = Promise.withResolvers();
42137
42225
  #cancellationRequested = false;
42138
42226
  #dispatch;
42139
- #text = "";
42140
42227
  #activities = /* @__PURE__ */ new Map();
42141
- #content = /* @__PURE__ */ new Map();
42142
42228
  #timeline;
42143
42229
  #sequence = 0;
42144
42230
  #interaction = null;
@@ -42185,9 +42271,17 @@ var ActiveDaemonTurn = class {
42185
42271
  effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
42186
42272
  recordEvent = (event) => {
42187
42273
  if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
42188
- this.#text += event.text;
42274
+ const sequence = this.advance();
42189
42275
  this.appendMessageText(event.messageId, event.text);
42190
- return this.updated();
42276
+ return {
42277
+ commandId: this.command.commandId,
42278
+ epoch: this.#epoch,
42279
+ kind: AGENT_MESSAGE_DELTA_KIND,
42280
+ messageId: event.messageId,
42281
+ sequence,
42282
+ sessionId: this.command.sessionId,
42283
+ text: event.text
42284
+ };
42191
42285
  }
42192
42286
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
42193
42287
  return event;
@@ -42234,7 +42328,6 @@ var ActiveDaemonTurn = class {
42234
42328
  toolKind: previous?.toolKind ?? ""
42235
42329
  });
42236
42330
  } else if (event.kind === AGENT_CONTENT_KIND) {
42237
- this.#content.set(event.contentId, event.content);
42238
42331
  const target = this.#timeline.findLastIndex(
42239
42332
  (entry) => entry.kind === "message" && entry.sourceMessageId === event.messageId
42240
42333
  );
@@ -42260,7 +42353,7 @@ var ActiveDaemonTurn = class {
42260
42353
  this.#interaction = null;
42261
42354
  }
42262
42355
  if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
42263
- return this.updated();
42356
+ this.advance();
42264
42357
  }
42265
42358
  return event;
42266
42359
  };
@@ -42269,7 +42362,7 @@ var ActiveDaemonTurn = class {
42269
42362
  while (remaining.length > 0) {
42270
42363
  const latest = this.#timeline.at(-1);
42271
42364
  if (latest?.kind === "message" && latest.sourceMessageId === messageId) {
42272
- const available = SESSION_HISTORY_CHARACTER_LIMIT - latest.text.length;
42365
+ const available = ACTIVE_TURN_TEXT_CHUNK_LIMIT - latest.text.length;
42273
42366
  if (available > 0) {
42274
42367
  this.#timeline = [
42275
42368
  ...this.#timeline.slice(0, -1),
@@ -42286,21 +42379,22 @@ var ActiveDaemonTurn = class {
42286
42379
  id: decodeIdentifier(randomUUID2()),
42287
42380
  kind: "message",
42288
42381
  sourceMessageId: messageId,
42289
- text: remaining.slice(0, SESSION_HISTORY_CHARACTER_LIMIT)
42382
+ text: remaining.slice(0, ACTIVE_TURN_TEXT_CHUNK_LIMIT)
42290
42383
  }
42291
42384
  ];
42292
- remaining = remaining.slice(SESSION_HISTORY_CHARACTER_LIMIT);
42385
+ remaining = remaining.slice(ACTIVE_TURN_TEXT_CHUNK_LIMIT);
42293
42386
  }
42294
42387
  }
42295
42388
  recordSteeringPrompt = (command) => {
42296
42389
  if (this.#dispatch.kind !== "running" || command.sessionId !== this.command.sessionId || command.targetCommandId !== this.command.commandId) {
42297
- return null;
42390
+ return false;
42298
42391
  }
42299
42392
  this.#timeline = [
42300
42393
  ...this.#timeline,
42301
42394
  { id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
42302
42395
  ];
42303
- return this.updated();
42396
+ this.advance();
42397
+ return true;
42304
42398
  };
42305
42399
  timelineMessages() {
42306
42400
  return this.#timeline.flatMap((entry) => {
@@ -42322,32 +42416,39 @@ var ActiveDaemonTurn = class {
42322
42416
  return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], id: entry.id, role: "assistant", text: "" }];
42323
42417
  });
42324
42418
  }
42325
- updated = () => {
42326
- this.#sequence += 1;
42327
- const turn = this.snapshot();
42328
- if (turn === null) {
42329
- throw new Error("Only a running turn can publish a snapshot");
42419
+ advance = () => {
42420
+ if (this.#dispatch.kind !== "running") {
42421
+ throw new Error("Only a running turn can advance its snapshot");
42330
42422
  }
42331
- return { kind: "session.turn.updated", sessionId: this.command.sessionId, turn };
42423
+ this.#sequence += 1;
42424
+ return this.#sequence;
42332
42425
  };
42333
42426
  snapshot = () => {
42334
42427
  if (this.#dispatch.kind !== "running") {
42335
42428
  return null;
42336
42429
  }
42337
- const completeMessages = this.timelineMessages();
42338
- const messages = completeMessages.slice(-SESSION_HISTORY_MESSAGE_LIMIT);
42430
+ const bounded2 = boundedRecoveryMessages(this.timelineMessages());
42339
42431
  return {
42340
- activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
42341
42432
  commandId: decodeIdentifier(this.command.commandId),
42342
- content: [...this.#content.values()],
42343
- prompt: this.command.prompt,
42344
- text: this.#text,
42345
- truncated: messages.length !== completeMessages.length,
42346
42433
  epoch: this.#epoch,
42434
+ hasOlder: bounded2.hasOlder,
42347
42435
  interaction: this.#interaction,
42348
- messages,
42436
+ messages: bounded2.messages,
42349
42437
  sequence: this.#sequence,
42350
- state: "running"
42438
+ state: "running",
42439
+ truncated: false
42440
+ };
42441
+ };
42442
+ recovery = () => {
42443
+ if (this.#dispatch.kind !== "running") {
42444
+ return null;
42445
+ }
42446
+ return {
42447
+ commandId: decodeIdentifier(this.command.commandId),
42448
+ epoch: this.#epoch,
42449
+ messages: this.timelineMessages(),
42450
+ state: "running",
42451
+ truncated: false
42351
42452
  };
42352
42453
  };
42353
42454
  matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
@@ -42373,6 +42474,7 @@ var ActiveDaemonTurn = class {
42373
42474
  };
42374
42475
 
42375
42476
  // src/daemon-turn-registry.ts
42477
+ var COMPLETED_TURN_RECOVERY_LIMIT = 32;
42376
42478
  var waitForTurnCompletion = (turn, waitSignal) => {
42377
42479
  waitSignal.throwIfAborted();
42378
42480
  return new Promise((resolve9, reject) => {
@@ -42399,6 +42501,7 @@ var waitForTurnCompletion = (turn, waitSignal) => {
42399
42501
  };
42400
42502
  var DaemonTurnRegistry = class {
42401
42503
  #turns = /* @__PURE__ */ new Map();
42504
+ #completed = /* @__PURE__ */ new Map();
42402
42505
  #operations;
42403
42506
  constructor(operations) {
42404
42507
  this.#operations = operations;
@@ -42410,7 +42513,22 @@ var DaemonTurnRegistry = class {
42410
42513
  };
42411
42514
  get = (commandId) => this.#turns.get(commandId);
42412
42515
  finish = (turn) => {
42516
+ const recovery = turn.recovery();
42413
42517
  this.#turns.delete(turn.command.commandId);
42518
+ if (recovery !== null) {
42519
+ this.#completed.delete(turn.command.sessionId);
42520
+ this.#completed.set(turn.command.sessionId, {
42521
+ command: turn.command,
42522
+ recovery: { ...recovery, state: "completed" }
42523
+ });
42524
+ while (this.#completed.size > COMPLETED_TURN_RECOVERY_LIMIT) {
42525
+ const oldestSessionId = this.#completed.keys().next().value;
42526
+ if (oldestSessionId === void 0) {
42527
+ break;
42528
+ }
42529
+ this.#completed.delete(oldestSessionId);
42530
+ }
42531
+ }
42414
42532
  turn.finish();
42415
42533
  };
42416
42534
  recordEvent = (event) => {
@@ -42431,7 +42549,7 @@ var DaemonTurnRegistry = class {
42431
42549
  };
42432
42550
  recordSteeringPrompt = (command) => {
42433
42551
  const target = this.#turns.get(command.targetCommandId);
42434
- return target?.recordSteeringPrompt(command) ?? null;
42552
+ return target?.recordSteeringPrompt(command) ?? false;
42435
42553
  };
42436
42554
  executionSnapshot = async (matches) => {
42437
42555
  const matching = [];
@@ -42462,12 +42580,30 @@ var DaemonTurnRegistry = class {
42462
42580
  }
42463
42581
  return null;
42464
42582
  };
42583
+ recovery = (matches) => {
42584
+ for (const turn of this.#turns.values()) {
42585
+ if (!matches(turn.command)) {
42586
+ continue;
42587
+ }
42588
+ const recovery = turn.recovery();
42589
+ if (recovery !== null) {
42590
+ return recovery;
42591
+ }
42592
+ }
42593
+ for (const completed of this.#completed.values()) {
42594
+ if (matches(completed.command)) {
42595
+ return completed.recovery;
42596
+ }
42597
+ }
42598
+ return null;
42599
+ };
42465
42600
  close = async () => {
42466
42601
  const turns = [...this.#turns.values()];
42467
42602
  for (const turn of turns) {
42468
42603
  turn.abortDaemon();
42469
42604
  }
42470
42605
  await Promise.all(turns.map((turn) => turn.completion));
42606
+ this.#completed.clear();
42471
42607
  };
42472
42608
  admitAndWait = async (turn, waitSignal, onQueued) => {
42473
42609
  const command = turn.command;
@@ -44775,10 +44911,10 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
44775
44911
  }
44776
44912
 
44777
44913
  // src/native-sessions/live-history-page.ts
44778
- function liveHistoryCursor(sessionId, endIndex) {
44779
- return Buffer.from(JSON.stringify({ endIndex, sessionId }), "utf8").toString("base64url");
44914
+ function encodeLiveHistoryCursor(cursor) {
44915
+ return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
44780
44916
  }
44781
- function liveHistoryEndIndex(cursor, sessionId) {
44917
+ function decodeLiveHistoryCursor(cursor, sessionId) {
44782
44918
  try {
44783
44919
  if (!/^[A-Za-z0-9_-]{1,512}$/u.test(cursor)) {
44784
44920
  throw new Error("Invalid cursor alphabet");
@@ -44788,14 +44924,32 @@ function liveHistoryEndIndex(cursor, sessionId) {
44788
44924
  throw new Error("Invalid cursor shape");
44789
44925
  }
44790
44926
  const record2 = Object.fromEntries(Object.entries(value));
44791
- if (Object.keys(record2).sort().join(",") !== "endIndex,sessionId" || record2["sessionId"] !== sessionId || typeof record2["endIndex"] !== "number" || !Number.isSafeInteger(record2["endIndex"]) || record2["endIndex"] < 0) {
44927
+ const keys = Object.keys(record2).sort().join(",");
44928
+ const legacyNative = keys === "endIndex,sessionId";
44929
+ const kind = legacyNative ? "native" : record2["kind"];
44930
+ if (keys !== "endIndex,kind,sessionId" && keys !== "endIndex,epoch,kind,sessionId" && !legacyNative || record2["sessionId"] !== sessionId || kind !== "active" && kind !== "native" || typeof record2["endIndex"] !== "number" || !Number.isSafeInteger(record2["endIndex"]) || record2["endIndex"] < 0) {
44792
44931
  throw new Error("Invalid cursor target");
44793
44932
  }
44794
- return record2["endIndex"];
44933
+ if (kind === "active") {
44934
+ if (keys !== "endIndex,epoch,kind,sessionId" || typeof record2["epoch"] !== "string") {
44935
+ throw new Error("Invalid active cursor target");
44936
+ }
44937
+ return { endIndex: record2["endIndex"], epoch: record2["epoch"], kind, sessionId };
44938
+ }
44939
+ if (keys !== "endIndex,kind,sessionId" && !legacyNative) {
44940
+ throw new Error("Invalid native cursor target");
44941
+ }
44942
+ return { endIndex: record2["endIndex"], kind, sessionId };
44795
44943
  } catch (cause) {
44796
44944
  throw new AcpExecutionError("The native Session history cursor is invalid", { cause }, "invalid_cursor");
44797
44945
  }
44798
44946
  }
44947
+ function activeHistoryCursor(sessionId, epoch, endIndex) {
44948
+ return encodeLiveHistoryCursor({ endIndex, epoch, kind: "active", sessionId });
44949
+ }
44950
+ function nativeHistoryCursor(sessionId, endIndex) {
44951
+ return encodeLiveHistoryCursor({ endIndex, kind: "native", sessionId });
44952
+ }
44799
44953
  function liveHistoryCoveredTurnRanges(history) {
44800
44954
  const ranges = [];
44801
44955
  let historyIndex = history.messages.length;
@@ -44816,139 +44970,180 @@ function liveHistoryCoveredTurnRanges(history) {
44816
44970
  function historyMessageCharacters(message) {
44817
44971
  return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
44818
44972
  }
44819
- function boundedActiveMessages(messages, messageLimit, characterLimit) {
44973
+ function isNativeHistoryImageMimeType(mimeType) {
44974
+ return mimeType === "image/png" || mimeType === "image/jpeg" || mimeType === "image/gif" || mimeType === "image/webp";
44975
+ }
44976
+ function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit) {
44820
44977
  const selected = [];
44821
44978
  let remainingCharacters = characterLimit;
44822
- for (let index = messages.length - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
44979
+ let startIndex = endIndex;
44980
+ for (let index = endIndex - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
44823
44981
  const message = messages[index];
44824
44982
  if (message === void 0) {
44825
44983
  break;
44826
44984
  }
44827
44985
  const characters = historyMessageCharacters(message);
44828
- if (characters <= remainingCharacters) {
44829
- selected.unshift(message);
44830
- remainingCharacters -= characters;
44831
- continue;
44832
- }
44833
- const structuredCharacters = characters - message.text.length;
44834
- if (selected.length === 0 && structuredCharacters <= remainingCharacters) {
44835
- const textCharacters = remainingCharacters - structuredCharacters;
44836
- selected.unshift({ ...message, text: textCharacters === 0 ? "" : message.text.slice(-textCharacters) });
44837
- remainingCharacters = 0;
44986
+ if (characters > remainingCharacters) {
44987
+ break;
44838
44988
  }
44839
- break;
44989
+ selected.unshift(message);
44990
+ remainingCharacters -= characters;
44991
+ startIndex = index;
44840
44992
  }
44841
- return {
44842
- characters: characterLimit - remainingCharacters,
44843
- messages: selected,
44844
- truncated: selected.length !== messages.length
44845
- };
44993
+ if (selected.length === 0 && endIndex > 0) {
44994
+ throw new AcpExecutionError(
44995
+ "A native Session history item exceeds the page budget",
44996
+ {},
44997
+ "history_item_too_large"
44998
+ );
44999
+ }
45000
+ return { characters: characterLimit - remainingCharacters, messages: selected, startIndex };
44846
45001
  }
44847
45002
  function nativeActiveMessage(message) {
44848
- return message.role === "user" ? { role: "user", text: message.text } : {
44849
- activities: message.activities,
44850
- content: message.content,
44851
- role: "assistant",
44852
- text: message.text
44853
- };
45003
+ if (message.role === "assistant") {
45004
+ return {
45005
+ activities: message.activities,
45006
+ content: message.content,
45007
+ role: "assistant",
45008
+ text: message.text
45009
+ };
45010
+ }
45011
+ const images = (message.images ?? []).flatMap((image) => {
45012
+ if (image.data.length < 4 || image.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(image.data) || !isNativeHistoryImageMimeType(image.mimeType)) {
45013
+ return [];
45014
+ }
45015
+ return [{ data: image.data, mimeType: image.mimeType, name: image.name }];
45016
+ });
45017
+ return { ...images.length === 0 ? {} : { images }, role: "user", text: message.text };
44854
45018
  }
44855
- function paginateAcpSessionHistory(history, sessionId, cursor, limit) {
45019
+ function nativeHistoryCoversCompletedRecovery(history, recovery) {
45020
+ const root = recovery.messages.find((message) => message.role === "user" && message.id === recovery.commandId);
45021
+ if (root === void 0) {
45022
+ return false;
45023
+ }
45024
+ const rootIndex = history.messages.findLastIndex(
45025
+ (message) => message.role === "user" && message.text === root.text
45026
+ );
45027
+ if (rootIndex < 0) {
45028
+ return false;
45029
+ }
45030
+ const nativeAssistant = history.messages.slice(rootIndex + 1).filter((message) => message.role === "assistant");
45031
+ if (nativeAssistant.length === 0) {
45032
+ return false;
45033
+ }
45034
+ const recoveryAssistant = recovery.messages.filter((message) => message.role === "assistant");
45035
+ const recoveryText = recoveryAssistant.map((message) => message.text).join("");
45036
+ const nativeText = nativeAssistant.map((message) => message.text).join("");
45037
+ if (recoveryText.length > 0 && !nativeText.includes(recoveryText)) {
45038
+ return false;
45039
+ }
45040
+ const nativeContent = new Set(
45041
+ nativeAssistant.flatMap((message) => message.content).map((content) => JSON.stringify(content))
45042
+ );
45043
+ return recoveryAssistant.flatMap((message) => message.content).every((content) => nativeContent.has(JSON.stringify(content)));
45044
+ }
45045
+ function historyBeforeActiveTurn(history, activeTurn) {
44856
45046
  if (history.status === "unavailable") {
44857
- if (cursor !== null) {
44858
- throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
44859
- }
44860
- return { cause: history.cause, nextCursor: null, status: "unavailable" };
45047
+ return history;
45048
+ }
45049
+ const activeRoot = activeTurn.messages.find(
45050
+ (message) => message.role === "user" && message.id === activeTurn.commandId
45051
+ );
45052
+ const matchingActiveUserIndex = activeRoot === void 0 ? -1 : activeTurn.state === "completed" || history.messages.at(-1)?.role === "user" && history.messages.at(-1)?.text === activeRoot.text || history.coveredCommandIds.includes(activeTurn.commandId) ? history.messages.findLastIndex((message) => message.role === "user" && message.text === activeRoot.text) : -1;
45053
+ const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
45054
+ if (activeUserIndex < 0) {
45055
+ return history;
44861
45056
  }
44862
- const endIndex = cursor === null ? history.messages.length : liveHistoryEndIndex(cursor, sessionId);
45057
+ return {
45058
+ ...history,
45059
+ coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
45060
+ coveredMessageIds: history.coveredMessageIds.filter(
45061
+ (id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
45062
+ ),
45063
+ messages: history.messages.slice(0, activeUserIndex)
45064
+ };
45065
+ }
45066
+ function paginateAvailableNativeHistory(history, sessionId, endIndex, limit, characterLimit) {
44863
45067
  if (endIndex > history.messages.length) {
44864
45068
  throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
44865
45069
  }
44866
- const startIndex = Math.max(0, endIndex - limit);
45070
+ const selected = selectMessagesBefore(history.messages, endIndex, limit, characterLimit);
44867
45071
  const coveredMessageIds = new Set(history.coveredMessageIds);
44868
45072
  const ranges = liveHistoryCoveredTurnRanges(history);
44869
45073
  return {
44870
- coveredCommandIds: ranges.filter((range) => range.userIndex >= startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
45074
+ coveredCommandIds: ranges.filter((range) => range.userIndex >= selected.startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
44871
45075
  coveredMessageIds: ranges.flatMap((range) => [
44872
- ...range.userIndex >= startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
44873
- ...range.assistantStartIndex >= startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
45076
+ ...range.userIndex >= selected.startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
45077
+ ...range.assistantStartIndex >= selected.startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
44874
45078
  ]),
44875
- messages: history.messages.slice(startIndex, endIndex),
44876
- nextCursor: startIndex > 0 ? liveHistoryCursor(sessionId, startIndex) : null,
45079
+ messages: selected.messages,
45080
+ nextCursor: selected.startIndex > 0 ? nativeHistoryCursor(sessionId, selected.startIndex) : null,
44877
45081
  status: "available",
44878
45082
  truncated: history.truncated
44879
45083
  };
44880
45084
  }
44881
- function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limit) {
44882
- if (activeTurn === null || cursor !== null) {
44883
- return paginateAcpSessionHistory(history, sessionId, cursor, limit);
45085
+ function paginateNativeHistory(history, sessionId, cursor, limit) {
45086
+ if (cursor?.kind === "active") {
45087
+ throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
44884
45088
  }
44885
45089
  if (history.status === "unavailable") {
44886
- const bounded3 = boundedActiveMessages(
44887
- activeTurn.messages.map(nativeActiveMessage),
44888
- limit,
44889
- SESSION_HISTORY_CHARACTER_LIMIT
44890
- );
44891
- return {
44892
- coveredCommandIds: [],
44893
- coveredMessageIds: [],
44894
- messages: bounded3.messages,
44895
- nextCursor: null,
44896
- status: "available",
44897
- truncated: activeTurn.truncated || bounded3.truncated
44898
- };
45090
+ if (cursor !== null) {
45091
+ throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
45092
+ }
45093
+ return { cause: history.cause, nextCursor: null, status: "unavailable" };
44899
45094
  }
44900
- const activeRoot = activeTurn.messages.find(
44901
- (message) => message.role === "user" && message.id === activeTurn.commandId
45095
+ return paginateAvailableNativeHistory(
45096
+ history,
45097
+ sessionId,
45098
+ cursor?.endIndex ?? history.messages.length,
45099
+ limit,
45100
+ SESSION_HISTORY_CHARACTER_LIMIT
44902
45101
  );
44903
- const coveredActiveRoot = history.coveredCommandIds.includes(activeTurn.commandId);
44904
- const matchingActiveUserIndex = coveredActiveRoot ? history.messages.findLastIndex(
44905
- (message) => message.role === "user" && message.text === (activeRoot?.text ?? activeTurn.prompt)
44906
- ) : -1;
44907
- const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
44908
- if (activeUserIndex >= 0) {
44909
- history = {
44910
- ...history,
44911
- coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
44912
- coveredMessageIds: history.coveredMessageIds.filter(
44913
- (id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
44914
- ),
44915
- messages: history.messages.slice(0, activeUserIndex + 1)
44916
- };
44917
- }
44918
- const latestNativeMessage = history.messages.at(-1);
44919
- const firstActiveMessage = activeTurn.messages[0];
44920
- const preserveNativeRoot = activeUserIndex >= 0 || firstActiveMessage?.role === "user" && latestNativeMessage?.role === "user" && latestNativeMessage.text === firstActiveMessage.text;
44921
- const activeMessages = activeTurn.messages.slice(preserveNativeRoot ? 1 : 0).map(nativeActiveMessage);
44922
- const bounded2 = boundedActiveMessages(activeMessages, limit, SESSION_HISTORY_CHARACTER_LIMIT);
44923
- let historicalMessageCount = 0;
44924
- let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters;
44925
- const historicalMessageLimit = Math.max(0, limit - bounded2.messages.length);
44926
- for (let index = history.messages.length - 1; index >= 0 && historicalMessageCount < historicalMessageLimit; index -= 1) {
44927
- const message = history.messages[index];
44928
- if (message === void 0) {
44929
- break;
44930
- }
44931
- const characters = historyMessageCharacters(message);
44932
- if (characters > remainingCharacters) {
44933
- break;
44934
- }
44935
- historicalMessageCount += 1;
44936
- remainingCharacters -= characters;
45102
+ }
45103
+ function paginateActiveTurn(history, activeTurn, sessionId, endIndex, limit) {
45104
+ if (endIndex > activeTurn.messages.length) {
45105
+ throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
44937
45106
  }
44938
- const page = historicalMessageCount === 0 ? {
44939
- coveredCommandIds: [],
44940
- coveredMessageIds: [],
44941
- messages: [],
44942
- nextCursor: history.messages.length === 0 ? null : liveHistoryCursor(sessionId, history.messages.length),
44943
- status: "available",
44944
- truncated: history.truncated
44945
- } : paginateAcpSessionHistory(history, sessionId, null, historicalMessageCount);
45107
+ const activeMessages = activeTurn.messages.map(nativeActiveMessage);
45108
+ const active = selectMessagesBefore(activeMessages, endIndex, limit, SESSION_HISTORY_CHARACTER_LIMIT);
45109
+ const historicalLimit = limit - active.messages.length;
45110
+ const historicalCharacterLimit = SESSION_HISTORY_CHARACTER_LIMIT - active.characters;
45111
+ const pendingHistoricalCursor = history.status === "available" && history.messages.length > 0 ? nativeHistoryCursor(sessionId, history.messages.length) : null;
45112
+ const latestHistoricalMessage = history.status === "available" ? history.messages.at(-1) : void 0;
45113
+ const historicalPageFits = latestHistoricalMessage === void 0 || historyMessageCharacters(latestHistoricalMessage) <= historicalCharacterLimit;
45114
+ const historical = active.startIndex === 0 && history.status === "available" && historicalLimit > 0 && historicalPageFits ? paginateAvailableNativeHistory(
45115
+ history,
45116
+ sessionId,
45117
+ history.messages.length,
45118
+ historicalLimit,
45119
+ historicalCharacterLimit
45120
+ ) : null;
44946
45121
  return {
44947
- ...page,
44948
- messages: [...page.messages, ...bounded2.messages],
44949
- truncated: page.truncated || activeTurn.truncated || bounded2.truncated
45122
+ coveredCommandIds: historical?.coveredCommandIds ?? [],
45123
+ coveredMessageIds: [
45124
+ ...historical?.coveredMessageIds ?? [],
45125
+ ...active.startIndex === 0 ? [`${activeTurn.commandId}:user`, `${activeTurn.commandId}:agent`] : []
45126
+ ],
45127
+ messages: [...historical?.messages ?? [], ...active.messages],
45128
+ nextCursor: active.startIndex > 0 ? activeHistoryCursor(sessionId, activeTurn.epoch, active.startIndex) : historical === null ? pendingHistoricalCursor : historical.nextCursor,
45129
+ status: "available",
45130
+ truncated: activeTurn.truncated || (historical?.truncated ?? false)
44950
45131
  };
44951
45132
  }
45133
+ function paginateLiveSessionHistory(history, activeTurn, sessionId, encodedCursor, limit) {
45134
+ const cursor = encodedCursor === null ? null : decodeLiveHistoryCursor(encodedCursor, sessionId);
45135
+ if (activeTurn === null || activeTurn.state === "completed" && history.status === "available" && nativeHistoryCoversCompletedRecovery(history, activeTurn)) {
45136
+ return paginateNativeHistory(history, sessionId, cursor, limit);
45137
+ }
45138
+ const historical = historyBeforeActiveTurn(history, activeTurn);
45139
+ if (cursor?.kind === "native") {
45140
+ return paginateNativeHistory(historical, sessionId, cursor, limit);
45141
+ }
45142
+ if (cursor !== null && cursor.epoch !== activeTurn.epoch) {
45143
+ throw new AcpExecutionError("The active Turn history cursor is stale", {}, "stale_cursor");
45144
+ }
45145
+ return paginateActiveTurn(historical, activeTurn, sessionId, cursor?.endIndex ?? activeTurn.messages.length, limit);
45146
+ }
44952
45147
  function mergeLiveSessionHistory(history, activeTurn, sessionId) {
44953
45148
  const page = paginateLiveSessionHistory(history, activeTurn, sessionId, null, 1e3);
44954
45149
  if (page.status === "unavailable") {
@@ -44959,7 +45154,7 @@ function mergeLiveSessionHistory(history, activeTurn, sessionId) {
44959
45154
  coveredMessageIds: page.coveredMessageIds,
44960
45155
  messages: page.messages,
44961
45156
  status: "available",
44962
- truncated: page.truncated
45157
+ truncated: page.truncated || page.nextCursor !== null
44963
45158
  };
44964
45159
  }
44965
45160
 
@@ -45478,15 +45673,13 @@ async function executePrompt({
45478
45673
  });
45479
45674
  operations.transitionExecution(command.commandId, "running");
45480
45675
  if (availability.disposition === SessionPromptDisposition.Steer) {
45481
- const updated = recordSteeringPrompt();
45482
- if (updated === null) {
45676
+ if (!recordSteeringPrompt()) {
45483
45677
  throw new AcpExecutionError(
45484
45678
  "The steering target is unavailable",
45485
45679
  {},
45486
45680
  "prompt_queue_target_unavailable"
45487
45681
  );
45488
45682
  }
45489
- publisher.publish(command.sessionId, updated);
45490
45683
  }
45491
45684
  const stream = activateAttempt();
45492
45685
  publisher.publish(command.sessionId, {
@@ -45874,7 +46067,7 @@ function createDaemonCommandHandler({
45874
46067
  resolveEnvironment: resolveAgentCatalogEnvironment
45875
46068
  });
45876
46069
  const queueChanged = (sessionId) => publisher.publish(sessionId, { kind: "session.queue.changed", sessionId });
45877
- const activeTurnSnapshot = (sessionId) => activeTurns.snapshot((command) => command.sessionId === sessionId);
46070
+ const activeTurnRecovery = (sessionId) => activeTurns.recovery((command) => command.sessionId === sessionId);
45878
46071
  const nativeRequestHandler = createNativeSessionRequestHandler({
45879
46072
  audit,
45880
46073
  diagnostics,
@@ -45895,7 +46088,7 @@ function createDaemonCommandHandler({
45895
46088
  directories,
45896
46089
  audit,
45897
46090
  sessions,
45898
- activeTurnSnapshot,
46091
+ activeTurnRecovery,
45899
46092
  signal
45900
46093
  );
45901
46094
  return;
@@ -45909,7 +46102,7 @@ function createDaemonCommandHandler({
45909
46102
  directories,
45910
46103
  audit,
45911
46104
  sessions,
45912
- activeTurnSnapshot,
46105
+ activeTurnRecovery,
45913
46106
  signal
45914
46107
  );
45915
46108
  return;
@@ -47574,7 +47767,7 @@ function createProgram() {
47574
47767
  process.stdout.write(`${package_default.version}
47575
47768
  `);
47576
47769
  });
47577
- program2.command("agents").description("show detected, missing, and integration-ready Agents").option("--json", "write the Agent inventory as JSON").action(async (options) => {
47770
+ program2.command("agents").description("show detected, missing, and integration-ready Agents").option("--json", "write the Agent inventory as JSON").option("--verbose", "include per-Agent detection timing").action(async (options) => {
47578
47771
  const installation = await openMobiusCliInstallation(shutdown.signal, process.env);
47579
47772
  const localContext = new DaemonLocalContext(installation.stateDirectory, process.env);
47580
47773
  const defaultWorkspace = loadDefaultWorkspace(localContext.environment);
@@ -47584,7 +47777,7 @@ function createProgram() {
47584
47777
  environment: localContext.environment,
47585
47778
  signal: shutdown.signal
47586
47779
  });
47587
- process.stdout.write(formatAgentDiagnostics(inventory, options.json === true));
47780
+ process.stdout.write(formatAgentDiagnostics(inventory, options.json === true, options.verbose === true));
47588
47781
  });
47589
47782
  program2.command("__manager", { hidden: true }).action(async () => {
47590
47783
  const installation = await openMobiusCliInstallation(shutdown.signal, process.env);