@moxt-ai/mobius 0.0.386 → 0.0.388

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 (149) hide show
  1. package/dist/{chunk-FVYSQLQL.js → chunk-7BSIM5AK.js} +132 -136
  2. package/dist/{chunk-FVYSQLQL.js.map → chunk-7BSIM5AK.js.map} +3 -3
  3. package/dist/{chunk-Z6JG65YI.js → chunk-Z4WUPVBL.js} +2 -2
  4. package/dist/{chunk-Z6JG65YI.js.map → chunk-Z4WUPVBL.js.map} +1 -1
  5. package/dist/cli/handler/daemon/index.d.ts.map +1 -1
  6. package/dist/cli/handler/daemon/index.js +9 -4
  7. package/dist/cli/handler/daemon/index.js.map +1 -1
  8. package/dist/cli/handler/daemon/quit.d.ts.map +1 -1
  9. package/dist/cli/handler/daemon/quit.js +5 -4
  10. package/dist/cli/handler/daemon/quit.js.map +1 -1
  11. package/dist/cli/handler/daemon/release.js +1 -1
  12. package/dist/cli/handler/daemon/start.d.ts.map +1 -1
  13. package/dist/cli/handler/daemon/start.js +3 -3
  14. package/dist/cli/handler/daemon/start.js.map +1 -1
  15. package/dist/cli/handler/daemon/upgrade.d.ts.map +1 -1
  16. package/dist/cli/handler/daemon/upgrade.js +8 -24
  17. package/dist/cli/handler/daemon/upgrade.js.map +1 -1
  18. package/dist/cli/handler/pair/pair.js +3 -3
  19. package/dist/cli/handler/pair/pair.js.map +1 -1
  20. package/dist/cli/handler/pair/remove.js +1 -1
  21. package/dist/cli/handler/pair/stop.js +1 -1
  22. package/dist/cli/handler/version/index.d.ts.map +1 -1
  23. package/dist/cli/handler/version/index.js +6 -2
  24. package/dist/cli/handler/version/index.js.map +1 -1
  25. package/dist/{cli-NLIGRBEL.js → cli-O57WJIFN.js} +412 -1143
  26. package/dist/cli-O57WJIFN.js.map +7 -0
  27. package/dist/cli.js +1998 -6
  28. package/dist/cli.js.map +4 -4
  29. package/dist/daemon/control/protocol.d.ts +1 -133
  30. package/dist/daemon/control/protocol.d.ts.map +1 -1
  31. package/dist/daemon/control/protocol.js +4 -63
  32. package/dist/daemon/control/protocol.js.map +1 -1
  33. package/dist/daemon/lifecycle/daemon-client.d.ts +8 -0
  34. package/dist/daemon/lifecycle/daemon-client.d.ts.map +1 -0
  35. package/dist/daemon/lifecycle/daemon-client.js +154 -0
  36. package/dist/daemon/lifecycle/daemon-client.js.map +1 -0
  37. package/dist/daemon/lifecycle/{worker.d.ts → daemon.d.ts} +2 -2
  38. package/dist/daemon/lifecycle/daemon.d.ts.map +1 -0
  39. package/dist/daemon/lifecycle/daemon.js +266 -0
  40. package/dist/daemon/lifecycle/daemon.js.map +1 -0
  41. package/dist/daemon/lifecycle/unhandled-rejection.d.ts +1 -2
  42. package/dist/daemon/lifecycle/unhandled-rejection.d.ts.map +1 -1
  43. package/dist/daemon/lifecycle/unhandled-rejection.js +4 -7
  44. package/dist/daemon/lifecycle/unhandled-rejection.js.map +1 -1
  45. package/dist/daemon/upgrades/data.d.ts +0 -1
  46. package/dist/daemon/upgrades/data.d.ts.map +1 -1
  47. package/dist/daemon/upgrades/data.js +0 -5
  48. package/dist/daemon/upgrades/data.js.map +1 -1
  49. package/dist/engine/runtime/command/registry/prompt.d.ts.map +1 -1
  50. package/dist/engine/runtime/command/registry/prompt.js +2 -3
  51. package/dist/engine/runtime/command/registry/prompt.js.map +1 -1
  52. package/dist/engine/runtime/relay/session-event-publisher.d.ts.map +1 -1
  53. package/dist/engine/runtime/relay/session-event-publisher.js +2 -4
  54. package/dist/engine/runtime/relay/session-event-publisher.js.map +1 -1
  55. package/dist/engine/session/api/session-layer.js +3 -3
  56. package/dist/engine/session/api/session-layer.js.map +1 -1
  57. package/dist/engine/session/live/agent-session.d.ts.map +1 -1
  58. package/dist/engine/session/live/agent-session.js +4 -3
  59. package/dist/engine/session/live/agent-session.js.map +1 -1
  60. package/dist/engine/session/prompt/execute-prompt.d.ts +8 -8
  61. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  62. package/dist/engine/session/prompt/execute-prompt.js +10 -10
  63. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  64. package/dist/engine/session/prompt/prompt-lifecycle.d.ts +8 -4
  65. package/dist/engine/session/prompt/prompt-lifecycle.d.ts.map +1 -1
  66. package/dist/engine/session/prompt/prompt-lifecycle.js +18 -17
  67. package/dist/engine/session/prompt/prompt-lifecycle.js.map +1 -1
  68. package/dist/engine/session/turn/active-executions.d.ts +4 -2
  69. package/dist/engine/session/turn/active-executions.d.ts.map +1 -1
  70. package/dist/engine/session/turn/active-executions.js +4 -6
  71. package/dist/engine/session/turn/active-executions.js.map +1 -1
  72. package/dist/engine/session/turn/active-turn.d.ts +12 -8
  73. package/dist/engine/session/turn/active-turn.d.ts.map +1 -1
  74. package/dist/engine/session/turn/active-turn.js +47 -36
  75. package/dist/engine/session/turn/active-turn.js.map +1 -1
  76. package/dist/engine/session/turn/execution-receipts.d.ts +6 -2
  77. package/dist/engine/session/turn/execution-receipts.d.ts.map +1 -1
  78. package/dist/engine/session/turn/execution-receipts.js +18 -32
  79. package/dist/engine/session/turn/execution-receipts.js.map +1 -1
  80. package/dist/engine/session/turn/session-execution.d.ts +6 -2
  81. package/dist/engine/session/turn/session-execution.d.ts.map +1 -1
  82. package/dist/engine/session/turn/session-execution.js +10 -7
  83. package/dist/engine/session/turn/session-execution.js.map +1 -1
  84. package/dist/engine/session/turn/session-turns.d.ts +1 -1
  85. package/dist/engine/session/turn/session-turns.d.ts.map +1 -1
  86. package/dist/engine/session/turn/session-turns.js +1 -1
  87. package/dist/engine/session/turn/session-turns.js.map +1 -1
  88. package/dist/engine/util/process/platform/windows.d.ts.map +1 -1
  89. package/dist/engine/util/process/platform/windows.js +7 -4
  90. package/dist/engine/util/process/platform/windows.js.map +1 -1
  91. package/dist/engine.js +2 -2
  92. package/dist/storage/daemon/daemon-lock.d.ts +9 -0
  93. package/dist/storage/daemon/daemon-lock.d.ts.map +1 -0
  94. package/dist/storage/daemon/{manager-lock.js → daemon-lock.js} +22 -7
  95. package/dist/storage/daemon/daemon-lock.js.map +1 -0
  96. package/dist/storage/state-root-layout.d.ts +0 -2
  97. package/dist/storage/state-root-layout.d.ts.map +1 -1
  98. package/dist/storage/state-root-layout.js +0 -2
  99. package/dist/storage/state-root-layout.js.map +1 -1
  100. package/package.json +2 -2
  101. package/dist/chunk-T2GPD4RK.js +0 -2002
  102. package/dist/chunk-T2GPD4RK.js.map +0 -7
  103. package/dist/cli/handler/daemon/manager.d.ts +0 -4
  104. package/dist/cli/handler/daemon/manager.d.ts.map +0 -1
  105. package/dist/cli/handler/daemon/manager.js +0 -9
  106. package/dist/cli/handler/daemon/manager.js.map +0 -1
  107. package/dist/cli/handler/daemon/worker.d.ts +0 -4
  108. package/dist/cli/handler/daemon/worker.d.ts.map +0 -1
  109. package/dist/cli/handler/daemon/worker.js +0 -7
  110. package/dist/cli/handler/daemon/worker.js.map +0 -1
  111. package/dist/cli-NLIGRBEL.js.map +0 -7
  112. package/dist/daemon/control/switch-status.d.ts +0 -4
  113. package/dist/daemon/control/switch-status.d.ts.map +0 -1
  114. package/dist/daemon/control/switch-status.js +0 -10
  115. package/dist/daemon/control/switch-status.js.map +0 -1
  116. package/dist/daemon/lifecycle/manager-client.d.ts +0 -8
  117. package/dist/daemon/lifecycle/manager-client.d.ts.map +0 -1
  118. package/dist/daemon/lifecycle/manager-client.js +0 -130
  119. package/dist/daemon/lifecycle/manager-client.js.map +0 -1
  120. package/dist/daemon/lifecycle/manager.d.ts +0 -3
  121. package/dist/daemon/lifecycle/manager.d.ts.map +0 -1
  122. package/dist/daemon/lifecycle/manager.js +0 -215
  123. package/dist/daemon/lifecycle/manager.js.map +0 -1
  124. package/dist/daemon/lifecycle/worker-lifecycle-log.d.ts +0 -14
  125. package/dist/daemon/lifecycle/worker-lifecycle-log.d.ts.map +0 -1
  126. package/dist/daemon/lifecycle/worker-lifecycle-log.js +0 -63
  127. package/dist/daemon/lifecycle/worker-lifecycle-log.js.map +0 -1
  128. package/dist/daemon/lifecycle/worker-process.d.ts +0 -26
  129. package/dist/daemon/lifecycle/worker-process.d.ts.map +0 -1
  130. package/dist/daemon/lifecycle/worker-process.js +0 -145
  131. package/dist/daemon/lifecycle/worker-process.js.map +0 -1
  132. package/dist/daemon/lifecycle/worker.d.ts.map +0 -1
  133. package/dist/daemon/lifecycle/worker.js +0 -213
  134. package/dist/daemon/lifecycle/worker.js.map +0 -1
  135. package/dist/daemon/upgrades/package.d.ts +0 -9
  136. package/dist/daemon/upgrades/package.d.ts.map +0 -1
  137. package/dist/daemon/upgrades/package.js +0 -157
  138. package/dist/daemon/upgrades/package.js.map +0 -1
  139. package/dist/daemon/upgrades/upgrade.d.ts +0 -21
  140. package/dist/daemon/upgrades/upgrade.d.ts.map +0 -1
  141. package/dist/daemon/upgrades/upgrade.js +0 -242
  142. package/dist/daemon/upgrades/upgrade.js.map +0 -1
  143. package/dist/storage/daemon/manager-lock.d.ts +0 -9
  144. package/dist/storage/daemon/manager-lock.d.ts.map +0 -1
  145. package/dist/storage/daemon/manager-lock.js.map +0 -1
  146. package/dist/storage/daemon/release-files.d.ts +0 -9
  147. package/dist/storage/daemon/release-files.d.ts.map +0 -1
  148. package/dist/storage/daemon/release-files.js +0 -14
  149. package/dist/storage/daemon/release-files.js.map +0 -1
@@ -3,7 +3,7 @@ import {
3
3
  __export,
4
4
  __using,
5
5
  package_default
6
- } from "./chunk-Z6JG65YI.js";
6
+ } from "./chunk-Z4WUPVBL.js";
7
7
 
8
8
  // src/engine/runtime/relay/runtime-revocation.ts
9
9
  var runtimeRevocationCloseCode = 1008;
@@ -20760,6 +20760,27 @@ var lifecycleMetadataSchema = external_exports.discriminatedUnion("kind", [
20760
20760
  message: external_exports.string().min(1).max(500)
20761
20761
  }).readonly()
20762
20762
  ]);
20763
+ var isPromptTerminal = (payload) => {
20764
+ switch (payload.kind) {
20765
+ case "prompt.completed":
20766
+ case "prompt.failed":
20767
+ case "prompt.failed-before-start":
20768
+ return true;
20769
+ case "prompt.requested":
20770
+ case "prompt.started":
20771
+ case "session.queue.changed":
20772
+ case "session.permission.requested":
20773
+ case "session.permission.resolved":
20774
+ case "session.elicitation.requested":
20775
+ case "session.elicitation.resolved":
20776
+ return false;
20777
+ default: {
20778
+ const unknownKind = payload;
20779
+ void unknownKind;
20780
+ return false;
20781
+ }
20782
+ }
20783
+ };
20763
20784
  var sessionEventPayloadSchema = external_exports.discriminatedUnion("type", [
20764
20785
  external_exports.object({ payload: acpSessionUpdateSchema, type: external_exports.literal("acp") }).readonly(),
20765
20786
  external_exports.object({ payload: lifecycleMetadataSchema, type: external_exports.literal("lifecycle-metadata") }).readonly()
@@ -67700,8 +67721,11 @@ async function resolveExecutableTarget(path7) {
67700
67721
  }
67701
67722
  if (extname(resolvedPath).toLowerCase() === ".cmd") {
67702
67723
  const shim = await readFile5(resolvedPath, "utf8");
67703
- if (shim.includes('SET "NPM_CLI_JS=%~dp0\\node_modules\\npm\\bin\\npm-cli.js"') && shim.includes('"%NODE_EXE%" "%NPM_CLI_JS%" %*')) {
67704
- return await realpath6(resolve8(dirname6(resolvedPath), "node_modules/npm/bin/npm-cli.js"));
67724
+ for (const tool of ["npm", "npx"]) {
67725
+ const variable = `${tool.toUpperCase()}_CLI_JS`;
67726
+ if (shim.includes(`SET "${variable}=%~dp0\\node_modules\\npm\\bin\\${tool}-cli.js"`) && shim.includes(`"%NODE_EXE%" "%${variable}%" %*`)) {
67727
+ return await realpath6(resolve8(dirname6(resolvedPath), `node_modules/npm/bin/${tool}-cli.js`));
67728
+ }
67705
67729
  }
67706
67730
  const script = /"%_prog%"\s+"%dp0%[\\/]([^"\r\n]+\.(?:js|mjs|cjs))"\s+%\*/iu.exec(shim)?.[1];
67707
67731
  if (script !== void 0 && shim.includes("SET dp0=%~dp0")) {
@@ -75446,7 +75470,6 @@ var LocalAgentInventory = class {
75446
75470
 
75447
75471
  // src/engine/util/process/local-executable.ts
75448
75472
  import { realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
75449
- import { realpath as realpath7, stat as stat6 } from "node:fs/promises";
75450
75473
  function readExecutableIdentity(path7) {
75451
75474
  const resolvedPath = realpathSync4(path7);
75452
75475
  const metadata = statSync4(resolvedPath);
@@ -75459,14 +75482,6 @@ function readExecutableIdentity(path7) {
75459
75482
  metadata.ctimeMs
75460
75483
  );
75461
75484
  }
75462
- async function resolveLaunchFiles(entry, executable) {
75463
- const resolvedEntry = await realpath7(entry);
75464
- const resolvedExecutable = await realpath7(executable);
75465
- if (!(await stat6(resolvedEntry)).isFile() || !(await stat6(resolvedExecutable)).isFile()) {
75466
- return null;
75467
- }
75468
- return { entry: resolvedEntry, executable: resolvedExecutable };
75469
- }
75470
75485
 
75471
75486
  // src/engine/acp/protocol/session-capabilities.ts
75472
75487
  function hasTrueChildField(value, childKey, fieldKey) {
@@ -86678,9 +86693,6 @@ var AgentSession = class _AgentSession {
86678
86693
  additionalDirectories: this.#additionalDirectories
86679
86694
  });
86680
86695
  prompt = async (options) => {
86681
- if (this.#turn.running) {
86682
- throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
86683
- }
86684
86696
  if (!this.#capabilities.loadSession && this.#sessionLoad.kind === "not-requested") {
86685
86697
  this.#sessionLoad = {
86686
86698
  kind: "loaded",
@@ -86699,6 +86711,7 @@ var AgentSession = class _AgentSession {
86699
86711
  await this.#completedHistory(options.signal);
86700
86712
  }
86701
86713
  validatePromptContent(options, this.#capabilities);
86714
+ options.signal.throwIfAborted();
86702
86715
  if (this.#sessionTitle === null || this.#sessionTitle.length === 0) {
86703
86716
  this.#sessionTitle = conversationTitleFromText(options.prompt);
86704
86717
  }
@@ -86779,6 +86792,7 @@ var AgentSession = class _AgentSession {
86779
86792
  throw new AcpExecutionError("The target turn is no longer active", {}, "steering_target_unavailable");
86780
86793
  }
86781
86794
  validatePromptContent(options, this.#capabilities);
86795
+ options.signal.throwIfAborted();
86782
86796
  const lifecycle = options.lifecycle;
86783
86797
  if (lifecycle !== void 0) {
86784
86798
  await this.recordLifecycleEvent({
@@ -87024,9 +87038,6 @@ var ActiveExecutions = class {
87024
87038
  };
87025
87039
  isBusy = (id) => this.#entries.has(id);
87026
87040
  begin = (id, commandId) => {
87027
- if (this.#entries.has(id)) {
87028
- throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
87029
- }
87030
87041
  this.#entries.set(id, { kind: "running", commandId });
87031
87042
  };
87032
87043
  cancel = (id, commandId, stop) => {
@@ -88357,16 +88368,17 @@ function promptContent(command) {
88357
88368
  }
88358
88369
  var PromptLifecycle = class {
88359
88370
  #sink;
88371
+ /** Terminal events held until their command's admission and execution state are released. */
88360
88372
  #terminal = /* @__PURE__ */ new Map();
88361
88373
  #publications = /* @__PURE__ */ new Map();
88362
88374
  #queued = /* @__PURE__ */ new Map();
88363
88375
  #recordActiveTurn;
88364
- #hasStarted;
88376
+ #executions;
88365
88377
  #recordLifecycle;
88366
- constructor(sink, recordLifecycle, recordActiveTurn, hasStarted) {
88378
+ constructor(sink, recordLifecycle, recordActiveTurn, executions) {
88367
88379
  this.#recordLifecycle = recordLifecycle;
88368
88380
  this.#recordActiveTurn = recordActiveTurn;
88369
- this.#hasStarted = hasStarted;
88381
+ this.#executions = executions;
88370
88382
  this.#sink = sink;
88371
88383
  }
88372
88384
  requested = (command) => {
@@ -88383,8 +88395,8 @@ var PromptLifecycle = class {
88383
88395
  ...command.targetCommandId.length === 0 ? {} : { targetCommandId: command.targetCommandId }
88384
88396
  });
88385
88397
  };
88386
- /** Metadata for an execution already claimed by the receipt owner. */
88387
- started = (sessionId, commandId, attemptId, epoch, disposition) => {
88398
+ /** The lifecycle metadata the Agent session records when it starts this claimed command. */
88399
+ lifecycle = (sessionId, commandId, attemptId, epoch, disposition) => {
88388
88400
  const request = this.#queued.get(commandId);
88389
88401
  if (request?.sessionId === sessionId) {
88390
88402
  return {
@@ -88401,7 +88413,7 @@ var PromptLifecycle = class {
88401
88413
  record = (recorded) => {
88402
88414
  this.#recordActiveTurn(recorded);
88403
88415
  const sessionId = recorded.sessionId;
88404
- if (recorded.type === "lifecycle-metadata" && (recorded.payload.kind === "prompt.completed" || recorded.payload.kind === "prompt.failed" || recorded.payload.kind === "prompt.failed-before-start")) {
88416
+ if (recorded.type === "lifecycle-metadata" && isPromptTerminal(recorded.payload)) {
88405
88417
  this.#terminal.set(recorded.payload.commandId, recorded);
88406
88418
  const pending2 = this.#publications.get(sessionId) ?? [];
88407
88419
  pending2.push(recorded);
@@ -88452,7 +88464,7 @@ var PromptLifecycle = class {
88452
88464
  };
88453
88465
  completed = async (sessionId, commandId, stopReason) => {
88454
88466
  const request = this.#queued.get(commandId);
88455
- if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
88467
+ if (request?.sessionId !== sessionId || this.#executions.isTerminalExecution(commandId, sessionId)) {
88456
88468
  return;
88457
88469
  }
88458
88470
  const recorded = await this.#recordLifecycle(sessionId, {
@@ -88461,7 +88473,7 @@ var PromptLifecycle = class {
88461
88473
  kind: "prompt.completed",
88462
88474
  commandId,
88463
88475
  stopReason,
88464
- ...this.#hasStarted(commandId, sessionId) ? {} : { execution: "not-started" }
88476
+ ...this.#executions.hasStarted(commandId, sessionId) ? {} : { execution: "not-started" }
88465
88477
  }
88466
88478
  });
88467
88479
  if (!recorded) {
@@ -88473,21 +88485,24 @@ var PromptLifecycle = class {
88473
88485
  );
88474
88486
  }
88475
88487
  };
88476
- failed = async (sessionId, commandId, code, message) => {
88488
+ /** Settles a failed command; whether it failed before or after starting is its receipt's fact. */
88489
+ failed = async (sessionId, commandId, attemptId, code, message) => {
88477
88490
  const request = this.#queued.get(commandId);
88478
- if (request?.sessionId !== sessionId || this.#terminal.has(commandId)) {
88491
+ if (request?.sessionId !== sessionId || this.#executions.isTerminalExecution(commandId, sessionId)) {
88479
88492
  return;
88480
88493
  }
88481
88494
  const recorded = await this.#recordLifecycle(sessionId, {
88482
88495
  type: "lifecycle-metadata",
88483
- payload: { kind: "prompt.failed-before-start", commandId, code, message }
88496
+ payload: this.#executions.hasStarted(commandId, sessionId) ? { kind: "prompt.failed", attemptId, commandId, code, message } : { kind: "prompt.failed-before-start", commandId, code, message }
88484
88497
  });
88485
88498
  if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
88486
88499
  this.#sink.publishOperationFailure(sessionId, commandId, code, message);
88487
88500
  }
88488
88501
  };
88489
88502
  promptRequestRecovery = (sessionId) => ({
88490
- queuedPromptRequests: [...this.#queued.values()].filter((request) => request.sessionId === sessionId && !this.#hasStarted(request.commandId, sessionId)).map(({ commandId, content, disposition, targetCommandId }) => ({
88503
+ queuedPromptRequests: [...this.#queued.values()].filter(
88504
+ (request) => request.sessionId === sessionId && !this.#executions.hasStarted(request.commandId, sessionId)
88505
+ ).map(({ commandId, content, disposition, targetCommandId }) => ({
88491
88506
  commandId,
88492
88507
  content,
88493
88508
  ...disposition === void 0 ? {} : { disposition },
@@ -88509,6 +88524,7 @@ async function settleAbandonedTurn(projection, operations, cancellation) {
88509
88524
  await projection.failed(
88510
88525
  cancellation.sessionId,
88511
88526
  cancellation.commandId,
88527
+ attemptId,
88512
88528
  "agent_execution_abandoned",
88513
88529
  "The local Agent execution was abandoned before it completed"
88514
88530
  );
@@ -88620,7 +88636,7 @@ var ExecutionReceipts = class {
88620
88636
  return { state: "accepted" };
88621
88637
  }
88622
88638
  const outcome = this.outcome(commandId);
88623
- if (outcome?.type !== "lifecycle-metadata") {
88639
+ if (outcome?.type !== "lifecycle-metadata" || !isPromptTerminal(outcome.payload)) {
88624
88640
  return { state: "expired" };
88625
88641
  }
88626
88642
  switch (outcome.payload.kind) {
@@ -88629,8 +88645,6 @@ var ExecutionReceipts = class {
88629
88645
  case "prompt.failed":
88630
88646
  case "prompt.failed-before-start":
88631
88647
  return { code: outcome.payload.code, state: "failed" };
88632
- default:
88633
- return { state: "expired" };
88634
88648
  }
88635
88649
  };
88636
88650
  /**
@@ -88653,7 +88667,7 @@ var ExecutionReceipts = class {
88653
88667
  }
88654
88668
  }
88655
88669
  const outcome = last === void 0 ? void 0 : this.outcome(last);
88656
- if (last === void 0 || outcome?.type !== "lifecycle-metadata") {
88670
+ if (last === void 0 || outcome?.type !== "lifecycle-metadata" || !isPromptTerminal(outcome.payload)) {
88657
88671
  return void 0;
88658
88672
  }
88659
88673
  switch (outcome.payload.kind) {
@@ -88667,8 +88681,6 @@ var ExecutionReceipts = class {
88667
88681
  message: outcome.payload.message,
88668
88682
  state: "failed"
88669
88683
  };
88670
- default:
88671
- return void 0;
88672
88684
  }
88673
88685
  };
88674
88686
  /** Started identities remain authoritative after their detailed receipt is evicted. */
@@ -88712,12 +88724,24 @@ var ExecutionReceipts = class {
88712
88724
  });
88713
88725
  return outcome;
88714
88726
  };
88715
- recordOutcome = (event) => {
88727
+ /**
88728
+ * Receipts follow their command's recorded lifecycle. `prompt.started` is recorded where the command is handed
88729
+ * to the Agent, so the started mark and the event clients see are one transition; a terminal event settles the
88730
+ * receipt. Nothing else marks a command started.
88731
+ */
88732
+ record = (event) => {
88716
88733
  if (event.type !== "lifecycle-metadata") {
88717
88734
  return;
88718
88735
  }
88719
88736
  const payload = event.payload;
88720
- if (payload.kind !== "prompt.completed" && payload.kind !== "prompt.failed" && payload.kind !== "prompt.failed-before-start") {
88737
+ if (payload.kind === "prompt.started") {
88738
+ const receipt2 = this.#executions.get(payload.commandId);
88739
+ if (receipt2?.state.kind === "pending") {
88740
+ this.#save(payload.commandId, { ...receipt2, state: { kind: "started" } });
88741
+ }
88742
+ return;
88743
+ }
88744
+ if (!isPromptTerminal(payload)) {
88721
88745
  return;
88722
88746
  }
88723
88747
  const receipt = this.#executions.get(payload.commandId);
@@ -88800,27 +88824,6 @@ var ExecutionReceipts = class {
88800
88824
  });
88801
88825
  return { attemptId, commandId, kind: "accepted" };
88802
88826
  };
88803
- markExecutionStarted = (commandId) => {
88804
- const current = this.#executions.get(commandId);
88805
- if (current === void 0) {
88806
- throw new Error("The runtime execution receipt does not exist");
88807
- }
88808
- const state = current.state;
88809
- switch (state.kind) {
88810
- case "pending":
88811
- this.#save(commandId, { ...current, state: { kind: "started" } });
88812
- return;
88813
- case "started":
88814
- return;
88815
- case "settled-before-start":
88816
- case "settled-after-start":
88817
- throw new Error("The runtime execution transition is invalid");
88818
- default: {
88819
- const unreachable2 = state;
88820
- throw new Error("Unexpected execution state", { cause: unreachable2 });
88821
- }
88822
- }
88823
- };
88824
88827
  /** Only commands without a terminal result can still be cancelled. */
88825
88828
  findUnsettledAttemptId = (commandId, sessionId) => {
88826
88829
  const receipt = this.#executions.get(commandId);
@@ -88928,69 +88931,79 @@ import { randomUUID as randomUUID16 } from "node:crypto";
88928
88931
  var ActiveRuntimeTurn = class {
88929
88932
  attemptId;
88930
88933
  command;
88934
+ epoch = decodeIdentifier(randomUUID16());
88931
88935
  #controller;
88932
88936
  #finished = Promise.withResolvers();
88937
+ #started;
88933
88938
  #cancellationRequested = false;
88934
- #dispatch;
88939
+ #admission = { kind: "waiting" };
88935
88940
  #sequence = 0;
88936
88941
  #interaction = null;
88937
- #epoch = decodeIdentifier(randomUUID16());
88938
- constructor(command, attemptId) {
88942
+ /** `started` reads the command's execution receipt, the single owner of whether the command started. */
88943
+ constructor(command, attemptId, started) {
88939
88944
  this.attemptId = attemptId;
88940
88945
  this.command = command;
88941
88946
  this.#controller = new AbortController();
88942
- this.#dispatch = { kind: "pending" };
88947
+ this.#started = started;
88943
88948
  }
88944
88949
  enqueue = () => {
88945
- if (this.#dispatch.kind !== "pending") {
88946
- throw new Error("Only a pending prompt can enter the queue");
88950
+ if (this.#admission.kind !== "waiting") {
88951
+ throw new Error("Only a waiting prompt can enter the queue");
88947
88952
  }
88948
- this.#dispatch = { kind: "queued", promotion: Promise.withResolvers() };
88953
+ this.#admission = { kind: "queued", promotion: Promise.withResolvers() };
88949
88954
  };
88950
- isQueued = () => (this.#dispatch.kind === "queued" || this.#dispatch.kind === "admitted" && this.#dispatch.disposition === SessionPromptDisposition.Queue) && !this.#controller.signal.aborted;
88955
+ isQueued = () => (this.#admission.kind === "queued" || this.#admission.kind === "admitted" && this.#admission.disposition === SessionPromptDisposition.Queue) && !this.#started() && !this.#controller.signal.aborted;
88956
+ /** Whether the command's execution was handed to the Agent. */
88957
+ hasStarted = () => this.#started();
88951
88958
  abortRuntime = () => {
88952
88959
  this.#controller.abort();
88953
88960
  };
88954
88961
  finish = () => {
88955
88962
  this.#finished.resolve();
88956
88963
  };
88957
- activate = (execution) => {
88958
- this.#dispatch = { kind: "running", execution };
88959
- return { epoch: this.#epoch, sequence: 0 };
88960
- };
88961
88964
  promoteQueuedPrompt = (command) => {
88962
88965
  if (command.commandId !== this.command.commandId || command.sessionId !== this.command.sessionId || this.#controller.signal.aborted) {
88963
88966
  return "unavailable";
88964
88967
  }
88965
- switch (this.#dispatch.kind) {
88968
+ switch (this.#admission.kind) {
88966
88969
  case "queued": {
88967
- const promotion = this.#dispatch.promotion;
88968
- this.#dispatch = { kind: "promoted" };
88970
+ const promotion = this.#admission.promotion;
88971
+ this.#admission = { kind: "promoted" };
88969
88972
  promotion.resolve();
88970
88973
  return "accepted";
88971
88974
  }
88972
88975
  case "promoted":
88973
88976
  return "accepted";
88974
88977
  case "admitted":
88975
- return this.#dispatch.disposition === SessionPromptDisposition.Steer ? "accepted" : "already-started";
88976
- case "running":
88977
- return "already-started";
88978
- case "pending":
88978
+ return this.#admission.disposition === SessionPromptDisposition.Steer ? "accepted" : "already-started";
88979
+ case "waiting":
88979
88980
  return "unavailable";
88980
88981
  }
88981
88982
  };
88982
88983
  admit = () => {
88983
88984
  const disposition = this.effectiveDisposition();
88984
- this.#dispatch = { kind: "admitted", disposition };
88985
+ this.#admission = { kind: "admitted", disposition };
88985
88986
  return disposition;
88986
88987
  };
88987
88988
  queuePromotion = () => {
88988
- if (this.#dispatch.kind === "queued") {
88989
- return this.#dispatch.promotion.promise;
88989
+ if (this.#admission.kind === "queued") {
88990
+ return this.#admission.promotion.promise;
88991
+ }
88992
+ return this.#admission.kind === "promoted" ? Promise.resolve() : null;
88993
+ };
88994
+ effectiveDisposition = () => {
88995
+ switch (this.#admission.kind) {
88996
+ case "waiting":
88997
+ case "queued":
88998
+ return this.command.disposition;
88999
+ case "promoted":
89000
+ return SessionPromptDisposition.Steer;
89001
+ case "admitted":
89002
+ return this.#admission.disposition;
88990
89003
  }
88991
- return this.#dispatch.kind === "promoted" ? Promise.resolve() : null;
88992
89004
  };
88993
- effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
89005
+ /** A steering prompt joins the execution of the turn it steers; every other prompt owns its execution. */
89006
+ execution = () => this.effectiveDisposition() === SessionPromptDisposition.Steer ? this.command.targetCommandId : this.command.commandId;
88994
89007
  recordEvent = (event) => {
88995
89008
  if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
88996
89009
  return event;
@@ -89002,33 +89015,33 @@ var ActiveRuntimeTurn = class {
89002
89015
  }
89003
89016
  return event;
89004
89017
  };
89005
- recordSteeringPrompt = (command) => {
89006
- return this.#dispatch.kind === "running" && command.sessionId === this.command.sessionId && command.targetCommandId === this.command.commandId;
89007
- };
89008
89018
  snapshot = () => {
89009
- if (this.#dispatch.kind !== "running") {
89019
+ if (!this.#started()) {
89010
89020
  return null;
89011
89021
  }
89012
89022
  return {
89013
89023
  commandId: decodeIdentifier(this.command.commandId),
89014
- epoch: this.#epoch,
89024
+ epoch: this.epoch,
89015
89025
  interaction: this.#interaction,
89016
89026
  sequence: this.#sequence,
89017
89027
  state: "running"
89018
89028
  };
89019
89029
  };
89020
- matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
89021
89030
  matchesInteraction = (interactionId, sessionId) => this.command.sessionId === sessionId && this.#interaction?.interactionId === interactionId;
89031
+ /**
89032
+ * Before the command starts, cancellation withdraws it by aborting its own admission and preparation. Once it
89033
+ * started, the Agent execution it belongs to must be asked to stop.
89034
+ */
89022
89035
  requestCancellation = () => {
89023
89036
  if (this.#cancellationRequested) {
89024
89037
  return { kind: "already-requested" };
89025
89038
  }
89026
89039
  this.#cancellationRequested = true;
89027
- if (this.#dispatch.kind !== "running") {
89028
- this.#controller.abort(new Error("The queued Agent turn was cancelled"));
89040
+ if (!this.#started()) {
89041
+ this.#controller.abort(new Error("The Agent turn was cancelled before it started"));
89029
89042
  return { kind: "pending" };
89030
89043
  }
89031
- return { kind: "running", execution: this.#dispatch.execution };
89044
+ return { kind: "running", execution: this.execution() };
89032
89045
  };
89033
89046
  cancellationRequested = () => this.#cancellationRequested;
89034
89047
  get signal() {
@@ -89074,7 +89087,11 @@ var SessionExecutionState = class {
89074
89087
  }
89075
89088
  isEmpty = () => this.#turnsByCommandId.size === 0;
89076
89089
  start = (command, attemptId) => {
89077
- const turn = new ActiveRuntimeTurn(command, attemptId);
89090
+ const turn = new ActiveRuntimeTurn(
89091
+ command,
89092
+ attemptId,
89093
+ () => this.#operations.hasStarted(command.commandId, this.#sessionId)
89094
+ );
89078
89095
  this.#turnsByCommandId.set(command.commandId, turn);
89079
89096
  return turn;
89080
89097
  };
@@ -89099,10 +89116,8 @@ var SessionExecutionState = class {
89099
89116
  }
89100
89117
  return event;
89101
89118
  };
89102
- recordSteeringPrompt = (command) => {
89103
- const target = this.#turnsByCommandId.get(command.targetCommandId);
89104
- return target?.recordSteeringPrompt(command) ?? false;
89105
- };
89119
+ /** A steering prompt can join only a target whose execution already started. */
89120
+ steerTargetStarted = (command) => this.#turnsByCommandId.get(command.targetCommandId)?.hasStarted() ?? false;
89106
89121
  turns = () => [...this.#turnsByCommandId.values()];
89107
89122
  close = async () => {
89108
89123
  const turns = [...this.#turnsByCommandId.values()];
@@ -89115,7 +89130,7 @@ var SessionExecutionState = class {
89115
89130
  const command = turn.command;
89116
89131
  waitSignal.throwIfAborted();
89117
89132
  const head = () => [...this.#turnsByCommandId.values()].find(
89118
- (turn2) => turn2.command.disposition !== SessionPromptDisposition.Steer
89133
+ (turn2) => turn2.effectiveDisposition() !== SessionPromptDisposition.Steer
89119
89134
  );
89120
89135
  if (command.disposition === SessionPromptDisposition.Queue) {
89121
89136
  const target = head();
@@ -89187,7 +89202,7 @@ var SessionTurns = class {
89187
89202
  this.recordEvent(event.payload.event);
89188
89203
  }
89189
89204
  };
89190
- recordSteeringPrompt = (command) => this.#bySessionId.get(command.sessionId)?.recordSteeringPrompt(command) ?? false;
89205
+ steerTargetStarted = (command) => this.#bySessionId.get(command.sessionId)?.steerTargetStarted(command) ?? false;
89191
89206
  executionSnapshot = async (matches) => {
89192
89207
  for (const session of this.#bySessionId.values()) {
89193
89208
  const matching = [];
@@ -89437,7 +89452,7 @@ function buildSessionLayer(options) {
89437
89452
  const manager = new SessionManager2({
89438
89453
  observer: new SessionLayerObserver(
89439
89454
  (event) => {
89440
- operations.recordOutcome(event);
89455
+ operations.record(event);
89441
89456
  eventProjection.record(event);
89442
89457
  },
89443
89458
  sink.publishInfo,
@@ -89460,12 +89475,12 @@ function buildSessionLayer(options) {
89460
89475
  return true;
89461
89476
  }
89462
89477
  const recorded = events.append(sessionId, event);
89463
- operations.recordOutcome(recorded);
89478
+ operations.record(recorded);
89464
89479
  eventProjection.record(recorded);
89465
89480
  return true;
89466
89481
  },
89467
89482
  activeSessions.recordSessionEvent,
89468
- operations.hasStarted
89483
+ operations
89469
89484
  );
89470
89485
  const nativeSessions = new NativeSessionService(
89471
89486
  bindingId,
@@ -89524,7 +89539,7 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
89524
89539
 
89525
89540
  // src/engine/storage/files/scratch-directory.ts
89526
89541
  import { randomUUID as randomUUID17 } from "node:crypto";
89527
- import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile7, realpath as realpath8, rename as rename4, rm as rm3, stat as stat7, utimes, writeFile as writeFile2 } from "node:fs/promises";
89542
+ import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile7, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
89528
89543
  import { dirname as dirname11, join as join28 } from "node:path";
89529
89544
  async function atomicWrite(path7, bytes, signal) {
89530
89545
  const temporary = `${path7}.${randomUUID17()}.tmp`;
@@ -89554,7 +89569,7 @@ var ScratchDirectory = class {
89554
89569
  if (path7 === this.#root) {
89555
89570
  continue;
89556
89571
  }
89557
- const modified = await stat7(path7).then(
89572
+ const modified = await stat6(path7).then(
89558
89573
  (entry) => entry.mtimeMs,
89559
89574
  () => Date.now()
89560
89575
  );
@@ -89579,8 +89594,8 @@ var ScratchDirectory = class {
89579
89594
  resolveFile = async (path7) => {
89580
89595
  try {
89581
89596
  const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
89582
- realpath8(dirname11(path7)),
89583
- realpath8(path7),
89597
+ realpath7(dirname11(path7)),
89598
+ realpath7(path7),
89584
89599
  lstat4(path7)
89585
89600
  ]);
89586
89601
  return file2.isFile() && !file2.isSymbolicLink() && dirname11(resolvedPath) === resolvedDirectory ? resolvedPath : null;
@@ -91748,7 +91763,6 @@ function warnIgnoredSetting(event, commandId, sessionId, agentId, selection, cat
91748
91763
 
91749
91764
  // src/engine/session/prompt/execute-prompt.ts
91750
91765
  async function executePrompt({
91751
- operations,
91752
91766
  eventProjection,
91753
91767
  command,
91754
91768
  resolveAgent,
@@ -91757,10 +91771,10 @@ async function executePrompt({
91757
91771
  directories,
91758
91772
  sessions,
91759
91773
  attemptId,
91760
- activateAttempt,
91774
+ epoch,
91761
91775
  waitForSessionAvailability,
91762
91776
  signal,
91763
- recordSteeringPrompt,
91777
+ steerTargetStarted,
91764
91778
  cancellationRequested
91765
91779
  }) {
91766
91780
  try {
@@ -91818,24 +91832,14 @@ async function executePrompt({
91818
91832
  prepared = await sessions.prepareExecutionSession(preparation);
91819
91833
  }
91820
91834
  signal.throwIfAborted();
91821
- operations.markExecutionStarted(command.commandId);
91822
- if (availability.disposition === SessionPromptDisposition.Steer) {
91823
- if (!recordSteeringPrompt()) {
91824
- throw new AcpExecutionError(
91825
- "The steering target is unavailable",
91826
- {},
91827
- "prompt_queue_target_unavailable"
91828
- );
91829
- }
91835
+ if (availability.disposition === SessionPromptDisposition.Steer && !steerTargetStarted()) {
91836
+ throw new AcpExecutionError("The steering target is unavailable", {}, "prompt_queue_target_unavailable");
91830
91837
  }
91831
- const stream = activateAttempt(
91832
- availability.disposition === SessionPromptDisposition.Steer ? command.targetCommandId : command.commandId
91833
- );
91834
- const lifecycle = eventProjection.started(
91838
+ const lifecycle = eventProjection.lifecycle(
91835
91839
  command.sessionId,
91836
91840
  command.commandId,
91837
91841
  attemptId,
91838
- stream.epoch,
91842
+ epoch,
91839
91843
  availability.disposition
91840
91844
  );
91841
91845
  const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
@@ -91894,7 +91898,7 @@ async function executePrompt({
91894
91898
  const code = operationErrorCode(error62);
91895
91899
  const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
91896
91900
  const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
91897
- await eventProjection.failed(command.sessionId, command.commandId, failureCode, failureMessage);
91901
+ await eventProjection.failed(command.sessionId, command.commandId, attemptId, failureCode, failureMessage);
91898
91902
  reportFailure("session_prompt_failed", command.commandId, {
91899
91903
  agentId: command.agentId,
91900
91904
  code: failureCode,
@@ -91964,7 +91968,6 @@ var sessionPromptCommand = {
91964
91968
  });
91965
91969
  };
91966
91970
  void executePrompt({
91967
- operations: context.operations,
91968
91971
  eventProjection: context.eventProjection,
91969
91972
  command: message,
91970
91973
  resolveAgent: context.resolveAgent,
@@ -91983,12 +91986,12 @@ var sessionPromptCommand = {
91983
91986
  directories: context.directories,
91984
91987
  sessions: context.sessions,
91985
91988
  attemptId: receipt.attemptId,
91986
- activateAttempt: turn.activate,
91989
+ epoch: turn.epoch,
91987
91990
  waitForSessionAvailability: (signal) => context.sessionTurns.admitAndWait(turn, signal, () => {
91988
91991
  queueChanged();
91989
91992
  }),
91990
91993
  signal: turn.signal,
91991
- recordSteeringPrompt: () => context.sessionTurns.recordSteeringPrompt(message),
91994
+ steerTargetStarted: () => context.sessionTurns.steerTargetStarted(message),
91992
91995
  cancellationRequested: turn.cancellationRequested
91993
91996
  }).catch((error62) => {
91994
91997
  console.error("Mobius daemon turn failed", error62);
@@ -93088,7 +93091,7 @@ var RuntimeSessionEventPublisher = class {
93088
93091
  commandId: payload.commandId,
93089
93092
  generationId: event.sessionGenerationId
93090
93093
  });
93091
- } else if ((payload.kind === "prompt.completed" || payload.kind === "prompt.failed" || payload.kind === "prompt.failed-before-start") && this.#awaitingFirstAnswer.get(event.sessionId)?.commandId === payload.commandId && this.#awaitingFirstAnswer.get(event.sessionId)?.generationId === event.sessionGenerationId) {
93094
+ } else if (isPromptTerminal(payload) && this.#awaitingFirstAnswer.get(event.sessionId)?.commandId === payload.commandId && this.#awaitingFirstAnswer.get(event.sessionId)?.generationId === event.sessionGenerationId) {
93092
93095
  this.#awaitingFirstAnswer.delete(event.sessionId);
93093
93096
  }
93094
93097
  return false;
@@ -93557,26 +93560,19 @@ export {
93557
93560
  external_exports,
93558
93561
  isNodeError,
93559
93562
  installationPointerPath,
93560
- decodeIdentifier,
93561
93563
  decodeRuntimeUpgradeVersion,
93562
- canonicalPath,
93563
93564
  ensurePrivateDirectory,
93564
93565
  platformSupportFor,
93565
93566
  validateLocalPath,
93566
93567
  RuntimeInstallationStoreError,
93567
93568
  RuntimeInstallationStore,
93568
- isRecord4 as isRecord,
93569
- findExecutableOnPath,
93570
- runBoundedProcess,
93571
93569
  MissingAdapter,
93572
93570
  UnsupportedAgentVersion,
93573
- resolveLaunchFiles,
93574
93571
  discoverLocalAgentInventory,
93575
93572
  BoundedLineLog,
93576
93573
  WORKER_LIFECYCLE_LOG_FILENAME,
93577
93574
  unhandledRejectionLogFilename,
93578
93575
  logDirectory,
93579
- RuntimeDiagnosticLog,
93580
93576
  RuntimeLocalContext,
93581
93577
  PairingClientError,
93582
93578
  parseRelayOrigin2 as parseRelayOrigin,
@@ -93600,4 +93596,4 @@ export {
93600
93596
  * MIT Licensed
93601
93597
  *)
93602
93598
  */
93603
- //# sourceMappingURL=chunk-FVYSQLQL.js.map
93599
+ //# sourceMappingURL=chunk-7BSIM5AK.js.map