@moxt-ai/mobius 0.0.150 → 0.0.152

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 (51) hide show
  1. package/dist/acp/agent-runtime-manager.d.ts.map +1 -1
  2. package/dist/acp/agent-runtime-manager.js +8 -1
  3. package/dist/acp/agent-runtime-manager.js.map +1 -1
  4. package/dist/acp/agent-session.d.ts.map +1 -1
  5. package/dist/acp/agent-session.js +8 -4
  6. package/dist/acp/agent-session.js.map +1 -1
  7. package/dist/acp/session-contracts.d.ts +2 -1
  8. package/dist/acp/session-contracts.d.ts.map +1 -1
  9. package/dist/acp/session-contracts.js +3 -1
  10. package/dist/acp/session-contracts.js.map +1 -1
  11. package/dist/acp/session-store.d.ts +2 -1
  12. package/dist/acp/session-store.d.ts.map +1 -1
  13. package/dist/acp/session-store.js +6 -2
  14. package/dist/acp/session-store.js.map +1 -1
  15. package/dist/cli.js +228 -45
  16. package/dist/cli.js.map +3 -3
  17. package/dist/daemon-command-handler.d.ts.map +1 -1
  18. package/dist/daemon-command-handler.js +1 -0
  19. package/dist/daemon-command-handler.js.map +1 -1
  20. package/dist/daemon-prompt-executor.d.ts.map +1 -1
  21. package/dist/daemon-prompt-executor.js +28 -8
  22. package/dist/daemon-prompt-executor.js.map +1 -1
  23. package/dist/daemon-turn-registry.d.ts +13 -13
  24. package/dist/generated/acp-session-store-migrations.d.ts +3 -0
  25. package/dist/generated/acp-session-store-migrations.d.ts.map +1 -1
  26. package/dist/generated/acp-session-store-migrations.js +5 -1
  27. package/dist/generated/acp-session-store-migrations.js.map +1 -1
  28. package/dist/index.js +227 -44
  29. package/dist/index.js.map +3 -3
  30. package/dist/native-sessions/handle-native-requests.d.ts +2 -0
  31. package/dist/native-sessions/handle-native-requests.d.ts.map +1 -1
  32. package/dist/native-sessions/handle-native-requests.js +12 -1
  33. package/dist/native-sessions/handle-native-requests.js.map +1 -1
  34. package/dist/native-sessions/service.d.ts.map +1 -1
  35. package/dist/native-sessions/service.js +47 -0
  36. package/dist/native-sessions/service.js.map +1 -1
  37. package/dist/relay-connection/session-event-outbox.d.ts +1 -0
  38. package/dist/relay-connection/session-event-outbox.d.ts.map +1 -1
  39. package/dist/relay-connection/session-event-outbox.js +37 -22
  40. package/dist/relay-connection/session-event-outbox.js.map +1 -1
  41. package/dist/relay-connection/session-event-publisher.d.ts +1 -0
  42. package/dist/relay-connection/session-event-publisher.d.ts.map +1 -1
  43. package/dist/relay-connection/session-event-publisher.js +10 -2
  44. package/dist/relay-connection/session-event-publisher.js.map +1 -1
  45. package/dist/runtime.js +229 -46
  46. package/dist/runtime.js.map +3 -3
  47. package/dist/schema/acp-session-store/acp-session.d.ts +19 -0
  48. package/dist/schema/acp-session-store/acp-session.d.ts.map +1 -1
  49. package/dist/schema/acp-session-store/acp-session.js +1 -0
  50. package/dist/schema/acp-session-store/acp-session.js.map +1 -1
  51. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21108,6 +21108,12 @@ var nativeSessionRequestSchema = external_exports.discriminatedUnion("action", [
21108
21108
  entryId: identifierStringSchema,
21109
21109
  targetSessionId: identifierStringSchema
21110
21110
  }).readonly(),
21111
+ external_exports.strictObject({
21112
+ ...identity,
21113
+ action: external_exports.literal("fork-recorded"),
21114
+ targetSessionId: identifierStringSchema,
21115
+ throughCommandId: identifierStringSchema
21116
+ }).readonly(),
21111
21117
  external_exports.strictObject({
21112
21118
  ...identity,
21113
21119
  action: external_exports.literal("delete"),
@@ -21131,6 +21137,12 @@ var nativeSessionCommandSchema = external_exports.discriminatedUnion("action", [
21131
21137
  entryId: identifierStringSchema,
21132
21138
  targetSessionId: identifierStringSchema
21133
21139
  }).readonly(),
21140
+ external_exports.strictObject({
21141
+ ...identity,
21142
+ action: external_exports.literal("fork-recorded"),
21143
+ targetSessionId: identifierStringSchema,
21144
+ throughCommandId: identifierStringSchema
21145
+ }).readonly(),
21134
21146
  external_exports.strictObject({
21135
21147
  ...identity,
21136
21148
  action: external_exports.literal("delete"),
@@ -21180,7 +21192,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21180
21192
  }).readonly(),
21181
21193
  external_exports.strictObject({
21182
21194
  ...resultEnvelope,
21183
- action: external_exports.enum(["import", "fork"]),
21195
+ action: external_exports.enum(["import", "fork", "fork-recorded"]),
21184
21196
  targetSessionId: identifierStringSchema,
21185
21197
  ready: sessionReadyEventSchema,
21186
21198
  title: external_exports.string().max(500)
@@ -21229,6 +21241,7 @@ var SESSION_EVENT_KIND = "session.event";
21229
21241
  var SESSION_EVENT_ACK_KIND = "session.event.ack";
21230
21242
  var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
21231
21243
  var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
21244
+ var SESSION_FORKED_KIND = "session.forked";
21232
21245
  var SessionEventRejectionCode = {
21233
21246
  IdempotencyConflict: "idempotency_conflict",
21234
21247
  InvalidEvent: "invalid_event",
@@ -21246,13 +21259,13 @@ var reliableDeliverySchema = external_exports.strictObject({
21246
21259
  sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
21247
21260
  streamId: identifierStringSchema
21248
21261
  }).readonly();
21249
- var reliableEventEnvelopeSchema = external_exports.strictObject({
21262
+ var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
21250
21263
  delivery: reliableDeliverySchema,
21251
21264
  kind: external_exports.literal(SESSION_EVENT_KIND),
21252
21265
  payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21253
21266
  sessionId: identifierStringSchema
21254
21267
  }).readonly();
21255
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableEventEnvelopeSchema]).readonly();
21268
+ var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
21256
21269
  var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
21257
21270
  external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
21258
21271
  external_exports.strictObject({
@@ -21281,6 +21294,12 @@ var eventRejectedSchema = external_exports.strictObject({
21281
21294
  }).readonly();
21282
21295
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
21283
21296
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
21297
+ var sessionForkedSchema = external_exports.strictObject({
21298
+ kind: external_exports.literal(SESSION_FORKED_KIND),
21299
+ sessionId: identifierStringSchema,
21300
+ sourceSessionId: identifierStringSchema,
21301
+ throughCommandId: identifierStringSchema
21302
+ }).readonly();
21284
21303
  function decode5(encoded, schema) {
21285
21304
  let value;
21286
21305
  try {
@@ -21318,6 +21337,8 @@ function decodeRecordedSessionEvent(encoded) {
21318
21337
  switch (kind) {
21319
21338
  case SESSION_QUEUE_CHANGED_KIND:
21320
21339
  return decode5(encoded, sessionQueueChangedSchema);
21340
+ case SESSION_FORKED_KIND:
21341
+ return decode5(encoded, sessionForkedSchema);
21321
21342
  case AGENT_ACTIVITY_KIND:
21322
21343
  return decodeAgentActivityEvent(encoded);
21323
21344
  case AGENT_ACTIVITY_NARRATION_KIND:
@@ -24097,13 +24118,15 @@ var AcpPreparedSession = class {
24097
24118
  capabilities;
24098
24119
  commands;
24099
24120
  configOptions;
24121
+ prompted;
24100
24122
  restored;
24101
- constructor(agentName, agentVersion, capabilities, commands, configOptions, restored) {
24123
+ constructor(agentName, agentVersion, capabilities, commands, configOptions, prompted, restored) {
24102
24124
  this.agentName = agentName;
24103
24125
  this.agentVersion = agentVersion;
24104
24126
  this.capabilities = capabilities;
24105
24127
  this.commands = commands;
24106
24128
  this.configOptions = configOptions;
24129
+ this.prompted = prompted;
24107
24130
  this.restored = restored;
24108
24131
  }
24109
24132
  };
@@ -30330,6 +30353,10 @@ var acpSessionStoreMigrations = [
30330
30353
  {
30331
30354
  "name": "0000_slimy_captain_midlands.sql",
30332
30355
  "sql": "CREATE TABLE `acp_session` (\n `session_id` text PRIMARY KEY NOT NULL,\n `agent_id` text NOT NULL,\n `native_session_id` text NOT NULL,\n `cwd` text NOT NULL,\n `additional_directories` text NOT NULL,\n `prompted` integer NOT NULL,\n `title` text NOT NULL,\n `updated_at` text NOT NULL\n);\n--> statement-breakpoint\nCREATE TABLE `deleted_acp_session` (\n `session_id` text PRIMARY KEY NOT NULL\n);\n"
30356
+ },
30357
+ {
30358
+ "name": "0001_regular_ultimates.sql",
30359
+ "sql": "ALTER TABLE `acp_session` ADD `last_terminal_command_id` text;"
30333
30360
  }
30334
30361
  ];
30335
30362
 
@@ -30347,6 +30374,7 @@ var acpSession = sqliteTable("acp_session", {
30347
30374
  nativeSessionId: text("native_session_id").notNull(),
30348
30375
  cwd: text("cwd").notNull(),
30349
30376
  additionalDirectories: text("additional_directories").notNull(),
30377
+ lastTerminalCommandId: text("last_terminal_command_id"),
30350
30378
  prompted: integer2("prompted", { mode: "boolean" }).notNull(),
30351
30379
  title: text("title").notNull(),
30352
30380
  updatedAt: text("updated_at").notNull()
@@ -30362,15 +30390,17 @@ var AcpStoredSession = class {
30362
30390
  additionalDirectories;
30363
30391
  agentId;
30364
30392
  cwd;
30393
+ lastTerminalCommandId;
30365
30394
  nativeSessionId;
30366
30395
  prompted;
30367
30396
  sessionId;
30368
30397
  title;
30369
30398
  updatedAt;
30370
- constructor(sessionId, agentId, nativeSessionId, cwd, additionalDirectories, prompted, title2, updatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
30399
+ constructor(sessionId, agentId, nativeSessionId, cwd, additionalDirectories, prompted, title2, updatedAt = (/* @__PURE__ */ new Date()).toISOString(), lastTerminalCommandId = null) {
30371
30400
  this.additionalDirectories = [...additionalDirectories];
30372
30401
  this.agentId = agentId;
30373
30402
  this.cwd = cwd;
30403
+ this.lastTerminalCommandId = lastTerminalCommandId;
30374
30404
  this.nativeSessionId = nativeSessionId;
30375
30405
  this.prompted = prompted;
30376
30406
  this.sessionId = sessionId;
@@ -30431,6 +30461,7 @@ var storedSessionRowSchema = external_exports.object({
30431
30461
  additionalDirectories: external_exports.string(),
30432
30462
  agentId: external_exports.string(),
30433
30463
  cwd: external_exports.string(),
30464
+ lastTerminalCommandId: external_exports.string().nullable(),
30434
30465
  nativeSessionId: external_exports.string(),
30435
30466
  prompted: external_exports.boolean(),
30436
30467
  sessionId: external_exports.string(),
@@ -30450,7 +30481,8 @@ function decodeStoredSession(value) {
30450
30481
  additionalDirectories,
30451
30482
  row.prompted,
30452
30483
  row.title,
30453
- row.updatedAt
30484
+ row.updatedAt,
30485
+ row.lastTerminalCommandId
30454
30486
  );
30455
30487
  }
30456
30488
  var SqliteAcpSessionStore = class {
@@ -30517,6 +30549,7 @@ var SqliteAcpSessionStore = class {
30517
30549
  additionalDirectories: JSON.stringify(session.additionalDirectories),
30518
30550
  agentId: session.agentId,
30519
30551
  cwd: session.cwd,
30552
+ lastTerminalCommandId: session.lastTerminalCommandId,
30520
30553
  nativeSessionId: session.nativeSessionId,
30521
30554
  prompted: session.prompted,
30522
30555
  sessionId: session.sessionId,
@@ -30569,6 +30602,7 @@ var AgentSession = class _AgentSession {
30569
30602
  #commands = [];
30570
30603
  #configRevision = 0;
30571
30604
  #configOptions = [];
30605
+ #lastTerminalCommandId = null;
30572
30606
  #prompted = false;
30573
30607
  #nativePrompt = null;
30574
30608
  #sessionLoad = { kind: "not-requested" };
@@ -30672,6 +30706,7 @@ var AgentSession = class _AgentSession {
30672
30706
  this.#capabilities,
30673
30707
  this.#commands,
30674
30708
  this.#configOptions,
30709
+ this.#prompted,
30675
30710
  this.#restored
30676
30711
  );
30677
30712
  loadHistory = async (signal) => {
@@ -30905,6 +30940,7 @@ var AgentSession = class _AgentSession {
30905
30940
  } else if (stored instanceof FoundAcpStoredSession && stored.session.agentId === this.#agentId && stored.session.cwd === this.#cwd && arraysEqual(stored.session.additionalDirectories, this.#additionalDirectories)) {
30906
30941
  this.selectNativeSession(stored.session.nativeSessionId);
30907
30942
  this.#prompted = stored.session.prompted;
30943
+ this.#lastTerminalCommandId = stored.session.lastTerminalCommandId;
30908
30944
  this.#sessionTitle = stored.session.title;
30909
30945
  this.#restored = true;
30910
30946
  if (this.#capabilities.resumeSession) {
@@ -30978,7 +31014,9 @@ var AgentSession = class _AgentSession {
30978
31014
  this.#cwd,
30979
31015
  this.#additionalDirectories,
30980
31016
  this.#prompted,
30981
- this.#sessionTitle ?? ""
31017
+ this.#sessionTitle ?? "",
31018
+ (/* @__PURE__ */ new Date()).toISOString(),
31019
+ this.#lastTerminalCommandId
30982
31020
  )
30983
31021
  );
30984
31022
  };
@@ -31178,7 +31216,9 @@ var AgentSession = class _AgentSession {
31178
31216
  this.#cwd,
31179
31217
  this.#additionalDirectories,
31180
31218
  true,
31181
- this.#sessionTitle
31219
+ this.#sessionTitle,
31220
+ (/* @__PURE__ */ new Date()).toISOString(),
31221
+ this.#lastTerminalCommandId
31182
31222
  )
31183
31223
  );
31184
31224
  this.#prompted = true;
@@ -31230,6 +31270,20 @@ var AgentSession = class _AgentSession {
31230
31270
  usage: result.usage ?? null
31231
31271
  });
31232
31272
  }
31273
+ this.#lastTerminalCommandId = options.commandId;
31274
+ this.#store.write(
31275
+ new AcpStoredSession(
31276
+ this.#mobiusSessionId,
31277
+ this.#agentId,
31278
+ this.#updates.sessionId(),
31279
+ this.#cwd,
31280
+ this.#additionalDirectories,
31281
+ true,
31282
+ this.#sessionTitle ?? "",
31283
+ (/* @__PURE__ */ new Date()).toISOString(),
31284
+ this.#lastTerminalCommandId
31285
+ )
31286
+ );
31233
31287
  return result;
31234
31288
  } catch (error62) {
31235
31289
  await running.activities.finish();
@@ -31422,7 +31476,9 @@ var AgentSession = class _AgentSession {
31422
31476
  this.#cwd,
31423
31477
  this.#additionalDirectories,
31424
31478
  this.#prompted,
31425
- this.#sessionTitle ?? ""
31479
+ this.#sessionTitle ?? "",
31480
+ (/* @__PURE__ */ new Date()).toISOString(),
31481
+ this.#lastTerminalCommandId
31426
31482
  )
31427
31483
  );
31428
31484
  }
@@ -32468,9 +32524,17 @@ var AgentRuntimeManager = class {
32468
32524
  const openedKey = `${options2.agent.id}:${runtime.nativeSessionId()}`;
32469
32525
  this.#nativeOperations.add(openedKey);
32470
32526
  try {
32527
+ const prepared = runtime.prepared();
32528
+ if (origin.kind === "fork" && options2.agent.id === "claude") {
32529
+ await this.#retireSessionProcess(
32530
+ options2.sessionId,
32531
+ runtime,
32532
+ async () => await runtime.closeProcess()
32533
+ );
32534
+ }
32471
32535
  return {
32472
32536
  sessionId: options2.sessionId,
32473
- prepared: runtime.prepared()
32537
+ prepared
32474
32538
  };
32475
32539
  } finally {
32476
32540
  this.#nativeOperations.delete(openedKey);
@@ -39937,6 +40001,7 @@ var readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTur
39937
40001
 
39938
40002
  // src/native-sessions/service.ts
39939
40003
  import { randomUUID as randomUUID3 } from "node:crypto";
40004
+ import { basename as basename5 } from "node:path";
39940
40005
 
39941
40006
  // src/native-sessions/acp-history.ts
39942
40007
  async function readAcpHistory(sessions, directories, bindingId, options, nativeSessionId) {
@@ -40077,6 +40142,64 @@ var NativeSessionService = class {
40077
40142
  sessionId: command.sessionId
40078
40143
  };
40079
40144
  }
40145
+ if (command.action === "fork-recorded") {
40146
+ const source = this.#sessions.findSessions([command.sessionId])[0];
40147
+ if (source === void 0 || !source.prompted) {
40148
+ throw new AcpExecutionError(
40149
+ "The source conversation has no resumable native Agent session",
40150
+ {},
40151
+ "native_session_not_found"
40152
+ );
40153
+ }
40154
+ if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index) => path2 !== additionalDirectories[index])) {
40155
+ throw new AcpExecutionError(
40156
+ "The source conversation execution target does not match the fork request",
40157
+ {},
40158
+ "native_session_target_changed"
40159
+ );
40160
+ }
40161
+ if (source.lastTerminalCommandId !== command.throughCommandId) {
40162
+ throw new AcpExecutionError(
40163
+ "The selected Turn is no longer the source conversation head",
40164
+ {},
40165
+ "fork_point_stale"
40166
+ );
40167
+ }
40168
+ const opened2 = await this.#sessions.openNativeSession(
40169
+ { ...options, sessionId: command.targetSessionId },
40170
+ { kind: "fork", nativeSessionId: source.nativeSessionId }
40171
+ );
40172
+ signal.throwIfAborted();
40173
+ const directory = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
40174
+ const ready2 = {
40175
+ additionalDirectories: additionalDirectories.map((path2, index) => ({
40176
+ directoryId: command.additionalDirectoryIds[index] ?? command.directoryId,
40177
+ name: basename5(path2) || path2
40178
+ })),
40179
+ agentId: command.agentId,
40180
+ agentName: opened2.prepared.agentName,
40181
+ agentVersion: opened2.prepared.agentVersion,
40182
+ capabilities: opened2.prepared.capabilities,
40183
+ commands: opened2.prepared.commands,
40184
+ configOptions: opened2.prepared.configOptions,
40185
+ directoryId: command.directoryId,
40186
+ directoryLabel: directory.directoryLabel,
40187
+ kind: "session.ready",
40188
+ requestId: command.requestId,
40189
+ restored: true,
40190
+ sessionId: opened2.sessionId
40191
+ };
40192
+ this.record(command, "native_recorded_session_forked");
40193
+ return {
40194
+ action: "fork-recorded",
40195
+ kind: "native.session.result",
40196
+ ready: ready2,
40197
+ requestId: command.requestId,
40198
+ sessionId: command.sessionId,
40199
+ targetSessionId: command.targetSessionId,
40200
+ title: source.title || "Untitled session"
40201
+ };
40202
+ }
40080
40203
  const prepared = await this.#sessions.prepareNativeSessionBrowser(options);
40081
40204
  if (!prepared.capabilities.listSessions) {
40082
40205
  throw new AcpExecutionError(
@@ -41398,7 +41521,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
41398
41521
  // src/artifacts/local-file-streamer.ts
41399
41522
  import { createReadStream as createReadStream2 } from "node:fs";
41400
41523
  import { realpath as realpath9, stat as stat8 } from "node:fs/promises";
41401
- import { basename as basename5, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve7 } from "node:path";
41524
+ import { basename as basename6, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve7 } from "node:path";
41402
41525
  import { fileURLToPath as fileURLToPath2 } from "node:url";
41403
41526
  var CHUNK_BYTES = 192 * 1024;
41404
41527
  function requestedPath(value) {
@@ -41449,7 +41572,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
41449
41572
  kind: FILE_BEGIN_KIND,
41450
41573
  mediaType: raster?.mimeType ?? "application/octet-stream",
41451
41574
  modifiedAt: before.mtime.toISOString(),
41452
- name: basename5(target) || "file",
41575
+ name: basename6(target) || "file",
41453
41576
  requestId: command.requestId,
41454
41577
  sessionId: command.sessionId
41455
41578
  });
@@ -41479,7 +41602,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
41479
41602
  }
41480
41603
 
41481
41604
  // src/authorization/resolve-session-directories.ts
41482
- import { basename as basename6 } from "node:path";
41605
+ import { basename as basename7 } from "node:path";
41483
41606
  var ResolvedSessionDirectories = class {
41484
41607
  additionalDirectories;
41485
41608
  additionalDirectoryEntries;
@@ -41504,7 +41627,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
41504
41627
  additionalDirectories.push(directory);
41505
41628
  additionalDirectoryEntries.push({
41506
41629
  directoryId: additionalDirectoryId,
41507
- name: basename6(directory)
41630
+ name: basename7(directory)
41508
41631
  });
41509
41632
  }
41510
41633
  return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
@@ -42241,14 +42364,15 @@ async function executePrompt({
42241
42364
  const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
42242
42365
  const executionAgent = appliedSettings?.agent ?? agent;
42243
42366
  const sessionConfigurations = appliedSettings?.sessionConfigurations;
42367
+ const preparation = {
42368
+ additionalDirectories: resolved.additionalDirectories,
42369
+ agent: executionAgent,
42370
+ cwd: resolved.cwd,
42371
+ sessionId: command.sessionId,
42372
+ signal
42373
+ };
42374
+ let prepared = await sessions.prepareExecutionSession(preparation);
42244
42375
  if (command.sessionConfigurations !== void 0) {
42245
- const prepared = await sessions.prepareExecutionSession({
42246
- additionalDirectories: resolved.additionalDirectories,
42247
- agent: executionAgent,
42248
- cwd: resolved.cwd,
42249
- sessionId: command.sessionId,
42250
- signal
42251
- });
42252
42376
  if (availability.disposition === SessionPromptDisposition.Steer) {
42253
42377
  assertAppliedSessionConfiguration(prepared.configOptions, sessionConfigurations ?? []);
42254
42378
  } else {
@@ -42264,6 +42388,7 @@ async function executePrompt({
42264
42388
  command.sessionId,
42265
42389
  signal
42266
42390
  );
42391
+ prepared = await sessions.prepareExecutionSession(preparation);
42267
42392
  }
42268
42393
  }
42269
42394
  audit.record({
@@ -42282,6 +42407,24 @@ async function executePrompt({
42282
42407
  }
42283
42408
  }
42284
42409
  const stream = activateAttempt();
42410
+ if (!prepared.prompted) {
42411
+ const listing = await directories.list(config2.bindingId, command.directoryId, signal);
42412
+ publisher.publish(command.sessionId, {
42413
+ additionalDirectories: resolved.additionalDirectoryEntries,
42414
+ agentId: command.agentId,
42415
+ agentName: prepared.agentName,
42416
+ agentVersion: prepared.agentVersion,
42417
+ capabilities: prepared.capabilities,
42418
+ commands: prepared.commands,
42419
+ configOptions: prepared.configOptions,
42420
+ directoryId: command.directoryId,
42421
+ directoryLabel: listing.directoryLabel,
42422
+ kind: SESSION_READY_KIND,
42423
+ requestId: command.commandId,
42424
+ restored: prepared.restored,
42425
+ sessionId: command.sessionId
42426
+ });
42427
+ }
42285
42428
  publisher.publish(command.sessionId, {
42286
42429
  commandId: command.commandId,
42287
42430
  epoch: stream.epoch,
@@ -42535,7 +42678,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
42535
42678
  // src/native-sessions/handle-native-requests.ts
42536
42679
  import { WebSocket as WebSocket5 } from "undici";
42537
42680
  function createNativeSessionRequestHandler(dependencies) {
42538
- const { audit, diagnostics, nativeSessions, signal, socket, timer } = dependencies;
42681
+ const { audit, diagnostics, nativeSessions, publisher, signal, socket, timer } = dependencies;
42539
42682
  const pending = /* @__PURE__ */ new Map();
42540
42683
  const cancel = (command) => {
42541
42684
  const request = pending.get(command.requestId);
@@ -42587,6 +42730,17 @@ function createNativeSessionRequestHandler(dependencies) {
42587
42730
  }
42588
42731
  operationSignal.throwIfAborted();
42589
42732
  const result = await nativeSessions.execute(command, operationSignal);
42733
+ if (command.action === "fork-recorded" && result.action === "fork-recorded") {
42734
+ publisher.publishBatch(result.ready.sessionId, [
42735
+ result.ready,
42736
+ {
42737
+ kind: "session.forked",
42738
+ sessionId: result.ready.sessionId,
42739
+ sourceSessionId: command.sessionId,
42740
+ throughCommandId: command.throughCommandId
42741
+ }
42742
+ ]);
42743
+ }
42590
42744
  if (socket.readyState === WebSocket5.OPEN) {
42591
42745
  send(socket, result);
42592
42746
  }
@@ -42672,6 +42826,7 @@ function createDaemonCommandHandler({
42672
42826
  audit,
42673
42827
  diagnostics,
42674
42828
  nativeSessions,
42829
+ publisher,
42675
42830
  signal,
42676
42831
  socket,
42677
42832
  timer
@@ -43424,6 +43579,16 @@ var SessionEventOutbox = class {
43424
43579
  this.#database.close();
43425
43580
  };
43426
43581
  enqueue = (sessionId, payload, critical) => {
43582
+ const envelope2 = this.enqueueBatch(sessionId, [payload], critical)[0];
43583
+ if (envelope2 === void 0) {
43584
+ throw new Error("The Session event outbox did not enqueue the event");
43585
+ }
43586
+ return envelope2;
43587
+ };
43588
+ enqueueBatch = (sessionId, payloads, critical) => {
43589
+ if (payloads.length < 1 || payloads.length > 32) {
43590
+ throw new Error("A Session event batch must contain between 1 and 32 events");
43591
+ }
43427
43592
  this.#database.exec("BEGIN IMMEDIATE");
43428
43593
  try {
43429
43594
  const state = this.#database.prepare(
@@ -43432,39 +43597,52 @@ var SessionEventOutbox = class {
43432
43597
  WHERE singleton = 1`
43433
43598
  ).get();
43434
43599
  const sourceSeq = rowNumber(state, "next_source_seq");
43435
- if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + 1)) {
43600
+ if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + payloads.length)) {
43436
43601
  throw new Error("The Session event source sequence is exhausted");
43437
43602
  }
43438
- const envelope2 = {
43439
- delivery: {
43440
- eventId: randomUUID7(),
43441
- kind: "reliable",
43442
- sourceSeq: sourceSeq.toString(),
43443
- streamId: rowString(state, "stream_id")
43444
- },
43445
- kind: SESSION_EVENT_KIND,
43446
- payload,
43447
- sessionId
43448
- };
43449
- const encoded = encodeSessionEventEnvelope(envelope2);
43450
- const byteLength = Buffer.byteLength(encoded, "utf8");
43603
+ const streamId = rowString(state, "stream_id");
43604
+ const stored = payloads.map((payload, index) => {
43605
+ const envelope2 = {
43606
+ delivery: {
43607
+ eventId: randomUUID7(),
43608
+ kind: "reliable",
43609
+ sourceSeq: (sourceSeq + index).toString(),
43610
+ streamId
43611
+ },
43612
+ kind: SESSION_EVENT_KIND,
43613
+ payload,
43614
+ sessionId
43615
+ };
43616
+ const encoded = encodeSessionEventEnvelope(envelope2);
43617
+ return { byteLength: Buffer.byteLength(encoded, "utf8"), encoded, envelope: envelope2 };
43618
+ });
43619
+ const byteLength = stored.reduce((total, entry) => total + entry.byteLength, 0);
43451
43620
  const maximumBytes = critical ? this.#limits.criticalEventBytes : this.#limits.standardEventBytes;
43452
43621
  if (rowNumber(state, "total_bytes") + byteLength > maximumBytes) {
43453
43622
  throw new SessionEventOutboxCapacityError();
43454
43623
  }
43455
- this.#database.prepare(
43624
+ const insert = this.#database.prepare(
43456
43625
  `INSERT INTO relay_session_event_outbox (
43457
- event_id, session_id, source_seq, byte_length, envelope_json
43458
- ) VALUES (?, ?, ?, ?, ?)`
43459
- ).run(envelope2.delivery.eventId, sessionId, sourceSeq, byteLength, encoded);
43626
+ event_id, session_id, source_seq, byte_length, envelope_json
43627
+ ) VALUES (?, ?, ?, ?, ?)`
43628
+ );
43629
+ for (const entry of stored) {
43630
+ insert.run(
43631
+ entry.envelope.delivery.eventId,
43632
+ sessionId,
43633
+ Number(entry.envelope.delivery.sourceSeq),
43634
+ entry.byteLength,
43635
+ entry.encoded
43636
+ );
43637
+ }
43460
43638
  this.#database.prepare(
43461
43639
  `UPDATE relay_session_event_outbox_state
43462
- SET next_source_seq = next_source_seq + 1,
43640
+ SET next_source_seq = next_source_seq + ?,
43463
43641
  total_bytes = total_bytes + ?
43464
43642
  WHERE singleton = 1`
43465
- ).run(byteLength);
43643
+ ).run(stored.length, byteLength);
43466
43644
  this.#database.exec("COMMIT");
43467
- return envelope2;
43645
+ return stored.map((entry) => entry.envelope);
43468
43646
  } catch (error62) {
43469
43647
  this.#database.exec("ROLLBACK");
43470
43648
  throw error62;
@@ -43565,7 +43743,7 @@ import { WebSocket as WebSocket9 } from "undici";
43565
43743
  var SESSION_EVENT_REPLAY_WINDOW = 16;
43566
43744
  var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
43567
43745
  function reservesSessionEventCapacity(event) {
43568
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND) {
43746
+ if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
43569
43747
  return true;
43570
43748
  }
43571
43749
  return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
@@ -43638,6 +43816,11 @@ var DaemonSessionEventPublisher = class {
43638
43816
  }
43639
43817
  this.#publishNextBatch();
43640
43818
  };
43819
+ publishBatch = (sessionId, events) => {
43820
+ const critical = events.some(reservesSessionEventCapacity);
43821
+ this.#outbox.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
43822
+ this.#publishNextBatch();
43823
+ };
43641
43824
  quarantine = (rejection) => {
43642
43825
  if (!this.#outbox.quarantine(rejection)) {
43643
43826
  return;