@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/runtime.js CHANGED
@@ -3354,11 +3354,11 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
3354
3354
  return payload;
3355
3355
  };
3356
3356
  });
3357
- function handleArrayResult(result, final, index) {
3357
+ function handleArrayResult(result, final, index2) {
3358
3358
  if (result.issues.length) {
3359
- final.issues.push(...prefixIssues(index, result.issues));
3359
+ final.issues.push(...prefixIssues(index2, result.issues));
3360
3360
  }
3361
- final.value[index] = result.value;
3361
+ final.value[index2] = result.value;
3362
3362
  }
3363
3363
  var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
3364
3364
  $ZodType.init(inst, def);
@@ -3969,14 +3969,14 @@ function mergeValues(a, b) {
3969
3969
  return { valid: false, mergeErrorPath: [] };
3970
3970
  }
3971
3971
  const newArray = [];
3972
- for (let index = 0; index < a.length; index++) {
3973
- const itemA = a[index];
3974
- const itemB = b[index];
3972
+ for (let index2 = 0; index2 < a.length; index2++) {
3973
+ const itemA = a[index2];
3974
+ const itemB = b[index2];
3975
3975
  const sharedValue = mergeValues(itemA, itemB);
3976
3976
  if (!sharedValue.valid) {
3977
3977
  return {
3978
3978
  valid: false,
3979
- mergeErrorPath: [index, ...sharedValue.mergeErrorPath]
3979
+ mergeErrorPath: [index2, ...sharedValue.mergeErrorPath]
3980
3980
  };
3981
3981
  }
3982
3982
  newArray.push(sharedValue.data);
@@ -4127,11 +4127,11 @@ function getTupleOptStart(items, key) {
4127
4127
  }
4128
4128
  return 0;
4129
4129
  }
4130
- function handleTupleResult(result, final, index) {
4130
+ function handleTupleResult(result, final, index2) {
4131
4131
  if (result.issues.length) {
4132
- final.issues.push(...prefixIssues(index, result.issues));
4132
+ final.issues.push(...prefixIssues(index2, result.issues));
4133
4133
  }
4134
- final.value[index] = result.value;
4134
+ final.value[index2] = result.value;
4135
4135
  }
4136
4136
  function handleTupleResults(itemResults, final, items, input2, optoutStart) {
4137
4137
  for (let i = 0; i < items.length; i++) {
@@ -18812,7 +18812,7 @@ function detectVersion(schema, defaultTarget) {
18812
18812
  return defaultTarget ?? "draft-2020-12";
18813
18813
  }
18814
18814
  function applyMinItems(items, minItems) {
18815
- return items.map((item, index) => index < minItems ? item : item.optional());
18815
+ return items.map((item, index2) => index2 < minItems ? item : item.optional());
18816
18816
  }
18817
18817
  function decodeJSONPointerSegment(segment) {
18818
18818
  return segment.replace(/~1/g, "/").replace(/~0/g, "~");
@@ -20000,12 +20000,12 @@ var DEFAULT_AGENT_EXECUTION_CONFIGURATION = Object.freeze({
20000
20000
  });
20001
20001
  var sessionConfigurationSelectionsSchema = external_exports.array(sessionConfigurationSelectionSchema).max(100).superRefine((selections, context) => {
20002
20002
  const identifiers = /* @__PURE__ */ new Set();
20003
- for (const [index, selection] of selections.entries()) {
20003
+ for (const [index2, selection] of selections.entries()) {
20004
20004
  if (identifiers.has(selection.configId)) {
20005
20005
  context.addIssue({
20006
20006
  code: "custom",
20007
20007
  message: "Session configuration identifiers must be unique",
20008
- path: [index, "configId"]
20008
+ path: [index2, "configId"]
20009
20009
  });
20010
20010
  }
20011
20011
  identifiers.add(selection.configId);
@@ -20741,16 +20741,8 @@ function decodeSessionQueuedEvent(encoded) {
20741
20741
  function decodeRuntimeLivenessReadyEvent(encoded) {
20742
20742
  const value = parseJson2(encoded);
20743
20743
  assertKind(value, RUNTIME_LIVENESS_READY_KIND);
20744
- if (value["sessionEventDelivery"] === void 0) {
20745
- assertExactKeys(value, ["kind"]);
20746
- return { kind: RUNTIME_LIVENESS_READY_KIND };
20747
- }
20748
- assertExactKeys(value, ["kind", "sessionEventDelivery"]);
20749
- const sessionEventDelivery = readString(value, "sessionEventDelivery", 32);
20750
- if (sessionEventDelivery !== "reliable-v1") {
20751
- throw new ProtocolMessageError("Unsupported Session event delivery mode");
20752
- }
20753
- return { kind: RUNTIME_LIVENESS_READY_KIND, sessionEventDelivery };
20744
+ assertExactKeys(value, ["kind"]);
20745
+ return { kind: RUNTIME_LIVENESS_READY_KIND };
20754
20746
  }
20755
20747
  function decodeRuntimeHeartbeatEvent(encoded) {
20756
20748
  const value = parseJson2(encoded);
@@ -21215,60 +21207,390 @@ var encodeNativeSessionResult = (value) => JSON.stringify(nativeSessionResultSch
21215
21207
  var decodeNativeSessionCancel = (encoded) => decode4(nativeSessionCancelSchema, encoded);
21216
21208
  var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSchema.parse(value));
21217
21209
 
21218
- // ../protocol/src/session-events.ts
21219
- var SESSION_EVENT_KIND = "session.event";
21220
- var SESSION_EVENT_ACK_KIND = "session.event.ack";
21221
- var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
21222
- var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
21223
- var SESSION_FORKED_KIND = "session.forked";
21224
- var SessionEventRejectionCode = {
21225
- IdempotencyConflict: "idempotency_conflict",
21226
- InvalidEvent: "invalid_event",
21227
- RecordingRejected: "recording_rejected"
21228
- };
21229
- var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
21230
- var ephemeralEventEnvelopeSchema = external_exports.strictObject({
21231
- kind: external_exports.literal(SESSION_EVENT_KIND),
21232
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21233
- sessionId: identifierStringSchema
21210
+ // ../protocol/src/session-event-log-v2.ts
21211
+ var MAX_EVENT_COUNT = 1e4;
21212
+ var MAX_COLLECTION_SIZE = 1e3;
21213
+ var MAX_CONTENT_LENGTH = 1e6;
21214
+ var MAX_JSON_DEPTH = 16;
21215
+ var MAX_JSON_KEYS = 1e3;
21216
+ var SESSION_EVENT_V2_KIND = "session.event.v2";
21217
+ var boundedString = external_exports.string().max(MAX_CONTENT_LENGTH);
21218
+ var shortString = external_exports.string().max(2048);
21219
+ function boundedJsonIssue(value, depth = 0) {
21220
+ if (depth > MAX_JSON_DEPTH) {
21221
+ return "JSON nesting exceeds the maximum depth";
21222
+ }
21223
+ if (typeof value === "string") {
21224
+ return value.length <= MAX_CONTENT_LENGTH ? null : "JSON string exceeds the maximum length";
21225
+ }
21226
+ if (typeof value === "number") {
21227
+ return Number.isFinite(value) ? null : "JSON number must be finite";
21228
+ }
21229
+ if (typeof value === "boolean" || value === null) {
21230
+ return null;
21231
+ }
21232
+ if (Array.isArray(value)) {
21233
+ if (value.length > MAX_COLLECTION_SIZE) {
21234
+ return "JSON array exceeds the maximum length";
21235
+ }
21236
+ for (const item of value) {
21237
+ const issue2 = boundedJsonIssue(item, depth + 1);
21238
+ if (issue2 !== null) {
21239
+ return issue2;
21240
+ }
21241
+ }
21242
+ return null;
21243
+ }
21244
+ if (typeof value === "object" && value !== void 0) {
21245
+ const entries = Object.entries(value);
21246
+ if (entries.length > MAX_JSON_KEYS) {
21247
+ return "JSON object exceeds the maximum key count";
21248
+ }
21249
+ for (const [key, item] of entries) {
21250
+ if (key.length > 255) {
21251
+ return "JSON key exceeds the maximum length";
21252
+ }
21253
+ const issue2 = boundedJsonIssue(item, depth + 1);
21254
+ if (issue2 !== null) {
21255
+ return issue2;
21256
+ }
21257
+ }
21258
+ return null;
21259
+ }
21260
+ return "Value is not bounded JSON";
21261
+ }
21262
+ var boundedJsonSchema = external_exports.unknown().superRefine((value, context) => {
21263
+ const issue2 = boundedJsonIssue(value);
21264
+ if (issue2 !== null) {
21265
+ context.addIssue({ code: "custom", message: issue2 });
21266
+ }
21267
+ });
21268
+ var metadataSchema = external_exports.record(external_exports.string().max(255), boundedJsonSchema).readonly();
21269
+ var optionalMetadata = metadataSchema.nullable().optional();
21270
+ var annotationsSchema = external_exports.strictObject({
21271
+ _meta: optionalMetadata,
21272
+ audience: external_exports.array(external_exports.enum(["assistant", "user"])).max(2).readonly().nullable().optional(),
21273
+ lastModified: shortString.nullable().optional(),
21274
+ priority: external_exports.number().finite().nullable().optional()
21234
21275
  }).readonly();
21235
- var reliableDeliverySchema = external_exports.strictObject({
21236
- eventId: identifierStringSchema,
21237
- kind: external_exports.literal("reliable"),
21238
- sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
21239
- streamId: identifierStringSchema
21276
+ var contentFields = { _meta: optionalMetadata, annotations: annotationsSchema.nullable().optional() };
21277
+ var textContentSchema = external_exports.strictObject({ ...contentFields, text: boundedString, type: external_exports.literal("text") }).readonly();
21278
+ var imageContentSchema = external_exports.strictObject({
21279
+ ...contentFields,
21280
+ data: boundedString,
21281
+ mimeType: shortString,
21282
+ type: external_exports.literal("image"),
21283
+ uri: boundedString.nullable().optional()
21240
21284
  }).readonly();
21241
- var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
21242
- delivery: reliableDeliverySchema,
21243
- kind: external_exports.literal(SESSION_EVENT_KIND),
21244
- payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21245
- sessionId: identifierStringSchema
21285
+ var audioContentSchema = external_exports.strictObject({ ...contentFields, data: boundedString, mimeType: shortString, type: external_exports.literal("audio") }).readonly();
21286
+ var resourceLinkSchema = external_exports.strictObject({
21287
+ ...contentFields,
21288
+ description: boundedString.nullable().optional(),
21289
+ mimeType: shortString.nullable().optional(),
21290
+ name: shortString,
21291
+ size: external_exports.number().int().nonnegative().safe().nullable().optional(),
21292
+ title: shortString.nullable().optional(),
21293
+ type: external_exports.literal("resource_link"),
21294
+ uri: boundedString
21295
+ }).readonly();
21296
+ var textResourceSchema = external_exports.strictObject({
21297
+ _meta: optionalMetadata,
21298
+ mimeType: shortString.nullable().optional(),
21299
+ text: boundedString,
21300
+ uri: boundedString
21301
+ }).readonly();
21302
+ var blobResourceSchema = external_exports.strictObject({
21303
+ _meta: optionalMetadata,
21304
+ blob: boundedString,
21305
+ mimeType: shortString.nullable().optional(),
21306
+ uri: boundedString
21307
+ }).readonly();
21308
+ var embeddedResourceSchema = external_exports.strictObject({
21309
+ ...contentFields,
21310
+ resource: external_exports.union([textResourceSchema, blobResourceSchema]),
21311
+ type: external_exports.literal("resource")
21312
+ }).readonly();
21313
+ var contentBlockV2Schema = external_exports.discriminatedUnion("type", [
21314
+ textContentSchema,
21315
+ imageContentSchema,
21316
+ audioContentSchema,
21317
+ resourceLinkSchema,
21318
+ embeddedResourceSchema
21319
+ ]);
21320
+ var toolCallContentSchema = external_exports.discriminatedUnion("type", [
21321
+ external_exports.strictObject({ _meta: optionalMetadata, content: contentBlockV2Schema, type: external_exports.literal("content") }).readonly(),
21322
+ external_exports.strictObject({
21323
+ _meta: optionalMetadata,
21324
+ newText: boundedString,
21325
+ oldText: boundedString.nullable().optional(),
21326
+ path: boundedString,
21327
+ type: external_exports.literal("diff")
21328
+ }).readonly(),
21329
+ external_exports.strictObject({ _meta: optionalMetadata, terminalId: shortString, type: external_exports.literal("terminal") }).readonly()
21330
+ ]);
21331
+ var toolCallLocationSchema = external_exports.strictObject({
21332
+ _meta: optionalMetadata,
21333
+ line: external_exports.number().int().nonnegative().safe().nullable().optional(),
21334
+ path: boundedString
21335
+ }).readonly();
21336
+ var toolKindSchema = external_exports.enum([
21337
+ "read",
21338
+ "edit",
21339
+ "delete",
21340
+ "move",
21341
+ "search",
21342
+ "execute",
21343
+ "think",
21344
+ "fetch",
21345
+ "switch_mode",
21346
+ "other"
21347
+ ]);
21348
+ var toolStatusSchema = external_exports.enum(["pending", "in_progress", "completed", "failed"]);
21349
+ var toolPatchFields = {
21350
+ _meta: optionalMetadata,
21351
+ content: external_exports.array(toolCallContentSchema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional(),
21352
+ kind: toolKindSchema.nullable().optional(),
21353
+ locations: external_exports.array(toolCallLocationSchema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional(),
21354
+ name: shortString.nullable().optional(),
21355
+ rawInput: boundedJsonSchema.optional(),
21356
+ rawOutput: boundedJsonSchema.optional(),
21357
+ status: toolStatusSchema.nullable().optional(),
21358
+ title: boundedString.nullable().optional()
21359
+ };
21360
+ var planEntrySchema = external_exports.strictObject({
21361
+ _meta: optionalMetadata,
21362
+ content: boundedString,
21363
+ priority: external_exports.enum(["high", "medium", "low"]),
21364
+ status: external_exports.enum(["pending", "in_progress", "completed"])
21365
+ }).readonly();
21366
+ var planContentSchema = external_exports.discriminatedUnion("type", [
21367
+ external_exports.strictObject({
21368
+ _meta: optionalMetadata,
21369
+ entries: external_exports.array(planEntrySchema).max(MAX_COLLECTION_SIZE).readonly(),
21370
+ planId: shortString,
21371
+ type: external_exports.literal("items")
21372
+ }).readonly(),
21373
+ external_exports.strictObject({ _meta: optionalMetadata, planId: shortString, type: external_exports.literal("file"), uri: boundedString }).readonly(),
21374
+ external_exports.strictObject({
21375
+ _meta: optionalMetadata,
21376
+ content: boundedString,
21377
+ planId: shortString,
21378
+ type: external_exports.literal("markdown")
21379
+ }).readonly()
21380
+ ]);
21381
+ var commandSchema = external_exports.strictObject({
21382
+ _meta: optionalMetadata,
21383
+ description: boundedString,
21384
+ input: external_exports.strictObject({ _meta: optionalMetadata, hint: boundedString }).readonly().nullable().optional(),
21385
+ name: shortString
21386
+ }).readonly();
21387
+ var configSelectOptionSchema = external_exports.strictObject({
21388
+ _meta: optionalMetadata,
21389
+ description: boundedString.nullable().optional(),
21390
+ name: shortString,
21391
+ value: shortString
21392
+ }).readonly();
21393
+ var configSelectGroupSchema = external_exports.strictObject({
21394
+ _meta: optionalMetadata,
21395
+ group: shortString,
21396
+ name: shortString,
21397
+ options: external_exports.array(configSelectOptionSchema).max(MAX_COLLECTION_SIZE).readonly()
21246
21398
  }).readonly();
21247
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
21248
- var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
21249
- external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
21399
+ var configBaseFields = {
21400
+ _meta: optionalMetadata,
21401
+ category: shortString.nullable().optional(),
21402
+ description: boundedString.nullable().optional(),
21403
+ id: shortString,
21404
+ name: shortString
21405
+ };
21406
+ var sessionConfigOptionSchema2 = external_exports.discriminatedUnion("type", [
21407
+ external_exports.strictObject({
21408
+ ...configBaseFields,
21409
+ currentValue: shortString,
21410
+ options: external_exports.union([
21411
+ external_exports.array(configSelectOptionSchema).max(MAX_COLLECTION_SIZE).readonly(),
21412
+ external_exports.array(configSelectGroupSchema).max(MAX_COLLECTION_SIZE).readonly()
21413
+ ]),
21414
+ type: external_exports.literal("select")
21415
+ }).readonly(),
21416
+ external_exports.strictObject({ ...configBaseFields, currentValue: external_exports.boolean(), type: external_exports.literal("boolean") }).readonly()
21417
+ ]);
21418
+ var contentChunkFields = {
21419
+ _meta: optionalMetadata,
21420
+ content: contentBlockV2Schema,
21421
+ messageId: shortString.nullable().optional()
21422
+ };
21423
+ var acpSessionUpdateV2Schema = external_exports.discriminatedUnion("sessionUpdate", [
21424
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("user_message_chunk") }).readonly(),
21425
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("agent_message_chunk") }).readonly(),
21426
+ external_exports.strictObject({ ...contentChunkFields, sessionUpdate: external_exports.literal("agent_thought_chunk") }).readonly(),
21427
+ external_exports.strictObject({
21428
+ _meta: optionalMetadata,
21429
+ content: external_exports.array(toolCallContentSchema).max(MAX_COLLECTION_SIZE).readonly().optional(),
21430
+ kind: toolKindSchema.optional(),
21431
+ locations: external_exports.array(toolCallLocationSchema).max(MAX_COLLECTION_SIZE).readonly().optional(),
21432
+ name: shortString.nullable().optional(),
21433
+ rawInput: boundedJsonSchema.optional(),
21434
+ rawOutput: boundedJsonSchema.optional(),
21435
+ sessionUpdate: external_exports.literal("tool_call"),
21436
+ status: toolStatusSchema.optional(),
21437
+ title: boundedString,
21438
+ toolCallId: shortString
21439
+ }).readonly(),
21440
+ external_exports.strictObject({ ...toolPatchFields, sessionUpdate: external_exports.literal("tool_call_update"), toolCallId: shortString }).readonly(),
21441
+ external_exports.strictObject({
21442
+ _meta: optionalMetadata,
21443
+ entries: external_exports.array(planEntrySchema).max(MAX_COLLECTION_SIZE).readonly(),
21444
+ sessionUpdate: external_exports.literal("plan")
21445
+ }).readonly(),
21446
+ external_exports.strictObject({ _meta: optionalMetadata, plan: planContentSchema, sessionUpdate: external_exports.literal("plan_update") }).readonly(),
21447
+ external_exports.strictObject({ _meta: optionalMetadata, planId: shortString, sessionUpdate: external_exports.literal("plan_removed") }).readonly(),
21448
+ external_exports.strictObject({
21449
+ _meta: optionalMetadata,
21450
+ availableCommands: external_exports.array(commandSchema).max(MAX_COLLECTION_SIZE).readonly(),
21451
+ sessionUpdate: external_exports.literal("available_commands_update")
21452
+ }).readonly(),
21453
+ external_exports.strictObject({
21454
+ _meta: optionalMetadata,
21455
+ currentModeId: shortString,
21456
+ sessionUpdate: external_exports.literal("current_mode_update")
21457
+ }).readonly(),
21458
+ external_exports.strictObject({
21459
+ _meta: optionalMetadata,
21460
+ configOptions: external_exports.array(sessionConfigOptionSchema2).max(MAX_COLLECTION_SIZE).readonly(),
21461
+ sessionUpdate: external_exports.literal("config_option_update")
21462
+ }).readonly(),
21250
21463
  external_exports.strictObject({
21251
- kind: external_exports.literal("recorded"),
21252
- providerId: identifierStringSchema,
21253
- recordingEpoch: identifierStringSchema
21464
+ _meta: optionalMetadata,
21465
+ sessionUpdate: external_exports.literal("session_info_update"),
21466
+ title: boundedString.nullable().optional(),
21467
+ updatedAt: shortString.nullable().optional()
21468
+ }).readonly(),
21469
+ external_exports.strictObject({
21470
+ _meta: optionalMetadata,
21471
+ cost: external_exports.strictObject({ _meta: optionalMetadata, amount: external_exports.number().finite(), currency: external_exports.string().max(16) }).readonly().nullable().optional(),
21472
+ sessionUpdate: external_exports.literal("usage_update"),
21473
+ size: external_exports.number().int().nonnegative().safe(),
21474
+ used: external_exports.number().int().nonnegative().safe()
21475
+ }).readonly(),
21476
+ external_exports.strictObject({
21477
+ _meta: optionalMetadata,
21478
+ compactionId: shortString,
21479
+ error: boundedString.nullable().optional(),
21480
+ sessionUpdate: external_exports.literal("compaction_update"),
21481
+ status: shortString,
21482
+ summary: external_exports.array(contentBlockV2Schema).max(MAX_COLLECTION_SIZE).readonly().nullable().optional()
21483
+ }).readonly(),
21484
+ external_exports.strictObject({
21485
+ _meta: optionalMetadata,
21486
+ compactionId: shortString,
21487
+ content: contentBlockV2Schema,
21488
+ sessionUpdate: external_exports.literal("compaction_summary_chunk")
21254
21489
  }).readonly()
21255
21490
  ]);
21256
- var eventAcknowledgementSchema = external_exports.strictObject({
21491
+ var lifecycleBase = { commandId: identifierStringSchema };
21492
+ var sessionEventPayloadV2Schema = external_exports.discriminatedUnion("kind", [
21493
+ external_exports.strictObject({ kind: external_exports.literal("acp.session.update"), update: acpSessionUpdateV2Schema }).readonly(),
21494
+ external_exports.strictObject({
21495
+ ...lifecycleBase,
21496
+ content: external_exports.array(contentBlockV2Schema).min(1).max(100).readonly(),
21497
+ kind: external_exports.literal("prompt.requested")
21498
+ }).readonly(),
21499
+ external_exports.strictObject({ ...lifecycleBase, attemptId: identifierStringSchema, epoch: identifierStringSchema, kind: external_exports.literal("prompt.started") }).readonly(),
21500
+ external_exports.strictObject({ ...lifecycleBase, kind: external_exports.literal("prompt.completed"), stopReason: shortString }).readonly(),
21501
+ external_exports.strictObject({
21502
+ ...lifecycleBase,
21503
+ code: identifierStringSchema,
21504
+ kind: external_exports.literal("prompt.failed-before-start"),
21505
+ message: external_exports.string().min(1).max(500)
21506
+ }).readonly(),
21507
+ external_exports.strictObject({
21508
+ ...lifecycleBase,
21509
+ attemptId: identifierStringSchema,
21510
+ code: identifierStringSchema,
21511
+ kind: external_exports.literal("prompt.failed"),
21512
+ message: external_exports.string().min(1).max(500)
21513
+ }).readonly()
21514
+ ]);
21515
+ var positionSchema = external_exports.string().regex(/^(0|[1-9][0-9]*)$/);
21516
+ var provenanceSchema = external_exports.discriminatedUnion("kind", [
21517
+ external_exports.strictObject({ kind: external_exports.literal("original") }).readonly(),
21518
+ external_exports.strictObject({
21519
+ kind: external_exports.literal("imported"),
21520
+ sourceEventId: identifierStringSchema,
21521
+ sourcePosition: positionSchema,
21522
+ sourceSessionId: identifierStringSchema
21523
+ }).readonly(),
21524
+ external_exports.strictObject({
21525
+ kind: external_exports.literal("forked"),
21526
+ sourceEventId: identifierStringSchema,
21527
+ sourcePosition: positionSchema,
21528
+ sourceSessionId: identifierStringSchema
21529
+ }).readonly()
21530
+ ]);
21531
+ var sessionEventV2Schema = external_exports.strictObject({
21257
21532
  eventId: identifierStringSchema,
21258
- kind: external_exports.literal(SESSION_EVENT_ACK_KIND),
21259
- outcome: acknowledgementOutcomeSchema,
21533
+ payload: sessionEventPayloadV2Schema,
21534
+ position: positionSchema,
21535
+ provenance: provenanceSchema,
21536
+ recordedAt: external_exports.iso.datetime({ offset: true }),
21260
21537
  sessionId: identifierStringSchema
21261
21538
  }).readonly();
21262
- var eventDeferredSchema = external_exports.strictObject({
21263
- eventId: identifierStringSchema,
21264
- kind: external_exports.literal(SESSION_EVENT_DEFERRED_KIND),
21265
- retryAfterMilliseconds: external_exports.number().int().min(100).max(6e4),
21266
- sessionId: identifierStringSchema
21539
+ var sessionEventEnvelopeV2Schema = external_exports.strictObject({ event: sessionEventV2Schema, kind: external_exports.literal(SESSION_EVENT_V2_KIND) }).readonly();
21540
+ var sessionEventLogPageV2Schema = external_exports.strictObject({
21541
+ events: external_exports.array(sessionEventV2Schema).max(MAX_EVENT_COUNT).readonly(),
21542
+ nextCursor: external_exports.string().min(1).max(512).nullable(),
21543
+ tailCursor: external_exports.string().max(512),
21544
+ truncated: external_exports.boolean(),
21545
+ version: external_exports.literal(2)
21267
21546
  }).readonly();
21268
- var eventRejectedSchema = external_exports.strictObject({
21269
- code: external_exports.enum(SessionEventRejectionCode),
21270
- eventId: identifierStringSchema,
21271
- kind: external_exports.literal(SESSION_EVENT_REJECTED_KIND),
21547
+ var nativeEventPageRequestV2Schema = external_exports.strictObject({ cursor: external_exports.string().min(1).max(512).nullable(), eventLimit: external_exports.number().int().min(1).max(1e4) }).readonly();
21548
+ var executingPromptRequestEventLogV2Schema = external_exports.strictObject({
21549
+ attemptId: identifierStringSchema,
21550
+ commandId: identifierStringSchema,
21551
+ epoch: identifierStringSchema,
21552
+ events: external_exports.array(sessionEventV2Schema).max(MAX_EVENT_COUNT).readonly(),
21553
+ tailCursor: external_exports.string().max(512),
21554
+ truncated: external_exports.boolean()
21555
+ }).readonly();
21556
+ var nativeSessionEventsV2Schema = external_exports.strictObject({
21557
+ executingPromptRequest: executingPromptRequestEventLogV2Schema.nullable(),
21558
+ history: sessionEventLogPageV2Schema
21559
+ }).readonly();
21560
+ function inputValue(value) {
21561
+ if (typeof value !== "string") {
21562
+ return value;
21563
+ }
21564
+ try {
21565
+ return JSON.parse(value);
21566
+ } catch (cause) {
21567
+ throw new ProtocolMessageError("Session Event Log V2 message is not valid JSON", { cause });
21568
+ }
21569
+ }
21570
+ function decode5(value, schema) {
21571
+ const result = schema.safeParse(inputValue(value));
21572
+ if (!result.success) {
21573
+ throw new ProtocolMessageError("Session Event Log V2 message does not match its schema", {
21574
+ cause: result.error
21575
+ });
21576
+ }
21577
+ return result.data;
21578
+ }
21579
+ function encode4(value, schema) {
21580
+ return JSON.stringify(decode5(value, schema));
21581
+ }
21582
+ var decodeSessionEventV2 = (value) => decode5(value, sessionEventV2Schema);
21583
+ var decodeSessionEventEnvelopeV2 = (value) => decode5(value, sessionEventEnvelopeV2Schema);
21584
+ var encodeSessionEventEnvelopeV2 = (value) => encode4(value, sessionEventEnvelopeV2Schema);
21585
+ var decodeAcpSessionUpdateV2 = (value) => decode5(value, acpSessionUpdateV2Schema);
21586
+
21587
+ // ../protocol/src/session-events.ts
21588
+ var SESSION_EVENT_KIND = "session.event";
21589
+ var SESSION_FORKED_KIND = "session.forked";
21590
+ var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
21591
+ var sessionEventEnvelopeSchema = external_exports.strictObject({
21592
+ kind: external_exports.literal(SESSION_EVENT_KIND),
21593
+ payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21272
21594
  sessionId: identifierStringSchema
21273
21595
  }).readonly();
21274
21596
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
@@ -21279,7 +21601,7 @@ var sessionForkedSchema = external_exports.strictObject({
21279
21601
  sourceSessionId: identifierStringSchema,
21280
21602
  throughCommandId: identifierStringSchema
21281
21603
  }).readonly();
21282
- function decode5(encoded, schema) {
21604
+ function decode6(encoded, schema) {
21283
21605
  let value;
21284
21606
  try {
21285
21607
  value = JSON.parse(encoded);
@@ -21294,7 +21616,7 @@ function decode5(encoded, schema) {
21294
21616
  }
21295
21617
  return decoded.data;
21296
21618
  }
21297
- var encode4 = (message, schema) => {
21619
+ var encode5 = (message, schema) => {
21298
21620
  const decoded = schema.safeParse(message);
21299
21621
  if (!decoded.success) {
21300
21622
  throw new ProtocolMessageError("Message does not match its schema", {
@@ -21303,21 +21625,15 @@ var encode4 = (message, schema) => {
21303
21625
  }
21304
21626
  return JSON.stringify(decoded.data);
21305
21627
  };
21306
- var decodeSessionEventEnvelope = (encoded) => decode5(encoded, eventEnvelopeSchema);
21307
- var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSchema);
21308
- var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAcknowledgementSchema);
21309
- var encodeSessionEventAcknowledgement = (message) => encode4(message, eventAcknowledgementSchema);
21310
- var decodeSessionEventDeferred = (encoded) => decode5(encoded, eventDeferredSchema);
21311
- var encodeSessionEventDeferred = (message) => encode4(message, eventDeferredSchema);
21312
- var decodeSessionEventRejected = (encoded) => decode5(encoded, eventRejectedSchema);
21313
- var encodeSessionEventRejected = (message) => encode4(message, eventRejectedSchema);
21628
+ var decodeSessionEventEnvelope = (encoded) => decode6(encoded, sessionEventEnvelopeSchema);
21629
+ var encodeSessionEventEnvelope = (message) => encode5(message, sessionEventEnvelopeSchema);
21314
21630
  function decodeRecordedSessionEvent(encoded) {
21315
21631
  const kind = decodeMessageKind(encoded);
21316
21632
  switch (kind) {
21317
21633
  case SESSION_QUEUE_CHANGED_KIND:
21318
- return decode5(encoded, sessionQueueChangedSchema);
21634
+ return decode6(encoded, sessionQueueChangedSchema);
21319
21635
  case SESSION_FORKED_KIND:
21320
- return decode5(encoded, sessionForkedSchema);
21636
+ return decode6(encoded, sessionForkedSchema);
21321
21637
  case AGENT_ACTIVITY_KIND:
21322
21638
  return decodeAgentActivityEvent(encoded);
21323
21639
  case AGENT_ACTIVITY_NARRATION_KIND:
@@ -21361,6 +21677,8 @@ var SESSION_LIVE_HISTORY_LOAD_KIND = "session.live-history.load";
21361
21677
  var SESSION_LIVE_HISTORY_LOADED_KIND = "session.live-history.loaded";
21362
21678
  var SESSION_LIVE_HISTORY_PAGE_LOAD_KIND = "session.live-history.page.load";
21363
21679
  var SESSION_LIVE_HISTORY_PAGE_LOADED_KIND = "session.live-history.page.loaded";
21680
+ var SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND = "session.live-history.v2.page.load";
21681
+ var SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND = "session.live-history.v2.page.loaded";
21364
21682
  var directoryIdentifier = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/);
21365
21683
  var sessionLiveHistoryLoadSchema = external_exports.strictObject({
21366
21684
  additionalDirectoryIds: external_exports.array(directoryIdentifier).max(16).readonly(),
@@ -21394,7 +21712,24 @@ var sessionLiveHistoryPageLoadedSchema = external_exports.strictObject({
21394
21712
  requestId: identifierStringSchema,
21395
21713
  sessionId: identifierStringSchema
21396
21714
  }).readonly();
21397
- function decode6(schema, encoded) {
21715
+ var sessionLiveHistoryV2PageLoadSchema = external_exports.strictObject({
21716
+ additionalDirectoryIds: external_exports.array(directoryIdentifier).max(16).readonly(),
21717
+ agentId: identifierStringSchema,
21718
+ bindingId: identifierStringSchema,
21719
+ cursor: external_exports.string().min(1).max(512).nullable(),
21720
+ directoryId: directoryIdentifier,
21721
+ kind: external_exports.literal(SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND),
21722
+ eventLimit: external_exports.number().int().min(1).max(1e4),
21723
+ requestId: identifierStringSchema,
21724
+ sessionId: identifierStringSchema
21725
+ }).readonly();
21726
+ var sessionLiveHistoryV2PageLoadedSchema = external_exports.strictObject({
21727
+ events: nativeSessionEventsV2Schema,
21728
+ kind: external_exports.literal(SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND),
21729
+ requestId: identifierStringSchema,
21730
+ sessionId: identifierStringSchema
21731
+ }).readonly();
21732
+ function decode7(schema, encoded) {
21398
21733
  try {
21399
21734
  const value = JSON.parse(encoded);
21400
21735
  return schema.parse(value);
@@ -21402,14 +21737,18 @@ function decode6(schema, encoded) {
21402
21737
  throw new ProtocolMessageError("Invalid live Session history message", { cause });
21403
21738
  }
21404
21739
  }
21405
- var decodeSessionLiveHistoryLoad = (encoded) => decode6(sessionLiveHistoryLoadSchema, encoded);
21406
- var decodeSessionLiveHistoryLoaded = (encoded) => decode6(sessionLiveHistoryLoadedSchema, encoded);
21740
+ var decodeSessionLiveHistoryLoad = (encoded) => decode7(sessionLiveHistoryLoadSchema, encoded);
21741
+ var decodeSessionLiveHistoryLoaded = (encoded) => decode7(sessionLiveHistoryLoadedSchema, encoded);
21407
21742
  var encodeSessionLiveHistoryLoad = (value) => JSON.stringify(sessionLiveHistoryLoadSchema.parse(value));
21408
21743
  var encodeSessionLiveHistoryLoaded = (value) => JSON.stringify(sessionLiveHistoryLoadedSchema.parse(value));
21409
- var decodeSessionLiveHistoryPageLoad = (encoded) => decode6(sessionLiveHistoryPageLoadSchema, encoded);
21410
- var decodeSessionLiveHistoryPageLoaded = (encoded) => decode6(sessionLiveHistoryPageLoadedSchema, encoded);
21744
+ var decodeSessionLiveHistoryPageLoad = (encoded) => decode7(sessionLiveHistoryPageLoadSchema, encoded);
21745
+ var decodeSessionLiveHistoryPageLoaded = (encoded) => decode7(sessionLiveHistoryPageLoadedSchema, encoded);
21411
21746
  var encodeSessionLiveHistoryPageLoad = (value) => JSON.stringify(sessionLiveHistoryPageLoadSchema.parse(value));
21412
21747
  var encodeSessionLiveHistoryPageLoaded = (value) => JSON.stringify(sessionLiveHistoryPageLoadedSchema.parse(value));
21748
+ var decodeSessionLiveHistoryV2PageLoad = (encoded) => decode7(sessionLiveHistoryV2PageLoadSchema, encoded);
21749
+ var decodeSessionLiveHistoryV2PageLoaded = (encoded) => decode7(sessionLiveHistoryV2PageLoadedSchema, encoded);
21750
+ var encodeSessionLiveHistoryV2PageLoad = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadSchema.parse(value));
21751
+ var encodeSessionLiveHistoryV2PageLoaded = (value) => JSON.stringify(sessionLiveHistoryV2PageLoadedSchema.parse(value));
21413
21752
 
21414
21753
  // ../protocol/src/daemon-transport.ts
21415
21754
  function defineMessageSignature(kind, encoder, decoder) {
@@ -21484,21 +21823,6 @@ var serviceToDaemonSignatures = {
21484
21823
  encodeSessionElicitationRespondCommand,
21485
21824
  decodeSessionElicitationRespondCommand
21486
21825
  ),
21487
- [SESSION_EVENT_ACK_KIND]: defineMessageSignature(
21488
- SESSION_EVENT_ACK_KIND,
21489
- encodeSessionEventAcknowledgement,
21490
- decodeSessionEventAcknowledgement
21491
- ),
21492
- [SESSION_EVENT_DEFERRED_KIND]: defineMessageSignature(
21493
- SESSION_EVENT_DEFERRED_KIND,
21494
- encodeSessionEventDeferred,
21495
- decodeSessionEventDeferred
21496
- ),
21497
- [SESSION_EVENT_REJECTED_KIND]: defineMessageSignature(
21498
- SESSION_EVENT_REJECTED_KIND,
21499
- encodeSessionEventRejected,
21500
- decodeSessionEventRejected
21501
- ),
21502
21826
  [SESSION_LIVE_HISTORY_LOAD_KIND]: defineMessageSignature(
21503
21827
  SESSION_LIVE_HISTORY_LOAD_KIND,
21504
21828
  encodeSessionLiveHistoryLoad,
@@ -21509,6 +21833,11 @@ var serviceToDaemonSignatures = {
21509
21833
  encodeSessionLiveHistoryPageLoad,
21510
21834
  decodeSessionLiveHistoryPageLoad
21511
21835
  ),
21836
+ [SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND]: defineMessageSignature(
21837
+ SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND,
21838
+ encodeSessionLiveHistoryV2PageLoad,
21839
+ decodeSessionLiveHistoryV2PageLoad
21840
+ ),
21512
21841
  [SESSION_PERMISSION_RESPOND_KIND]: defineMessageSignature(
21513
21842
  SESSION_PERMISSION_RESPOND_KIND,
21514
21843
  encodeSessionPermissionRespondCommand,
@@ -21624,6 +21953,11 @@ var daemonToServiceSignatures = {
21624
21953
  encodeSessionEventEnvelope,
21625
21954
  decodeSessionEventEnvelope
21626
21955
  ),
21956
+ [SESSION_EVENT_V2_KIND]: defineMessageSignature(
21957
+ SESSION_EVENT_V2_KIND,
21958
+ encodeSessionEventEnvelopeV2,
21959
+ decodeSessionEventEnvelopeV2
21960
+ ),
21627
21961
  [SESSION_OPERATION_FAILED_KIND]: defineMessageSignature(
21628
21962
  SESSION_OPERATION_FAILED_KIND,
21629
21963
  encodeSessionOperationFailedEvent,
@@ -21639,6 +21973,11 @@ var daemonToServiceSignatures = {
21639
21973
  encodeSessionLiveHistoryPageLoaded,
21640
21974
  decodeSessionLiveHistoryPageLoaded
21641
21975
  ),
21976
+ [SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND]: defineMessageSignature(
21977
+ SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND,
21978
+ encodeSessionLiveHistoryV2PageLoaded,
21979
+ decodeSessionLiveHistoryV2PageLoaded
21980
+ ),
21642
21981
  [SESSION_READY_KIND]: defineMessageSignature(SESSION_READY_KIND, encodeSessionReadyEvent, decodeSessionReadyEvent),
21643
21982
  [WORKSPACE_ENTRIES_KIND]: defineMessageSignature(
21644
21983
  WORKSPACE_ENTRIES_KIND,
@@ -26278,9 +26617,9 @@ function comparePrerelease(left, right) {
26278
26617
  if (left.length === 0 || right.length === 0) {
26279
26618
  return left.length === right.length ? 0 : left.length === 0 ? 1 : -1;
26280
26619
  }
26281
- for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
26282
- const leftPart = left[index];
26283
- const rightPart = right[index];
26620
+ for (let index2 = 0; index2 < Math.max(left.length, right.length); index2 += 1) {
26621
+ const leftPart = left[index2];
26622
+ const rightPart = right[index2];
26284
26623
  if (leftPart === void 0 || rightPart === void 0) {
26285
26624
  return leftPart === rightPart ? 0 : leftPart === void 0 ? -1 : 1;
26286
26625
  }
@@ -26305,8 +26644,8 @@ function compareAgentVersions(left, right) {
26305
26644
  if (parsedLeft === null || parsedRight === null) {
26306
26645
  return null;
26307
26646
  }
26308
- for (let index = 0; index < Math.max(parsedLeft.core.length, parsedRight.core.length); index += 1) {
26309
- const difference = (parsedLeft.core[index] ?? 0) - (parsedRight.core[index] ?? 0);
26647
+ for (let index2 = 0; index2 < Math.max(parsedLeft.core.length, parsedRight.core.length); index2 += 1) {
26648
+ const difference = (parsedLeft.core[index2] ?? 0) - (parsedRight.core[index2] ?? 0);
26310
26649
  if (difference !== 0) {
26311
26650
  return Math.sign(difference);
26312
26651
  }
@@ -26793,7 +27132,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
26793
27132
  }
26794
27133
 
26795
27134
  // src/run-daemon.ts
26796
- import { createHash as createHash5, randomUUID as randomUUID7 } from "node:crypto";
27135
+ import { createHash as createHash6, randomUUID as randomUUID6 } from "node:crypto";
26797
27136
  import { join as join17 } from "node:path";
26798
27137
  import { styleText } from "node:util";
26799
27138
 
@@ -26916,7 +27255,7 @@ function startsWith(bytes, signature, offset = 0) {
26916
27255
  if (bytes.byteLength < offset + signature.byteLength) {
26917
27256
  return false;
26918
27257
  }
26919
- return signature.every((value, index) => bytes[offset + index] === value);
27258
+ return signature.every((value, index2) => bytes[offset + index2] === value);
26920
27259
  }
26921
27260
  function sniffRasterMime(bytes) {
26922
27261
  if (startsWith(bytes, PNG_SIGNATURE)) {
@@ -27044,7 +27383,7 @@ function startsWith2(bytes, signature, offset = 0) {
27044
27383
  if (bytes.byteLength < offset + signature.byteLength) {
27045
27384
  return false;
27046
27385
  }
27047
- return signature.every((value, index) => bytes[offset + index] === value);
27386
+ return signature.every((value, index2) => bytes[offset + index2] === value);
27048
27387
  }
27049
27388
  function sniffVideoMime(bytes) {
27050
27389
  if (startsWith2(bytes, MP4_FILE_TYPE, 4)) {
@@ -27173,10 +27512,10 @@ async function replaceImageMarkers(text2, replace) {
27173
27512
  let cursor = 0;
27174
27513
  let rewritten = "";
27175
27514
  for (const match of matches) {
27176
- const index = match.index ?? 0;
27177
- rewritten += text2.slice(cursor, index);
27515
+ const index2 = match.index ?? 0;
27516
+ rewritten += text2.slice(cursor, index2);
27178
27517
  rewritten += await replace(match[1] ?? "");
27179
- cursor = index + match[0].length;
27518
+ cursor = index2 + match[0].length;
27180
27519
  }
27181
27520
  return `${rewritten}${text2.slice(cursor)}`;
27182
27521
  }
@@ -28342,6 +28681,7 @@ function sessionConfigProtocolForAgent(_agentId) {
28342
28681
 
28343
28682
  // src/acp/session-contracts.ts
28344
28683
  var NullAcpSessionObserver = class {
28684
+ onAcpUpdate = (_sessionId, _update) => Promise.resolve();
28345
28685
  onCommands = () => Promise.resolve();
28346
28686
  onConfig = () => Promise.resolve();
28347
28687
  onContent = () => Promise.resolve();
@@ -28409,6 +28749,7 @@ function historyContentCharacters(messages) {
28409
28749
  var AcpHistoryReplay = class {
28410
28750
  #activities = /* @__PURE__ */ new Map();
28411
28751
  #messages = [];
28752
+ #updates = [];
28412
28753
  #turnActivityIds = /* @__PURE__ */ new Set();
28413
28754
  #activityTracker = new AcpActivityTracker(
28414
28755
  async (activity2) => {
@@ -28430,7 +28771,8 @@ var AcpHistoryReplay = class {
28430
28771
  #firstMessageIndex = 0;
28431
28772
  #characters = 0;
28432
28773
  #truncated = false;
28433
- record = async (update) => {
28774
+ record = async (update, rawUpdate) => {
28775
+ this.#updates.push(rawUpdate);
28434
28776
  if (update.sessionUpdate === "agent_thought_chunk") {
28435
28777
  if (update.content.type === "text") {
28436
28778
  await this.#activityTracker.recordNarrative(
@@ -28511,6 +28853,20 @@ var AcpHistoryReplay = class {
28511
28853
  this.#lastMessageId = id;
28512
28854
  this.trimMessages();
28513
28855
  };
28856
+ eventPage = (eventLimit, cursor) => {
28857
+ const parsedCursor = cursor === null ? this.#updates.length : Number(cursor);
28858
+ if (!Number.isSafeInteger(parsedCursor) || parsedCursor < 0 || parsedCursor > this.#updates.length) {
28859
+ throw new Error("The native event cursor is invalid");
28860
+ }
28861
+ const endUpdate = parsedCursor;
28862
+ const startUpdate = Math.max(0, endUpdate - eventLimit);
28863
+ return {
28864
+ nextCursor: startUpdate === 0 ? null : startUpdate.toString(),
28865
+ startPosition: startUpdate + 1,
28866
+ truncated: startUpdate > 0,
28867
+ updates: this.#updates.slice(startUpdate, endUpdate)
28868
+ };
28869
+ };
28514
28870
  snapshot = async () => {
28515
28871
  await this.#activityTracker.finish();
28516
28872
  const messages = this.#messages.slice(this.#firstMessageIndex).map((message) => {
@@ -30498,8 +30854,8 @@ function haveSameKeys(left, right) {
30498
30854
  if (leftKeys.length !== rightKeys.length) {
30499
30855
  return false;
30500
30856
  }
30501
- for (const [index, key] of leftKeys.entries()) {
30502
- if (key !== rightKeys[index]) {
30857
+ for (const [index2, key] of leftKeys.entries()) {
30858
+ if (key !== rightKeys[index2]) {
30503
30859
  return false;
30504
30860
  }
30505
30861
  }
@@ -31687,6 +32043,55 @@ var sqliteTable = (name, columns, extraConfig) => {
31687
32043
  return sqliteTableBase(name, columns, extraConfig);
31688
32044
  };
31689
32045
 
32046
+ // ../../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
32047
+ var IndexBuilderOn = class {
32048
+ constructor(name, unique) {
32049
+ this.name = name;
32050
+ this.unique = unique;
32051
+ }
32052
+ static [entityKind] = "SQLiteIndexBuilderOn";
32053
+ on(...columns) {
32054
+ return new IndexBuilder(this.name, columns, this.unique);
32055
+ }
32056
+ };
32057
+ var IndexBuilder = class {
32058
+ static [entityKind] = "SQLiteIndexBuilder";
32059
+ /** @internal */
32060
+ config;
32061
+ constructor(name, columns, unique) {
32062
+ this.config = {
32063
+ name,
32064
+ columns,
32065
+ unique,
32066
+ where: void 0
32067
+ };
32068
+ }
32069
+ /**
32070
+ * Condition for partial index.
32071
+ */
32072
+ where(condition) {
32073
+ this.config.where = condition;
32074
+ return this;
32075
+ }
32076
+ /** @internal */
32077
+ build(table) {
32078
+ return new Index(this.config, table);
32079
+ }
32080
+ };
32081
+ var Index = class {
32082
+ static [entityKind] = "SQLiteIndex";
32083
+ config;
32084
+ constructor(config2, table) {
32085
+ this.config = { ...config2, table };
32086
+ }
32087
+ };
32088
+ function index(name) {
32089
+ return new IndexBuilderOn(name, false);
32090
+ }
32091
+ function uniqueIndex(name) {
32092
+ return new IndexBuilderOn(name, true);
32093
+ }
32094
+
31690
32095
  // ../../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
31691
32096
  function extractUsedTable(table) {
31692
32097
  if (is(table, SQLiteTable)) {
@@ -32035,8 +32440,8 @@ var SQLiteDialect = class {
32035
32440
  }
32036
32441
  const joinsArray = [];
32037
32442
  if (joins) {
32038
- for (const [index, joinMeta] of joins.entries()) {
32039
- if (index === 0) {
32443
+ for (const [index2, joinMeta] of joins.entries()) {
32444
+ if (index2 === 0) {
32040
32445
  joinsArray.push(sql` `);
32041
32446
  }
32042
32447
  const table = joinMeta.table;
@@ -32056,7 +32461,7 @@ var SQLiteDialect = class {
32056
32461
  sql`${sql.raw(joinMeta.joinType)} join ${table}${onSql}`
32057
32462
  );
32058
32463
  }
32059
- if (index < joins.length - 1) {
32464
+ if (index2 < joins.length - 1) {
32060
32465
  joinsArray.push(sql` `);
32061
32466
  }
32062
32467
  }
@@ -32069,9 +32474,9 @@ var SQLiteDialect = class {
32069
32474
  buildOrderBy(orderBy) {
32070
32475
  const orderByList = [];
32071
32476
  if (orderBy) {
32072
- for (const [index, orderByValue] of orderBy.entries()) {
32477
+ for (const [index2, orderByValue] of orderBy.entries()) {
32073
32478
  orderByList.push(orderByValue);
32074
- if (index < orderBy.length - 1) {
32479
+ if (index2 < orderBy.length - 1) {
32075
32480
  orderByList.push(sql`, `);
32076
32481
  }
32077
32482
  }
@@ -32124,9 +32529,9 @@ var SQLiteDialect = class {
32124
32529
  const havingSql = having ? sql` having ${having}` : void 0;
32125
32530
  const groupByList = [];
32126
32531
  if (groupBy) {
32127
- for (const [index, groupByValue] of groupBy.entries()) {
32532
+ for (const [index2, groupByValue] of groupBy.entries()) {
32128
32533
  groupByList.push(groupByValue);
32129
- if (index < groupBy.length - 1) {
32534
+ if (index2 < groupBy.length - 1) {
32130
32535
  groupByList.push(sql`, `);
32131
32536
  }
32132
32537
  }
@@ -34540,6 +34945,10 @@ var acpSessionStoreMigrations = [
34540
34945
  {
34541
34946
  "name": "0001_regular_ultimates.sql",
34542
34947
  "sql": "ALTER TABLE `acp_session` ADD `last_terminal_command_id` text;"
34948
+ },
34949
+ {
34950
+ "name": "0002_equal_black_queen.sql",
34951
+ "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`);"
34543
34952
  }
34544
34953
  ];
34545
34954
 
@@ -34547,7 +34956,8 @@ var acpSessionStoreMigrations = [
34547
34956
  var acp_session_store_exports = {};
34548
34957
  __export(acp_session_store_exports, {
34549
34958
  acpSession: () => acpSession,
34550
- deletedAcpSession: () => deletedAcpSession
34959
+ deletedAcpSession: () => deletedAcpSession,
34960
+ sessionEventV2: () => sessionEventV2
34551
34961
  });
34552
34962
 
34553
34963
  // src/schema/acp-session-store/acp-session.ts
@@ -34568,6 +34978,21 @@ var deletedAcpSession = sqliteTable("deleted_acp_session", {
34568
34978
  sessionId: text("session_id").primaryKey()
34569
34979
  });
34570
34980
 
34981
+ // src/schema/acp-session-store/session-event-v2.ts
34982
+ var sessionEventV2 = sqliteTable(
34983
+ "session_event_v2",
34984
+ {
34985
+ eventId: text("event_id").primaryKey(),
34986
+ eventJson: text("event_json").notNull(),
34987
+ position: integer2("position").notNull(),
34988
+ sessionId: text("session_id").notNull()
34989
+ },
34990
+ (table) => [
34991
+ uniqueIndex("session_event_v2_session_position_unique").on(table.sessionId, table.position),
34992
+ index("session_event_v2_session_position_index").on(table.sessionId, table.position)
34993
+ ]
34994
+ );
34995
+
34571
34996
  // src/acp/session-store.ts
34572
34997
  var AcpStoredSession = class {
34573
34998
  additionalDirectories;
@@ -34610,9 +35035,14 @@ var DeletedAcpStoredSession = class extends AcpStoredSessionLookup {
34610
35035
  var MemoryAcpSessionStore = class {
34611
35036
  #sessions = /* @__PURE__ */ new Map();
34612
35037
  #deleted = /* @__PURE__ */ new Set();
35038
+ #eventsV2 = /* @__PURE__ */ new Map();
35039
+ appendEventV2 = (event) => {
35040
+ this.#eventsV2.set(event.sessionId, [...this.#eventsV2.get(event.sessionId) ?? [], event]);
35041
+ };
34613
35042
  close = () => {
34614
35043
  this.#sessions.clear();
34615
35044
  this.#deleted.clear();
35045
+ this.#eventsV2.clear();
34616
35046
  };
34617
35047
  findNative = (agentId, nativeSessionId) => [...this.#sessions.values()].filter(
34618
35048
  (session) => session.agentId === agentId && session.nativeSessionId === nativeSessionId
@@ -34623,6 +35053,7 @@ var MemoryAcpSessionStore = class {
34623
35053
  for (const id of ids) {
34624
35054
  this.#sessions.delete(id);
34625
35055
  this.#deleted.add(id);
35056
+ this.#eventsV2.delete(id);
34626
35057
  }
34627
35058
  return ids;
34628
35059
  };
@@ -34635,7 +35066,9 @@ var MemoryAcpSessionStore = class {
34635
35066
  };
34636
35067
  remove = (sessionId) => {
34637
35068
  this.#sessions.delete(sessionId);
35069
+ this.#eventsV2.delete(sessionId);
34638
35070
  };
35071
+ readEventsV2 = (sessionId) => this.#eventsV2.get(sessionId) ?? [];
34639
35072
  write = (session) => {
34640
35073
  this.#sessions.set(session.sessionId, session);
34641
35074
  };
@@ -34684,15 +35117,15 @@ var SqliteAcpSessionStore = class {
34684
35117
  this.#sqliteDatabase.close();
34685
35118
  throw new Error("The ACP Session database was created by a newer Mobius version");
34686
35119
  }
34687
- for (let index = version3; index < acpSessionStoreMigrations.length; index += 1) {
34688
- const migration = acpSessionStoreMigrations[index];
35120
+ for (let index2 = version3; index2 < acpSessionStoreMigrations.length; index2 += 1) {
35121
+ const migration = acpSessionStoreMigrations[index2];
34689
35122
  if (migration === void 0) {
34690
35123
  throw new Error("The ACP Session migration is unavailable");
34691
35124
  }
34692
35125
  this.#sqliteDatabase.exec("BEGIN IMMEDIATE");
34693
35126
  try {
34694
35127
  this.#sqliteDatabase.exec(migration.sql);
34695
- this.#sqliteDatabase.pragma(`user_version = ${index + 1}`);
35128
+ this.#sqliteDatabase.pragma(`user_version = ${index2 + 1}`);
34696
35129
  this.#sqliteDatabase.exec("COMMIT");
34697
35130
  } catch (error62) {
34698
35131
  this.#sqliteDatabase.exec("ROLLBACK");
@@ -34703,6 +35136,14 @@ var SqliteAcpSessionStore = class {
34703
35136
  close = () => {
34704
35137
  this.#sqliteDatabase.close();
34705
35138
  };
35139
+ appendEventV2 = (event) => {
35140
+ this.#database.insert(sessionEventV2).values({
35141
+ eventId: event.eventId,
35142
+ eventJson: JSON.stringify(event),
35143
+ position: Number(event.position),
35144
+ sessionId: event.sessionId
35145
+ }).run();
35146
+ };
34706
35147
  findNative = (agentId, nativeSessionId) => this.#database.select().from(acpSession).where(and(eq(acpSession.agentId, agentId), eq(acpSession.nativeSessionId, nativeSessionId))).all().map(decodeStoredSession);
34707
35148
  list = () => this.#database.select().from(acpSession).orderBy(desc(acpSession.updatedAt)).all().map(decodeStoredSession);
34708
35149
  markDeleted = (agentId, nativeSessionId) => {
@@ -34711,6 +35152,7 @@ var SqliteAcpSessionStore = class {
34711
35152
  transaction.delete(acpSession).where(and(eq(acpSession.agentId, agentId), eq(acpSession.nativeSessionId, nativeSessionId))).run();
34712
35153
  for (const id of ids) {
34713
35154
  transaction.insert(deletedAcpSession).values({ sessionId: id }).onConflictDoNothing().run();
35155
+ transaction.delete(sessionEventV2).where(eq(sessionEventV2.sessionId, id)).run();
34714
35156
  }
34715
35157
  });
34716
35158
  return ids;
@@ -34724,8 +35166,12 @@ var SqliteAcpSessionStore = class {
34724
35166
  const row = this.#database.select().from(acpSession).where(eq(acpSession.sessionId, sessionId)).get();
34725
35167
  return row === void 0 ? new MissingAcpStoredSession() : new FoundAcpStoredSession(decodeStoredSession(row));
34726
35168
  };
35169
+ 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));
34727
35170
  remove = (sessionId) => {
34728
- this.#database.delete(acpSession).where(eq(acpSession.sessionId, sessionId)).run();
35171
+ this.#database.transaction((transaction) => {
35172
+ transaction.delete(acpSession).where(eq(acpSession.sessionId, sessionId)).run();
35173
+ transaction.delete(sessionEventV2).where(eq(sessionEventV2.sessionId, sessionId)).run();
35174
+ });
34729
35175
  };
34730
35176
  write = (session) => {
34731
35177
  const value = {
@@ -34758,7 +35204,7 @@ var RetryableAcpInitializationError = class extends AcpExecutionError {
34758
35204
  }
34759
35205
  };
34760
35206
  function arraysEqual(left, right) {
34761
- return left.length === right.length && left.every((value, index) => value === right[index]);
35207
+ return left.length === right.length && left.every((value, index2) => value === right[index2]);
34762
35208
  }
34763
35209
  function recordsEqual(left, right) {
34764
35210
  const leftEntries = Object.entries(left);
@@ -34905,6 +35351,17 @@ var AgentSession = class _AgentSession {
34905
35351
  const loaded = await this.#loadSession(signal, "ACP agent exited while loading history");
34906
35352
  return await embedLocalHistoryImages(await loaded.history.snapshot(), signal);
34907
35353
  };
35354
+ loadHistoryEventsV2 = async (eventLimit, cursor, signal) => {
35355
+ if (!this.#capabilities.loadSession) {
35356
+ throw new AcpExecutionError(
35357
+ "This Agent restores context but does not provide message history.",
35358
+ {},
35359
+ "native_history_unsupported"
35360
+ );
35361
+ }
35362
+ const loaded = await this.#loadSession(signal, "ACP agent exited while loading history");
35363
+ return loaded.history.eventPage(eventLimit, cursor);
35364
+ };
34908
35365
  async #loadSession(signal, exitMessage) {
34909
35366
  if (this.#sessionLoad.kind === "loaded") {
34910
35367
  return this.#sessionLoad;
@@ -35551,8 +36008,14 @@ var AgentSession = class _AgentSession {
35551
36008
  #processUpdate = async (notification) => {
35552
36009
  this.assertNativeSession(notification.sessionId);
35553
36010
  const update = notification.update;
36011
+ const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(update));
35554
36012
  if (this.#sessionLoad.kind !== "not-requested") {
35555
- await this.#sessionLoad.history.record(update);
36013
+ await this.#sessionLoad.history.record(update, rawUpdate);
36014
+ } else {
36015
+ const onAcpUpdate = this.#getObserver().onAcpUpdate;
36016
+ if (onAcpUpdate !== void 0) {
36017
+ await onAcpUpdate(this.#mobiusSessionId, rawUpdate);
36018
+ }
35556
36019
  }
35557
36020
  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")) {
35558
36021
  return;
@@ -35934,6 +36397,21 @@ var AgentQueryProcesses = class {
35934
36397
  async (runtime) => await runtime.closeProcess()
35935
36398
  );
35936
36399
  };
36400
+ previewEventsV2 = async (options, nativeSessionId, eventLimit, cursor) => {
36401
+ return await this.#processes.runTransient(
36402
+ options.signal,
36403
+ async () => await AgentSession.startNativeSessionBrowser(
36404
+ options,
36405
+ () => this.#observer,
36406
+ new MemoryAcpSessionStore()
36407
+ ),
36408
+ async (runtime) => {
36409
+ runtime.selectNativeSession(nativeSessionId);
36410
+ return await runtime.loadHistoryEventsV2(eventLimit, cursor, options.signal);
36411
+ },
36412
+ async (runtime) => await runtime.closeProcess()
36413
+ );
36414
+ };
35937
36415
  close = async () => {
35938
36416
  await Promise.all(
35939
36417
  this.#processesByQuery.entries().map(async ([id, runtime]) => await this.retire(id, runtime))
@@ -36003,9 +36481,9 @@ var AcpProcessCapacityLock = class {
36003
36481
  return await waiter.completion.promise;
36004
36482
  } finally {
36005
36483
  signal.removeEventListener("abort", waiter.cancel);
36006
- const index = this.#waiters.indexOf(waiter);
36007
- if (index >= 0) {
36008
- this.#waiters.splice(index, 1);
36484
+ const index2 = this.#waiters.indexOf(waiter);
36485
+ if (index2 >= 0) {
36486
+ this.#waiters.splice(index2, 1);
36009
36487
  }
36010
36488
  }
36011
36489
  };
@@ -36635,6 +37113,22 @@ var AgentRuntimeManager = class {
36635
37113
  this.#nativeOperations.delete(key);
36636
37114
  }
36637
37115
  });
37116
+ previewNativeSessionEventsV2 = async (options, nativeSessionId, eventLimit, cursor) => this.#operations.run(options, async (options2) => {
37117
+ const key = `${options2.agent.id}:${nativeSessionId}`;
37118
+ if (this.#nativeOperations.has(key)) {
37119
+ throw new AcpExecutionError(
37120
+ "Wait for the native session's running operation to finish",
37121
+ {},
37122
+ "session_busy"
37123
+ );
37124
+ }
37125
+ this.#nativeOperations.add(key);
37126
+ try {
37127
+ return await this.#queryProcesses.previewEventsV2(options2, nativeSessionId, eventLimit, cursor);
37128
+ } finally {
37129
+ this.#nativeOperations.delete(key);
37130
+ }
37131
+ });
36638
37132
  loadSessionHistory = async (options) => this.#operations.run(options, async (options2) => {
36639
37133
  return await this.#executionProcesses.use(options2.sessionId, async () => {
36640
37134
  const runtime = await this.ensureSession(options2);
@@ -36652,6 +37146,12 @@ var AgentRuntimeManager = class {
36652
37146
  return await runtime.loadHistory(options2.signal);
36653
37147
  });
36654
37148
  });
37149
+ loadSessionEventsV2 = async (options, eventLimit, cursor) => this.#operations.run(options, async (options2) => {
37150
+ return await this.#executionProcesses.use(options2.sessionId, async () => {
37151
+ const runtime = await this.ensureSession(options2);
37152
+ return await runtime.loadHistoryEventsV2(eventLimit, cursor, options2.signal);
37153
+ });
37154
+ });
36655
37155
  openNativeSession = async (options, origin) => this.#operations.run(options, async (options2) => {
36656
37156
  const key = `${options2.agent.id}:${origin.nativeSessionId}`;
36657
37157
  if (this.#nativeOperations.has(key)) {
@@ -37854,9 +38354,15 @@ function reportOperationFailure(socket, requestId, sessionId, error62, runtimeTi
37854
38354
  // src/daemon-observers.ts
37855
38355
  var DaemonAcpObserver = class {
37856
38356
  #record;
37857
- constructor(record2) {
38357
+ #recordV2;
38358
+ constructor(record2, recordV2 = () => void 0) {
37858
38359
  this.#record = record2;
38360
+ this.#recordV2 = recordV2;
37859
38361
  }
38362
+ onAcpUpdate = (sessionId, update) => {
38363
+ this.#recordV2(sessionId, update);
38364
+ return Promise.resolve();
38365
+ };
37860
38366
  onCommands = (event) => {
37861
38367
  this.#record(event.sessionId, event);
37862
38368
  return Promise.resolve();
@@ -37993,8 +38499,8 @@ var ACTIVE_TURN_TEXT_CHUNK_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT /
37993
38499
  function boundedRecoveryMessages(messages) {
37994
38500
  const selected = [];
37995
38501
  let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT;
37996
- for (let index = messages.length - 1; index >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index -= 1) {
37997
- const message = messages[index];
38502
+ for (let index2 = messages.length - 1; index2 >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index2 -= 1) {
38503
+ const message = messages[index2];
37998
38504
  if (message === void 0) {
37999
38505
  break;
38000
38506
  }
@@ -38135,7 +38641,7 @@ var ActiveDaemonTurn = class {
38135
38641
  ];
38136
38642
  } else {
38137
38643
  this.#timeline = this.#timeline.map(
38138
- (entry, index) => index === target && entry.kind === "message" ? { ...entry, content: new Map([...entry.content, [event.contentId, event.content]]) } : entry
38644
+ (entry, index2) => index2 === target && entry.kind === "message" ? { ...entry, content: new Map([...entry.content, [event.contentId, event.content]]) } : entry
38139
38645
  );
38140
38646
  }
38141
38647
  } else if (event.kind === SESSION_PERMISSION_REQUESTED_KIND || event.kind === SESSION_ELICITATION_REQUESTED_KIND) {
@@ -39146,7 +39652,7 @@ async function readAcpHistory(sessions, directories, bindingId, options, nativeS
39146
39652
  async (directory) => await directories.identify(bindingId, directory, options.signal)
39147
39653
  )
39148
39654
  );
39149
- if (primary.path !== options.cwd || additional.length !== options.additionalDirectories.length || additional.some((directory, index) => directory.path !== options.additionalDirectories[index])) {
39655
+ if (primary.path !== options.cwd || additional.length !== options.additionalDirectories.length || additional.some((directory, index2) => directory.path !== options.additionalDirectories[index2])) {
39150
39656
  throw new AcpExecutionError(
39151
39657
  "The native Session belongs to another workspace.",
39152
39658
  {},
@@ -39279,7 +39785,7 @@ var NativeSessionService = class {
39279
39785
  "native_session_not_found"
39280
39786
  );
39281
39787
  }
39282
- if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index) => path2 !== additionalDirectories[index])) {
39788
+ if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index2) => path2 !== additionalDirectories[index2])) {
39283
39789
  throw new AcpExecutionError(
39284
39790
  "The source conversation execution target does not match the fork request",
39285
39791
  {},
@@ -39300,8 +39806,8 @@ var NativeSessionService = class {
39300
39806
  signal.throwIfAborted();
39301
39807
  const directory = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
39302
39808
  const ready2 = {
39303
- additionalDirectories: additionalDirectories.map((path2, index) => ({
39304
- directoryId: command.additionalDirectoryIds[index] ?? command.directoryId,
39809
+ additionalDirectories: additionalDirectories.map((path2, index2) => ({
39810
+ directoryId: command.additionalDirectoryIds[index2] ?? command.directoryId,
39305
39811
  name: basename4(path2) || path2
39306
39812
  })),
39307
39813
  agentId: command.agentId,
@@ -39633,7 +40139,7 @@ var NativeSessionService = class {
39633
40139
  resolveTarget = async (command, options, selected) => {
39634
40140
  let cursor = null;
39635
40141
  const visited = /* @__PURE__ */ new Set();
39636
- for (let index = 0; index < 100; index += 1) {
40142
+ for (let index2 = 0; index2 < 100; index2 += 1) {
39637
40143
  const page = await this.#sessions.listNativeSessions(options, cursor);
39638
40144
  const info = page.sessions.find((entry) => entry.sessionId === selected.nativeSessionId);
39639
40145
  if (info !== void 0) {
@@ -39641,7 +40147,7 @@ var NativeSessionService = class {
39641
40147
  if (target === null) {
39642
40148
  throw new LocalAuthorizationError("The selected native session is not authorized");
39643
40149
  }
39644
- if (target.cwd !== selected.cwd || target.additionalDirectories.length !== selected.additionalDirectories.length || target.additionalDirectories.some((path2, index2) => path2 !== selected.additionalDirectories[index2])) {
40150
+ if (target.cwd !== selected.cwd || target.additionalDirectories.length !== selected.additionalDirectories.length || target.additionalDirectories.some((path2, index3) => path2 !== selected.additionalDirectories[index3])) {
39645
40151
  throw new AcpExecutionError(
39646
40152
  "This session's directory changed. Refresh the list before continuing.",
39647
40153
  {},
@@ -40729,6 +41235,9 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
40729
41235
  });
40730
41236
  }
40731
41237
 
41238
+ // src/daemon-history-commands.ts
41239
+ import { createHash as createHash5 } from "node:crypto";
41240
+
40732
41241
  // src/authorization/resolve-session-directories.ts
40733
41242
  import { basename as basename6 } from "node:path";
40734
41243
  var ResolvedSessionDirectories = class {
@@ -40828,8 +41337,8 @@ function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit)
40828
41337
  const selected = [];
40829
41338
  let remainingCharacters = characterLimit;
40830
41339
  let startIndex = endIndex;
40831
- for (let index = endIndex - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
40832
- const message = messages[index];
41340
+ for (let index2 = endIndex - 1; index2 >= 0 && selected.length < messageLimit; index2 -= 1) {
41341
+ const message = messages[index2];
40833
41342
  if (message === void 0) {
40834
41343
  break;
40835
41344
  }
@@ -40839,7 +41348,7 @@ function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit)
40839
41348
  }
40840
41349
  selected.unshift(message);
40841
41350
  remainingCharacters -= characters;
40842
- startIndex = index;
41351
+ startIndex = index2;
40843
41352
  }
40844
41353
  if (selected.length === 0 && endIndex > 0) {
40845
41354
  throw new AcpExecutionError(
@@ -41119,6 +41628,79 @@ async function executeSessionLiveHistoryPageLoad(socket, command, config2, direc
41119
41628
  });
41120
41629
  }
41121
41630
  }
41631
+ function replayEvent(sessionId, position, update) {
41632
+ const encoded = JSON.stringify(update);
41633
+ const eventId = `native-${createHash5("sha256").update(sessionId).update(":").update(position.toString()).update(":").update(encoded).digest("hex")}`;
41634
+ return {
41635
+ eventId,
41636
+ payload: { kind: "acp.session.update", update },
41637
+ position: position.toString(),
41638
+ provenance: { kind: "original" },
41639
+ recordedAt: "1970-01-01T00:00:00.000Z",
41640
+ sessionId
41641
+ };
41642
+ }
41643
+ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, directories, audit, sessions, localRecovery, executingPromptRequest, signal) {
41644
+ try {
41645
+ const local = localRecovery(command.sessionId, command.eventLimit, command.cursor);
41646
+ if (local !== null) {
41647
+ send(socket, {
41648
+ events: local,
41649
+ kind: "session.live-history.v2.page.loaded",
41650
+ requestId: command.requestId,
41651
+ sessionId: command.sessionId
41652
+ });
41653
+ return;
41654
+ }
41655
+ const resolved = await resolveSessionDirectories(
41656
+ directories,
41657
+ config2.bindingId,
41658
+ command.directoryId,
41659
+ command.additionalDirectoryIds,
41660
+ signal
41661
+ );
41662
+ const replay = await sessions.loadSessionEventsV2(
41663
+ {
41664
+ additionalDirectories: resolved.additionalDirectories,
41665
+ agent: config2.catalog.find(command.agentId),
41666
+ cwd: resolved.cwd,
41667
+ sessionId: command.sessionId,
41668
+ signal
41669
+ },
41670
+ command.eventLimit,
41671
+ command.cursor
41672
+ );
41673
+ signal.throwIfAborted();
41674
+ const events = replay.updates.map(
41675
+ (update, index2) => replayEvent(command.sessionId, replay.startPosition + index2, update)
41676
+ );
41677
+ const tailCursor = events.at(-1)?.eventId ?? "";
41678
+ audit.record({
41679
+ commandId: command.requestId,
41680
+ event: "session_event_log_v2_loaded",
41681
+ sessionId: command.sessionId
41682
+ });
41683
+ send(socket, {
41684
+ events: {
41685
+ executingPromptRequest: executingPromptRequest(command.sessionId),
41686
+ history: {
41687
+ events,
41688
+ nextCursor: replay.nextCursor,
41689
+ tailCursor,
41690
+ truncated: replay.truncated,
41691
+ version: 2
41692
+ }
41693
+ },
41694
+ kind: "session.live-history.v2.page.loaded",
41695
+ requestId: command.requestId,
41696
+ sessionId: command.sessionId
41697
+ });
41698
+ } catch (error62) {
41699
+ if (!signal.aborted) {
41700
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62);
41701
+ }
41702
+ }
41703
+ }
41122
41704
 
41123
41705
  // src/acp/session-config/apply-session-configuration.ts
41124
41706
  import { randomUUID as randomUUID4 } from "node:crypto";
@@ -41433,6 +42015,7 @@ function daemonActivity(command, activity2) {
41433
42015
  async function executePrompt({
41434
42016
  operations,
41435
42017
  publisher,
42018
+ eventLogV2,
41436
42019
  command,
41437
42020
  config: config2,
41438
42021
  directories,
@@ -41537,6 +42120,7 @@ async function executePrompt({
41537
42120
  }
41538
42121
  }
41539
42122
  const stream = activateAttempt();
42123
+ eventLogV2.started(command.sessionId, command.commandId, attemptId, stream.epoch);
41540
42124
  if (!prepared.prompted) {
41541
42125
  const listing = await directories.list(config2.bindingId, command.directoryId, signal);
41542
42126
  publisher.publish(command.sessionId, {
@@ -41606,6 +42190,7 @@ async function executePrompt({
41606
42190
  sessionId: command.sessionId,
41607
42191
  stopReason
41608
42192
  });
42193
+ eventLogV2.completed(command.sessionId, command.commandId, stopReason);
41609
42194
  operations.transitionExecution(command.commandId, stopReason === "cancelled" ? "cancelled" : "succeeded");
41610
42195
  audit.record({
41611
42196
  commandId: command.commandId,
@@ -41621,6 +42206,7 @@ async function executePrompt({
41621
42206
  sessionId: command.sessionId,
41622
42207
  stopReason: "cancelled"
41623
42208
  });
42209
+ eventLogV2.completed(command.sessionId, command.commandId, "cancelled");
41624
42210
  operations.transitionExecution(command.commandId, "cancelled");
41625
42211
  audit.record({
41626
42212
  commandId: command.commandId,
@@ -41635,12 +42221,10 @@ async function executePrompt({
41635
42221
  sessionId: command.sessionId
41636
42222
  });
41637
42223
  const code = operationErrorCode(error62);
41638
- reportFailure(
41639
- publisher,
41640
- command,
41641
- code === "session_operation_failed" ? "agent_execution_failed" : code,
41642
- code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62)
41643
- );
42224
+ const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
42225
+ const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
42226
+ eventLogV2.failed(command.sessionId, command.commandId, failureCode, failureMessage);
42227
+ reportFailure(publisher, command, failureCode, failureMessage);
41644
42228
  operations.transitionExecution(command.commandId, "failed");
41645
42229
  console.error("Mobius daemon command failed", error62);
41646
42230
  }
@@ -41923,6 +42507,7 @@ function createDaemonCommandHandler({
41923
42507
  nativeSessions,
41924
42508
  operations,
41925
42509
  publisher,
42510
+ eventLogV2,
41926
42511
  activeTurns,
41927
42512
  diagnostics,
41928
42513
  socket,
@@ -41992,6 +42577,20 @@ function createDaemonCommandHandler({
41992
42577
  );
41993
42578
  return;
41994
42579
  }
42580
+ if (kind === SESSION_LIVE_HISTORY_V2_PAGE_LOAD_KIND) {
42581
+ void executeSessionLiveHistoryV2PageLoad(
42582
+ socket,
42583
+ message,
42584
+ config2,
42585
+ directories,
42586
+ audit,
42587
+ sessions,
42588
+ eventLogV2.recovery,
42589
+ eventLogV2.executingPromptRequest,
42590
+ signal
42591
+ );
42592
+ return;
42593
+ }
41995
42594
  if (kind === NATIVE_SESSION_CANCEL_KIND) {
41996
42595
  nativeRequestHandler.cancel(message);
41997
42596
  return;
@@ -42177,9 +42776,11 @@ function createDaemonCommandHandler({
42177
42776
  return;
42178
42777
  }
42179
42778
  const turn = activeTurns.start(command, receipt.attemptId);
42779
+ eventLogV2.requested(command);
42180
42780
  void executePrompt({
42181
42781
  operations,
42182
42782
  publisher,
42783
+ eventLogV2,
42183
42784
  command,
42184
42785
  config: config2,
42185
42786
  directories,
@@ -42469,6 +43070,7 @@ async function runRelayConnection({
42469
43070
  nativeSessions,
42470
43071
  operations,
42471
43072
  publisher,
43073
+ eventLogV2,
42472
43074
  activeTurns,
42473
43075
  connectionEpoch,
42474
43076
  diagnostics,
@@ -42479,7 +43081,6 @@ async function runRelayConnection({
42479
43081
  }) {
42480
43082
  const relayUrl = new URL(config2.relayUrl);
42481
43083
  relayUrl.searchParams.set("liveness", "1");
42482
- relayUrl.searchParams.set("sessionEventDelivery", "reliable-v1");
42483
43084
  const socket = await connectRelay(relayUrl, signal);
42484
43085
  diagnostics.connectionOpened(connectionEpoch);
42485
43086
  const connectionController = new AbortController();
@@ -42492,6 +43093,7 @@ async function runRelayConnection({
42492
43093
  nativeSessions,
42493
43094
  operations,
42494
43095
  publisher,
43096
+ eventLogV2,
42495
43097
  activeTurns,
42496
43098
  diagnostics,
42497
43099
  socket,
@@ -42599,10 +43201,7 @@ async function runRelayConnection({
42599
43201
  const message = decodeServiceToDaemonMessage(encoded);
42600
43202
  const kind = message.kind;
42601
43203
  if (kind === RUNTIME_LIVENESS_READY_KIND) {
42602
- publisher.connect(
42603
- socket,
42604
- message.sessionEventDelivery === "reliable-v1" ? "reliable" : "ephemeral"
42605
- );
43204
+ publisher.connect(socket);
42606
43205
  connectionLiveness.start();
42607
43206
  return;
42608
43207
  }
@@ -42610,18 +43209,6 @@ async function runRelayConnection({
42610
43209
  connectionLiveness.acknowledge(message);
42611
43210
  return;
42612
43211
  }
42613
- if (kind === SESSION_EVENT_ACK_KIND) {
42614
- publisher.acknowledge(message);
42615
- return;
42616
- }
42617
- if (kind === SESSION_EVENT_DEFERRED_KIND) {
42618
- publisher.defer(message);
42619
- return;
42620
- }
42621
- if (kind === SESSION_EVENT_REJECTED_KIND) {
42622
- publisher.reject(message);
42623
- return;
42624
- }
42625
43212
  commands.handle(message);
42626
43213
  } catch (error62) {
42627
43214
  console.error("Mobius daemon rejected a message", error62);
@@ -42648,245 +43235,304 @@ async function runRelayConnection({
42648
43235
 
42649
43236
  // src/relay-connection/session-event-publisher.ts
42650
43237
  import { WebSocket as WebSocket9 } from "undici";
42651
-
42652
- // src/relay-connection/session-event-queue.ts
42653
- import { randomUUID as randomUUID6 } from "node:crypto";
42654
- var STANDARD_EVENT_BYTES = 96 * 1024 * 1024;
42655
- var CRITICAL_EVENT_BYTES = 128 * 1024 * 1024;
42656
- var SessionEventQueueCapacityError = class extends Error {
42657
- code = "session_event_queue_full";
42658
- constructor() {
42659
- super("The in-memory Session event queue is full");
42660
- this.name = "SessionEventQueueCapacityError";
42661
- }
42662
- };
42663
- var SessionEventQueue = class {
42664
- #streamId = randomUUID6();
42665
- #events = /* @__PURE__ */ new Map();
42666
- #nextSourceSeq = 1;
42667
- #totalBytes = 0;
42668
- enqueueBatch = (sessionId, payloads, critical) => {
42669
- if (payloads.length < 1 || payloads.length > 32) {
42670
- throw new Error("A Session event batch must contain between 1 and 32 events");
42671
- }
42672
- if (!Number.isSafeInteger(this.#nextSourceSeq + payloads.length)) {
42673
- throw new Error("The Session event source sequence is exhausted");
42674
- }
42675
- const entries = payloads.map((payload, index) => {
42676
- const envelope2 = {
42677
- delivery: {
42678
- eventId: randomUUID6(),
42679
- kind: "reliable",
42680
- sourceSeq: (this.#nextSourceSeq + index).toString(),
42681
- streamId: this.#streamId
42682
- },
42683
- kind: SESSION_EVENT_KIND,
42684
- payload,
42685
- sessionId
42686
- };
42687
- return { envelope: envelope2, byteLength: Buffer.byteLength(encodeSessionEventEnvelope(envelope2), "utf8") };
43238
+ var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
43239
+ var DaemonSessionEventPublisher = class {
43240
+ #socket = null;
43241
+ connect = (socket) => {
43242
+ this.#socket = socket;
43243
+ };
43244
+ disconnect = (socket) => {
43245
+ if (this.#socket === socket) {
43246
+ this.#socket = null;
43247
+ }
43248
+ };
43249
+ close = () => {
43250
+ this.#socket = null;
43251
+ };
43252
+ publish = (sessionId, event) => {
43253
+ const socket = this.#socket;
43254
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
43255
+ return;
43256
+ }
43257
+ const encoded = encodeDaemonToServiceMessage({
43258
+ kind: SESSION_EVENT_KIND,
43259
+ payload: encodeRecordedSessionEvent(event),
43260
+ sessionId
42688
43261
  });
42689
- const byteLength = entries.reduce((total, entry) => total + entry.byteLength, 0);
42690
- if (this.#totalBytes + byteLength > (critical ? CRITICAL_EVENT_BYTES : STANDARD_EVENT_BYTES)) {
42691
- throw new SessionEventQueueCapacityError();
43262
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
43263
+ socket.close(1013, "Live event transport overloaded");
43264
+ return;
42692
43265
  }
42693
- for (const entry of entries) {
42694
- this.#events.set(entry.envelope.delivery.eventId, entry);
43266
+ try {
43267
+ socket.send(encoded);
43268
+ } catch {
42695
43269
  }
42696
- this.#nextSourceSeq += entries.length;
42697
- this.#totalBytes += byteLength;
42698
43270
  };
42699
- pending = (limit, excludedEventIds) => {
42700
- const result = [];
42701
- for (const [eventId, entry] of this.#events) {
42702
- if (!excludedEventIds.has(eventId)) {
42703
- result.push(entry.envelope);
42704
- if (result.length === limit) {
42705
- break;
42706
- }
42707
- }
43271
+ publishBatch = (sessionId, events) => {
43272
+ for (const event of events) {
43273
+ this.publish(sessionId, event);
42708
43274
  }
42709
- return result;
42710
43275
  };
42711
- remove = (eventId, sessionId) => {
42712
- const entry = this.#events.get(eventId);
42713
- if (entry === void 0 || entry.envelope.sessionId !== sessionId) {
42714
- return false;
43276
+ publishV2 = (event) => {
43277
+ const socket = this.#socket;
43278
+ if (socket === null || socket.readyState !== WebSocket9.OPEN) {
43279
+ return;
43280
+ }
43281
+ const encoded = encodeDaemonToServiceMessage({ event, kind: SESSION_EVENT_V2_KIND });
43282
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
43283
+ socket.close(1013, "Live event transport overloaded");
43284
+ return;
43285
+ }
43286
+ try {
43287
+ socket.send(encoded);
43288
+ } catch {
42715
43289
  }
42716
- this.#events.delete(eventId);
42717
- this.#totalBytes -= entry.byteLength;
42718
- return true;
42719
43290
  };
42720
- clear = () => {
42721
- this.#events.clear();
42722
- this.#totalBytes = 0;
43291
+ };
43292
+
43293
+ // src/relay-connection/timer.ts
43294
+ var SystemDaemonTimer = class {
43295
+ schedule = (callback, milliseconds) => {
43296
+ const timeout = setTimeout(callback, milliseconds);
43297
+ return { cancel: () => clearTimeout(timeout) };
42723
43298
  };
42724
43299
  };
43300
+ var systemDaemonTimer = new SystemDaemonTimer();
42725
43301
 
42726
- // src/relay-connection/session-event-publisher.ts
42727
- var SESSION_EVENT_REPLAY_WINDOW = 16;
42728
- var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
42729
- function reservesSessionEventCapacity(event) {
42730
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
42731
- return true;
43302
+ // src/session-event-log-v2.ts
43303
+ var EXECUTING_PROMPT_EVENT_LIMIT = 1e4;
43304
+ function promptContent(command) {
43305
+ const content = [];
43306
+ if (command.prompt.length > 0) {
43307
+ content.push({ text: command.prompt, type: "text" });
43308
+ }
43309
+ for (const image of command.images) {
43310
+ content.push({
43311
+ _meta: { mobius: { name: image.name } },
43312
+ data: image.data,
43313
+ mimeType: image.mimeType,
43314
+ type: "image"
43315
+ });
42732
43316
  }
42733
- return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
42734
- }
42735
- var DaemonSessionEventPublisher = class {
42736
- #inFlight = /* @__PURE__ */ new Map();
42737
- #queue = new SessionEventQueue();
42738
- #reportedCapacityKinds = /* @__PURE__ */ new Set();
42739
- #timer;
42740
- #connection = { kind: "disconnected" };
42741
- #deferredReplay = null;
42742
- #inFlightBytes = 0;
42743
- constructor(timer) {
42744
- this.#timer = timer;
43317
+ for (const resource of command.resources) {
43318
+ content.push(
43319
+ resource.type === "embedded" ? {
43320
+ resource: { mimeType: resource.mimeType, text: resource.text, uri: resource.uri },
43321
+ type: "resource"
43322
+ } : { mimeType: resource.mimeType, name: resource.name, type: "resource_link", uri: resource.uri }
43323
+ );
42745
43324
  }
42746
- acknowledge = (acknowledgement) => {
42747
- if (!this.#queue.remove(acknowledgement.eventId, acknowledgement.sessionId)) {
42748
- return;
43325
+ return content;
43326
+ }
43327
+ function encodeLocalEventCursor(cursor) {
43328
+ return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
43329
+ }
43330
+ function decodeLocalEventCursor(sessionId, cursor) {
43331
+ try {
43332
+ const value = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
43333
+ if (typeof value !== "object" || value === null || Array.isArray(value) || Object.keys(value).sort().join(",") !== "endEvent,sessionId" || Reflect.get(value, "sessionId") !== sessionId) {
43334
+ throw new Error("Invalid V2 event cursor target");
42749
43335
  }
42750
- this.#removeInFlight(acknowledgement.eventId);
42751
- this.#publishNextBatch();
42752
- };
42753
- close = () => {
42754
- this.#deferredReplay?.cancel();
42755
- this.#deferredReplay = null;
42756
- this.#connection = { kind: "disconnected" };
42757
- this.#clearInFlight();
42758
- this.#queue.clear();
42759
- };
42760
- connect = (socket, delivery) => {
42761
- this.#connection = { delivery, kind: "connected", socket };
42762
- this.#clearInFlight();
42763
- this.#publishNextBatch();
42764
- };
42765
- defer = (deferred) => {
42766
- if (!this.#inFlight.has(deferred.eventId)) {
42767
- return;
43336
+ const endEvent = Reflect.get(value, "endEvent");
43337
+ if (typeof endEvent !== "number" || !Number.isSafeInteger(endEvent) || endEvent < 0) {
43338
+ throw new Error("Invalid V2 event cursor boundary");
42768
43339
  }
42769
- this.#clearInFlight();
42770
- if (this.#deferredReplay !== null) {
42771
- return;
43340
+ return { endEvent, sessionId };
43341
+ } catch (cause) {
43342
+ throw new AcpExecutionError("The native Session event cursor is invalid", { cause }, "invalid_cursor");
43343
+ }
43344
+ }
43345
+ var DaemonSessionEventLogV2 = class {
43346
+ #positions = /* @__PURE__ */ new Map();
43347
+ #events = /* @__PURE__ */ new Map();
43348
+ #requests = /* @__PURE__ */ new Map();
43349
+ #loadedRequestSessions = /* @__PURE__ */ new Set();
43350
+ #publisher;
43351
+ #store;
43352
+ constructor(publisher, store) {
43353
+ this.#publisher = publisher;
43354
+ this.#store = store;
43355
+ }
43356
+ #eventsFor = (sessionId) => {
43357
+ const cached2 = this.#events.get(sessionId);
43358
+ if (cached2 !== void 0) {
43359
+ return cached2;
43360
+ }
43361
+ const stored = this.#store.readEventsV2(sessionId);
43362
+ this.#events.set(sessionId, stored);
43363
+ const lastPosition = stored.at(-1)?.position;
43364
+ if (lastPosition !== void 0) {
43365
+ this.#positions.set(sessionId, Number(lastPosition));
42772
43366
  }
42773
- this.#deferredReplay = this.#timer.schedule(() => {
42774
- this.#deferredReplay = null;
42775
- this.#publishNextBatch();
42776
- }, deferred.retryAfterMilliseconds);
43367
+ return stored;
42777
43368
  };
42778
- disconnect = (socket) => {
42779
- if (this.#connection.kind !== "connected" || this.#connection.socket !== socket) {
43369
+ #loadRequests = (sessionId) => {
43370
+ if (this.#loadedRequestSessions.has(sessionId)) {
42780
43371
  return;
42781
43372
  }
42782
- this.#connection = { kind: "disconnected" };
42783
- this.#clearInFlight();
42784
- };
42785
- publish = (sessionId, event) => {
42786
- try {
42787
- this.#queue.enqueueBatch(
42788
- sessionId,
42789
- [encodeRecordedSessionEvent(event)],
42790
- reservesSessionEventCapacity(event)
42791
- );
42792
- } catch (error62) {
42793
- if (!(error62 instanceof SessionEventQueueCapacityError)) {
42794
- throw error62;
43373
+ for (const event of this.#eventsFor(sessionId)) {
43374
+ const payload = event.payload;
43375
+ if (payload.kind === "prompt.requested") {
43376
+ this.#requests.set(payload.commandId, {
43377
+ commandId: payload.commandId,
43378
+ events: [event],
43379
+ kind: "requested",
43380
+ sessionId
43381
+ });
43382
+ continue;
42795
43383
  }
42796
- if (!this.#reportedCapacityKinds.has(event.kind)) {
42797
- this.#reportedCapacityKinds.add(event.kind);
42798
- console.warn(`Mobius daemon could not buffer "${event.kind}" because the Session event queue is full`);
43384
+ if (payload.kind === "acp.session.update") {
43385
+ const executing = [...this.#requests.values()].find(
43386
+ (request) => request.sessionId === sessionId && request.kind === "executing"
43387
+ );
43388
+ if (executing !== void 0) {
43389
+ this.#requests.set(executing.commandId, {
43390
+ ...executing,
43391
+ events: [...executing.events, event]
43392
+ });
43393
+ }
43394
+ continue;
42799
43395
  }
42800
- return;
42801
- }
42802
- this.#publishNextBatch();
43396
+ if (!("commandId" in payload)) {
43397
+ continue;
43398
+ }
43399
+ const state = this.#requests.get(payload.commandId);
43400
+ if (state === void 0) {
43401
+ continue;
43402
+ }
43403
+ const events = [...state.events, event];
43404
+ if (payload.kind === "prompt.started") {
43405
+ this.#requests.set(payload.commandId, {
43406
+ attemptId: payload.attemptId,
43407
+ commandId: payload.commandId,
43408
+ epoch: payload.epoch,
43409
+ events,
43410
+ kind: "executing",
43411
+ sessionId
43412
+ });
43413
+ } else if (payload.kind === "prompt.completed" || payload.kind === "prompt.failed" || payload.kind === "prompt.failed-before-start") {
43414
+ this.#requests.delete(payload.commandId);
43415
+ }
43416
+ }
43417
+ this.#loadedRequestSessions.add(sessionId);
43418
+ };
43419
+ #append = (sessionId, payload) => {
43420
+ this.#eventsFor(sessionId);
43421
+ const position = (this.#positions.get(sessionId) ?? 0) + 1;
43422
+ const event = {
43423
+ eventId: `event-${crypto.randomUUID()}`,
43424
+ payload,
43425
+ position: position.toString(),
43426
+ provenance: { kind: "original" },
43427
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
43428
+ sessionId
43429
+ };
43430
+ this.#store.appendEventV2(event);
43431
+ this.#positions.set(sessionId, position);
43432
+ this.#events.set(sessionId, [...this.#eventsFor(sessionId), event]);
43433
+ this.#publisher.publishV2(event);
43434
+ return event;
42803
43435
  };
42804
- publishBatch = (sessionId, events) => {
42805
- const critical = events.some(reservesSessionEventCapacity);
42806
- this.#queue.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
42807
- this.#publishNextBatch();
43436
+ requested = (command) => {
43437
+ const event = this.#append(command.sessionId, {
43438
+ commandId: command.commandId,
43439
+ content: promptContent(command),
43440
+ kind: "prompt.requested"
43441
+ });
43442
+ this.#requests.set(command.commandId, {
43443
+ commandId: command.commandId,
43444
+ events: [event],
43445
+ kind: "requested",
43446
+ sessionId: command.sessionId
43447
+ });
42808
43448
  };
42809
- reject = (rejection) => {
42810
- if (!this.#queue.remove(rejection.eventId, rejection.sessionId)) {
43449
+ started = (sessionId, commandId, attemptId, epoch) => {
43450
+ this.#loadRequests(sessionId);
43451
+ const request = this.#requests.get(commandId);
43452
+ if (request?.sessionId !== sessionId) {
42811
43453
  return;
42812
43454
  }
42813
- this.#removeInFlight(rejection.eventId);
42814
- console.error(`Mobius Relay rejected Session event ${rejection.eventId} with code ${rejection.code}`);
42815
- this.#publishNextBatch();
42816
- };
42817
- #clearInFlight = () => {
42818
- this.#inFlight.clear();
42819
- this.#inFlightBytes = 0;
43455
+ const event = this.#append(sessionId, { attemptId, commandId, epoch, kind: "prompt.started" });
43456
+ this.#requests.set(commandId, {
43457
+ attemptId,
43458
+ commandId,
43459
+ epoch,
43460
+ events: [...request.events, event],
43461
+ kind: "executing",
43462
+ sessionId
43463
+ });
42820
43464
  };
42821
- #publishNextBatch = () => {
42822
- if (this.#deferredReplay !== null || this.#connection.kind !== "connected") {
42823
- return;
42824
- }
42825
- while (this.#inFlight.size < SESSION_EVENT_REPLAY_WINDOW) {
42826
- const batch = this.#queue.pending(
42827
- SESSION_EVENT_REPLAY_WINDOW - this.#inFlight.size,
42828
- new Set(this.#inFlight.keys())
42829
- );
42830
- let sent = 0;
42831
- for (const envelope2 of batch) {
42832
- const encoded = encodeDaemonToServiceMessage(
42833
- this.#connection.delivery === "reliable" ? envelope2 : {
42834
- kind: envelope2.kind,
42835
- payload: envelope2.payload,
42836
- sessionId: envelope2.sessionId
42837
- }
42838
- );
42839
- const byteLength = Buffer.byteLength(encoded, "utf8");
42840
- if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
42841
- return;
42842
- }
42843
- if (!this.#send(encoded)) {
42844
- this.#clearInFlight();
42845
- return;
42846
- }
42847
- if (this.#connection.delivery === "ephemeral") {
42848
- this.#queue.remove(envelope2.delivery.eventId, envelope2.sessionId);
42849
- sent += 1;
42850
- continue;
42851
- }
42852
- this.#inFlight.set(envelope2.delivery.eventId, { byteLength });
42853
- this.#inFlightBytes += byteLength;
42854
- sent += 1;
42855
- }
42856
- if (sent === 0) {
42857
- return;
42858
- }
43465
+ acpUpdate = (sessionId, update) => {
43466
+ this.#loadRequests(sessionId);
43467
+ const event = this.#append(sessionId, { kind: "acp.session.update", update });
43468
+ const executing = [...this.#requests.values()].find(
43469
+ (request) => request.sessionId === sessionId && request.kind === "executing"
43470
+ );
43471
+ if (executing !== void 0) {
43472
+ this.#requests.set(executing.commandId, { ...executing, events: [...executing.events, event] });
42859
43473
  }
42860
43474
  };
42861
- #removeInFlight = (eventId) => {
42862
- const inFlight = this.#inFlight.get(eventId);
42863
- if (inFlight === void 0) {
42864
- return;
42865
- }
42866
- this.#inFlight.delete(eventId);
42867
- this.#inFlightBytes -= inFlight.byteLength;
43475
+ completed = (sessionId, commandId, stopReason) => {
43476
+ this.#append(sessionId, { commandId, kind: "prompt.completed", stopReason });
43477
+ this.#requests.delete(commandId);
42868
43478
  };
42869
- #send = (encoded) => {
42870
- if (this.#connection.kind !== "connected" || this.#connection.socket.readyState !== WebSocket9.OPEN) {
42871
- return false;
43479
+ failed = (sessionId, commandId, code, message) => {
43480
+ this.#loadRequests(sessionId);
43481
+ const request = this.#requests.get(commandId);
43482
+ if (request?.kind === "executing" && request.commandId === commandId) {
43483
+ this.#append(sessionId, { attemptId: request.attemptId, code, commandId, kind: "prompt.failed", message });
43484
+ } else {
43485
+ this.#append(sessionId, { code, commandId, kind: "prompt.failed-before-start", message });
42872
43486
  }
42873
- try {
42874
- this.#connection.socket.send(encoded);
42875
- return true;
42876
- } catch {
42877
- return false;
43487
+ this.#requests.delete(commandId);
43488
+ };
43489
+ executingPromptRequest = (sessionId) => {
43490
+ this.#loadRequests(sessionId);
43491
+ const request = [...this.#requests.values()].find(
43492
+ (candidate) => candidate.sessionId === sessionId && candidate.kind === "executing"
43493
+ );
43494
+ if (request?.kind !== "executing") {
43495
+ return null;
42878
43496
  }
43497
+ const events = request.events.slice(-EXECUTING_PROMPT_EVENT_LIMIT);
43498
+ return {
43499
+ attemptId: request.attemptId,
43500
+ commandId: request.commandId,
43501
+ epoch: request.epoch,
43502
+ events,
43503
+ tailCursor: events.at(-1)?.eventId ?? "",
43504
+ truncated: events.length < request.events.length
43505
+ };
42879
43506
  };
42880
- };
42881
-
42882
- // src/relay-connection/timer.ts
42883
- var SystemDaemonTimer = class {
42884
- schedule = (callback, milliseconds) => {
42885
- const timeout = setTimeout(callback, milliseconds);
42886
- return { cancel: () => clearTimeout(timeout) };
43507
+ recovery = (sessionId, eventLimit, cursor) => {
43508
+ const events = this.#eventsFor(sessionId);
43509
+ if (events.length === 0) {
43510
+ return null;
43511
+ }
43512
+ const executingPromptRequest = this.executingPromptRequest(sessionId);
43513
+ const executingRequestState = [...this.#requests.values()].find(
43514
+ (request) => request.sessionId === sessionId && request.kind === "executing"
43515
+ );
43516
+ const firstExecutingPosition = executingRequestState?.events[0]?.position;
43517
+ const historyEvents = firstExecutingPosition === void 0 ? events : events.filter((event) => BigInt(event.position) < BigInt(firstExecutingPosition));
43518
+ const endEvent = cursor === null ? historyEvents.length : decodeLocalEventCursor(sessionId, cursor).endEvent;
43519
+ if (endEvent > historyEvents.length) {
43520
+ throw new AcpExecutionError("The native Session event cursor is invalid", {}, "invalid_cursor");
43521
+ }
43522
+ const startEvent = Math.max(0, endEvent - eventLimit);
43523
+ const pageEvents = historyEvents.slice(startEvent, endEvent);
43524
+ return {
43525
+ executingPromptRequest,
43526
+ history: {
43527
+ events: pageEvents,
43528
+ nextCursor: startEvent === 0 ? null : encodeLocalEventCursor({ endEvent: startEvent, sessionId }),
43529
+ tailCursor: pageEvents.at(-1)?.eventId ?? "",
43530
+ truncated: startEvent > 0,
43531
+ version: 2
43532
+ }
43533
+ };
42887
43534
  };
42888
43535
  };
42889
- var systemDaemonTimer = new SystemDaemonTimer();
42890
43536
 
42891
43537
  // src/run-daemon.ts
42892
43538
  var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
@@ -42936,7 +43582,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
42936
43582
  {
42937
43583
  agentId: agent.id,
42938
43584
  kind: AGENT_INSTALL_REQUEST_KIND,
42939
- requestId: `automatic-integration-${randomUUID7()}`
43585
+ requestId: `automatic-integration-${randomUUID6()}`
42940
43586
  },
42941
43587
  signal
42942
43588
  );
@@ -42955,16 +43601,17 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
42955
43601
  stateDirectory
42956
43602
  });
42957
43603
  const sessionStore = new SqliteAcpSessionStore(
42958
- join17(stateDirectory, "sessions", `${createHash5("sha256").update(config2.channelId).digest("hex")}.sqlite`)
43604
+ join17(stateDirectory, "sessions", `${createHash6("sha256").update(config2.channelId).digest("hex")}.sqlite`)
42959
43605
  );
42960
43606
  const operations = new DaemonOperationState();
42961
- const publisher = new DaemonSessionEventPublisher(timer);
43607
+ const publisher = new DaemonSessionEventPublisher();
43608
+ const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
42962
43609
  const activeTurns = new DaemonTurnRegistry(operations);
42963
43610
  const recordSessionEvent = (sessionId, event) => {
42964
43611
  publisher.publish(sessionId, activeTurns.recordEvent(event));
42965
43612
  };
42966
43613
  const agentRuntime = new AgentRuntimeManager(
42967
- new DaemonAcpObserver(recordSessionEvent),
43614
+ new DaemonAcpObserver(recordSessionEvent, eventLogV2.acpUpdate),
42968
43615
  sessionStore,
42969
43616
  {
42970
43617
  read: async (options2, nativeSessionId, nativeTurn) => options2.agent.id === "codex" ? (await readCodexFullHistory(
@@ -43002,7 +43649,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43002
43649
  options2.signal
43003
43650
  );
43004
43651
  return cwd === options2.cwd && additionalDirectories.length === options2.additionalDirectories.length && additionalDirectories.every(
43005
- (directory, index) => directory === options2.additionalDirectories[index]
43652
+ (directory, index2) => directory === options2.additionalDirectories[index2]
43006
43653
  );
43007
43654
  });
43008
43655
  }
@@ -43088,6 +43735,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43088
43735
  nativeSessions,
43089
43736
  operations,
43090
43737
  publisher,
43738
+ eventLogV2,
43091
43739
  activeTurns,
43092
43740
  connectionEpoch,
43093
43741
  diagnostics,
@@ -43150,7 +43798,7 @@ import { basename as basename7, resolve as resolve7 } from "node:path";
43150
43798
  import { fetch as fetch4 } from "undici";
43151
43799
 
43152
43800
  // src/storage/runtime-installation-store.ts
43153
- import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
43801
+ import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
43154
43802
  import { mkdir as mkdir4, open as open5, readdir as readdir3, rename as rename3, unlink, writeFile as writeFile3 } from "node:fs/promises";
43155
43803
  import { dirname as dirname5, join as join18, resolve as resolve6 } from "node:path";
43156
43804
  var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
@@ -43280,13 +43928,13 @@ function parseRelayOrigin(value) {
43280
43928
  return origin;
43281
43929
  }
43282
43930
  function connectionId() {
43283
- return `mcn_${randomUUID8().replaceAll("-", "")}`;
43931
+ return `mcn_${randomUUID7().replaceAll("-", "")}`;
43284
43932
  }
43285
43933
  function installationId() {
43286
- return `min_${randomUUID8().replaceAll("-", "")}`;
43934
+ return `min_${randomUUID7().replaceAll("-", "")}`;
43287
43935
  }
43288
43936
  function channelIndexFileName(channelId) {
43289
- return `mci_${createHash6("sha256").update(channelId).digest("hex")}.json`;
43937
+ return `mci_${createHash7("sha256").update(channelId).digest("hex")}.json`;
43290
43938
  }
43291
43939
  function decodeInstallationPointer(value) {
43292
43940
  if (!isRecord9(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
@@ -43395,7 +44043,7 @@ async function readJsonFile(path2, signal, missingCode) {
43395
44043
  async function writeJsonAtomically(path2, value, signal) {
43396
44044
  signal.throwIfAborted();
43397
44045
  const directory = dirname5(path2);
43398
- const temporaryPath = join18(directory, `.${randomUUID8()}.tmp`);
44046
+ const temporaryPath = join18(directory, `.${randomUUID7()}.tmp`);
43399
44047
  try {
43400
44048
  await mkdir4(directory, { mode: 448, recursive: true });
43401
44049
  signal.throwIfAborted();
@@ -43472,16 +44120,16 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
43472
44120
  };
43473
44121
  #readConnectionForChannel = async (channelId, signal) => {
43474
44122
  const normalizedChannelId = validateIdentifier(channelId, "invalid_channel_id");
43475
- const index = decodeChannelIndex(
44123
+ const index2 = decodeChannelIndex(
43476
44124
  await readJsonFile(this.channelIndexPath(normalizedChannelId), signal, "connection_not_found")
43477
44125
  );
43478
- if (index.applicationId !== this.applicationId || index.installationId !== this.installationId || index.channelId !== normalizedChannelId) {
44126
+ if (index2.applicationId !== this.applicationId || index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
43479
44127
  throw new RuntimeInstallationStoreError(
43480
44128
  "connection_owner_mismatch",
43481
44129
  "The saved Runtime connection belongs to another installation"
43482
44130
  );
43483
44131
  }
43484
- return await this.readConnection(index.connectionId, signal);
44132
+ return await this.readConnection(index2.connectionId, signal);
43485
44133
  };
43486
44134
  saveConnection = async (input2, signal) => {
43487
44135
  const stored = new VerifiedRuntimeConnection(