@moxt-ai/mobius 0.0.154 → 0.0.156

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 (78) hide show
  1. package/dist/acp/agent-query-processes.d.ts +2 -1
  2. package/dist/acp/agent-query-processes.d.ts.map +1 -1
  3. package/dist/acp/agent-query-processes.js +7 -1
  4. package/dist/acp/agent-query-processes.js.map +1 -1
  5. package/dist/acp/agent-runtime-manager.d.ts +4 -2
  6. package/dist/acp/agent-runtime-manager.d.ts.map +1 -1
  7. package/dist/acp/agent-runtime-manager.js +19 -0
  8. package/dist/acp/agent-runtime-manager.js.map +1 -1
  9. package/dist/acp/agent-session.d.ts +2 -1
  10. package/dist/acp/agent-session.d.ts.map +1 -1
  11. package/dist/acp/agent-session.js +16 -2
  12. package/dist/acp/agent-session.js.map +1 -1
  13. package/dist/acp/session-contracts.d.ts +9 -1
  14. package/dist/acp/session-contracts.d.ts.map +1 -1
  15. package/dist/acp/session-contracts.js +1 -0
  16. package/dist/acp/session-contracts.js.map +1 -1
  17. package/dist/acp/session-history.d.ts +3 -2
  18. package/dist/acp/session-history.d.ts.map +1 -1
  19. package/dist/acp/session-history.js +17 -1
  20. package/dist/acp/session-history.js.map +1 -1
  21. package/dist/acp/session-store.d.ts +7 -0
  22. package/dist/acp/session-store.d.ts.map +1 -1
  23. package/dist/acp/session-store.js +34 -3
  24. package/dist/acp/session-store.js.map +1 -1
  25. package/dist/cli.js +1050 -402
  26. package/dist/cli.js.map +4 -4
  27. package/dist/daemon-command-handler.d.ts +3 -1
  28. package/dist/daemon-command-handler.d.ts.map +1 -1
  29. package/dist/daemon-command-handler.js +9 -3
  30. package/dist/daemon-command-handler.js.map +1 -1
  31. package/dist/daemon-history-commands.d.ts +2 -1
  32. package/dist/daemon-history-commands.d.ts.map +1 -1
  33. package/dist/daemon-history-commands.js +64 -1
  34. package/dist/daemon-history-commands.js.map +1 -1
  35. package/dist/daemon-observers.d.ts +3 -2
  36. package/dist/daemon-observers.d.ts.map +1 -1
  37. package/dist/daemon-observers.js +7 -1
  38. package/dist/daemon-observers.js.map +1 -1
  39. package/dist/daemon-prompt-executor.d.ts +3 -1
  40. package/dist/daemon-prompt-executor.d.ts.map +1 -1
  41. package/dist/daemon-prompt-executor.js +9 -3
  42. package/dist/daemon-prompt-executor.js.map +1 -1
  43. package/dist/generated/acp-session-store-migrations.d.ts +3 -0
  44. package/dist/generated/acp-session-store-migrations.d.ts.map +1 -1
  45. package/dist/generated/acp-session-store-migrations.js +5 -1
  46. package/dist/generated/acp-session-store-migrations.js.map +1 -1
  47. package/dist/index.js +1033 -385
  48. package/dist/index.js.map +4 -4
  49. package/dist/relay-connection/run-relay-connection.d.ts +3 -1
  50. package/dist/relay-connection/run-relay-connection.d.ts.map +1 -1
  51. package/dist/relay-connection/run-relay-connection.js +4 -16
  52. package/dist/relay-connection/run-relay-connection.js.map +1 -1
  53. package/dist/relay-connection/session-event-publisher.d.ts +5 -9
  54. package/dist/relay-connection/session-event-publisher.d.ts.map +1 -1
  55. package/dist/relay-connection/session-event-publisher.js +34 -131
  56. package/dist/relay-connection/session-event-publisher.js.map +1 -1
  57. package/dist/run-daemon.d.ts.map +1 -1
  58. package/dist/run-daemon.js +5 -2
  59. package/dist/run-daemon.js.map +1 -1
  60. package/dist/runtime.js +1032 -384
  61. package/dist/runtime.js.map +4 -4
  62. package/dist/schema/acp-session-store/index.d.ts +1 -0
  63. package/dist/schema/acp-session-store/index.d.ts.map +1 -1
  64. package/dist/schema/acp-session-store/index.js +1 -0
  65. package/dist/schema/acp-session-store/index.js.map +1 -1
  66. package/dist/schema/acp-session-store/session-event-v2.d.ts +82 -0
  67. package/dist/schema/acp-session-store/session-event-v2.d.ts.map +1 -0
  68. package/dist/schema/acp-session-store/session-event-v2.js +11 -0
  69. package/dist/schema/acp-session-store/session-event-v2.js.map +1 -0
  70. package/dist/session-event-log-v2.d.ts +15 -0
  71. package/dist/session-event-log-v2.d.ts.map +1 -0
  72. package/dist/session-event-log-v2.js +238 -0
  73. package/dist/session-event-log-v2.js.map +1 -0
  74. package/package.json +1 -1
  75. package/dist/relay-connection/session-event-queue.d.ts +0 -14
  76. package/dist/relay-connection/session-event-queue.d.ts.map +0 -1
  77. package/dist/relay-connection/session-event-queue.js +0 -75
  78. package/dist/relay-connection/session-event-queue.js.map +0 -1
package/dist/index.js CHANGED
@@ -3380,11 +3380,11 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
3380
3380
  return payload;
3381
3381
  };
3382
3382
  });
3383
- function handleArrayResult(result, final, index) {
3383
+ function handleArrayResult(result, final, index2) {
3384
3384
  if (result.issues.length) {
3385
- final.issues.push(...prefixIssues(index, result.issues));
3385
+ final.issues.push(...prefixIssues(index2, result.issues));
3386
3386
  }
3387
- final.value[index] = result.value;
3387
+ final.value[index2] = result.value;
3388
3388
  }
3389
3389
  var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
3390
3390
  $ZodType.init(inst, def);
@@ -3995,14 +3995,14 @@ function mergeValues(a, b) {
3995
3995
  return { valid: false, mergeErrorPath: [] };
3996
3996
  }
3997
3997
  const newArray = [];
3998
- for (let index = 0; index < a.length; index++) {
3999
- const itemA = a[index];
4000
- const itemB = b[index];
3998
+ for (let index2 = 0; index2 < a.length; index2++) {
3999
+ const itemA = a[index2];
4000
+ const itemB = b[index2];
4001
4001
  const sharedValue = mergeValues(itemA, itemB);
4002
4002
  if (!sharedValue.valid) {
4003
4003
  return {
4004
4004
  valid: false,
4005
- mergeErrorPath: [index, ...sharedValue.mergeErrorPath]
4005
+ mergeErrorPath: [index2, ...sharedValue.mergeErrorPath]
4006
4006
  };
4007
4007
  }
4008
4008
  newArray.push(sharedValue.data);
@@ -4153,11 +4153,11 @@ function getTupleOptStart(items, key) {
4153
4153
  }
4154
4154
  return 0;
4155
4155
  }
4156
- function handleTupleResult(result, final, index) {
4156
+ function handleTupleResult(result, final, index2) {
4157
4157
  if (result.issues.length) {
4158
- final.issues.push(...prefixIssues(index, result.issues));
4158
+ final.issues.push(...prefixIssues(index2, result.issues));
4159
4159
  }
4160
- final.value[index] = result.value;
4160
+ final.value[index2] = result.value;
4161
4161
  }
4162
4162
  function handleTupleResults(itemResults, final, items, input2, optoutStart) {
4163
4163
  for (let i = 0; i < items.length; i++) {
@@ -18838,7 +18838,7 @@ function detectVersion(schema, defaultTarget) {
18838
18838
  return defaultTarget ?? "draft-2020-12";
18839
18839
  }
18840
18840
  function applyMinItems(items, minItems) {
18841
- return items.map((item, index) => index < minItems ? item : item.optional());
18841
+ return items.map((item, index2) => index2 < minItems ? item : item.optional());
18842
18842
  }
18843
18843
  function decodeJSONPointerSegment(segment) {
18844
18844
  return segment.replace(/~1/g, "/").replace(/~0/g, "~");
@@ -20026,12 +20026,12 @@ var DEFAULT_AGENT_EXECUTION_CONFIGURATION = Object.freeze({
20026
20026
  });
20027
20027
  var sessionConfigurationSelectionsSchema = external_exports.array(sessionConfigurationSelectionSchema).max(100).superRefine((selections, context) => {
20028
20028
  const identifiers = /* @__PURE__ */ new Set();
20029
- for (const [index, selection] of selections.entries()) {
20029
+ for (const [index2, selection] of selections.entries()) {
20030
20030
  if (identifiers.has(selection.configId)) {
20031
20031
  context.addIssue({
20032
20032
  code: "custom",
20033
20033
  message: "Session configuration identifiers must be unique",
20034
- path: [index, "configId"]
20034
+ path: [index2, "configId"]
20035
20035
  });
20036
20036
  }
20037
20037
  identifiers.add(selection.configId);
@@ -20767,16 +20767,8 @@ function decodeSessionQueuedEvent(encoded) {
20767
20767
  function decodeRuntimeLivenessReadyEvent(encoded) {
20768
20768
  const value = parseJson2(encoded);
20769
20769
  assertKind(value, RUNTIME_LIVENESS_READY_KIND);
20770
- if (value["sessionEventDelivery"] === void 0) {
20771
- assertExactKeys(value, ["kind"]);
20772
- return { kind: RUNTIME_LIVENESS_READY_KIND };
20773
- }
20774
- assertExactKeys(value, ["kind", "sessionEventDelivery"]);
20775
- const sessionEventDelivery = readString(value, "sessionEventDelivery", 32);
20776
- if (sessionEventDelivery !== "reliable-v1") {
20777
- throw new ProtocolMessageError("Unsupported Session event delivery mode");
20778
- }
20779
- return { kind: RUNTIME_LIVENESS_READY_KIND, sessionEventDelivery };
20770
+ assertExactKeys(value, ["kind"]);
20771
+ return { kind: RUNTIME_LIVENESS_READY_KIND };
20780
20772
  }
20781
20773
  function decodeRuntimeHeartbeatEvent(encoded) {
20782
20774
  const value = parseJson2(encoded);
@@ -21241,60 +21233,390 @@ var encodeNativeSessionResult = (value) => JSON.stringify(nativeSessionResultSch
21241
21233
  var decodeNativeSessionCancel = (encoded) => decode4(nativeSessionCancelSchema, encoded);
21242
21234
  var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSchema.parse(value));
21243
21235
 
21244
- // ../protocol/src/session-events.ts
21245
- var SESSION_EVENT_KIND = "session.event";
21246
- var SESSION_EVENT_ACK_KIND = "session.event.ack";
21247
- var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
21248
- var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
21249
- var SESSION_FORKED_KIND = "session.forked";
21250
- var SessionEventRejectionCode = {
21251
- IdempotencyConflict: "idempotency_conflict",
21252
- InvalidEvent: "invalid_event",
21253
- RecordingRejected: "recording_rejected"
21254
- };
21255
- var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
21256
- var ephemeralEventEnvelopeSchema = external_exports.strictObject({
21257
- kind: external_exports.literal(SESSION_EVENT_KIND),
21258
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21259
- sessionId: identifierStringSchema
21236
+ // ../protocol/src/session-event-log-v2.ts
21237
+ var MAX_EVENT_COUNT = 1e4;
21238
+ var MAX_COLLECTION_SIZE = 1e3;
21239
+ var MAX_CONTENT_LENGTH = 1e6;
21240
+ var MAX_JSON_DEPTH = 16;
21241
+ var MAX_JSON_KEYS = 1e3;
21242
+ var SESSION_EVENT_V2_KIND = "session.event.v2";
21243
+ var boundedString = external_exports.string().max(MAX_CONTENT_LENGTH);
21244
+ var shortString = external_exports.string().max(2048);
21245
+ function boundedJsonIssue(value, depth = 0) {
21246
+ if (depth > MAX_JSON_DEPTH) {
21247
+ return "JSON nesting exceeds the maximum depth";
21248
+ }
21249
+ if (typeof value === "string") {
21250
+ return value.length <= MAX_CONTENT_LENGTH ? null : "JSON string exceeds the maximum length";
21251
+ }
21252
+ if (typeof value === "number") {
21253
+ return Number.isFinite(value) ? null : "JSON number must be finite";
21254
+ }
21255
+ if (typeof value === "boolean" || value === null) {
21256
+ return null;
21257
+ }
21258
+ if (Array.isArray(value)) {
21259
+ if (value.length > MAX_COLLECTION_SIZE) {
21260
+ return "JSON array exceeds the maximum length";
21261
+ }
21262
+ for (const item of value) {
21263
+ const issue2 = boundedJsonIssue(item, depth + 1);
21264
+ if (issue2 !== null) {
21265
+ return issue2;
21266
+ }
21267
+ }
21268
+ return null;
21269
+ }
21270
+ if (typeof value === "object" && value !== void 0) {
21271
+ const entries = Object.entries(value);
21272
+ if (entries.length > MAX_JSON_KEYS) {
21273
+ return "JSON object exceeds the maximum key count";
21274
+ }
21275
+ for (const [key, item] of entries) {
21276
+ if (key.length > 255) {
21277
+ return "JSON key exceeds the maximum length";
21278
+ }
21279
+ const issue2 = boundedJsonIssue(item, depth + 1);
21280
+ if (issue2 !== null) {
21281
+ return issue2;
21282
+ }
21283
+ }
21284
+ return null;
21285
+ }
21286
+ return "Value is not bounded JSON";
21287
+ }
21288
+ var boundedJsonSchema = external_exports.unknown().superRefine((value, context) => {
21289
+ const issue2 = boundedJsonIssue(value);
21290
+ if (issue2 !== null) {
21291
+ context.addIssue({ code: "custom", message: issue2 });
21292
+ }
21293
+ });
21294
+ var metadataSchema = external_exports.record(external_exports.string().max(255), boundedJsonSchema).readonly();
21295
+ var optionalMetadata = metadataSchema.nullable().optional();
21296
+ var annotationsSchema = external_exports.strictObject({
21297
+ _meta: optionalMetadata,
21298
+ audience: external_exports.array(external_exports.enum(["assistant", "user"])).max(2).readonly().nullable().optional(),
21299
+ lastModified: shortString.nullable().optional(),
21300
+ priority: external_exports.number().finite().nullable().optional()
21260
21301
  }).readonly();
21261
- var reliableDeliverySchema = external_exports.strictObject({
21262
- eventId: identifierStringSchema,
21263
- kind: external_exports.literal("reliable"),
21264
- sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
21265
- streamId: identifierStringSchema
21302
+ var contentFields = { _meta: optionalMetadata, annotations: annotationsSchema.nullable().optional() };
21303
+ var textContentSchema = external_exports.strictObject({ ...contentFields, text: boundedString, type: external_exports.literal("text") }).readonly();
21304
+ var imageContentSchema = external_exports.strictObject({
21305
+ ...contentFields,
21306
+ data: boundedString,
21307
+ mimeType: shortString,
21308
+ type: external_exports.literal("image"),
21309
+ uri: boundedString.nullable().optional()
21266
21310
  }).readonly();
21267
- var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
21268
- delivery: reliableDeliverySchema,
21269
- kind: external_exports.literal(SESSION_EVENT_KIND),
21270
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21271
- sessionId: identifierStringSchema
21311
+ var audioContentSchema = external_exports.strictObject({ ...contentFields, data: boundedString, mimeType: shortString, type: external_exports.literal("audio") }).readonly();
21312
+ var resourceLinkSchema = external_exports.strictObject({
21313
+ ...contentFields,
21314
+ description: boundedString.nullable().optional(),
21315
+ mimeType: shortString.nullable().optional(),
21316
+ name: shortString,
21317
+ size: external_exports.number().int().nonnegative().safe().nullable().optional(),
21318
+ title: shortString.nullable().optional(),
21319
+ type: external_exports.literal("resource_link"),
21320
+ uri: boundedString
21321
+ }).readonly();
21322
+ var textResourceSchema = external_exports.strictObject({
21323
+ _meta: optionalMetadata,
21324
+ mimeType: shortString.nullable().optional(),
21325
+ text: boundedString,
21326
+ uri: boundedString
21327
+ }).readonly();
21328
+ var blobResourceSchema = external_exports.strictObject({
21329
+ _meta: optionalMetadata,
21330
+ blob: boundedString,
21331
+ mimeType: shortString.nullable().optional(),
21332
+ uri: boundedString
21333
+ }).readonly();
21334
+ var embeddedResourceSchema = external_exports.strictObject({
21335
+ ...contentFields,
21336
+ resource: external_exports.union([textResourceSchema, blobResourceSchema]),
21337
+ type: external_exports.literal("resource")
21338
+ }).readonly();
21339
+ var contentBlockV2Schema = external_exports.discriminatedUnion("type", [
21340
+ textContentSchema,
21341
+ imageContentSchema,
21342
+ audioContentSchema,
21343
+ resourceLinkSchema,
21344
+ embeddedResourceSchema
21345
+ ]);
21346
+ var toolCallContentSchema = external_exports.discriminatedUnion("type", [
21347
+ external_exports.strictObject({ _meta: optionalMetadata, content: contentBlockV2Schema, type: external_exports.literal("content") }).readonly(),
21348
+ external_exports.strictObject({
21349
+ _meta: optionalMetadata,
21350
+ newText: boundedString,
21351
+ oldText: boundedString.nullable().optional(),
21352
+ path: boundedString,
21353
+ type: external_exports.literal("diff")
21354
+ }).readonly(),
21355
+ external_exports.strictObject({ _meta: optionalMetadata, terminalId: shortString, type: external_exports.literal("terminal") }).readonly()
21356
+ ]);
21357
+ var toolCallLocationSchema = external_exports.strictObject({
21358
+ _meta: optionalMetadata,
21359
+ line: external_exports.number().int().nonnegative().safe().nullable().optional(),
21360
+ path: boundedString
21361
+ }).readonly();
21362
+ var toolKindSchema = external_exports.enum([
21363
+ "read",
21364
+ "edit",
21365
+ "delete",
21366
+ "move",
21367
+ "search",
21368
+ "execute",
21369
+ "think",
21370
+ "fetch",
21371
+ "switch_mode",
21372
+ "other"
21373
+ ]);
21374
+ var toolStatusSchema = external_exports.enum(["pending", "in_progress", "completed", "failed"]);
21375
+ var toolPatchFields = {
21376
+ _meta: optionalMetadata,
21377
+ content: external_exports.array(toolCallContentSchema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional(),
21378
+ kind: toolKindSchema.nullable().optional(),
21379
+ locations: external_exports.array(toolCallLocationSchema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional(),
21380
+ name: shortString.nullable().optional(),
21381
+ rawInput: boundedJsonSchema.optional(),
21382
+ rawOutput: boundedJsonSchema.optional(),
21383
+ status: toolStatusSchema.nullable().optional(),
21384
+ title: boundedString.nullable().optional()
21385
+ };
21386
+ var planEntrySchema = external_exports.strictObject({
21387
+ _meta: optionalMetadata,
21388
+ content: boundedString,
21389
+ priority: external_exports.enum(["high", "medium", "low"]),
21390
+ status: external_exports.enum(["pending", "in_progress", "completed"])
21391
+ }).readonly();
21392
+ var planContentSchema = external_exports.discriminatedUnion("type", [
21393
+ external_exports.strictObject({
21394
+ _meta: optionalMetadata,
21395
+ entries: external_exports.array(planEntrySchema).max(MAX_COLLECTION_SIZE).readonly(),
21396
+ planId: shortString,
21397
+ type: external_exports.literal("items")
21398
+ }).readonly(),
21399
+ external_exports.strictObject({ _meta: optionalMetadata, planId: shortString, type: external_exports.literal("file"), uri: boundedString }).readonly(),
21400
+ external_exports.strictObject({
21401
+ _meta: optionalMetadata,
21402
+ content: boundedString,
21403
+ planId: shortString,
21404
+ type: external_exports.literal("markdown")
21405
+ }).readonly()
21406
+ ]);
21407
+ var commandSchema = external_exports.strictObject({
21408
+ _meta: optionalMetadata,
21409
+ description: boundedString,
21410
+ input: external_exports.strictObject({ _meta: optionalMetadata, hint: boundedString }).readonly().nullable().optional(),
21411
+ name: shortString
21412
+ }).readonly();
21413
+ var configSelectOptionSchema = external_exports.strictObject({
21414
+ _meta: optionalMetadata,
21415
+ description: boundedString.nullable().optional(),
21416
+ name: shortString,
21417
+ value: shortString
21418
+ }).readonly();
21419
+ var configSelectGroupSchema = external_exports.strictObject({
21420
+ _meta: optionalMetadata,
21421
+ group: shortString,
21422
+ name: shortString,
21423
+ options: external_exports.array(configSelectOptionSchema).max(MAX_COLLECTION_SIZE).readonly()
21272
21424
  }).readonly();
21273
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
21274
- var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
21275
- external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
21425
+ var configBaseFields = {
21426
+ _meta: optionalMetadata,
21427
+ category: shortString.nullable().optional(),
21428
+ description: boundedString.nullable().optional(),
21429
+ id: shortString,
21430
+ name: shortString
21431
+ };
21432
+ var sessionConfigOptionSchema2 = external_exports.discriminatedUnion("type", [
21433
+ external_exports.strictObject({
21434
+ ...configBaseFields,
21435
+ currentValue: shortString,
21436
+ options: external_exports.union([
21437
+ external_exports.array(configSelectOptionSchema).max(MAX_COLLECTION_SIZE).readonly(),
21438
+ external_exports.array(configSelectGroupSchema).max(MAX_COLLECTION_SIZE).readonly()
21439
+ ]),
21440
+ type: external_exports.literal("select")
21441
+ }).readonly(),
21442
+ external_exports.strictObject({ ...configBaseFields, currentValue: external_exports.boolean(), type: external_exports.literal("boolean") }).readonly()
21443
+ ]);
21444
+ var contentChunkFields = {
21445
+ _meta: optionalMetadata,
21446
+ content: contentBlockV2Schema,
21447
+ messageId: shortString.nullable().optional()
21448
+ };
21449
+ var acpSessionUpdateV2Schema = external_exports.discriminatedUnion("sessionUpdate", [
21450
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("user_message_chunk") }).readonly(),
21451
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("agent_message_chunk") }).readonly(),
21452
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("agent_thought_chunk") }).readonly(),
21453
+ external_exports.strictObject({
21454
+ _meta: optionalMetadata,
21455
+ content: external_exports.array(toolCallContentSchema).max(MAX_COLLECTION_SIZE).readonly().optional(),
21456
+ kind: toolKindSchema.optional(),
21457
+ locations: external_exports.array(toolCallLocationSchema).max(MAX_COLLECTION_SIZE).readonly().optional(),
21458
+ name: shortString.nullable().optional(),
21459
+ rawInput: boundedJsonSchema.optional(),
21460
+ rawOutput: boundedJsonSchema.optional(),
21461
+ sessionUpdate: external_exports.literal("tool_call"),
21462
+ status: toolStatusSchema.optional(),
21463
+ title: boundedString,
21464
+ toolCallId: shortString
21465
+ }).readonly(),
21466
+ external_exports.strictObject({ ...toolPatchFields, sessionUpdate: external_exports.literal("tool_call_update"), toolCallId: shortString }).readonly(),
21467
+ external_exports.strictObject({
21468
+ _meta: optionalMetadata,
21469
+ entries: external_exports.array(planEntrySchema).max(MAX_COLLECTION_SIZE).readonly(),
21470
+ sessionUpdate: external_exports.literal("plan")
21471
+ }).readonly(),
21472
+ external_exports.strictObject({ _meta: optionalMetadata, plan: planContentSchema, sessionUpdate: external_exports.literal("plan_update") }).readonly(),
21473
+ external_exports.strictObject({ _meta: optionalMetadata, planId: shortString, sessionUpdate: external_exports.literal("plan_removed") }).readonly(),
21474
+ external_exports.strictObject({
21475
+ _meta: optionalMetadata,
21476
+ availableCommands: external_exports.array(commandSchema).max(MAX_COLLECTION_SIZE).readonly(),
21477
+ sessionUpdate: external_exports.literal("available_commands_update")
21478
+ }).readonly(),
21479
+ external_exports.strictObject({
21480
+ _meta: optionalMetadata,
21481
+ currentModeId: shortString,
21482
+ sessionUpdate: external_exports.literal("current_mode_update")
21483
+ }).readonly(),
21484
+ external_exports.strictObject({
21485
+ _meta: optionalMetadata,
21486
+ configOptions: external_exports.array(sessionConfigOptionSchema2).max(MAX_COLLECTION_SIZE).readonly(),
21487
+ sessionUpdate: external_exports.literal("config_option_update")
21488
+ }).readonly(),
21276
21489
  external_exports.strictObject({
21277
- kind: external_exports.literal("recorded"),
21278
- providerId: identifierStringSchema,
21279
- recordingEpoch: identifierStringSchema
21490
+ _meta: optionalMetadata,
21491
+ sessionUpdate: external_exports.literal("session_info_update"),
21492
+ title: boundedString.nullable().optional(),
21493
+ updatedAt: shortString.nullable().optional()
21494
+ }).readonly(),
21495
+ external_exports.strictObject({
21496
+ _meta: optionalMetadata,
21497
+ cost: external_exports.strictObject({ _meta: optionalMetadata, amount: external_exports.number().finite(), currency: external_exports.string().max(16) }).readonly().nullable().optional(),
21498
+ sessionUpdate: external_exports.literal("usage_update"),
21499
+ size: external_exports.number().int().nonnegative().safe(),
21500
+ used: external_exports.number().int().nonnegative().safe()
21501
+ }).readonly(),
21502
+ external_exports.strictObject({
21503
+ _meta: optionalMetadata,
21504
+ compactionId: shortString,
21505
+ error: boundedString.nullable().optional(),
21506
+ sessionUpdate: external_exports.literal("compaction_update"),
21507
+ status: shortString,
21508
+ summary: external_exports.array(contentBlockV2Schema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional()
21509
+ }).readonly(),
21510
+ external_exports.strictObject({
21511
+ _meta: optionalMetadata,
21512
+ compactionId: shortString,
21513
+ content: contentBlockV2Schema,
21514
+ sessionUpdate: external_exports.literal("compaction_summary_chunk")
21280
21515
  }).readonly()
21281
21516
  ]);
21282
- var eventAcknowledgementSchema = external_exports.strictObject({
21517
+ var lifecycleBase = { commandId: identifierStringSchema };
21518
+ var sessionEventPayloadV2Schema = external_exports.discriminatedUnion("kind", [
21519
+ external_exports.strictObject({ kind: external_exports.literal("acp.session.update"), update: acpSessionUpdateV2Schema }).readonly(),
21520
+ external_exports.strictObject({
21521
+ ...lifecycleBase,
21522
+ content: external_exports.array(contentBlockV2Schema).min(1).max(100).readonly(),
21523
+ kind: external_exports.literal("prompt.requested")
21524
+ }).readonly(),
21525
+ external_exports.strictObject({ ...lifecycleBase, attemptId: identifierStringSchema, epoch: identifierStringSchema, kind: external_exports.literal("prompt.started") }).readonly(),
21526
+ external_exports.strictObject({ ...lifecycleBase, kind: external_exports.literal("prompt.completed"), stopReason: shortString }).readonly(),
21527
+ external_exports.strictObject({
21528
+ ...lifecycleBase,
21529
+ code: identifierStringSchema,
21530
+ kind: external_exports.literal("prompt.failed-before-start"),
21531
+ message: external_exports.string().min(1).max(500)
21532
+ }).readonly(),
21533
+ external_exports.strictObject({
21534
+ ...lifecycleBase,
21535
+ attemptId: identifierStringSchema,
21536
+ code: identifierStringSchema,
21537
+ kind: external_exports.literal("prompt.failed"),
21538
+ message: external_exports.string().min(1).max(500)
21539
+ }).readonly()
21540
+ ]);
21541
+ var positionSchema = external_exports.string().regex(/^(0|[1-9][0-9]*)$/);
21542
+ var provenanceSchema = external_exports.discriminatedUnion("kind", [
21543
+ external_exports.strictObject({ kind: external_exports.literal("original") }).readonly(),
21544
+ external_exports.strictObject({
21545
+ kind: external_exports.literal("imported"),
21546
+ sourceEventId: identifierStringSchema,
21547
+ sourcePosition: positionSchema,
21548
+ sourceSessionId: identifierStringSchema
21549
+ }).readonly(),
21550
+ external_exports.strictObject({
21551
+ kind: external_exports.literal("forked"),
21552
+ sourceEventId: identifierStringSchema,
21553
+ sourcePosition: positionSchema,
21554
+ sourceSessionId: identifierStringSchema
21555
+ }).readonly()
21556
+ ]);
21557
+ var sessionEventV2Schema = external_exports.strictObject({
21283
21558
  eventId: identifierStringSchema,
21284
- kind: external_exports.literal(SESSION_EVENT_ACK_KIND),
21285
- outcome: acknowledgementOutcomeSchema,
21559
+ payload: sessionEventPayloadV2Schema,
21560
+ position: positionSchema,
21561
+ provenance: provenanceSchema,
21562
+ recordedAt: external_exports.iso.datetime({ offset: true }),
21286
21563
  sessionId: identifierStringSchema
21287
21564
  }).readonly();
21288
- var eventDeferredSchema = external_exports.strictObject({
21289
- eventId: identifierStringSchema,
21290
- kind: external_exports.literal(SESSION_EVENT_DEFERRED_KIND),
21291
- retryAfterMilliseconds: external_exports.number().int().min(100).max(6e4),
21292
- sessionId: identifierStringSchema
21565
+ var sessionEventEnvelopeV2Schema = external_exports.strictObject({ event: sessionEventV2Schema, kind: external_exports.literal(SESSION_EVENT_V2_KIND) }).readonly();
21566
+ var sessionEventLogPageV2Schema = external_exports.strictObject({
21567
+ events: external_exports.array(sessionEventV2Schema).max(MAX_EVENT_COUNT).readonly(),
21568
+ nextCursor: external_exports.string().min(1).max(512).nullable(),
21569
+ tailCursor: external_exports.string().max(512),
21570
+ truncated: external_exports.boolean(),
21571
+ version: external_exports.literal(2)
21293
21572
  }).readonly();
21294
- var eventRejectedSchema = external_exports.strictObject({
21295
- code: external_exports.enum(SessionEventRejectionCode),
21296
- eventId: identifierStringSchema,
21297
- kind: external_exports.literal(SESSION_EVENT_REJECTED_KIND),
21573
+ var nativeEventPageRequestV2Schema = external_exports.strictObject({ cursor: external_exports.string().min(1).max(512).nullable(), eventLimit: external_exports.number().int().min(1).max(1e4) }).readonly();
21574
+ var executingPromptRequestEventLogV2Schema = external_exports.strictObject({
21575
+ attemptId: identifierStringSchema,
21576
+ commandId: identifierStringSchema,
21577
+ epoch: identifierStringSchema,
21578
+ events: external_exports.array(sessionEventV2Schema).max(MAX_EVENT_COUNT).readonly(),
21579
+ tailCursor: external_exports.string().max(512),
21580
+ truncated: external_exports.boolean()
21581
+ }).readonly();
21582
+ var nativeSessionEventsV2Schema = external_exports.strictObject({
21583
+ executingPromptRequest: executingPromptRequestEventLogV2Schema.nullable(),
21584
+ history: sessionEventLogPageV2Schema
21585
+ }).readonly();
21586
+ function inputValue(value) {
21587
+ if (typeof value !== "string") {
21588
+ return value;
21589
+ }
21590
+ try {
21591
+ return JSON.parse(value);
21592
+ } catch (cause) {
21593
+ throw new ProtocolMessageError("Session Event Log V2 message is not valid JSON", { cause });
21594
+ }
21595
+ }
21596
+ function decode5(value, schema) {
21597
+ const result = schema.safeParse(inputValue(value));
21598
+ if (!result.success) {
21599
+ throw new ProtocolMessageError("Session Event Log V2 message does not match its schema", {
21600
+ cause: result.error
21601
+ });
21602
+ }
21603
+ return result.data;
21604
+ }
21605
+ function encode4(value, schema) {
21606
+ return JSON.stringify(decode5(value, schema));
21607
+ }
21608
+ var decodeSessionEventV2 = (value) => decode5(value, sessionEventV2Schema);
21609
+ var decodeSessionEventEnvelopeV2 = (value) => decode5(value, sessionEventEnvelopeV2Schema);
21610
+ var encodeSessionEventEnvelopeV2 = (value) => encode4(value, sessionEventEnvelopeV2Schema);
21611
+ var decodeAcpSessionUpdateV2 = (value) => decode5(value, acpSessionUpdateV2Schema);
21612
+
21613
+ // ../protocol/src/session-events.ts
21614
+ var SESSION_EVENT_KIND = "session.event";
21615
+ var SESSION_FORKED_KIND = "session.forked";
21616
+ var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
21617
+ var sessionEventEnvelopeSchema = external_exports.strictObject({
21618
+ kind: external_exports.literal(SESSION_EVENT_KIND),
21619
+ payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21298
21620
  sessionId: identifierStringSchema
21299
21621
  }).readonly();
21300
21622
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
@@ -21305,7 +21627,7 @@ var sessionForkedSchema = external_exports.strictObject({
21305
21627
  sourceSessionId: identifierStringSchema,
21306
21628
  throughCommandId: identifierStringSchema
21307
21629
  }).readonly();
21308
- function decode5(encoded, schema) {
21630
+ function decode6(encoded, schema) {
21309
21631
  let value;
21310
21632
  try {
21311
21633
  value = JSON.parse(encoded);
@@ -21320,7 +21642,7 @@ function decode5(encoded, schema) {
21320
21642
  }
21321
21643
  return decoded.data;
21322
21644
  }
21323
- var encode4 = (message, schema) => {
21645
+ var encode5 = (message, schema) => {
21324
21646
  const decoded = schema.safeParse(message);
21325
21647
  if (!decoded.success) {
21326
21648
  throw new ProtocolMessageError("Message does not match its schema", {
@@ -21329,21 +21651,15 @@ var encode4 = (message, schema) => {
21329
21651
  }
21330
21652
  return JSON.stringify(decoded.data);
21331
21653
  };
21332
- var decodeSessionEventEnvelope = (encoded) => decode5(encoded, eventEnvelopeSchema);
21333
- var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSchema);
21334
- var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAcknowledgementSchema);
21335
- var encodeSessionEventAcknowledgement = (message) => encode4(message, eventAcknowledgementSchema);
21336
- var decodeSessionEventDeferred = (encoded) => decode5(encoded, eventDeferredSchema);
21337
- var encodeSessionEventDeferred = (message) => encode4(message, eventDeferredSchema);
21338
- var decodeSessionEventRejected = (encoded) => decode5(encoded, eventRejectedSchema);
21339
- var encodeSessionEventRejected = (message) => encode4(message, eventRejectedSchema);
21654
+ var decodeSessionEventEnvelope = (encoded) => decode6(encoded, sessionEventEnvelopeSchema);
21655
+ var encodeSessionEventEnvelope = (message) => encode5(message, sessionEventEnvelopeSchema);
21340
21656
  function decodeRecordedSessionEvent(encoded) {
21341
21657
  const kind = decodeMessageKind(encoded);
21342
21658
  switch (kind) {
21343
21659
  case SESSION_QUEUE_CHANGED_KIND:
21344
- return decode5(encoded, sessionQueueChangedSchema);
21660
+ return decode6(encoded, sessionQueueChangedSchema);
21345
21661
  case SESSION_FORKED_KIND:
21346
- return decode5(encoded, sessionForkedSchema);
21662
+ return decode6(encoded, sessionForkedSchema);
21347
21663
  case AGENT_ACTIVITY_KIND:
21348
21664
  return decodeAgentActivityEvent(encoded);
21349
21665
  case AGENT_ACTIVITY_NARRATION_KIND:
@@ -21387,6 +21703,8 @@ var SESSION_LIVE_HISTORY_LOAD_KIND = "session.live-history.load";
21387
21703
  var SESSION_LIVE_HISTORY_LOADED_KIND = "session.live-history.loaded";
21388
21704
  var SESSION_LIVE_HISTORY_PAGE_LOAD_KIND = "session.live-history.page.load";
21389
21705
  var SESSION_LIVE_HISTORY_PAGE_LOADED_KIND = "session.live-history.page.loaded";
21706
+ var SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND = "session.live-history.v2.page.load";
21707
+ var SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND = "session.live-history.v2.page.loaded";
21390
21708
  var directoryIdentifier = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/);
21391
21709
  var sessionLiveHistoryLoadSchema = external_exports.strictObject({
21392
21710
  additionalDirectoryIds: external_exports.array(directoryIdentifier).max(16).readonly(),
@@ -21420,7 +21738,24 @@ var sessionLiveHistoryPageLoadedSchema = external_exports.strictObject({
21420
21738
  requestId: identifierStringSchema,
21421
21739
  sessionId: identifierStringSchema
21422
21740
  }).readonly();
21423
- function decode6(schema, encoded) {
21741
+ var sessionLiveHistoryV2PageLoadSchema = external_exports.strictObject({
21742
+ additionalDirectoryIds: external_exports.array(directoryIdentifier).max(16).readonly(),
21743
+ agentId: identifierStringSchema,
21744
+ bindingId: identifierStringSchema,
21745
+ cursor: external_exports.string().min(1).max(512).nullable(),
21746
+ directoryId: directoryIdentifier,
21747
+ kind: external_exports.literal(SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND),
21748
+ eventLimit: external_exports.number().int().min(1).max(1e4),
21749
+ requestId: identifierStringSchema,
21750
+ sessionId: identifierStringSchema
21751
+ }).readonly();
21752
+ var sessionLiveHistoryV2PageLoadedSchema = external_exports.strictObject({
21753
+ events: nativeSessionEventsV2Schema,
21754
+ kind: external_exports.literal(SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND),
21755
+ requestId: identifierStringSchema,
21756
+ sessionId: identifierStringSchema
21757
+ }).readonly();
21758
+ function decode7(schema, encoded) {
21424
21759
  try {
21425
21760
  const value = JSON.parse(encoded);
21426
21761
  return schema.parse(value);
@@ -21428,14 +21763,18 @@ function decode6(schema, encoded) {
21428
21763
  throw new ProtocolMessageError("Invalid live Session history message", { cause });
21429
21764
  }
21430
21765
  }
21431
- var decodeSessionLiveHistoryLoad = (encoded) => decode6(sessionLiveHistoryLoadSchema, encoded);
21432
- var decodeSessionLiveHistoryLoaded = (encoded) => decode6(sessionLiveHistoryLoadedSchema, encoded);
21766
+ var decodeSessionLiveHistoryLoad = (encoded) => decode7(sessionLiveHistoryLoadSchema, encoded);
21767
+ var decodeSessionLiveHistoryLoaded = (encoded) => decode7(sessionLiveHistoryLoadedSchema, encoded);
21433
21768
  var encodeSessionLiveHistoryLoad = (value) => JSON.stringify(sessionLiveHistoryLoadSchema.parse(value));
21434
21769
  var encodeSessionLiveHistoryLoaded = (value) => JSON.stringify(sessionLiveHistoryLoadedSchema.parse(value));
21435
- var decodeSessionLiveHistoryPageLoad = (encoded) => decode6(sessionLiveHistoryPageLoadSchema, encoded);
21436
- var decodeSessionLiveHistoryPageLoaded = (encoded) => decode6(sessionLiveHistoryPageLoadedSchema, encoded);
21770
+ var decodeSessionLiveHistoryPageLoad = (encoded) => decode7(sessionLiveHistoryPageLoadSchema, encoded);
21771
+ var decodeSessionLiveHistoryPageLoaded = (encoded) => decode7(sessionLiveHistoryPageLoadedSchema, encoded);
21437
21772
  var encodeSessionLiveHistoryPageLoad = (value) => JSON.stringify(sessionLiveHistoryPageLoadSchema.parse(value));
21438
21773
  var encodeSessionLiveHistoryPageLoaded = (value) => JSON.stringify(sessionLiveHistoryPageLoadedSchema.parse(value));
21774
+ var decodeSessionLiveHistoryV2PageLoad = (encoded) => decode7(sessionLiveHistoryV2PageLoadSchema, encoded);
21775
+ var decodeSessionLiveHistoryV2PageLoaded = (encoded) => decode7(sessionLiveHistoryV2PageLoadedSchema, encoded);
21776
+ var encodeSessionLiveHistoryV2PageLoad = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadSchema.parse(value));
21777
+ var encodeSessionLiveHistoryV2PageLoaded = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadedSchema.parse(value));
21439
21778
 
21440
21779
  // ../protocol/src/daemon-transport.ts
21441
21780
  function defineMessageSignature(kind, encoder, decoder) {
@@ -21510,21 +21849,6 @@ var serviceToDaemonSignatures = {
21510
21849
  encodeSessionElicitationRespondCommand,
21511
21850
  decodeSessionElicitationRespondCommand
21512
21851
  ),
21513
- [SESSION_EVENT_ACK_KIND]: defineMessageSignature(
21514
- SESSION_EVENT_ACK_KIND,
21515
- encodeSessionEventAcknowledgement,
21516
- decodeSessionEventAcknowledgement
21517
- ),
21518
- [SESSION_EVENT_DEFERRED_KIND]: defineMessageSignature(
21519
- SESSION_EVENT_DEFERRED_KIND,
21520
- encodeSessionEventDeferred,
21521
- decodeSessionEventDeferred
21522
- ),
21523
- [SESSION_EVENT_REJECTED_KIND]: defineMessageSignature(
21524
- SESSION_EVENT_REJECTED_KIND,
21525
- encodeSessionEventRejected,
21526
- decodeSessionEventRejected
21527
- ),
21528
21852
  [SESSION_LIVE_HISTORY_LOAD_KIND]: defineMessageSignature(
21529
21853
  SESSION_LIVE_HISTORY_LOAD_KIND,
21530
21854
  encodeSessionLiveHistoryLoad,
@@ -21535,6 +21859,11 @@ var serviceToDaemonSignatures = {
21535
21859
  encodeSessionLiveHistoryPageLoad,
21536
21860
  decodeSessionLiveHistoryPageLoad
21537
21861
  ),
21862
+ [SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND]: defineMessageSignature(
21863
+ SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND,
21864
+ encodeSessionLiveHistoryV2PageLoad,
21865
+ decodeSessionLiveHistoryV2PageLoad
21866
+ ),
21538
21867
  [SESSION_PERMISSION_RESPOND_KIND]: defineMessageSignature(
21539
21868
  SESSION_PERMISSION_RESPOND_KIND,
21540
21869
  encodeSessionPermissionRespondCommand,
@@ -21650,6 +21979,11 @@ var daemonToServiceSignatures = {
21650
21979
  encodeSessionEventEnvelope,
21651
21980
  decodeSessionEventEnvelope
21652
21981
  ),
21982
+ [SESSION_EVENT_V2_KIND]: defineMessageSignature(
21983
+ SESSION_EVENT_V2_KIND,
21984
+ encodeSessionEventEnvelopeV2,
21985
+ decodeSessionEventEnvelopeV2
21986
+ ),
21653
21987
  [SESSION_OPERATION_FAILED_KIND]: defineMessageSignature(
21654
21988
  SESSION_OPERATION_FAILED_KIND,
21655
21989
  encodeSessionOperationFailedEvent,
@@ -21665,6 +21999,11 @@ var daemonToServiceSignatures = {
21665
21999
  encodeSessionLiveHistoryPageLoaded,
21666
22000
  decodeSessionLiveHistoryPageLoaded
21667
22001
  ),
22002
+ [SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND]: defineMessageSignature(
22003
+ SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND,
22004
+ encodeSessionLiveHistoryV2PageLoaded,
22005
+ decodeSessionLiveHistoryV2PageLoaded
22006
+ ),
21668
22007
  [SESSION_READY_KIND]: defineMessageSignature(SESSION_READY_KIND, encodeSessionReadyEvent, decodeSessionReadyEvent),
21669
22008
  [WORKSPACE_ENTRIES_KIND]: defineMessageSignature(
21670
22009
  WORKSPACE_ENTRIES_KIND,
@@ -22654,7 +22993,7 @@ function startsWith(bytes, signature, offset = 0) {
22654
22993
  if (bytes.byteLength < offset + signature.byteLength) {
22655
22994
  return false;
22656
22995
  }
22657
- return signature.every((value, index) => bytes[offset + index] === value);
22996
+ return signature.every((value, index2) => bytes[offset + index2] === value);
22658
22997
  }
22659
22998
  function sniffRasterMime(bytes) {
22660
22999
  if (startsWith(bytes, PNG_SIGNATURE)) {
@@ -22782,7 +23121,7 @@ function startsWith2(bytes, signature, offset = 0) {
22782
23121
  if (bytes.byteLength < offset + signature.byteLength) {
22783
23122
  return false;
22784
23123
  }
22785
- return signature.every((value, index) => bytes[offset + index] === value);
23124
+ return signature.every((value, index2) => bytes[offset + index2] === value);
22786
23125
  }
22787
23126
  function sniffVideoMime(bytes) {
22788
23127
  if (startsWith2(bytes, MP4_FILE_TYPE, 4)) {
@@ -22911,10 +23250,10 @@ async function replaceImageMarkers(text2, replace) {
22911
23250
  let cursor = 0;
22912
23251
  let rewritten = "";
22913
23252
  for (const match of matches) {
22914
- const index = match.index ?? 0;
22915
- rewritten += text2.slice(cursor, index);
23253
+ const index2 = match.index ?? 0;
23254
+ rewritten += text2.slice(cursor, index2);
22916
23255
  rewritten += await replace(match[1] ?? "");
22917
- cursor = index + match[0].length;
23256
+ cursor = index2 + match[0].length;
22918
23257
  }
22919
23258
  return `${rewritten}${text2.slice(cursor)}`;
22920
23259
  }
@@ -24107,6 +24446,7 @@ function sessionConfigProtocolForAgent(_agentId) {
24107
24446
 
24108
24447
  // src/acp/session-contracts.ts
24109
24448
  var NullAcpSessionObserver = class {
24449
+ onAcpUpdate = (_sessionId, _update) => Promise.resolve();
24110
24450
  onCommands = () => Promise.resolve();
24111
24451
  onConfig = () => Promise.resolve();
24112
24452
  onContent = () => Promise.resolve();
@@ -24231,6 +24571,7 @@ function historyContentCharacters(messages) {
24231
24571
  var AcpHistoryReplay = class {
24232
24572
  #activities = /* @__PURE__ */ new Map();
24233
24573
  #messages = [];
24574
+ #updates = [];
24234
24575
  #turnActivityIds = /* @__PURE__ */ new Set();
24235
24576
  #activityTracker = new AcpActivityTracker(
24236
24577
  async (activity2) => {
@@ -24252,7 +24593,8 @@ var AcpHistoryReplay = class {
24252
24593
  #firstMessageIndex = 0;
24253
24594
  #characters = 0;
24254
24595
  #truncated = false;
24255
- record = async (update) => {
24596
+ record = async (update, rawUpdate) => {
24597
+ this.#updates.push(rawUpdate);
24256
24598
  if (update.sessionUpdate === "agent_thought_chunk") {
24257
24599
  if (update.content.type === "text") {
24258
24600
  await this.#activityTracker.recordNarrative(
@@ -24333,6 +24675,20 @@ var AcpHistoryReplay = class {
24333
24675
  this.#lastMessageId = id;
24334
24676
  this.trimMessages();
24335
24677
  };
24678
+ eventPage = (eventLimit, cursor) => {
24679
+ const parsedCursor = cursor === null ? this.#updates.length : Number(cursor);
24680
+ if (!Number.isSafeInteger(parsedCursor) || parsedCursor < 0 || parsedCursor > this.#updates.length) {
24681
+ throw new Error("The native event cursor is invalid");
24682
+ }
24683
+ const endUpdate = parsedCursor;
24684
+ const startUpdate = Math.max(0, endUpdate - eventLimit);
24685
+ return {
24686
+ nextCursor: startUpdate === 0 ? null : startUpdate.toString(),
24687
+ startPosition: startUpdate + 1,
24688
+ truncated: startUpdate > 0,
24689
+ updates: this.#updates.slice(startUpdate, endUpdate)
24690
+ };
24691
+ };
24336
24692
  snapshot = async () => {
24337
24693
  await this.#activityTracker.finish();
24338
24694
  const messages = this.#messages.slice(this.#firstMessageIndex).map((message) => {
@@ -26320,8 +26676,8 @@ function haveSameKeys(left, right) {
26320
26676
  if (leftKeys.length !== rightKeys.length) {
26321
26677
  return false;
26322
26678
  }
26323
- for (const [index, key] of leftKeys.entries()) {
26324
- if (key !== rightKeys[index]) {
26679
+ for (const [index2, key] of leftKeys.entries()) {
26680
+ if (key !== rightKeys[index2]) {
26325
26681
  return false;
26326
26682
  }
26327
26683
  }
@@ -27509,6 +27865,55 @@ var sqliteTable = (name, columns, extraConfig) => {
27509
27865
  return sqliteTableBase(name, columns, extraConfig);
27510
27866
  };
27511
27867
 
27868
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@5.20260918.1_@types+better-sqlite3@7.6.13_better-sqlite3@12.4.1/node_modules/drizzle-orm/sqlite-core/indexes.js
27869
+ var IndexBuilderOn = class {
27870
+ constructor(name, unique) {
27871
+ this.name = name;
27872
+ this.unique = unique;
27873
+ }
27874
+ static [entityKind] = "SQLiteIndexBuilderOn";
27875
+ on(...columns) {
27876
+ return new IndexBuilder(this.name, columns, this.unique);
27877
+ }
27878
+ };
27879
+ var IndexBuilder = class {
27880
+ static [entityKind] = "SQLiteIndexBuilder";
27881
+ /** @internal */
27882
+ config;
27883
+ constructor(name, columns, unique) {
27884
+ this.config = {
27885
+ name,
27886
+ columns,
27887
+ unique,
27888
+ where: void 0
27889
+ };
27890
+ }
27891
+ /**
27892
+ * Condition for partial index.
27893
+ */
27894
+ where(condition) {
27895
+ this.config.where = condition;
27896
+ return this;
27897
+ }
27898
+ /** @internal */
27899
+ build(table) {
27900
+ return new Index(this.config, table);
27901
+ }
27902
+ };
27903
+ var Index = class {
27904
+ static [entityKind] = "SQLiteIndex";
27905
+ config;
27906
+ constructor(config2, table) {
27907
+ this.config = { ...config2, table };
27908
+ }
27909
+ };
27910
+ function index(name) {
27911
+ return new IndexBuilderOn(name, false);
27912
+ }
27913
+ function uniqueIndex(name) {
27914
+ return new IndexBuilderOn(name, true);
27915
+ }
27916
+
27512
27917
  // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@5.20260918.1_@types+better-sqlite3@7.6.13_better-sqlite3@12.4.1/node_modules/drizzle-orm/sqlite-core/utils.js
27513
27918
  function extractUsedTable(table) {
27514
27919
  if (is(table, SQLiteTable)) {
@@ -27857,8 +28262,8 @@ var SQLiteDialect = class {
27857
28262
  }
27858
28263
  const joinsArray = [];
27859
28264
  if (joins) {
27860
- for (const [index, joinMeta] of joins.entries()) {
27861
- if (index === 0) {
28265
+ for (const [index2, joinMeta] of joins.entries()) {
28266
+ if (index2 === 0) {
27862
28267
  joinsArray.push(sql` `);
27863
28268
  }
27864
28269
  const table = joinMeta.table;
@@ -27878,7 +28283,7 @@ var SQLiteDialect = class {
27878
28283
  sql`${sql.raw(joinMeta.joinType)} join ${table}${onSql}`
27879
28284
  );
27880
28285
  }
27881
- if (index < joins.length - 1) {
28286
+ if (index2 < joins.length - 1) {
27882
28287
  joinsArray.push(sql` `);
27883
28288
  }
27884
28289
  }
@@ -27891,9 +28296,9 @@ var SQLiteDialect = class {
27891
28296
  buildOrderBy(orderBy) {
27892
28297
  const orderByList = [];
27893
28298
  if (orderBy) {
27894
- for (const [index, orderByValue] of orderBy.entries()) {
28299
+ for (const [index2, orderByValue] of orderBy.entries()) {
27895
28300
  orderByList.push(orderByValue);
27896
- if (index < orderBy.length - 1) {
28301
+ if (index2 < orderBy.length - 1) {
27897
28302
  orderByList.push(sql`, `);
27898
28303
  }
27899
28304
  }
@@ -27946,9 +28351,9 @@ var SQLiteDialect = class {
27946
28351
  const havingSql = having ? sql` having ${having}` : void 0;
27947
28352
  const groupByList = [];
27948
28353
  if (groupBy) {
27949
- for (const [index, groupByValue] of groupBy.entries()) {
28354
+ for (const [index2, groupByValue] of groupBy.entries()) {
27950
28355
  groupByList.push(groupByValue);
27951
- if (index < groupBy.length - 1) {
28356
+ if (index2 < groupBy.length - 1) {
27952
28357
  groupByList.push(sql`, `);
27953
28358
  }
27954
28359
  }
@@ -30362,6 +30767,10 @@ var acpSessionStoreMigrations = [
30362
30767
  {
30363
30768
  "name": "0001_regular_ultimates.sql",
30364
30769
  "sql": "ALTER TABLE `acp_session` ADD `last_terminal_command_id` text;"
30770
+ },
30771
+ {
30772
+ "name": "0002_equal_black_queen.sql",
30773
+ "sql": "CREATE TABLE `session_event_v2` (\n `event_id` text PRIMARY KEY NOT NULL,\n `event_json` text NOT NULL,\n `position` integer NOT NULL,\n `session_id` text NOT NULL\n);\n--> statement-breakpoint\nCREATE UNIQUE INDEX `session_event_v2_session_position_unique` ON `session_event_v2` (`session_id`,`position`);--> statement-breakpoint\nCREATE INDEX `session_event_v2_session_position_index` ON `session_event_v2` (`session_id`,`position`);"
30365
30774
  }
30366
30775
  ];
30367
30776
 
@@ -30369,7 +30778,8 @@ var acpSessionStoreMigrations = [
30369
30778
  var acp_session_store_exports = {};
30370
30779
  __export(acp_session_store_exports, {
30371
30780
  acpSession: () => acpSession,
30372
- deletedAcpSession: () => deletedAcpSession
30781
+ deletedAcpSession: () => deletedAcpSession,
30782
+ sessionEventV2: () => sessionEventV2
30373
30783
  });
30374
30784
 
30375
30785
  // src/schema/acp-session-store/acp-session.ts
@@ -30390,6 +30800,21 @@ var deletedAcpSession = sqliteTable("deleted_acp_session", {
30390
30800
  sessionId: text("session_id").primaryKey()
30391
30801
  });
30392
30802
 
30803
+ // src/schema/acp-session-store/session-event-v2.ts
30804
+ var sessionEventV2 = sqliteTable(
30805
+ "session_event_v2",
30806
+ {
30807
+ eventId: text("event_id").primaryKey(),
30808
+ eventJson: text("event_json").notNull(),
30809
+ position: integer2("position").notNull(),
30810
+ sessionId: text("session_id").notNull()
30811
+ },
30812
+ (table) => [
30813
+ uniqueIndex("session_event_v2_session_position_unique").on(table.sessionId, table.position),
30814
+ index("session_event_v2_session_position_index").on(table.sessionId, table.position)
30815
+ ]
30816
+ );
30817
+
30393
30818
  // src/acp/session-store.ts
30394
30819
  var AcpStoredSession = class {
30395
30820
  additionalDirectories;
@@ -30432,9 +30857,14 @@ var DeletedAcpStoredSession = class extends AcpStoredSessionLookup {
30432
30857
  var MemoryAcpSessionStore = class {
30433
30858
  #sessions = /* @__PURE__ */ new Map();
30434
30859
  #deleted = /* @__PURE__ */ new Set();
30860
+ #eventsV2 = /* @__PURE__ */ new Map();
30861
+ appendEventV2 = (event) => {
30862
+ this.#eventsV2.set(event.sessionId, [...this.#eventsV2.get(event.sessionId) ?? [], event]);
30863
+ };
30435
30864
  close = () => {
30436
30865
  this.#sessions.clear();
30437
30866
  this.#deleted.clear();
30867
+ this.#eventsV2.clear();
30438
30868
  };
30439
30869
  findNative = (agentId, nativeSessionId) => [...this.#sessions.values()].filter(
30440
30870
  (session) => session.agentId === agentId && session.nativeSessionId === nativeSessionId
@@ -30445,6 +30875,7 @@ var MemoryAcpSessionStore = class {
30445
30875
  for (const id of ids) {
30446
30876
  this.#sessions.delete(id);
30447
30877
  this.#deleted.add(id);
30878
+ this.#eventsV2.delete(id);
30448
30879
  }
30449
30880
  return ids;
30450
30881
  };
@@ -30457,7 +30888,9 @@ var MemoryAcpSessionStore = class {
30457
30888
  };
30458
30889
  remove = (sessionId) => {
30459
30890
  this.#sessions.delete(sessionId);
30891
+ this.#eventsV2.delete(sessionId);
30460
30892
  };
30893
+ readEventsV2 = (sessionId) => this.#eventsV2.get(sessionId) ?? [];
30461
30894
  write = (session) => {
30462
30895
  this.#sessions.set(session.sessionId, session);
30463
30896
  };
@@ -30506,15 +30939,15 @@ var SqliteAcpSessionStore = class {
30506
30939
  this.#sqliteDatabase.close();
30507
30940
  throw new Error("The ACP Session database was created by a newer Mobius version");
30508
30941
  }
30509
- for (let index = version3; index < acpSessionStoreMigrations.length; index += 1) {
30510
- const migration = acpSessionStoreMigrations[index];
30942
+ for (let index2 = version3; index2 < acpSessionStoreMigrations.length; index2 += 1) {
30943
+ const migration = acpSessionStoreMigrations[index2];
30511
30944
  if (migration === void 0) {
30512
30945
  throw new Error("The ACP Session migration is unavailable");
30513
30946
  }
30514
30947
  this.#sqliteDatabase.exec("BEGIN IMMEDIATE");
30515
30948
  try {
30516
30949
  this.#sqliteDatabase.exec(migration.sql);
30517
- this.#sqliteDatabase.pragma(`user_version = ${index + 1}`);
30950
+ this.#sqliteDatabase.pragma(`user_version = ${index2 + 1}`);
30518
30951
  this.#sqliteDatabase.exec("COMMIT");
30519
30952
  } catch (error62) {
30520
30953
  this.#sqliteDatabase.exec("ROLLBACK");
@@ -30525,6 +30958,14 @@ var SqliteAcpSessionStore = class {
30525
30958
  close = () => {
30526
30959
  this.#sqliteDatabase.close();
30527
30960
  };
30961
+ appendEventV2 = (event) => {
30962
+ this.#database.insert(sessionEventV2).values({
30963
+ eventId: event.eventId,
30964
+ eventJson: JSON.stringify(event),
30965
+ position: Number(event.position),
30966
+ sessionId: event.sessionId
30967
+ }).run();
30968
+ };
30528
30969
  findNative = (agentId, nativeSessionId) => this.#database.select().from(acpSession).where(and(eq(acpSession.agentId, agentId), eq(acpSession.nativeSessionId, nativeSessionId))).all().map(decodeStoredSession);
30529
30970
  list = () => this.#database.select().from(acpSession).orderBy(desc(acpSession.updatedAt)).all().map(decodeStoredSession);
30530
30971
  markDeleted = (agentId, nativeSessionId) => {
@@ -30533,6 +30974,7 @@ var SqliteAcpSessionStore = class {
30533
30974
  transaction.delete(acpSession).where(and(eq(acpSession.agentId, agentId), eq(acpSession.nativeSessionId, nativeSessionId))).run();
30534
30975
  for (const id of ids) {
30535
30976
  transaction.insert(deletedAcpSession).values({ sessionId: id }).onConflictDoNothing().run();
30977
+ transaction.delete(sessionEventV2).where(eq(sessionEventV2.sessionId, id)).run();
30536
30978
  }
30537
30979
  });
30538
30980
  return ids;
@@ -30546,8 +30988,12 @@ var SqliteAcpSessionStore = class {
30546
30988
  const row = this.#database.select().from(acpSession).where(eq(acpSession.sessionId, sessionId)).get();
30547
30989
  return row === void 0 ? new MissingAcpStoredSession() : new FoundAcpStoredSession(decodeStoredSession(row));
30548
30990
  };
30991
+ readEventsV2 = (sessionId) => this.#database.select({ eventJson: sessionEventV2.eventJson }).from(sessionEventV2).where(eq(sessionEventV2.sessionId, sessionId)).orderBy(asc(sessionEventV2.position)).all().map((row) => decodeSessionEventV2(row.eventJson));
30549
30992
  remove = (sessionId) => {
30550
- this.#database.delete(acpSession).where(eq(acpSession.sessionId, sessionId)).run();
30993
+ this.#database.transaction((transaction) => {
30994
+ transaction.delete(acpSession).where(eq(acpSession.sessionId, sessionId)).run();
30995
+ transaction.delete(sessionEventV2).where(eq(sessionEventV2.sessionId, sessionId)).run();
30996
+ });
30551
30997
  };
30552
30998
  write = (session) => {
30553
30999
  const value = {
@@ -30580,7 +31026,7 @@ var RetryableAcpInitializationError = class extends AcpExecutionError {
30580
31026
  }
30581
31027
  };
30582
31028
  function arraysEqual(left, right) {
30583
- return left.length === right.length && left.every((value, index) => value === right[index]);
31029
+ return left.length === right.length && left.every((value, index2) => value === right[index2]);
30584
31030
  }
30585
31031
  function recordsEqual(left, right) {
30586
31032
  const leftEntries = Object.entries(left);
@@ -30727,6 +31173,17 @@ var AgentSession = class _AgentSession {
30727
31173
  const loaded = await this.#loadSession(signal, "ACP agent exited while loading history");
30728
31174
  return await embedLocalHistoryImages(await loaded.history.snapshot(), signal);
30729
31175
  };
31176
+ loadHistoryEventsV2 = async (eventLimit, cursor, signal) => {
31177
+ if (!this.#capabilities.loadSession) {
31178
+ throw new AcpExecutionError(
31179
+ "This Agent restores context but does not provide message history.",
31180
+ {},
31181
+ "native_history_unsupported"
31182
+ );
31183
+ }
31184
+ const loaded = await this.#loadSession(signal, "ACP agent exited while loading history");
31185
+ return loaded.history.eventPage(eventLimit, cursor);
31186
+ };
30730
31187
  async #loadSession(signal, exitMessage) {
30731
31188
  if (this.#sessionLoad.kind === "loaded") {
30732
31189
  return this.#sessionLoad;
@@ -31373,8 +31830,14 @@ var AgentSession = class _AgentSession {
31373
31830
  #processUpdate = async (notification) => {
31374
31831
  this.assertNativeSession(notification.sessionId);
31375
31832
  const update = notification.update;
31833
+ const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(update));
31376
31834
  if (this.#sessionLoad.kind !== "not-requested") {
31377
- await this.#sessionLoad.history.record(update);
31835
+ await this.#sessionLoad.history.record(update, rawUpdate);
31836
+ } else {
31837
+ const onAcpUpdate = this.#getObserver().onAcpUpdate;
31838
+ if (onAcpUpdate !== void 0) {
31839
+ await onAcpUpdate(this.#mobiusSessionId, rawUpdate);
31840
+ }
31378
31841
  }
31379
31842
  if (this.#sessionLoad.kind === "capturing" && (update.sessionUpdate === "user_message_chunk" || update.sessionUpdate === "agent_message_chunk" || update.sessionUpdate === "agent_thought_chunk" || update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update" || update.sessionUpdate === "plan" || update.sessionUpdate === "plan_update" || update.sessionUpdate === "plan_removed")) {
31380
31843
  return;
@@ -31756,6 +32219,21 @@ var AgentQueryProcesses = class {
31756
32219
  async (runtime) => await runtime.closeProcess()
31757
32220
  );
31758
32221
  };
32222
+ previewEventsV2 = async (options, nativeSessionId, eventLimit, cursor) => {
32223
+ return await this.#processes.runTransient(
32224
+ options.signal,
32225
+ async () => await AgentSession.startNativeSessionBrowser(
32226
+ options,
32227
+ () => this.#observer,
32228
+ new MemoryAcpSessionStore()
32229
+ ),
32230
+ async (runtime) => {
32231
+ runtime.selectNativeSession(nativeSessionId);
32232
+ return await runtime.loadHistoryEventsV2(eventLimit, cursor, options.signal);
32233
+ },
32234
+ async (runtime) => await runtime.closeProcess()
32235
+ );
32236
+ };
31759
32237
  close = async () => {
31760
32238
  await Promise.all(
31761
32239
  this.#processesByQuery.entries().map(async ([id, runtime]) => await this.retire(id, runtime))
@@ -31825,9 +32303,9 @@ var AcpProcessCapacityLock = class {
31825
32303
  return await waiter.completion.promise;
31826
32304
  } finally {
31827
32305
  signal.removeEventListener("abort", waiter.cancel);
31828
- const index = this.#waiters.indexOf(waiter);
31829
- if (index >= 0) {
31830
- this.#waiters.splice(index, 1);
32306
+ const index2 = this.#waiters.indexOf(waiter);
32307
+ if (index2 >= 0) {
32308
+ this.#waiters.splice(index2, 1);
31831
32309
  }
31832
32310
  }
31833
32311
  };
@@ -32457,6 +32935,22 @@ var AgentRuntimeManager = class {
32457
32935
  this.#nativeOperations.delete(key);
32458
32936
  }
32459
32937
  });
32938
+ previewNativeSessionEventsV2 = async (options, nativeSessionId, eventLimit, cursor) => this.#operations.run(options, async (options2) => {
32939
+ const key = `${options2.agent.id}:${nativeSessionId}`;
32940
+ if (this.#nativeOperations.has(key)) {
32941
+ throw new AcpExecutionError(
32942
+ "Wait for the native session's running operation to finish",
32943
+ {},
32944
+ "session_busy"
32945
+ );
32946
+ }
32947
+ this.#nativeOperations.add(key);
32948
+ try {
32949
+ return await this.#queryProcesses.previewEventsV2(options2, nativeSessionId, eventLimit, cursor);
32950
+ } finally {
32951
+ this.#nativeOperations.delete(key);
32952
+ }
32953
+ });
32460
32954
  loadSessionHistory = async (options) => this.#operations.run(options, async (options2) => {
32461
32955
  return await this.#executionProcesses.use(options2.sessionId, async () => {
32462
32956
  const runtime = await this.ensureSession(options2);
@@ -32474,6 +32968,12 @@ var AgentRuntimeManager = class {
32474
32968
  return await runtime.loadHistory(options2.signal);
32475
32969
  });
32476
32970
  });
32971
+ loadSessionEventsV2 = async (options, eventLimit, cursor) => this.#operations.run(options, async (options2) => {
32972
+ return await this.#executionProcesses.use(options2.sessionId, async () => {
32973
+ const runtime = await this.ensureSession(options2);
32974
+ return await runtime.loadHistoryEventsV2(eventLimit, cursor, options2.signal);
32975
+ });
32976
+ });
32477
32977
  openNativeSession = async (options, origin) => this.#operations.run(options, async (options2) => {
32478
32978
  const key = `${options2.agent.id}:${origin.nativeSessionId}`;
32479
32979
  if (this.#nativeOperations.has(key)) {
@@ -36376,9 +36876,9 @@ function comparePrerelease(left, right) {
36376
36876
  if (left.length === 0 || right.length === 0) {
36377
36877
  return left.length === right.length ? 0 : left.length === 0 ? 1 : -1;
36378
36878
  }
36379
- for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
36380
- const leftPart = left[index];
36381
- const rightPart = right[index];
36879
+ for (let index2 = 0; index2 < Math.max(left.length, right.length); index2 += 1) {
36880
+ const leftPart = left[index2];
36881
+ const rightPart = right[index2];
36382
36882
  if (leftPart === void 0 || rightPart === void 0) {
36383
36883
  return leftPart === rightPart ? 0 : leftPart === void 0 ? -1 : 1;
36384
36884
  }
@@ -36403,8 +36903,8 @@ function compareAgentVersions(left, right) {
36403
36903
  if (parsedLeft === null || parsedRight === null) {
36404
36904
  return null;
36405
36905
  }
36406
- for (let index = 0; index < Math.max(parsedLeft.core.length, parsedRight.core.length); index += 1) {
36407
- const difference = (parsedLeft.core[index] ?? 0) - (parsedRight.core[index] ?? 0);
36906
+ for (let index2 = 0; index2 < Math.max(parsedLeft.core.length, parsedRight.core.length); index2 += 1) {
36907
+ const difference = (parsedLeft.core[index2] ?? 0) - (parsedRight.core[index2] ?? 0);
36408
36908
  if (difference !== 0) {
36409
36909
  return Math.sign(difference);
36410
36910
  }
@@ -37147,16 +37647,16 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37147
37647
  };
37148
37648
  #readConnectionForChannel = async (channelId, signal) => {
37149
37649
  const normalizedChannelId = validateIdentifier(channelId, "invalid_channel_id");
37150
- const index = decodeChannelIndex(
37650
+ const index2 = decodeChannelIndex(
37151
37651
  await readJsonFile(this.channelIndexPath(normalizedChannelId), signal, "connection_not_found")
37152
37652
  );
37153
- if (index.applicationId !== this.applicationId || index.installationId !== this.installationId || index.channelId !== normalizedChannelId) {
37653
+ if (index2.applicationId !== this.applicationId || index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
37154
37654
  throw new RuntimeInstallationStoreError(
37155
37655
  "connection_owner_mismatch",
37156
37656
  "The saved Runtime connection belongs to another installation"
37157
37657
  );
37158
37658
  }
37159
- return await this.readConnection(index.connectionId, signal);
37659
+ return await this.readConnection(index2.connectionId, signal);
37160
37660
  };
37161
37661
  saveConnection = async (input2, signal) => {
37162
37662
  const stored = new VerifiedRuntimeConnection(
@@ -37351,16 +37851,16 @@ function hasExactKeys2(value, expectedKeys) {
37351
37851
  }
37352
37852
  function readSingleOption(arguments_, option) {
37353
37853
  const values = [];
37354
- for (let index = 0; index < arguments_.length; index += 1) {
37355
- if (arguments_[index] !== option) {
37854
+ for (let index2 = 0; index2 < arguments_.length; index2 += 1) {
37855
+ if (arguments_[index2] !== option) {
37356
37856
  continue;
37357
37857
  }
37358
- const value = arguments_[index + 1];
37858
+ const value = arguments_[index2 + 1];
37359
37859
  if (value === void 0 || value.startsWith("--")) {
37360
37860
  throw new PairingClientError("invalid_arguments", `${option} requires a value`);
37361
37861
  }
37362
37862
  values.push(value);
37363
- index += 1;
37863
+ index2 += 1;
37364
37864
  }
37365
37865
  if (values.length !== 1) {
37366
37866
  throw new PairingClientError("invalid_arguments", `${option} must be provided exactly once`);
@@ -37368,8 +37868,8 @@ function readSingleOption(arguments_, option) {
37368
37868
  return values[0] ?? "";
37369
37869
  }
37370
37870
  function assertKnownArguments(arguments_) {
37371
- for (let index = 0; index < arguments_.length; index += 2) {
37372
- const option = arguments_[index];
37871
+ for (let index2 = 0; index2 < arguments_.length; index2 += 2) {
37872
+ const option = arguments_[index2];
37373
37873
  if (option !== "--url" && option !== "--code" && option !== "--pairing" && option !== "--workspace") {
37374
37874
  throw new PairingClientError("invalid_arguments", `Unknown pairing option: ${option ?? "missing option"}`);
37375
37875
  }
@@ -37660,7 +38160,7 @@ function isRuntimeRelayRevocation(closeCode, closeReason) {
37660
38160
  }
37661
38161
 
37662
38162
  // src/run-daemon.ts
37663
- import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
38163
+ import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
37664
38164
  import { join as join18 } from "node:path";
37665
38165
  import { styleText } from "node:util";
37666
38166
 
@@ -38732,9 +39232,15 @@ function reportOperationFailure(socket, requestId, sessionId, error62, runtimeTi
38732
39232
  // src/daemon-observers.ts
38733
39233
  var DaemonAcpObserver = class {
38734
39234
  #record;
38735
- constructor(record2) {
39235
+ #recordV2;
39236
+ constructor(record2, recordV2 = () => void 0) {
38736
39237
  this.#record = record2;
39238
+ this.#recordV2 = recordV2;
38737
39239
  }
39240
+ onAcpUpdate = (sessionId, update) => {
39241
+ this.#recordV2(sessionId, update);
39242
+ return Promise.resolve();
39243
+ };
38738
39244
  onCommands = (event) => {
38739
39245
  this.#record(event.sessionId, event);
38740
39246
  return Promise.resolve();
@@ -38871,8 +39377,8 @@ var ACTIVE_TURN_TEXT_CHUNK_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT /
38871
39377
  function boundedRecoveryMessages(messages) {
38872
39378
  const selected = [];
38873
39379
  let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT;
38874
- for (let index = messages.length - 1; index >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index -= 1) {
38875
- const message = messages[index];
39380
+ for (let index2 = messages.length - 1; index2 >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index2 -= 1) {
39381
+ const message = messages[index2];
38876
39382
  if (message === void 0) {
38877
39383
  break;
38878
39384
  }
@@ -39013,7 +39519,7 @@ var ActiveDaemonTurn = class {
39013
39519
  ];
39014
39520
  } else {
39015
39521
  this.#timeline = this.#timeline.map(
39016
- (entry, index) => index === target && entry.kind === "message" ? { ...entry, content: new Map([...entry.content, [event.contentId, event.content]]) } : entry
39522
+ (entry, index2) => index2 === target && entry.kind === "message" ? { ...entry, content: new Map([...entry.content, [event.contentId, event.content]]) } : entry
39017
39523
  );
39018
39524
  }
39019
39525
  } else if (event.kind === SESSION_PERMISSION_REQUESTED_KIND || event.kind === SESSION_ELICITATION_REQUESTED_KIND) {
@@ -40024,7 +40530,7 @@ async function readAcpHistory(sessions, directories, bindingId, options, nativeS
40024
40530
  async (directory) => await directories.identify(bindingId, directory, options.signal)
40025
40531
  )
40026
40532
  );
40027
- if (primary.path !== options.cwd || additional.length !== options.additionalDirectories.length || additional.some((directory, index) => directory.path !== options.additionalDirectories[index])) {
40533
+ if (primary.path !== options.cwd || additional.length !== options.additionalDirectories.length || additional.some((directory, index2) => directory.path !== options.additionalDirectories[index2])) {
40028
40534
  throw new AcpExecutionError(
40029
40535
  "The native Session belongs to another workspace.",
40030
40536
  {},
@@ -40157,7 +40663,7 @@ var NativeSessionService = class {
40157
40663
  "native_session_not_found"
40158
40664
  );
40159
40665
  }
40160
- if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index) => path2 !== additionalDirectories[index])) {
40666
+ if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index2) => path2 !== additionalDirectories[index2])) {
40161
40667
  throw new AcpExecutionError(
40162
40668
  "The source conversation execution target does not match the fork request",
40163
40669
  {},
@@ -40178,8 +40684,8 @@ var NativeSessionService = class {
40178
40684
  signal.throwIfAborted();
40179
40685
  const directory = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
40180
40686
  const ready2 = {
40181
- additionalDirectories: additionalDirectories.map((path2, index) => ({
40182
- directoryId: command.additionalDirectoryIds[index] ?? command.directoryId,
40687
+ additionalDirectories: additionalDirectories.map((path2, index2) => ({
40688
+ directoryId: command.additionalDirectoryIds[index2] ?? command.directoryId,
40183
40689
  name: basename5(path2) || path2
40184
40690
  })),
40185
40691
  agentId: command.agentId,
@@ -40511,7 +41017,7 @@ var NativeSessionService = class {
40511
41017
  resolveTarget = async (command, options, selected) => {
40512
41018
  let cursor = null;
40513
41019
  const visited = /* @__PURE__ */ new Set();
40514
- for (let index = 0; index < 100; index += 1) {
41020
+ for (let index2 = 0; index2 < 100; index2 += 1) {
40515
41021
  const page = await this.#sessions.listNativeSessions(options, cursor);
40516
41022
  const info = page.sessions.find((entry) => entry.sessionId === selected.nativeSessionId);
40517
41023
  if (info !== void 0) {
@@ -40519,7 +41025,7 @@ var NativeSessionService = class {
40519
41025
  if (target === null) {
40520
41026
  throw new LocalAuthorizationError("The selected native session is not authorized");
40521
41027
  }
40522
- if (target.cwd !== selected.cwd || target.additionalDirectories.length !== selected.additionalDirectories.length || target.additionalDirectories.some((path2, index2) => path2 !== selected.additionalDirectories[index2])) {
41028
+ if (target.cwd !== selected.cwd || target.additionalDirectories.length !== selected.additionalDirectories.length || target.additionalDirectories.some((path2, index3) => path2 !== selected.additionalDirectories[index3])) {
40523
41029
  throw new AcpExecutionError(
40524
41030
  "This session's directory changed. Refresh the list before continuing.",
40525
41031
  {},
@@ -41607,6 +42113,9 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
41607
42113
  });
41608
42114
  }
41609
42115
 
42116
+ // src/daemon-history-commands.ts
42117
+ import { createHash as createHash6 } from "node:crypto";
42118
+
41610
42119
  // src/authorization/resolve-session-directories.ts
41611
42120
  import { basename as basename7 } from "node:path";
41612
42121
  var ResolvedSessionDirectories = class {
@@ -41706,8 +42215,8 @@ function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit)
41706
42215
  const selected = [];
41707
42216
  let remainingCharacters = characterLimit;
41708
42217
  let startIndex = endIndex;
41709
- for (let index = endIndex - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
41710
- const message = messages[index];
42218
+ for (let index2 = endIndex - 1; index2 >= 0 && selected.length < messageLimit; index2 -= 1) {
42219
+ const message = messages[index2];
41711
42220
  if (message === void 0) {
41712
42221
  break;
41713
42222
  }
@@ -41717,7 +42226,7 @@ function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit)
41717
42226
  }
41718
42227
  selected.unshift(message);
41719
42228
  remainingCharacters -= characters;
41720
- startIndex = index;
42229
+ startIndex = index2;
41721
42230
  }
41722
42231
  if (selected.length === 0 && endIndex > 0) {
41723
42232
  throw new AcpExecutionError(
@@ -41997,6 +42506,79 @@ async function executeSessionLiveHistoryPageLoad(socket, command, config2, direc
41997
42506
  });
41998
42507
  }
41999
42508
  }
42509
+ function replayEvent(sessionId, position, update) {
42510
+ const encoded = JSON.stringify(update);
42511
+ const eventId = `native-${createHash6("sha256").update(sessionId).update(":").update(position.toString()).update(":").update(encoded).digest("hex")}`;
42512
+ return {
42513
+ eventId,
42514
+ payload: { kind: "acp.session.update", update },
42515
+ position: position.toString(),
42516
+ provenance: { kind: "original" },
42517
+ recordedAt: "1970-01-01T00:00:00.000Z",
42518
+ sessionId
42519
+ };
42520
+ }
42521
+ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, directories, audit, sessions, localRecovery, executingPromptRequest, signal) {
42522
+ try {
42523
+ const local = localRecovery(command.sessionId, command.eventLimit, command.cursor);
42524
+ if (local !== null) {
42525
+ send(socket, {
42526
+ events: local,
42527
+ kind: "session.live-history.v2.page.loaded",
42528
+ requestId: command.requestId,
42529
+ sessionId: command.sessionId
42530
+ });
42531
+ return;
42532
+ }
42533
+ const resolved = await resolveSessionDirectories(
42534
+ directories,
42535
+ config2.bindingId,
42536
+ command.directoryId,
42537
+ command.additionalDirectoryIds,
42538
+ signal
42539
+ );
42540
+ const replay = await sessions.loadSessionEventsV2(
42541
+ {
42542
+ additionalDirectories: resolved.additionalDirectories,
42543
+ agent: config2.catalog.find(command.agentId),
42544
+ cwd: resolved.cwd,
42545
+ sessionId: command.sessionId,
42546
+ signal
42547
+ },
42548
+ command.eventLimit,
42549
+ command.cursor
42550
+ );
42551
+ signal.throwIfAborted();
42552
+ const events = replay.updates.map(
42553
+ (update, index2) => replayEvent(command.sessionId, replay.startPosition + index2, update)
42554
+ );
42555
+ const tailCursor = events.at(-1)?.eventId ?? "";
42556
+ audit.record({
42557
+ commandId: command.requestId,
42558
+ event: "session_event_log_v2_loaded",
42559
+ sessionId: command.sessionId
42560
+ });
42561
+ send(socket, {
42562
+ events: {
42563
+ executingPromptRequest: executingPromptRequest(command.sessionId),
42564
+ history: {
42565
+ events,
42566
+ nextCursor: replay.nextCursor,
42567
+ tailCursor,
42568
+ truncated: replay.truncated,
42569
+ version: 2
42570
+ }
42571
+ },
42572
+ kind: "session.live-history.v2.page.loaded",
42573
+ requestId: command.requestId,
42574
+ sessionId: command.sessionId
42575
+ });
42576
+ } catch (error62) {
42577
+ if (!signal.aborted) {
42578
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62);
42579
+ }
42580
+ }
42581
+ }
42000
42582
 
42001
42583
  // src/acp/session-config/apply-session-configuration.ts
42002
42584
  import { randomUUID as randomUUID5 } from "node:crypto";
@@ -42311,6 +42893,7 @@ function daemonActivity(command, activity2) {
42311
42893
  async function executePrompt({
42312
42894
  operations,
42313
42895
  publisher,
42896
+ eventLogV2,
42314
42897
  command,
42315
42898
  config: config2,
42316
42899
  directories,
@@ -42415,6 +42998,7 @@ async function executePrompt({
42415
42998
  }
42416
42999
  }
42417
43000
  const stream = activateAttempt();
43001
+ eventLogV2.started(command.sessionId, command.commandId, attemptId, stream.epoch);
42418
43002
  if (!prepared.prompted) {
42419
43003
  const listing = await directories.list(config2.bindingId, command.directoryId, signal);
42420
43004
  publisher.publish(command.sessionId, {
@@ -42484,6 +43068,7 @@ async function executePrompt({
42484
43068
  sessionId: command.sessionId,
42485
43069
  stopReason
42486
43070
  });
43071
+ eventLogV2.completed(command.sessionId, command.commandId, stopReason);
42487
43072
  operations.transitionExecution(command.commandId, stopReason === "cancelled" ? "cancelled" : "succeeded");
42488
43073
  audit.record({
42489
43074
  commandId: command.commandId,
@@ -42499,6 +43084,7 @@ async function executePrompt({
42499
43084
  sessionId: command.sessionId,
42500
43085
  stopReason: "cancelled"
42501
43086
  });
43087
+ eventLogV2.completed(command.sessionId, command.commandId, "cancelled");
42502
43088
  operations.transitionExecution(command.commandId, "cancelled");
42503
43089
  audit.record({
42504
43090
  commandId: command.commandId,
@@ -42513,12 +43099,10 @@ async function executePrompt({
42513
43099
  sessionId: command.sessionId
42514
43100
  });
42515
43101
  const code = operationErrorCode(error62);
42516
- reportFailure(
42517
- publisher,
42518
- command,
42519
- code === "session_operation_failed" ? "agent_execution_failed" : code,
42520
- code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62)
42521
- );
43102
+ const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
43103
+ const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
43104
+ eventLogV2.failed(command.sessionId, command.commandId, failureCode, failureMessage);
43105
+ reportFailure(publisher, command, failureCode, failureMessage);
42522
43106
  operations.transitionExecution(command.commandId, "failed");
42523
43107
  console.error("Mobius daemon command failed", error62);
42524
43108
  }
@@ -42801,6 +43385,7 @@ function createDaemonCommandHandler({
42801
43385
  nativeSessions,
42802
43386
  operations,
42803
43387
  publisher,
43388
+ eventLogV2,
42804
43389
  activeTurns,
42805
43390
  diagnostics,
42806
43391
  socket,
@@ -42870,6 +43455,20 @@ function createDaemonCommandHandler({
42870
43455
  );
42871
43456
  return;
42872
43457
  }
43458
+ if (kind === SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND) {
43459
+ void executeSessionLiveHistoryV2PageLoad(
43460
+ socket,
43461
+ message,
43462
+ config2,
43463
+ directories,
43464
+ audit,
43465
+ sessions,
43466
+ eventLogV2.recovery,
43467
+ eventLogV2.executingPromptRequest,
43468
+ signal
43469
+ );
43470
+ return;
43471
+ }
42873
43472
  if (kind === NATIVE_SESSION_CANCEL_KIND) {
42874
43473
  nativeRequestHandler.cancel(message);
42875
43474
  return;
@@ -43055,9 +43654,11 @@ function createDaemonCommandHandler({
43055
43654
  return;
43056
43655
  }
43057
43656
  const turn = activeTurns.start(command, receipt.attemptId);
43657
+ eventLogV2.requested(command);
43058
43658
  void executePrompt({
43059
43659
  operations,
43060
43660
  publisher,
43661
+ eventLogV2,
43061
43662
  command,
43062
43663
  config: config2,
43063
43664
  directories,
@@ -43327,6 +43928,7 @@ async function runRelayConnection({
43327
43928
  nativeSessions,
43328
43929
  operations,
43329
43930
  publisher,
43931
+ eventLogV2,
43330
43932
  activeTurns,
43331
43933
  connectionEpoch,
43332
43934
  diagnostics,
@@ -43337,7 +43939,6 @@ async function runRelayConnection({
43337
43939
  }) {
43338
43940
  const relayUrl = new URL(config2.relayUrl);
43339
43941
  relayUrl.searchParams.set("liveness", "1");
43340
- relayUrl.searchParams.set("sessionEventDelivery", "reliable-v1");
43341
43942
  const socket = await connectRelay(relayUrl, signal);
43342
43943
  diagnostics.connectionOpened(connectionEpoch);
43343
43944
  const connectionController = new AbortController();
@@ -43350,6 +43951,7 @@ async function runRelayConnection({
43350
43951
  nativeSessions,
43351
43952
  operations,
43352
43953
  publisher,
43954
+ eventLogV2,
43353
43955
  activeTurns,
43354
43956
  diagnostics,
43355
43957
  socket,
@@ -43457,10 +44059,7 @@ async function runRelayConnection({
43457
44059
  const message = decodeServiceToDaemonMessage(encoded);
43458
44060
  const kind = message.kind;
43459
44061
  if (kind === RUNTIME_LIVENESS_READY_KIND) {
43460
- publisher.connect(
43461
- socket,
43462
- message.sessionEventDelivery === "reliable-v1" ? "reliable" : "ephemeral"
43463
- );
44062
+ publisher.connect(socket);
43464
44063
  connectionLiveness.start();
43465
44064
  return;
43466
44065
  }
@@ -43468,18 +44067,6 @@ async function runRelayConnection({
43468
44067
  connectionLiveness.acknowledge(message);
43469
44068
  return;
43470
44069
  }
43471
- if (kind === SESSION_EVENT_ACK_KIND) {
43472
- publisher.acknowledge(message);
43473
- return;
43474
- }
43475
- if (kind === SESSION_EVENT_DEFERRED_KIND) {
43476
- publisher.defer(message);
43477
- return;
43478
- }
43479
- if (kind === SESSION_EVENT_REJECTED_KIND) {
43480
- publisher.reject(message);
43481
- return;
43482
- }
43483
44070
  commands.handle(message);
43484
44071
  } catch (error62) {
43485
44072
  console.error("Mobius daemon rejected a message", error62);
@@ -43506,245 +44093,304 @@ async function runRelayConnection({
43506
44093
 
43507
44094
  // src/relay-connection/session-event-publisher.ts
43508
44095
  import { WebSocket as WebSocket9 } from "undici";
43509
-
43510
- // src/relay-connection/session-event-queue.ts
43511
- import { randomUUID as randomUUID7 } from "node:crypto";
43512
- var STANDARD_EVENT_BYTES = 96 * 1024 * 1024;
43513
- var CRITICAL_EVENT_BYTES = 128 * 1024 * 1024;
43514
- var SessionEventQueueCapacityError = class extends Error {
43515
- code = "session_event_queue_full";
43516
- constructor() {
43517
- super("The in-memory Session event queue is full");
43518
- this.name = "SessionEventQueueCapacityError";
43519
- }
43520
- };
43521
- var SessionEventQueue = class {
43522
- #streamId = randomUUID7();
43523
- #events = /* @__PURE__ */ new Map();
43524
- #nextSourceSeq = 1;
43525
- #totalBytes = 0;
43526
- enqueueBatch = (sessionId, payloads, critical) => {
43527
- if (payloads.length < 1 || payloads.length > 32) {
43528
- throw new Error("A Session event batch must contain between 1 and 32 events");
43529
- }
43530
- if (!Number.isSafeInteger(this.#nextSourceSeq + payloads.length)) {
43531
- throw new Error("The Session event source sequence is exhausted");
43532
- }
43533
- const entries = payloads.map((payload, index) => {
43534
- const envelope2 = {
43535
- delivery: {
43536
- eventId: randomUUID7(),
43537
- kind: "reliable",
43538
- sourceSeq: (this.#nextSourceSeq + index).toString(),
43539
- streamId: this.#streamId
43540
- },
43541
- kind: SESSION_EVENT_KIND,
43542
- payload,
43543
- sessionId
43544
- };
43545
- return { envelope: envelope2, byteLength: Buffer.byteLength(encodeSessionEventEnvelope(envelope2), "utf8") };
44096
+ var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
44097
+ var DaemonSessionEventPublisher = class {
44098
+ #socket = null;
44099
+ connect = (socket) => {
44100
+ this.#socket = socket;
44101
+ };
44102
+ disconnect = (socket) => {
44103
+ if (this.#socket === socket) {
44104
+ this.#socket = null;
44105
+ }
44106
+ };
44107
+ close = () => {
44108
+ this.#socket = null;
44109
+ };
44110
+ publish = (sessionId, event) => {
44111
+ const socket = this.#socket;
44112
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
44113
+ return;
44114
+ }
44115
+ const encoded = encodeDaemonToServiceMessage({
44116
+ kind: SESSION_EVENT_KIND,
44117
+ payload: encodeRecordedSessionEvent(event),
44118
+ sessionId
43546
44119
  });
43547
- const byteLength = entries.reduce((total, entry) => total + entry.byteLength, 0);
43548
- if (this.#totalBytes + byteLength > (critical ? CRITICAL_EVENT_BYTES : STANDARD_EVENT_BYTES)) {
43549
- throw new SessionEventQueueCapacityError();
44120
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
44121
+ socket.close(1013, "Live event transport overloaded");
44122
+ return;
43550
44123
  }
43551
- for (const entry of entries) {
43552
- this.#events.set(entry.envelope.delivery.eventId, entry);
44124
+ try {
44125
+ socket.send(encoded);
44126
+ } catch {
43553
44127
  }
43554
- this.#nextSourceSeq += entries.length;
43555
- this.#totalBytes += byteLength;
43556
44128
  };
43557
- pending = (limit, excludedEventIds) => {
43558
- const result = [];
43559
- for (const [eventId, entry] of this.#events) {
43560
- if (!excludedEventIds.has(eventId)) {
43561
- result.push(entry.envelope);
43562
- if (result.length === limit) {
43563
- break;
43564
- }
43565
- }
44129
+ publishBatch = (sessionId, events) => {
44130
+ for (const event of events) {
44131
+ this.publish(sessionId, event);
43566
44132
  }
43567
- return result;
43568
44133
  };
43569
- remove = (eventId, sessionId) => {
43570
- const entry = this.#events.get(eventId);
43571
- if (entry === void 0 || entry.envelope.sessionId !== sessionId) {
43572
- return false;
44134
+ publishV2 = (event) => {
44135
+ const socket = this.#socket;
44136
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
44137
+ return;
44138
+ }
44139
+ const encoded = encodeDaemonToServiceMessage({ event, kind: SESSION_EVENT_V2_KIND });
44140
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
44141
+ socket.close(1013, "Live event transport overloaded");
44142
+ return;
44143
+ }
44144
+ try {
44145
+ socket.send(encoded);
44146
+ } catch {
43573
44147
  }
43574
- this.#events.delete(eventId);
43575
- this.#totalBytes -= entry.byteLength;
43576
- return true;
43577
44148
  };
43578
- clear = () => {
43579
- this.#events.clear();
43580
- this.#totalBytes = 0;
44149
+ };
44150
+
44151
+ // src/relay-connection/timer.ts
44152
+ var SystemDaemonTimer = class {
44153
+ schedule = (callback, milliseconds) => {
44154
+ const timeout = setTimeout(callback, milliseconds);
44155
+ return { cancel: () => clearTimeout(timeout) };
43581
44156
  };
43582
44157
  };
44158
+ var systemDaemonTimer = new SystemDaemonTimer();
43583
44159
 
43584
- // src/relay-connection/session-event-publisher.ts
43585
- var SESSION_EVENT_REPLAY_WINDOW = 16;
43586
- var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
43587
- function reservesSessionEventCapacity(event) {
43588
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
43589
- return true;
44160
+ // src/session-event-log-v2.ts
44161
+ var EXECUTING_PROMPT_EVENT_LIMIT = 1e4;
44162
+ function promptContent(command) {
44163
+ const content = [];
44164
+ if (command.prompt.length > 0) {
44165
+ content.push({ text: command.prompt, type: "text" });
44166
+ }
44167
+ for (const image of command.images) {
44168
+ content.push({
44169
+ _meta: { mobius: { name: image.name } },
44170
+ data: image.data,
44171
+ mimeType: image.mimeType,
44172
+ type: "image"
44173
+ });
43590
44174
  }
43591
- return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
43592
- }
43593
- var DaemonSessionEventPublisher = class {
43594
- #inFlight = /* @__PURE__ */ new Map();
43595
- #queue = new SessionEventQueue();
43596
- #reportedCapacityKinds = /* @__PURE__ */ new Set();
43597
- #timer;
43598
- #connection = { kind: "disconnected" };
43599
- #deferredReplay = null;
43600
- #inFlightBytes = 0;
43601
- constructor(timer) {
43602
- this.#timer = timer;
44175
+ for (const resource of command.resources) {
44176
+ content.push(
44177
+ resource.type === "embedded" ? {
44178
+ resource: { mimeType: resource.mimeType, text: resource.text, uri: resource.uri },
44179
+ type: "resource"
44180
+ } : { mimeType: resource.mimeType, name: resource.name, type: "resource_link", uri: resource.uri }
44181
+ );
43603
44182
  }
43604
- acknowledge = (acknowledgement) => {
43605
- if (!this.#queue.remove(acknowledgement.eventId, acknowledgement.sessionId)) {
43606
- return;
44183
+ return content;
44184
+ }
44185
+ function encodeLocalEventCursor(cursor) {
44186
+ return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
44187
+ }
44188
+ function decodeLocalEventCursor(sessionId, cursor) {
44189
+ try {
44190
+ const value = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
44191
+ if (typeof value !== "object" || value === null || Array.isArray(value) || Object.keys(value).sort().join(",") !== "endEvent,sessionId" || Reflect.get(value, "sessionId") !== sessionId) {
44192
+ throw new Error("Invalid V2 event cursor target");
43607
44193
  }
43608
- this.#removeInFlight(acknowledgement.eventId);
43609
- this.#publishNextBatch();
43610
- };
43611
- close = () => {
43612
- this.#deferredReplay?.cancel();
43613
- this.#deferredReplay = null;
43614
- this.#connection = { kind: "disconnected" };
43615
- this.#clearInFlight();
43616
- this.#queue.clear();
43617
- };
43618
- connect = (socket, delivery) => {
43619
- this.#connection = { delivery, kind: "connected", socket };
43620
- this.#clearInFlight();
43621
- this.#publishNextBatch();
43622
- };
43623
- defer = (deferred) => {
43624
- if (!this.#inFlight.has(deferred.eventId)) {
43625
- return;
44194
+ const endEvent = Reflect.get(value, "endEvent");
44195
+ if (typeof endEvent !== "number" || !Number.isSafeInteger(endEvent) || endEvent < 0) {
44196
+ throw new Error("Invalid V2 event cursor boundary");
43626
44197
  }
43627
- this.#clearInFlight();
43628
- if (this.#deferredReplay !== null) {
43629
- return;
44198
+ return { endEvent, sessionId };
44199
+ } catch (cause) {
44200
+ throw new AcpExecutionError("The native Session event cursor is invalid", { cause }, "invalid_cursor");
44201
+ }
44202
+ }
44203
+ var DaemonSessionEventLogV2 = class {
44204
+ #positions = /* @__PURE__ */ new Map();
44205
+ #events = /* @__PURE__ */ new Map();
44206
+ #requests = /* @__PURE__ */ new Map();
44207
+ #loadedRequestSessions = /* @__PURE__ */ new Set();
44208
+ #publisher;
44209
+ #store;
44210
+ constructor(publisher, store) {
44211
+ this.#publisher = publisher;
44212
+ this.#store = store;
44213
+ }
44214
+ #eventsFor = (sessionId) => {
44215
+ const cached2 = this.#events.get(sessionId);
44216
+ if (cached2 !== void 0) {
44217
+ return cached2;
44218
+ }
44219
+ const stored = this.#store.readEventsV2(sessionId);
44220
+ this.#events.set(sessionId, stored);
44221
+ const lastPosition = stored.at(-1)?.position;
44222
+ if (lastPosition !== void 0) {
44223
+ this.#positions.set(sessionId, Number(lastPosition));
43630
44224
  }
43631
- this.#deferredReplay = this.#timer.schedule(() => {
43632
- this.#deferredReplay = null;
43633
- this.#publishNextBatch();
43634
- }, deferred.retryAfterMilliseconds);
44225
+ return stored;
43635
44226
  };
43636
- disconnect = (socket) => {
43637
- if (this.#connection.kind !== "connected" || this.#connection.socket !== socket) {
44227
+ #loadRequests = (sessionId) => {
44228
+ if (this.#loadedRequestSessions.has(sessionId)) {
43638
44229
  return;
43639
44230
  }
43640
- this.#connection = { kind: "disconnected" };
43641
- this.#clearInFlight();
43642
- };
43643
- publish = (sessionId, event) => {
43644
- try {
43645
- this.#queue.enqueueBatch(
43646
- sessionId,
43647
- [encodeRecordedSessionEvent(event)],
43648
- reservesSessionEventCapacity(event)
43649
- );
43650
- } catch (error62) {
43651
- if (!(error62 instanceof SessionEventQueueCapacityError)) {
43652
- throw error62;
44231
+ for (const event of this.#eventsFor(sessionId)) {
44232
+ const payload = event.payload;
44233
+ if (payload.kind === "prompt.requested") {
44234
+ this.#requests.set(payload.commandId, {
44235
+ commandId: payload.commandId,
44236
+ events: [event],
44237
+ kind: "requested",
44238
+ sessionId
44239
+ });
44240
+ continue;
43653
44241
  }
43654
- if (!this.#reportedCapacityKinds.has(event.kind)) {
43655
- this.#reportedCapacityKinds.add(event.kind);
43656
- console.warn(`Mobius daemon could not buffer "${event.kind}" because the Session event queue is full`);
44242
+ if (payload.kind === "acp.session.update") {
44243
+ const executing = [...this.#requests.values()].find(
44244
+ (request) => request.sessionId === sessionId && request.kind === "executing"
44245
+ );
44246
+ if (executing !== void 0) {
44247
+ this.#requests.set(executing.commandId, {
44248
+ ...executing,
44249
+ events: [...executing.events, event]
44250
+ });
44251
+ }
44252
+ continue;
43657
44253
  }
43658
- return;
43659
- }
43660
- this.#publishNextBatch();
44254
+ if (!("commandId" in payload)) {
44255
+ continue;
44256
+ }
44257
+ const state = this.#requests.get(payload.commandId);
44258
+ if (state === void 0) {
44259
+ continue;
44260
+ }
44261
+ const events = [...state.events, event];
44262
+ if (payload.kind === "prompt.started") {
44263
+ this.#requests.set(payload.commandId, {
44264
+ attemptId: payload.attemptId,
44265
+ commandId: payload.commandId,
44266
+ epoch: payload.epoch,
44267
+ events,
44268
+ kind: "executing",
44269
+ sessionId
44270
+ });
44271
+ } else if (payload.kind === "prompt.completed" || payload.kind === "prompt.failed" || payload.kind === "prompt.failed-before-start") {
44272
+ this.#requests.delete(payload.commandId);
44273
+ }
44274
+ }
44275
+ this.#loadedRequestSessions.add(sessionId);
44276
+ };
44277
+ #append = (sessionId, payload) => {
44278
+ this.#eventsFor(sessionId);
44279
+ const position = (this.#positions.get(sessionId) ?? 0) + 1;
44280
+ const event = {
44281
+ eventId: `event-${crypto.randomUUID()}`,
44282
+ payload,
44283
+ position: position.toString(),
44284
+ provenance: { kind: "original" },
44285
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
44286
+ sessionId
44287
+ };
44288
+ this.#store.appendEventV2(event);
44289
+ this.#positions.set(sessionId, position);
44290
+ this.#events.set(sessionId, [...this.#eventsFor(sessionId), event]);
44291
+ this.#publisher.publishV2(event);
44292
+ return event;
43661
44293
  };
43662
- publishBatch = (sessionId, events) => {
43663
- const critical = events.some(reservesSessionEventCapacity);
43664
- this.#queue.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
43665
- this.#publishNextBatch();
44294
+ requested = (command) => {
44295
+ const event = this.#append(command.sessionId, {
44296
+ commandId: command.commandId,
44297
+ content: promptContent(command),
44298
+ kind: "prompt.requested"
44299
+ });
44300
+ this.#requests.set(command.commandId, {
44301
+ commandId: command.commandId,
44302
+ events: [event],
44303
+ kind: "requested",
44304
+ sessionId: command.sessionId
44305
+ });
43666
44306
  };
43667
- reject = (rejection) => {
43668
- if (!this.#queue.remove(rejection.eventId, rejection.sessionId)) {
44307
+ started = (sessionId, commandId, attemptId, epoch) => {
44308
+ this.#loadRequests(sessionId);
44309
+ const request = this.#requests.get(commandId);
44310
+ if (request?.sessionId !== sessionId) {
43669
44311
  return;
43670
44312
  }
43671
- this.#removeInFlight(rejection.eventId);
43672
- console.error(`Mobius Relay rejected Session event ${rejection.eventId} with code ${rejection.code}`);
43673
- this.#publishNextBatch();
43674
- };
43675
- #clearInFlight = () => {
43676
- this.#inFlight.clear();
43677
- this.#inFlightBytes = 0;
44313
+ const event = this.#append(sessionId, { attemptId, commandId, epoch, kind: "prompt.started" });
44314
+ this.#requests.set(commandId, {
44315
+ attemptId,
44316
+ commandId,
44317
+ epoch,
44318
+ events: [...request.events, event],
44319
+ kind: "executing",
44320
+ sessionId
44321
+ });
43678
44322
  };
43679
- #publishNextBatch = () => {
43680
- if (this.#deferredReplay !== null || this.#connection.kind !== "connected") {
43681
- return;
43682
- }
43683
- while (this.#inFlight.size < SESSION_EVENT_REPLAY_WINDOW) {
43684
- const batch = this.#queue.pending(
43685
- SESSION_EVENT_REPLAY_WINDOW - this.#inFlight.size,
43686
- new Set(this.#inFlight.keys())
43687
- );
43688
- let sent = 0;
43689
- for (const envelope2 of batch) {
43690
- const encoded = encodeDaemonToServiceMessage(
43691
- this.#connection.delivery === "reliable" ? envelope2 : {
43692
- kind: envelope2.kind,
43693
- payload: envelope2.payload,
43694
- sessionId: envelope2.sessionId
43695
- }
43696
- );
43697
- const byteLength = Buffer.byteLength(encoded, "utf8");
43698
- if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
43699
- return;
43700
- }
43701
- if (!this.#send(encoded)) {
43702
- this.#clearInFlight();
43703
- return;
43704
- }
43705
- if (this.#connection.delivery === "ephemeral") {
43706
- this.#queue.remove(envelope2.delivery.eventId, envelope2.sessionId);
43707
- sent += 1;
43708
- continue;
43709
- }
43710
- this.#inFlight.set(envelope2.delivery.eventId, { byteLength });
43711
- this.#inFlightBytes += byteLength;
43712
- sent += 1;
43713
- }
43714
- if (sent === 0) {
43715
- return;
43716
- }
44323
+ acpUpdate = (sessionId, update) => {
44324
+ this.#loadRequests(sessionId);
44325
+ const event = this.#append(sessionId, { kind: "acp.session.update", update });
44326
+ const executing = [...this.#requests.values()].find(
44327
+ (request) => request.sessionId === sessionId && request.kind === "executing"
44328
+ );
44329
+ if (executing !== void 0) {
44330
+ this.#requests.set(executing.commandId, { ...executing, events: [...executing.events, event] });
43717
44331
  }
43718
44332
  };
43719
- #removeInFlight = (eventId) => {
43720
- const inFlight = this.#inFlight.get(eventId);
43721
- if (inFlight === void 0) {
43722
- return;
43723
- }
43724
- this.#inFlight.delete(eventId);
43725
- this.#inFlightBytes -= inFlight.byteLength;
44333
+ completed = (sessionId, commandId, stopReason) => {
44334
+ this.#append(sessionId, { commandId, kind: "prompt.completed", stopReason });
44335
+ this.#requests.delete(commandId);
43726
44336
  };
43727
- #send = (encoded) => {
43728
- if (this.#connection.kind !== "connected" || this.#connection.socket.readyState !== WebSocket9.OPEN) {
43729
- return false;
44337
+ failed = (sessionId, commandId, code, message) => {
44338
+ this.#loadRequests(sessionId);
44339
+ const request = this.#requests.get(commandId);
44340
+ if (request?.kind === "executing" && request.commandId === commandId) {
44341
+ this.#append(sessionId, { attemptId: request.attemptId, code, commandId, kind: "prompt.failed", message });
44342
+ } else {
44343
+ this.#append(sessionId, { code, commandId, kind: "prompt.failed-before-start", message });
43730
44344
  }
43731
- try {
43732
- this.#connection.socket.send(encoded);
43733
- return true;
43734
- } catch {
43735
- return false;
44345
+ this.#requests.delete(commandId);
44346
+ };
44347
+ executingPromptRequest = (sessionId) => {
44348
+ this.#loadRequests(sessionId);
44349
+ const request = [...this.#requests.values()].find(
44350
+ (candidate) => candidate.sessionId === sessionId && candidate.kind === "executing"
44351
+ );
44352
+ if (request?.kind !== "executing") {
44353
+ return null;
43736
44354
  }
44355
+ const events = request.events.slice(-EXECUTING_PROMPT_EVENT_LIMIT);
44356
+ return {
44357
+ attemptId: request.attemptId,
44358
+ commandId: request.commandId,
44359
+ epoch: request.epoch,
44360
+ events,
44361
+ tailCursor: events.at(-1)?.eventId ?? "",
44362
+ truncated: events.length < request.events.length
44363
+ };
43737
44364
  };
43738
- };
43739
-
43740
- // src/relay-connection/timer.ts
43741
- var SystemDaemonTimer = class {
43742
- schedule = (callback, milliseconds) => {
43743
- const timeout = setTimeout(callback, milliseconds);
43744
- return { cancel: () => clearTimeout(timeout) };
44365
+ recovery = (sessionId, eventLimit, cursor) => {
44366
+ const events = this.#eventsFor(sessionId);
44367
+ if (events.length === 0) {
44368
+ return null;
44369
+ }
44370
+ const executingPromptRequest = this.executingPromptRequest(sessionId);
44371
+ const executingRequestState = [...this.#requests.values()].find(
44372
+ (request) => request.sessionId === sessionId && request.kind === "executing"
44373
+ );
44374
+ const firstExecutingPosition = executingRequestState?.events[0]?.position;
44375
+ const historyEvents = firstExecutingPosition === void 0 ? events : events.filter((event) => BigInt(event.position) < BigInt(firstExecutingPosition));
44376
+ const endEvent = cursor === null ? historyEvents.length : decodeLocalEventCursor(sessionId, cursor).endEvent;
44377
+ if (endEvent > historyEvents.length) {
44378
+ throw new AcpExecutionError("The native Session event cursor is invalid", {}, "invalid_cursor");
44379
+ }
44380
+ const startEvent = Math.max(0, endEvent - eventLimit);
44381
+ const pageEvents = historyEvents.slice(startEvent, endEvent);
44382
+ return {
44383
+ executingPromptRequest,
44384
+ history: {
44385
+ events: pageEvents,
44386
+ nextCursor: startEvent === 0 ? null : encodeLocalEventCursor({ endEvent: startEvent, sessionId }),
44387
+ tailCursor: pageEvents.at(-1)?.eventId ?? "",
44388
+ truncated: startEvent > 0,
44389
+ version: 2
44390
+ }
44391
+ };
43745
44392
  };
43746
44393
  };
43747
- var systemDaemonTimer = new SystemDaemonTimer();
43748
44394
 
43749
44395
  // src/run-daemon.ts
43750
44396
  var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
@@ -43794,7 +44440,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
43794
44440
  {
43795
44441
  agentId: agent.id,
43796
44442
  kind: AGENT_INSTALL_REQUEST_KIND,
43797
- requestId: `automatic-integration-${randomUUID8()}`
44443
+ requestId: `automatic-integration-${randomUUID7()}`
43798
44444
  },
43799
44445
  signal
43800
44446
  );
@@ -43813,16 +44459,17 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43813
44459
  stateDirectory
43814
44460
  });
43815
44461
  const sessionStore = new SqliteAcpSessionStore(
43816
- join18(stateDirectory, "sessions", `${createHash6("sha256").update(config2.channelId).digest("hex")}.sqlite`)
44462
+ join18(stateDirectory, "sessions", `${createHash7("sha256").update(config2.channelId).digest("hex")}.sqlite`)
43817
44463
  );
43818
44464
  const operations = new DaemonOperationState();
43819
- const publisher = new DaemonSessionEventPublisher(timer);
44465
+ const publisher = new DaemonSessionEventPublisher();
44466
+ const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
43820
44467
  const activeTurns = new DaemonTurnRegistry(operations);
43821
44468
  const recordSessionEvent = (sessionId, event) => {
43822
44469
  publisher.publish(sessionId, activeTurns.recordEvent(event));
43823
44470
  };
43824
44471
  const agentRuntime = new AgentRuntimeManager(
43825
- new DaemonAcpObserver(recordSessionEvent),
44472
+ new DaemonAcpObserver(recordSessionEvent, eventLogV2.acpUpdate),
43826
44473
  sessionStore,
43827
44474
  {
43828
44475
  read: async (options2, nativeSessionId, nativeTurn) => options2.agent.id === "codex" ? (await readCodexFullHistory(
@@ -43860,7 +44507,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43860
44507
  options2.signal
43861
44508
  );
43862
44509
  return cwd === options2.cwd && additionalDirectories.length === options2.additionalDirectories.length && additionalDirectories.every(
43863
- (directory, index) => directory === options2.additionalDirectories[index]
44510
+ (directory, index2) => directory === options2.additionalDirectories[index2]
43864
44511
  );
43865
44512
  });
43866
44513
  }
@@ -43946,6 +44593,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43946
44593
  nativeSessions,
43947
44594
  operations,
43948
44595
  publisher,
44596
+ eventLogV2,
43949
44597
  activeTurns,
43950
44598
  connectionEpoch,
43951
44599
  diagnostics,