@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/runtime.js CHANGED
@@ -21082,6 +21082,12 @@ var nativeSessionRequestSchema = external_exports.discriminatedUnion("action", [
21082
21082
  entryId: identifierStringSchema,
21083
21083
  targetSessionId: identifierStringSchema
21084
21084
  }).readonly(),
21085
+ external_exports.strictObject({
21086
+ ...identity,
21087
+ action: external_exports.literal("fork-recorded"),
21088
+ targetSessionId: identifierStringSchema,
21089
+ throughCommandId: identifierStringSchema
21090
+ }).readonly(),
21085
21091
  external_exports.strictObject({
21086
21092
  ...identity,
21087
21093
  action: external_exports.literal("delete"),
@@ -21105,6 +21111,12 @@ var nativeSessionCommandSchema = external_exports.discriminatedUnion("action", [
21105
21111
  entryId: identifierStringSchema,
21106
21112
  targetSessionId: identifierStringSchema
21107
21113
  }).readonly(),
21114
+ external_exports.strictObject({
21115
+ ...identity,
21116
+ action: external_exports.literal("fork-recorded"),
21117
+ targetSessionId: identifierStringSchema,
21118
+ throughCommandId: identifierStringSchema
21119
+ }).readonly(),
21108
21120
  external_exports.strictObject({
21109
21121
  ...identity,
21110
21122
  action: external_exports.literal("delete"),
@@ -21154,7 +21166,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21154
21166
  }).readonly(),
21155
21167
  external_exports.strictObject({
21156
21168
  ...resultEnvelope,
21157
- action: external_exports.enum(["import", "fork"]),
21169
+ action: external_exports.enum(["import", "fork", "fork-recorded"]),
21158
21170
  targetSessionId: identifierStringSchema,
21159
21171
  ready: sessionReadyEventSchema,
21160
21172
  title: external_exports.string().max(500)
@@ -21203,6 +21215,7 @@ var SESSION_EVENT_KIND = "session.event";
21203
21215
  var SESSION_EVENT_ACK_KIND = "session.event.ack";
21204
21216
  var SESSION_EVENT_DEFERRED_KIND = "session.event.deferred";
21205
21217
  var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
21218
+ var SESSION_FORKED_KIND = "session.forked";
21206
21219
  var SessionEventRejectionCode = {
21207
21220
  IdempotencyConflict: "idempotency_conflict",
21208
21221
  InvalidEvent: "invalid_event",
@@ -21220,13 +21233,13 @@ var reliableDeliverySchema = external_exports.strictObject({
21220
21233
  sourceSeq: external_exports.string().regex(/^(?:0|[1-9][0-9]*)$/u).max(40),
21221
21234
  streamId: identifierStringSchema
21222
21235
  }).readonly();
21223
- var reliableEventEnvelopeSchema = external_exports.strictObject({
21236
+ var reliableSessionEventEnvelopeSchema = external_exports.strictObject({
21224
21237
  delivery: reliableDeliverySchema,
21225
21238
  kind: external_exports.literal(SESSION_EVENT_KIND),
21226
21239
  payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
21227
21240
  sessionId: identifierStringSchema
21228
21241
  }).readonly();
21229
- var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableEventEnvelopeSchema]).readonly();
21242
+ var eventEnvelopeSchema = external_exports.union([ephemeralEventEnvelopeSchema, reliableSessionEventEnvelopeSchema]).readonly();
21230
21243
  var acknowledgementOutcomeSchema = external_exports.discriminatedUnion("kind", [
21231
21244
  external_exports.strictObject({ kind: external_exports.literal("relayed") }).readonly(),
21232
21245
  external_exports.strictObject({
@@ -21255,6 +21268,12 @@ var eventRejectedSchema = external_exports.strictObject({
21255
21268
  }).readonly();
21256
21269
  var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
21257
21270
  var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
21271
+ var sessionForkedSchema = external_exports.strictObject({
21272
+ kind: external_exports.literal(SESSION_FORKED_KIND),
21273
+ sessionId: identifierStringSchema,
21274
+ sourceSessionId: identifierStringSchema,
21275
+ throughCommandId: identifierStringSchema
21276
+ }).readonly();
21258
21277
  function decode5(encoded, schema) {
21259
21278
  let value;
21260
21279
  try {
@@ -21292,6 +21311,8 @@ function decodeRecordedSessionEvent(encoded) {
21292
21311
  switch (kind) {
21293
21312
  case SESSION_QUEUE_CHANGED_KIND:
21294
21313
  return decode5(encoded, sessionQueueChangedSchema);
21314
+ case SESSION_FORKED_KIND:
21315
+ return decode5(encoded, sessionForkedSchema);
21295
21316
  case AGENT_ACTIVITY_KIND:
21296
21317
  return decodeAgentActivityEvent(encoded);
21297
21318
  case AGENT_ACTIVITY_NARRATION_KIND:
@@ -28332,13 +28353,15 @@ var AcpPreparedSession = class {
28332
28353
  capabilities;
28333
28354
  commands;
28334
28355
  configOptions;
28356
+ prompted;
28335
28357
  restored;
28336
- constructor(agentName, agentVersion, capabilities, commands, configOptions, restored) {
28358
+ constructor(agentName, agentVersion, capabilities, commands, configOptions, prompted, restored) {
28337
28359
  this.agentName = agentName;
28338
28360
  this.agentVersion = agentVersion;
28339
28361
  this.capabilities = capabilities;
28340
28362
  this.commands = commands;
28341
28363
  this.configOptions = configOptions;
28364
+ this.prompted = prompted;
28342
28365
  this.restored = restored;
28343
28366
  }
28344
28367
  };
@@ -34508,6 +34531,10 @@ var acpSessionStoreMigrations = [
34508
34531
  {
34509
34532
  "name": "0000_slimy_captain_midlands.sql",
34510
34533
  "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"
34534
+ },
34535
+ {
34536
+ "name": "0001_regular_ultimates.sql",
34537
+ "sql": "ALTER TABLE `acp_session` ADD `last_terminal_command_id` text;"
34511
34538
  }
34512
34539
  ];
34513
34540
 
@@ -34525,6 +34552,7 @@ var acpSession = sqliteTable("acp_session", {
34525
34552
  nativeSessionId: text("native_session_id").notNull(),
34526
34553
  cwd: text("cwd").notNull(),
34527
34554
  additionalDirectories: text("additional_directories").notNull(),
34555
+ lastTerminalCommandId: text("last_terminal_command_id"),
34528
34556
  prompted: integer2("prompted", { mode: "boolean" }).notNull(),
34529
34557
  title: text("title").notNull(),
34530
34558
  updatedAt: text("updated_at").notNull()
@@ -34540,15 +34568,17 @@ var AcpStoredSession = class {
34540
34568
  additionalDirectories;
34541
34569
  agentId;
34542
34570
  cwd;
34571
+ lastTerminalCommandId;
34543
34572
  nativeSessionId;
34544
34573
  prompted;
34545
34574
  sessionId;
34546
34575
  title;
34547
34576
  updatedAt;
34548
- constructor(sessionId, agentId, nativeSessionId, cwd, additionalDirectories, prompted, title2, updatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
34577
+ constructor(sessionId, agentId, nativeSessionId, cwd, additionalDirectories, prompted, title2, updatedAt = (/* @__PURE__ */ new Date()).toISOString(), lastTerminalCommandId = null) {
34549
34578
  this.additionalDirectories = [...additionalDirectories];
34550
34579
  this.agentId = agentId;
34551
34580
  this.cwd = cwd;
34581
+ this.lastTerminalCommandId = lastTerminalCommandId;
34552
34582
  this.nativeSessionId = nativeSessionId;
34553
34583
  this.prompted = prompted;
34554
34584
  this.sessionId = sessionId;
@@ -34609,6 +34639,7 @@ var storedSessionRowSchema = external_exports.object({
34609
34639
  additionalDirectories: external_exports.string(),
34610
34640
  agentId: external_exports.string(),
34611
34641
  cwd: external_exports.string(),
34642
+ lastTerminalCommandId: external_exports.string().nullable(),
34612
34643
  nativeSessionId: external_exports.string(),
34613
34644
  prompted: external_exports.boolean(),
34614
34645
  sessionId: external_exports.string(),
@@ -34628,7 +34659,8 @@ function decodeStoredSession(value) {
34628
34659
  additionalDirectories,
34629
34660
  row.prompted,
34630
34661
  row.title,
34631
- row.updatedAt
34662
+ row.updatedAt,
34663
+ row.lastTerminalCommandId
34632
34664
  );
34633
34665
  }
34634
34666
  var SqliteAcpSessionStore = class {
@@ -34695,6 +34727,7 @@ var SqliteAcpSessionStore = class {
34695
34727
  additionalDirectories: JSON.stringify(session.additionalDirectories),
34696
34728
  agentId: session.agentId,
34697
34729
  cwd: session.cwd,
34730
+ lastTerminalCommandId: session.lastTerminalCommandId,
34698
34731
  nativeSessionId: session.nativeSessionId,
34699
34732
  prompted: session.prompted,
34700
34733
  sessionId: session.sessionId,
@@ -34747,6 +34780,7 @@ var AgentSession = class _AgentSession {
34747
34780
  #commands = [];
34748
34781
  #configRevision = 0;
34749
34782
  #configOptions = [];
34783
+ #lastTerminalCommandId = null;
34750
34784
  #prompted = false;
34751
34785
  #nativePrompt = null;
34752
34786
  #sessionLoad = { kind: "not-requested" };
@@ -34850,6 +34884,7 @@ var AgentSession = class _AgentSession {
34850
34884
  this.#capabilities,
34851
34885
  this.#commands,
34852
34886
  this.#configOptions,
34887
+ this.#prompted,
34853
34888
  this.#restored
34854
34889
  );
34855
34890
  loadHistory = async (signal) => {
@@ -35083,6 +35118,7 @@ var AgentSession = class _AgentSession {
35083
35118
  } else if (stored instanceof FoundAcpStoredSession && stored.session.agentId === this.#agentId && stored.session.cwd === this.#cwd && arraysEqual(stored.session.additionalDirectories, this.#additionalDirectories)) {
35084
35119
  this.selectNativeSession(stored.session.nativeSessionId);
35085
35120
  this.#prompted = stored.session.prompted;
35121
+ this.#lastTerminalCommandId = stored.session.lastTerminalCommandId;
35086
35122
  this.#sessionTitle = stored.session.title;
35087
35123
  this.#restored = true;
35088
35124
  if (this.#capabilities.resumeSession) {
@@ -35156,7 +35192,9 @@ var AgentSession = class _AgentSession {
35156
35192
  this.#cwd,
35157
35193
  this.#additionalDirectories,
35158
35194
  this.#prompted,
35159
- this.#sessionTitle ?? ""
35195
+ this.#sessionTitle ?? "",
35196
+ (/* @__PURE__ */ new Date()).toISOString(),
35197
+ this.#lastTerminalCommandId
35160
35198
  )
35161
35199
  );
35162
35200
  };
@@ -35356,7 +35394,9 @@ var AgentSession = class _AgentSession {
35356
35394
  this.#cwd,
35357
35395
  this.#additionalDirectories,
35358
35396
  true,
35359
- this.#sessionTitle
35397
+ this.#sessionTitle,
35398
+ (/* @__PURE__ */ new Date()).toISOString(),
35399
+ this.#lastTerminalCommandId
35360
35400
  )
35361
35401
  );
35362
35402
  this.#prompted = true;
@@ -35408,6 +35448,20 @@ var AgentSession = class _AgentSession {
35408
35448
  usage: result.usage ?? null
35409
35449
  });
35410
35450
  }
35451
+ this.#lastTerminalCommandId = options.commandId;
35452
+ this.#store.write(
35453
+ new AcpStoredSession(
35454
+ this.#mobiusSessionId,
35455
+ this.#agentId,
35456
+ this.#updates.sessionId(),
35457
+ this.#cwd,
35458
+ this.#additionalDirectories,
35459
+ true,
35460
+ this.#sessionTitle ?? "",
35461
+ (/* @__PURE__ */ new Date()).toISOString(),
35462
+ this.#lastTerminalCommandId
35463
+ )
35464
+ );
35411
35465
  return result;
35412
35466
  } catch (error62) {
35413
35467
  await running.activities.finish();
@@ -35600,7 +35654,9 @@ var AgentSession = class _AgentSession {
35600
35654
  this.#cwd,
35601
35655
  this.#additionalDirectories,
35602
35656
  this.#prompted,
35603
- this.#sessionTitle ?? ""
35657
+ this.#sessionTitle ?? "",
35658
+ (/* @__PURE__ */ new Date()).toISOString(),
35659
+ this.#lastTerminalCommandId
35604
35660
  )
35605
35661
  );
35606
35662
  }
@@ -36646,9 +36702,17 @@ var AgentRuntimeManager = class {
36646
36702
  const openedKey = `${options2.agent.id}:${runtime.nativeSessionId()}`;
36647
36703
  this.#nativeOperations.add(openedKey);
36648
36704
  try {
36705
+ const prepared = runtime.prepared();
36706
+ if (origin.kind === "fork" && options2.agent.id === "claude") {
36707
+ await this.#retireSessionProcess(
36708
+ options2.sessionId,
36709
+ runtime,
36710
+ async () => await runtime.closeProcess()
36711
+ );
36712
+ }
36649
36713
  return {
36650
36714
  sessionId: options2.sessionId,
36651
- prepared: runtime.prepared()
36715
+ prepared
36652
36716
  };
36653
36717
  } finally {
36654
36718
  this.#nativeOperations.delete(openedKey);
@@ -39059,6 +39123,7 @@ var readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTur
39059
39123
 
39060
39124
  // src/native-sessions/service.ts
39061
39125
  import { randomUUID as randomUUID2 } from "node:crypto";
39126
+ import { basename as basename4 } from "node:path";
39062
39127
 
39063
39128
  // src/native-sessions/acp-history.ts
39064
39129
  async function readAcpHistory(sessions, directories, bindingId, options, nativeSessionId) {
@@ -39199,6 +39264,64 @@ var NativeSessionService = class {
39199
39264
  sessionId: command.sessionId
39200
39265
  };
39201
39266
  }
39267
+ if (command.action === "fork-recorded") {
39268
+ const source = this.#sessions.findSessions([command.sessionId])[0];
39269
+ if (source === void 0 || !source.prompted) {
39270
+ throw new AcpExecutionError(
39271
+ "The source conversation has no resumable native Agent session",
39272
+ {},
39273
+ "native_session_not_found"
39274
+ );
39275
+ }
39276
+ if (source.agentId !== command.agentId || source.cwd !== cwd || source.additionalDirectories.length !== additionalDirectories.length || source.additionalDirectories.some((path2, index) => path2 !== additionalDirectories[index])) {
39277
+ throw new AcpExecutionError(
39278
+ "The source conversation execution target does not match the fork request",
39279
+ {},
39280
+ "native_session_target_changed"
39281
+ );
39282
+ }
39283
+ if (source.lastTerminalCommandId !== command.throughCommandId) {
39284
+ throw new AcpExecutionError(
39285
+ "The selected Turn is no longer the source conversation head",
39286
+ {},
39287
+ "fork_point_stale"
39288
+ );
39289
+ }
39290
+ const opened2 = await this.#sessions.openNativeSession(
39291
+ { ...options, sessionId: command.targetSessionId },
39292
+ { kind: "fork", nativeSessionId: source.nativeSessionId }
39293
+ );
39294
+ signal.throwIfAborted();
39295
+ const directory = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
39296
+ const ready2 = {
39297
+ additionalDirectories: additionalDirectories.map((path2, index) => ({
39298
+ directoryId: command.additionalDirectoryIds[index] ?? command.directoryId,
39299
+ name: basename4(path2) || path2
39300
+ })),
39301
+ agentId: command.agentId,
39302
+ agentName: opened2.prepared.agentName,
39303
+ agentVersion: opened2.prepared.agentVersion,
39304
+ capabilities: opened2.prepared.capabilities,
39305
+ commands: opened2.prepared.commands,
39306
+ configOptions: opened2.prepared.configOptions,
39307
+ directoryId: command.directoryId,
39308
+ directoryLabel: directory.directoryLabel,
39309
+ kind: "session.ready",
39310
+ requestId: command.requestId,
39311
+ restored: true,
39312
+ sessionId: opened2.sessionId
39313
+ };
39314
+ this.record(command, "native_recorded_session_forked");
39315
+ return {
39316
+ action: "fork-recorded",
39317
+ kind: "native.session.result",
39318
+ ready: ready2,
39319
+ requestId: command.requestId,
39320
+ sessionId: command.sessionId,
39321
+ targetSessionId: command.targetSessionId,
39322
+ title: source.title || "Untitled session"
39323
+ };
39324
+ }
39202
39325
  const prepared = await this.#sessions.prepareNativeSessionBrowser(options);
39203
39326
  if (!prepared.capabilities.listSessions) {
39204
39327
  throw new AcpExecutionError(
@@ -40520,7 +40643,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
40520
40643
  // src/artifacts/local-file-streamer.ts
40521
40644
  import { createReadStream as createReadStream2 } from "node:fs";
40522
40645
  import { realpath as realpath8, stat as stat7 } from "node:fs/promises";
40523
- import { basename as basename4, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve5 } from "node:path";
40646
+ import { basename as basename5, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve5 } from "node:path";
40524
40647
  import { fileURLToPath as fileURLToPath2 } from "node:url";
40525
40648
  var CHUNK_BYTES = 192 * 1024;
40526
40649
  function requestedPath(value) {
@@ -40571,7 +40694,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
40571
40694
  kind: FILE_BEGIN_KIND,
40572
40695
  mediaType: raster?.mimeType ?? "application/octet-stream",
40573
40696
  modifiedAt: before.mtime.toISOString(),
40574
- name: basename4(target) || "file",
40697
+ name: basename5(target) || "file",
40575
40698
  requestId: command.requestId,
40576
40699
  sessionId: command.sessionId
40577
40700
  });
@@ -40601,7 +40724,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
40601
40724
  }
40602
40725
 
40603
40726
  // src/authorization/resolve-session-directories.ts
40604
- import { basename as basename5 } from "node:path";
40727
+ import { basename as basename6 } from "node:path";
40605
40728
  var ResolvedSessionDirectories = class {
40606
40729
  additionalDirectories;
40607
40730
  additionalDirectoryEntries;
@@ -40626,7 +40749,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
40626
40749
  additionalDirectories.push(directory);
40627
40750
  additionalDirectoryEntries.push({
40628
40751
  directoryId: additionalDirectoryId,
40629
- name: basename5(directory)
40752
+ name: basename6(directory)
40630
40753
  });
40631
40754
  }
40632
40755
  return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
@@ -41363,14 +41486,15 @@ async function executePrompt({
41363
41486
  const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
41364
41487
  const executionAgent = appliedSettings?.agent ?? agent;
41365
41488
  const sessionConfigurations = appliedSettings?.sessionConfigurations;
41489
+ const preparation = {
41490
+ additionalDirectories: resolved.additionalDirectories,
41491
+ agent: executionAgent,
41492
+ cwd: resolved.cwd,
41493
+ sessionId: command.sessionId,
41494
+ signal
41495
+ };
41496
+ let prepared = await sessions.prepareExecutionSession(preparation);
41366
41497
  if (command.sessionConfigurations !== void 0) {
41367
- const prepared = await sessions.prepareExecutionSession({
41368
- additionalDirectories: resolved.additionalDirectories,
41369
- agent: executionAgent,
41370
- cwd: resolved.cwd,
41371
- sessionId: command.sessionId,
41372
- signal
41373
- });
41374
41498
  if (availability.disposition === SessionPromptDisposition.Steer) {
41375
41499
  assertAppliedSessionConfiguration(prepared.configOptions, sessionConfigurations ?? []);
41376
41500
  } else {
@@ -41386,6 +41510,7 @@ async function executePrompt({
41386
41510
  command.sessionId,
41387
41511
  signal
41388
41512
  );
41513
+ prepared = await sessions.prepareExecutionSession(preparation);
41389
41514
  }
41390
41515
  }
41391
41516
  audit.record({
@@ -41404,6 +41529,24 @@ async function executePrompt({
41404
41529
  }
41405
41530
  }
41406
41531
  const stream = activateAttempt();
41532
+ if (!prepared.prompted) {
41533
+ const listing = await directories.list(config2.bindingId, command.directoryId, signal);
41534
+ publisher.publish(command.sessionId, {
41535
+ additionalDirectories: resolved.additionalDirectoryEntries,
41536
+ agentId: command.agentId,
41537
+ agentName: prepared.agentName,
41538
+ agentVersion: prepared.agentVersion,
41539
+ capabilities: prepared.capabilities,
41540
+ commands: prepared.commands,
41541
+ configOptions: prepared.configOptions,
41542
+ directoryId: command.directoryId,
41543
+ directoryLabel: listing.directoryLabel,
41544
+ kind: SESSION_READY_KIND,
41545
+ requestId: command.commandId,
41546
+ restored: prepared.restored,
41547
+ sessionId: command.sessionId
41548
+ });
41549
+ }
41407
41550
  publisher.publish(command.sessionId, {
41408
41551
  commandId: command.commandId,
41409
41552
  epoch: stream.epoch,
@@ -41657,7 +41800,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
41657
41800
  // src/native-sessions/handle-native-requests.ts
41658
41801
  import { WebSocket as WebSocket5 } from "undici";
41659
41802
  function createNativeSessionRequestHandler(dependencies) {
41660
- const { audit, diagnostics, nativeSessions, signal, socket, timer } = dependencies;
41803
+ const { audit, diagnostics, nativeSessions, publisher, signal, socket, timer } = dependencies;
41661
41804
  const pending = /* @__PURE__ */ new Map();
41662
41805
  const cancel = (command) => {
41663
41806
  const request = pending.get(command.requestId);
@@ -41709,6 +41852,17 @@ function createNativeSessionRequestHandler(dependencies) {
41709
41852
  }
41710
41853
  operationSignal.throwIfAborted();
41711
41854
  const result = await nativeSessions.execute(command, operationSignal);
41855
+ if (command.action === "fork-recorded" && result.action === "fork-recorded") {
41856
+ publisher.publishBatch(result.ready.sessionId, [
41857
+ result.ready,
41858
+ {
41859
+ kind: "session.forked",
41860
+ sessionId: result.ready.sessionId,
41861
+ sourceSessionId: command.sessionId,
41862
+ throughCommandId: command.throughCommandId
41863
+ }
41864
+ ]);
41865
+ }
41712
41866
  if (socket.readyState === WebSocket5.OPEN) {
41713
41867
  send(socket, result);
41714
41868
  }
@@ -41794,6 +41948,7 @@ function createDaemonCommandHandler({
41794
41948
  audit,
41795
41949
  diagnostics,
41796
41950
  nativeSessions,
41951
+ publisher,
41797
41952
  signal,
41798
41953
  socket,
41799
41954
  timer
@@ -42566,6 +42721,16 @@ var SessionEventOutbox = class {
42566
42721
  this.#database.close();
42567
42722
  };
42568
42723
  enqueue = (sessionId, payload, critical) => {
42724
+ const envelope2 = this.enqueueBatch(sessionId, [payload], critical)[0];
42725
+ if (envelope2 === void 0) {
42726
+ throw new Error("The Session event outbox did not enqueue the event");
42727
+ }
42728
+ return envelope2;
42729
+ };
42730
+ enqueueBatch = (sessionId, payloads, critical) => {
42731
+ if (payloads.length < 1 || payloads.length > 32) {
42732
+ throw new Error("A Session event batch must contain between 1 and 32 events");
42733
+ }
42569
42734
  this.#database.exec("BEGIN IMMEDIATE");
42570
42735
  try {
42571
42736
  const state = this.#database.prepare(
@@ -42574,39 +42739,52 @@ var SessionEventOutbox = class {
42574
42739
  WHERE singleton = 1`
42575
42740
  ).get();
42576
42741
  const sourceSeq = rowNumber(state, "next_source_seq");
42577
- if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + 1)) {
42742
+ if (sourceSeq < 1 || !Number.isSafeInteger(sourceSeq + payloads.length)) {
42578
42743
  throw new Error("The Session event source sequence is exhausted");
42579
42744
  }
42580
- const envelope2 = {
42581
- delivery: {
42582
- eventId: randomUUID6(),
42583
- kind: "reliable",
42584
- sourceSeq: sourceSeq.toString(),
42585
- streamId: rowString(state, "stream_id")
42586
- },
42587
- kind: SESSION_EVENT_KIND,
42588
- payload,
42589
- sessionId
42590
- };
42591
- const encoded = encodeSessionEventEnvelope(envelope2);
42592
- const byteLength = Buffer.byteLength(encoded, "utf8");
42745
+ const streamId = rowString(state, "stream_id");
42746
+ const stored = payloads.map((payload, index) => {
42747
+ const envelope2 = {
42748
+ delivery: {
42749
+ eventId: randomUUID6(),
42750
+ kind: "reliable",
42751
+ sourceSeq: (sourceSeq + index).toString(),
42752
+ streamId
42753
+ },
42754
+ kind: SESSION_EVENT_KIND,
42755
+ payload,
42756
+ sessionId
42757
+ };
42758
+ const encoded = encodeSessionEventEnvelope(envelope2);
42759
+ return { byteLength: Buffer.byteLength(encoded, "utf8"), encoded, envelope: envelope2 };
42760
+ });
42761
+ const byteLength = stored.reduce((total, entry) => total + entry.byteLength, 0);
42593
42762
  const maximumBytes = critical ? this.#limits.criticalEventBytes : this.#limits.standardEventBytes;
42594
42763
  if (rowNumber(state, "total_bytes") + byteLength > maximumBytes) {
42595
42764
  throw new SessionEventOutboxCapacityError();
42596
42765
  }
42597
- this.#database.prepare(
42766
+ const insert = this.#database.prepare(
42598
42767
  `INSERT INTO relay_session_event_outbox (
42599
- event_id, session_id, source_seq, byte_length, envelope_json
42600
- ) VALUES (?, ?, ?, ?, ?)`
42601
- ).run(envelope2.delivery.eventId, sessionId, sourceSeq, byteLength, encoded);
42768
+ event_id, session_id, source_seq, byte_length, envelope_json
42769
+ ) VALUES (?, ?, ?, ?, ?)`
42770
+ );
42771
+ for (const entry of stored) {
42772
+ insert.run(
42773
+ entry.envelope.delivery.eventId,
42774
+ sessionId,
42775
+ Number(entry.envelope.delivery.sourceSeq),
42776
+ entry.byteLength,
42777
+ entry.encoded
42778
+ );
42779
+ }
42602
42780
  this.#database.prepare(
42603
42781
  `UPDATE relay_session_event_outbox_state
42604
- SET next_source_seq = next_source_seq + 1,
42782
+ SET next_source_seq = next_source_seq + ?,
42605
42783
  total_bytes = total_bytes + ?
42606
42784
  WHERE singleton = 1`
42607
- ).run(byteLength);
42785
+ ).run(stored.length, byteLength);
42608
42786
  this.#database.exec("COMMIT");
42609
- return envelope2;
42787
+ return stored.map((entry) => entry.envelope);
42610
42788
  } catch (error62) {
42611
42789
  this.#database.exec("ROLLBACK");
42612
42790
  throw error62;
@@ -42707,7 +42885,7 @@ import { WebSocket as WebSocket9 } from "undici";
42707
42885
  var SESSION_EVENT_REPLAY_WINDOW = 16;
42708
42886
  var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
42709
42887
  function reservesSessionEventCapacity(event) {
42710
- if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND) {
42888
+ if (event.kind === SESSION_COMPLETED_KIND || event.kind === SESSION_FAILED_KIND || event.kind === SESSION_FORKED_KIND || event.kind === SESSION_READY_KIND) {
42711
42889
  return true;
42712
42890
  }
42713
42891
  return event.kind === AGENT_ACTIVITY_KIND && (event.activityType === "progress" || event.activityType === "reasoning") && (event.status === "completed" || event.status === "failed");
@@ -42780,6 +42958,11 @@ var DaemonSessionEventPublisher = class {
42780
42958
  }
42781
42959
  this.#publishNextBatch();
42782
42960
  };
42961
+ publishBatch = (sessionId, events) => {
42962
+ const critical = events.some(reservesSessionEventCapacity);
42963
+ this.#outbox.enqueueBatch(sessionId, events.map(encodeRecordedSessionEvent), critical);
42964
+ this.#publishNextBatch();
42965
+ };
42783
42966
  quarantine = (rejection) => {
42784
42967
  if (!this.#outbox.quarantine(rejection)) {
42785
42968
  return;
@@ -43128,7 +43311,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43128
43311
  // src/pairing/pair-local-machine.ts
43129
43312
  import { mkdir as mkdir5, realpath as realpath9, stat as stat8 } from "node:fs/promises";
43130
43313
  import { hostname as hostname3 } from "node:os";
43131
- import { basename as basename6, resolve as resolve7 } from "node:path";
43314
+ import { basename as basename7, resolve as resolve7 } from "node:path";
43132
43315
  import { fetch as fetch4 } from "undici";
43133
43316
 
43134
43317
  // src/storage/runtime-installation-store.ts
@@ -43770,7 +43953,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
43770
43953
  installableAgents,
43771
43954
  machineName: hostname3(),
43772
43955
  pairingCode: options.code,
43773
- workspaceName: basename6(defaultWorkspace) || "Local workspace"
43956
+ workspaceName: basename7(defaultWorkspace) || "Local workspace"
43774
43957
  }),
43775
43958
  dispatcher: environmentProxyDispatcher,
43776
43959
  headers: { "content-type": "application/json" },