@moxt-ai/mobius 0.0.344 → 0.0.346

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 (162) hide show
  1. package/dist/cli/handler/agents/index.js +4 -4
  2. package/dist/cli/handler/agents/index.js.map +1 -1
  3. package/dist/cli/handler/agents/logic/agent-diagnostics.js +1 -1
  4. package/dist/cli/handler/agents/logic/agent-diagnostics.js.map +1 -1
  5. package/dist/cli/handler/daemon/start.js +2 -2
  6. package/dist/cli/handler/daemon/start.js.map +1 -1
  7. package/dist/cli/handler/logs/logic/collect-local-logs.js +2 -2
  8. package/dist/cli/handler/logs/logic/collect-local-logs.js.map +1 -1
  9. package/dist/cli/handler/pair/logic/pair-list-output.js +1 -1
  10. package/dist/cli/handler/pair/logic/pair-list-output.js.map +1 -1
  11. package/dist/cli/handler/pair/pair.js +2 -2
  12. package/dist/cli/handler/pair/pair.js.map +1 -1
  13. package/dist/cli/index.js +1 -1
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli.js +10139 -10031
  16. package/dist/cli.js.map +4 -4
  17. package/dist/daemon/config.d.ts +5 -0
  18. package/dist/daemon/config.d.ts.map +1 -0
  19. package/dist/daemon/config.js +40 -0
  20. package/dist/daemon/config.js.map +1 -0
  21. package/dist/daemon/control/local-client.d.ts.map +1 -1
  22. package/dist/daemon/control/local-client.js +1 -1
  23. package/dist/daemon/control/local-client.js.map +1 -1
  24. package/dist/daemon/control/local-server.d.ts.map +1 -1
  25. package/dist/daemon/control/local-server.js +1 -1
  26. package/dist/daemon/control/local-server.js.map +1 -1
  27. package/dist/daemon/lifecycle/manager-client.d.ts.map +1 -1
  28. package/dist/daemon/lifecycle/manager-client.js +3 -3
  29. package/dist/daemon/lifecycle/manager-client.js.map +1 -1
  30. package/dist/daemon/lifecycle/manager.d.ts.map +1 -1
  31. package/dist/daemon/lifecycle/manager.js +1 -1
  32. package/dist/daemon/lifecycle/manager.js.map +1 -1
  33. package/dist/daemon/lifecycle/worker.d.ts.map +1 -1
  34. package/dist/daemon/lifecycle/worker.js +6 -3
  35. package/dist/daemon/lifecycle/worker.js.map +1 -1
  36. package/dist/daemon/pairing/pair-local-machine.d.ts.map +1 -1
  37. package/dist/daemon/pairing/pair-local-machine.js +26 -21
  38. package/dist/daemon/pairing/pair-local-machine.js.map +1 -1
  39. package/dist/daemon/upgrades/data.d.ts.map +1 -1
  40. package/dist/daemon/upgrades/data.js +2 -2
  41. package/dist/daemon/upgrades/data.js.map +1 -1
  42. package/dist/daemon/upgrades/package.d.ts.map +1 -1
  43. package/dist/daemon/upgrades/package.js +1 -1
  44. package/dist/daemon/upgrades/package.js.map +1 -1
  45. package/dist/engine/index.d.ts +1 -1
  46. package/dist/engine/index.d.ts.map +1 -1
  47. package/dist/engine/index.js +1 -1
  48. package/dist/engine/index.js.map +1 -1
  49. package/dist/engine/runtime/catalog/refresh-agent-catalog.js +1 -1
  50. package/dist/engine/runtime/catalog/refresh-agent-catalog.js.map +1 -1
  51. package/dist/engine/runtime/catalog/resolve-catalog-agent.js +1 -1
  52. package/dist/engine/runtime/catalog/resolve-catalog-agent.js.map +1 -1
  53. package/dist/engine/runtime/command/registry/index.d.ts.map +1 -1
  54. package/dist/engine/runtime/command/registry/index.js +18 -1
  55. package/dist/engine/runtime/command/registry/index.js.map +1 -1
  56. package/dist/engine/runtime/config.d.ts +6 -8
  57. package/dist/engine/runtime/config.d.ts.map +1 -1
  58. package/dist/engine/runtime/config.js +9 -15
  59. package/dist/engine/runtime/config.js.map +1 -1
  60. package/dist/engine/runtime/connection/runtime-connection.d.ts +1 -2
  61. package/dist/engine/runtime/connection/runtime-connection.d.ts.map +1 -1
  62. package/dist/engine/runtime/connection/runtime-connection.js +1 -3
  63. package/dist/engine/runtime/connection/runtime-connection.js.map +1 -1
  64. package/dist/engine/runtime/connection/runtime-installation-store.d.ts +4 -7
  65. package/dist/engine/runtime/connection/runtime-installation-store.d.ts.map +1 -1
  66. package/dist/engine/runtime/connection/runtime-installation-store.js +56 -60
  67. package/dist/engine/runtime/connection/runtime-installation-store.js.map +1 -1
  68. package/dist/engine/runtime/engine.d.ts +10 -4
  69. package/dist/engine/runtime/engine.d.ts.map +1 -1
  70. package/dist/engine/runtime/engine.js +6 -25
  71. package/dist/engine/runtime/engine.js.map +1 -1
  72. package/dist/engine/runtime/relay/diagnostics.d.ts.map +1 -1
  73. package/dist/engine/runtime/relay/diagnostics.js +15 -0
  74. package/dist/engine/runtime/relay/diagnostics.js.map +1 -1
  75. package/dist/engine/runtime/relay/run-relay-connection.d.ts.map +1 -1
  76. package/dist/engine/runtime/relay/run-relay-connection.js +3 -0
  77. package/dist/engine/runtime/relay/run-relay-connection.js.map +1 -1
  78. package/dist/engine/runtime/run.js +2 -2
  79. package/dist/engine/runtime/run.js.map +1 -1
  80. package/dist/engine/session/api/session-layer.d.ts.map +1 -1
  81. package/dist/engine/session/api/session-layer.js +9 -4
  82. package/dist/engine/session/api/session-layer.js.map +1 -1
  83. package/dist/engine/session/native/native-session-browser.d.ts +1 -1
  84. package/dist/engine/session/native/native-session-browser.d.ts.map +1 -1
  85. package/dist/engine/session/native/native-session-browser.js.map +1 -1
  86. package/dist/engine/session/process/agent-process-pool.d.ts +0 -1
  87. package/dist/engine/session/process/agent-process-pool.d.ts.map +1 -1
  88. package/dist/engine/session/process/agent-process-pool.js +0 -14
  89. package/dist/engine/session/process/agent-process-pool.js.map +1 -1
  90. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  91. package/dist/engine/session/prompt/execute-prompt.js +10 -1
  92. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  93. package/dist/engine/session/prompt/prompt-artifacts.d.ts.map +1 -1
  94. package/dist/engine/session/prompt/prompt-artifacts.js +6 -7
  95. package/dist/engine/session/prompt/prompt-artifacts.js.map +1 -1
  96. package/dist/engine/session/turn/execution-receipts.d.ts +8 -1
  97. package/dist/engine/session/turn/execution-receipts.d.ts.map +1 -1
  98. package/dist/engine/session/turn/execution-receipts.js +37 -0
  99. package/dist/engine/session/turn/execution-receipts.js.map +1 -1
  100. package/dist/engine/storage/installation/installation-files.d.ts +3 -4
  101. package/dist/engine/storage/installation/installation-files.d.ts.map +1 -1
  102. package/dist/engine/storage/installation/installation-files.js +5 -9
  103. package/dist/engine/storage/installation/installation-files.js.map +1 -1
  104. package/dist/engine/storage/logs/log-files.d.ts +2 -26
  105. package/dist/engine/storage/logs/log-files.d.ts.map +1 -1
  106. package/dist/engine/storage/logs/log-files.js +5 -128
  107. package/dist/engine/storage/logs/log-files.js.map +1 -1
  108. package/dist/engine.js +534 -471
  109. package/dist/engine.js.map +4 -4
  110. package/dist/{engine/storage → storage}/daemon/control-token.d.ts +1 -1
  111. package/dist/storage/daemon/control-token.d.ts.map +1 -0
  112. package/dist/{engine/storage → storage}/daemon/control-token.js +1 -1
  113. package/dist/storage/daemon/control-token.js.map +1 -0
  114. package/dist/{engine/storage → storage}/daemon/manager-lock.d.ts +1 -1
  115. package/dist/storage/daemon/manager-lock.d.ts.map +1 -0
  116. package/dist/{engine/storage → storage}/daemon/manager-lock.js +1 -1
  117. package/dist/storage/daemon/manager-lock.js.map +1 -0
  118. package/dist/storage/daemon/release-files.d.ts.map +1 -0
  119. package/dist/storage/daemon/release-files.js.map +1 -0
  120. package/dist/{engine/storage → storage}/daemon/version-data.d.ts +2 -0
  121. package/dist/storage/daemon/version-data.d.ts.map +1 -0
  122. package/dist/{engine/storage → storage}/daemon/version-data.js +17 -2
  123. package/dist/storage/daemon/version-data.js.map +1 -0
  124. package/dist/storage/files/output-file.d.ts.map +1 -0
  125. package/dist/{engine/storage → storage}/files/output-file.js +1 -1
  126. package/dist/storage/files/output-file.js.map +1 -0
  127. package/dist/storage/logs/log-files.d.ts +24 -0
  128. package/dist/storage/logs/log-files.d.ts.map +1 -0
  129. package/dist/storage/logs/log-files.js +122 -0
  130. package/dist/storage/logs/log-files.js.map +1 -0
  131. package/dist/storage/state-directory.d.ts.map +1 -0
  132. package/dist/storage/state-directory.js.map +1 -0
  133. package/dist/storage/state-root-layout.d.ts.map +1 -0
  134. package/dist/storage/state-root-layout.js.map +1 -0
  135. package/dist/storage/state-root.d.ts.map +1 -0
  136. package/dist/{engine/storage → storage}/state-root.js +1 -1
  137. package/dist/storage/state-root.js.map +1 -0
  138. package/package.json +2 -2
  139. package/dist/engine/storage/daemon/control-token.d.ts.map +0 -1
  140. package/dist/engine/storage/daemon/control-token.js.map +0 -1
  141. package/dist/engine/storage/daemon/manager-lock.d.ts.map +0 -1
  142. package/dist/engine/storage/daemon/manager-lock.js.map +0 -1
  143. package/dist/engine/storage/daemon/release-files.d.ts.map +0 -1
  144. package/dist/engine/storage/daemon/release-files.js.map +0 -1
  145. package/dist/engine/storage/daemon/version-data.d.ts.map +0 -1
  146. package/dist/engine/storage/daemon/version-data.js.map +0 -1
  147. package/dist/engine/storage/files/output-file.d.ts.map +0 -1
  148. package/dist/engine/storage/files/output-file.js.map +0 -1
  149. package/dist/engine/storage/state-directory.d.ts.map +0 -1
  150. package/dist/engine/storage/state-directory.js.map +0 -1
  151. package/dist/engine/storage/state-root-layout.d.ts.map +0 -1
  152. package/dist/engine/storage/state-root-layout.js.map +0 -1
  153. package/dist/engine/storage/state-root.d.ts.map +0 -1
  154. package/dist/engine/storage/state-root.js.map +0 -1
  155. /package/dist/{engine/storage → storage}/daemon/release-files.d.ts +0 -0
  156. /package/dist/{engine/storage → storage}/daemon/release-files.js +0 -0
  157. /package/dist/{engine/storage → storage}/files/output-file.d.ts +0 -0
  158. /package/dist/{engine/storage → storage}/state-directory.d.ts +0 -0
  159. /package/dist/{engine/storage → storage}/state-directory.js +0 -0
  160. /package/dist/{engine/storage → storage}/state-root-layout.d.ts +0 -0
  161. /package/dist/{engine/storage → storage}/state-root-layout.js +0 -0
  162. /package/dist/{engine/storage → storage}/state-root.d.ts +0 -0
package/dist/engine.js CHANGED
@@ -51,7 +51,7 @@ var __callDispose = (stack, error62, hasError) => {
51
51
 
52
52
  // src/daemon/pairing/pair-local-machine.ts
53
53
  import { hostname as hostname3 } from "node:os";
54
- import { basename as basename6, join as join26, resolve as resolve16 } from "node:path";
54
+ import { basename as basename9, join as join31, resolve as resolve16 } from "node:path";
55
55
 
56
56
  // ../mobius-sdk/src/protocol/platform/mobius-api.ts
57
57
  var MOBIUS_API_PREFIX = "/mobius/api";
@@ -5102,7 +5102,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
5102
5102
  var NONE = 0;
5103
5103
  var ASSUMED = 1;
5104
5104
  var PROVEN = 2;
5105
- function isRecursive(inst, stack, resolve18) {
5105
+ function isRecursive(inst, stack, resolve17) {
5106
5106
  const cached2 = recursive.get(inst);
5107
5107
  if (cached2 !== void 0)
5108
5108
  return cached2 ? PROVEN : NONE;
@@ -5112,7 +5112,7 @@ function isRecursive(inst, stack, resolve18) {
5112
5112
  let result = NONE;
5113
5113
  const check2 = (child) => {
5114
5114
  if (result !== PROVEN && child?._zod) {
5115
- const answer = isRecursive(child, stack, resolve18);
5115
+ const answer = isRecursive(child, stack, resolve17);
5116
5116
  if (answer > result)
5117
5117
  result = answer;
5118
5118
  }
@@ -5123,7 +5123,7 @@ function isRecursive(inst, stack, resolve18) {
5123
5123
  const desc2 = Object.getOwnPropertyDescriptor(sh, key);
5124
5124
  if (spread && !desc2.enumerable)
5125
5125
  continue;
5126
- const child = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve18) : NONE;
5126
+ const child = desc2.get ? ASSUMED : desc2.value?._zod ? isRecursive(desc2.value, stack, resolve17) : NONE;
5127
5127
  if (child > answer)
5128
5128
  answer = child;
5129
5129
  }
@@ -5187,7 +5187,7 @@ function isRecursive(inst, stack, resolve18) {
5187
5187
  break;
5188
5188
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
5189
5189
  case "lazy": {
5190
- const inner = def._cachedInner ?? (resolve18 ? inst._zod.innerType : void 0);
5190
+ const inner = def._cachedInner ?? (resolve17 ? inst._zod.innerType : void 0);
5191
5191
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
5192
5192
  break;
5193
5193
  }
@@ -19757,7 +19757,7 @@ function decodeIdentifier(value) {
19757
19757
 
19758
19758
  // ../mobius-sdk/src/protocol/runtime/diagnostics.ts
19759
19759
  var identifier = external_exports.custom(isIdentifier);
19760
- var runtimeDiagnosticsRequestSchema = external_exports.strictObject({
19760
+ var runtimeDiagnosticsRequestSchema = external_exports.object({
19761
19761
  kind: external_exports.literal("runtime.diagnostics.read"),
19762
19762
  requestId: identifier
19763
19763
  });
@@ -21326,6 +21326,15 @@ var commandDeliverySchema = external_exports.discriminatedUnion("state", [
21326
21326
  // The command started, but the Runtime no longer retains its result.
21327
21327
  external_exports.object({ state: external_exports.literal("expired") }).readonly()
21328
21328
  ]);
21329
+ var lastTurnOutcomeSchema = external_exports.discriminatedUnion("state", [
21330
+ external_exports.object({ commandId: identifierStringSchema, state: external_exports.literal("completed"), stopReason: external_exports.string().max(2048) }).readonly(),
21331
+ external_exports.object({
21332
+ code: identifierStringSchema,
21333
+ commandId: identifierStringSchema,
21334
+ message: external_exports.string().min(1).max(500),
21335
+ state: external_exports.literal("failed")
21336
+ }).readonly()
21337
+ ]);
21329
21338
  var identity = {
21330
21339
  ...envelope,
21331
21340
  kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
@@ -21407,7 +21416,9 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
21407
21416
  turn: activeTurnSnapshotSchema.nullable(),
21408
21417
  // Present only when the request named a command and every hop understands it. An
21409
21418
  // unrecognized delivery from a newer peer reads as absent instead of failing the snapshot.
21410
- command: commandDeliverySchema.optional().catch(void 0)
21419
+ command: commandDeliverySchema.optional().catch(void 0),
21420
+ // Absent from older Runtimes and while the last started command is still running.
21421
+ lastTurn: lastTurnOutcomeSchema.optional().catch(void 0)
21411
21422
  }).readonly(),
21412
21423
  external_exports.object({
21413
21424
  ...resultEnvelope,
@@ -21762,12 +21773,12 @@ var serviceToDaemonSignatures = {
21762
21773
  };
21763
21774
  var serviceToDaemonRegistry = serviceToDaemonSignatures;
21764
21775
  function decodeKnownServiceToDaemonMessage(encoded) {
21765
- const kind = decodeMessageKind(encoded);
21766
- const signature = serviceToDaemonRegistry[kind];
21767
- if (signature === void 0) {
21768
- return null;
21769
- }
21770
21776
  try {
21777
+ const kind = decodeMessageKind(encoded);
21778
+ const signature = serviceToDaemonRegistry[kind];
21779
+ if (signature === void 0) {
21780
+ return null;
21781
+ }
21771
21782
  return signature.decoder(encoded);
21772
21783
  } catch {
21773
21784
  return null;
@@ -21911,7 +21922,7 @@ import { fetch as fetch3 } from "undici";
21911
21922
  // package.json
21912
21923
  var package_default = {
21913
21924
  name: "@moxt-ai/mobius",
21914
- version: "0.0.344",
21925
+ version: "0.0.346",
21915
21926
  description: "Mobius CLI for pairing and running local AI agent services.",
21916
21927
  type: "module",
21917
21928
  bin: {
@@ -58990,11 +59001,11 @@ var Pushable = class {
58990
59001
  done = false;
58991
59002
  push(item) {
58992
59003
  if (this.resolvers.length > 0) {
58993
- const resolve18 = this.resolvers.shift();
58994
- if (resolve18 === void 0) {
59004
+ const resolve17 = this.resolvers.shift();
59005
+ if (resolve17 === void 0) {
58995
59006
  return;
58996
59007
  }
58997
- resolve18({ value: item, done: false });
59008
+ resolve17({ value: item, done: false });
58998
59009
  } else {
58999
59010
  this.queue.push(item);
59000
59011
  }
@@ -59002,8 +59013,8 @@ var Pushable = class {
59002
59013
  end() {
59003
59014
  this.done = true;
59004
59015
  while (this.resolvers.length > 0) {
59005
- const resolve18 = this.resolvers.shift();
59006
- resolve18?.({ done: true, value: void 0 });
59016
+ const resolve17 = this.resolvers.shift();
59017
+ resolve17?.({ done: true, value: void 0 });
59007
59018
  }
59008
59019
  }
59009
59020
  [Symbol.asyncIterator]() {
@@ -59019,8 +59030,8 @@ var Pushable = class {
59019
59030
  if (this.done) {
59020
59031
  return Promise.resolve({ done: true, value: void 0 });
59021
59032
  }
59022
- return new Promise((resolve18) => {
59023
- this.resolvers.push(resolve18);
59033
+ return new Promise((resolve17) => {
59034
+ this.resolvers.push(resolve17);
59024
59035
  });
59025
59036
  }
59026
59037
  };
@@ -59038,14 +59049,14 @@ function unreachable(value, logger = console) {
59038
59049
  async function withDeadline(signal, timeoutMilliseconds, operation) {
59039
59050
  const deadline = AbortSignal.any([signal, AbortSignal.timeout(timeoutMilliseconds)]);
59040
59051
  deadline.throwIfAborted();
59041
- return await new Promise((resolve18, reject2) => {
59052
+ return await new Promise((resolve17, reject2) => {
59042
59053
  const settle2 = (callback) => {
59043
59054
  deadline.removeEventListener("abort", onAbort);
59044
59055
  callback();
59045
59056
  };
59046
59057
  const onAbort = () => settle2(() => reject2(deadline.reason));
59047
59058
  deadline.addEventListener("abort", onAbort, { once: true });
59048
- operation().then((value) => settle2(() => resolve18(value)), (error62) => settle2(() => reject2(error62)));
59059
+ operation().then((value) => settle2(() => resolve17(value)), (error62) => settle2(() => reject2(error62)));
59049
59060
  });
59050
59061
  }
59051
59062
  var environmentChain = Promise.resolve();
@@ -59588,8 +59599,8 @@ function inputPath(context, key) {
59588
59599
  return plainString(context.input[key]);
59589
59600
  }
59590
59601
  function isInside(directory, candidate) {
59591
- const relative4 = path.relative(path.resolve(directory), path.resolve(candidate));
59592
- return relative4 === "" || !relative4.startsWith(`..${path.sep}`) && relative4 !== "..";
59602
+ const relative3 = path.relative(path.resolve(directory), path.resolve(candidate));
59603
+ return relative3 === "" || !relative3.startsWith(`..${path.sep}`) && relative3 !== "..";
59593
59604
  }
59594
59605
  function hasSessionAllowRuleFor(changeSet, toolName) {
59595
59606
  return !!changeSet?.updates.some((update) => update.type === "addRules" && update.destination === "session" && update.behavior === "allow" && update.rules.some((rule) => rule.toolName === toolName));
@@ -61738,14 +61749,14 @@ function waitUnlessAborted(milliseconds, signal) {
61738
61749
  if (signal.aborted) {
61739
61750
  return Promise.resolve(false);
61740
61751
  }
61741
- return new Promise((resolve18) => {
61752
+ return new Promise((resolve17) => {
61742
61753
  const timer = setTimeout(() => {
61743
61754
  signal.removeEventListener("abort", onAbort);
61744
- resolve18(true);
61755
+ resolve17(true);
61745
61756
  }, milliseconds);
61746
61757
  const onAbort = () => {
61747
61758
  clearTimeout(timer);
61748
- resolve18(false);
61759
+ resolve17(false);
61749
61760
  };
61750
61761
  signal.addEventListener("abort", onAbort, { once: true });
61751
61762
  });
@@ -61991,7 +62002,7 @@ var ClientConnection = class {
61991
62002
  }
61992
62003
  };
61993
62004
  function raceWithAbort(operation, signal) {
61994
- return new Promise((resolve18, reject2) => {
62005
+ return new Promise((resolve17, reject2) => {
61995
62006
  const cleanup = () => signal.removeEventListener("abort", onAbort);
61996
62007
  const onAbort = () => {
61997
62008
  cleanup();
@@ -62003,7 +62014,7 @@ function raceWithAbort(operation, signal) {
62003
62014
  }
62004
62015
  void operation.then((value) => {
62005
62016
  cleanup();
62006
- resolve18(value);
62017
+ resolve17(value);
62007
62018
  }, (error62) => {
62008
62019
  cleanup();
62009
62020
  reject2(error62);
@@ -62586,12 +62597,12 @@ var ClaudeAcpAgent = class {
62586
62597
  }
62587
62598
  };
62588
62599
  let completeTurn;
62589
- turn.completion = new Promise((resolve18) => {
62590
- completeTurn = resolve18;
62600
+ turn.completion = new Promise((resolve17) => {
62601
+ completeTurn = resolve17;
62591
62602
  });
62592
- const response = new Promise((resolve18, reject2) => {
62603
+ const response = new Promise((resolve17, reject2) => {
62593
62604
  turn.resolve = (result) => {
62594
- resolve18(result);
62605
+ resolve17(result);
62595
62606
  completeTurn();
62596
62607
  };
62597
62608
  turn.reject = (error62) => {
@@ -63006,8 +63017,8 @@ var ClaudeAcpAgent = class {
63006
63017
  pendingNext ??= session.query.next().then((result) => ({ kind: "message", result }));
63007
63018
  const nextMessage = pendingNext;
63008
63019
  let onAbort;
63009
- const abortRace = new Promise((resolve18) => {
63010
- onAbort = () => resolve18("abort");
63020
+ const abortRace = new Promise((resolve17) => {
63021
+ onAbort = () => resolve17("abort");
63011
63022
  cancelController.signal.addEventListener("abort", onAbort, { once: true });
63012
63023
  });
63013
63024
  const raced = await Promise.race([nextMessage, abortRace]);
@@ -70594,10 +70605,10 @@ var PiRpcProcess = class _PiRpcProcess {
70594
70605
  shell: shouldUseShellForPiCommand(cmd)
70595
70606
  });
70596
70607
  try {
70597
- await new Promise((resolve18, reject2) => {
70608
+ await new Promise((resolve17, reject2) => {
70598
70609
  const onSpawn = () => {
70599
70610
  cleanup();
70600
- resolve18();
70611
+ resolve17();
70601
70612
  };
70602
70613
  const onError = (err) => {
70603
70614
  cleanup();
@@ -70799,7 +70810,7 @@ var PiRpcProcess = class _PiRpcProcess {
70799
70810
  const timeoutMs = opts?.timeoutMs;
70800
70811
  const line = `${JSON.stringify(withId)}
70801
70812
  `;
70802
- return new Promise((resolve18, reject2) => {
70813
+ return new Promise((resolve17, reject2) => {
70803
70814
  const signal = opts?.signal;
70804
70815
  if (signal?.aborted === true) {
70805
70816
  reject2(signal.reason);
@@ -70821,7 +70832,7 @@ var PiRpcProcess = class _PiRpcProcess {
70821
70832
  this.pending.set(id, {
70822
70833
  resolve: (res) => {
70823
70834
  drop();
70824
- resolve18(res);
70835
+ resolve17(res);
70825
70836
  },
70826
70837
  reject: (error62) => {
70827
70838
  drop();
@@ -70854,14 +70865,14 @@ var PiRpcProcess = class _PiRpcProcess {
70854
70865
  });
70855
70866
  }
70856
70867
  writeLine(line) {
70857
- return new Promise((resolve18, reject2) => {
70868
+ return new Promise((resolve17, reject2) => {
70858
70869
  try {
70859
70870
  this.child.stdin.write(line, (error62) => {
70860
70871
  if (error62) {
70861
70872
  reject2(error62);
70862
70873
  return;
70863
70874
  }
70864
- resolve18();
70875
+ resolve17();
70865
70876
  });
70866
70877
  } catch (error62) {
70867
70878
  reject2(error62);
@@ -72132,8 +72143,8 @@ var PiAcpSession = class {
72132
72143
  }
72133
72144
  async prompt(message, images = []) {
72134
72145
  const expandedMessage = expandSlashCommand(message, this.fileCommands);
72135
- const turnPromise = new Promise((resolve18, reject2) => {
72136
- const queued = { message: expandedMessage, images, resolve: resolve18, reject: reject2 };
72146
+ const turnPromise = new Promise((resolve17, reject2) => {
72147
+ const queued = { message: expandedMessage, images, resolve: resolve17, reject: reject2 };
72137
72148
  if (this.pendingTurn) {
72138
72149
  this.turnQueue.push(queued);
72139
72150
  this.emit({
@@ -75100,8 +75111,8 @@ var AdapterRegistry = class {
75100
75111
  #resolve;
75101
75112
  #dependencies;
75102
75113
  #adapters = /* @__PURE__ */ new Map();
75103
- constructor(resolve18, dependencies) {
75104
- this.#resolve = resolve18;
75114
+ constructor(resolve17, dependencies) {
75115
+ this.#resolve = resolve17;
75105
75116
  this.#dependencies = dependencies;
75106
75117
  }
75107
75118
  resolve = (agent) => {
@@ -76093,14 +76104,14 @@ function mergeTextChunk(previous, incoming) {
76093
76104
  var SessionEventHistoryProjection = class {
76094
76105
  #toolCallEventIds = /* @__PURE__ */ new Map();
76095
76106
  #latestEvent = null;
76096
- apply = (liveEvent2, resolve18) => {
76107
+ apply = (liveEvent2, resolve17) => {
76097
76108
  if (liveEvent2.type === "lifecycle-metadata") {
76098
76109
  this.#latestEvent = null;
76099
76110
  return { kind: "skip" };
76100
76111
  }
76101
76112
  if (liveEvent2.type === "acp" && liveEvent2.payload.sessionUpdate === "tool_call_update") {
76102
76113
  const targetEventId = this.#toolCallEventIds.get(liveEvent2.payload.toolCallId);
76103
- const current = targetEventId === void 0 ? void 0 : resolve18([targetEventId]).get(targetEventId);
76114
+ const current = targetEventId === void 0 ? void 0 : resolve17([targetEventId]).get(targetEventId);
76104
76115
  if (current?.type === "acp" && (current.payload.sessionUpdate === "tool_call" || current.payload.sessionUpdate === "tool_call_update")) {
76105
76116
  return this.#replace(
76106
76117
  current,
@@ -76124,12 +76135,12 @@ var SessionEventHistoryProjection = class {
76124
76135
  * The projected tool call announced with this identifier, in its current
76125
76136
  * merged form, or `undefined` when the projection has not recorded one.
76126
76137
  */
76127
- getToolCall = (toolCallId, resolve18) => {
76138
+ getToolCall = (toolCallId, resolve17) => {
76128
76139
  const eventId = this.#toolCallEventIds.get(toolCallId);
76129
76140
  if (eventId === void 0) {
76130
76141
  return void 0;
76131
76142
  }
76132
- const event = resolve18([eventId]).get(eventId);
76143
+ const event = resolve17([eventId]).get(eventId);
76133
76144
  if (event?.type === "acp" && (event.payload.sessionUpdate === "tool_call" || event.payload.sessionUpdate === "tool_call_update")) {
76134
76145
  return event.payload;
76135
76146
  }
@@ -76189,8 +76200,8 @@ var SessionEvents = class {
76189
76200
  this.sessionGenerationId = sessionGenerationId;
76190
76201
  this.#projection = new SessionEventHistoryProjection();
76191
76202
  }
76192
- apply = (event, resolve18) => {
76193
- const projected = this.#projection.apply(event, resolve18);
76203
+ apply = (event, resolve17) => {
76204
+ const projected = this.#projection.apply(event, resolve17);
76194
76205
  this.#throughPosition = event.position;
76195
76206
  if (projected.kind === "skip") {
76196
76207
  return;
@@ -76217,7 +76228,7 @@ var SessionEvents = class {
76217
76228
  return this.#cachedItemsByEventId.size;
76218
76229
  }
76219
76230
  /** The projected tool call for this identifier, materializing it if needed. */
76220
- toolCall = (toolCallId, resolve18) => this.#projection.getToolCall(toolCallId, resolve18);
76231
+ toolCall = (toolCallId, resolve17) => this.#projection.getToolCall(toolCallId, resolve17);
76221
76232
  endIndex = (cursor) => {
76222
76233
  if (cursor === null) {
76223
76234
  return this.#eventIds.length;
@@ -77571,7 +77582,7 @@ function sql(strings, ...params) {
77571
77582
  return new SQL([new StringChunk(str)]);
77572
77583
  }
77573
77584
  _sql.raw = raw;
77574
- function join34(chunks, separator) {
77585
+ function join32(chunks, separator) {
77575
77586
  const result = [];
77576
77587
  for (const [i, chunk] of chunks.entries()) {
77577
77588
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -77579,7 +77590,7 @@ function sql(strings, ...params) {
77579
77590
  }
77580
77591
  return new SQL(result);
77581
77592
  }
77582
- _sql.join = join34;
77593
+ _sql.join = join32;
77583
77594
  function identifier2(value) {
77584
77595
  return new Name(value);
77585
77596
  }
@@ -79300,7 +79311,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
79300
79311
  const baseTableName = this.tableName;
79301
79312
  const tableName = getTableLikeName(table);
79302
79313
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
79303
- if (typeof tableName === "string" && this.config.joins?.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
79314
+ if (typeof tableName === "string" && this.config.joins?.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
79304
79315
  if (!this.isPartialSelect) {
79305
79316
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
79306
79317
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -80846,7 +80857,7 @@ var SQLiteDialect = class {
80846
80857
  if (!joins2) return;
80847
80858
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
80848
80859
  if (!withEntries.length) return;
80849
- return sql.join(withEntries.map(([k2, join34]) => {
80860
+ return sql.join(withEntries.map(([k2, join32]) => {
80850
80861
  const relation = tableConfig.relations[k2];
80851
80862
  const isSingle2 = is(relation, One2);
80852
80863
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -80857,7 +80868,7 @@ var SQLiteDialect = class {
80857
80868
  table: targetTable,
80858
80869
  mode: isSingle2 ? "first" : "many",
80859
80870
  schema,
80860
- queryConfig: join34,
80871
+ queryConfig: join32,
80861
80872
  tableConfig: schema[relation.targetTableName],
80862
80873
  relationWhere: filter,
80863
80874
  isNested: true,
@@ -80871,7 +80882,7 @@ var SQLiteDialect = class {
80871
80882
  key: k2,
80872
80883
  selection: innerQuery.selection,
80873
80884
  isArray: !isSingle2,
80874
- isOptional: (relation.optional ?? false) || join34 !== true && !!join34.where
80885
+ isOptional: (relation.optional ?? false) || join32 !== true && !!join32.where
80875
80886
  });
80876
80887
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
80877
80888
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -81225,7 +81236,7 @@ var SQLiteUpdateBase = class {
81225
81236
  createJoin(joinType) {
81226
81237
  return ((table, on2) => {
81227
81238
  const tableName = getTableLikeName(table);
81228
- if (typeof tableName === "string" && this.config.joins.some((join34) => join34.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
81239
+ if (typeof tableName === "string" && this.config.joins.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
81229
81240
  if (typeof on2 === "function") {
81230
81241
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
81231
81242
  on2 = on2(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -82885,7 +82896,7 @@ async function publishAgentCatalog(config2, signal) {
82885
82896
  }
82886
82897
 
82887
82898
  // src/engine/runtime/config.ts
82888
- import { join as join24, resolve as resolve14 } from "node:path";
82899
+ import { resolve as resolve13 } from "node:path";
82889
82900
 
82890
82901
  // src/engine/util/serial-task-queue.ts
82891
82902
  var SerialTaskQueue = class {
@@ -82956,24 +82967,15 @@ var LocalAgentCatalog = class {
82956
82967
  };
82957
82968
  };
82958
82969
 
82959
- // src/engine/storage/state-directory.ts
82960
- import { homedir as homedir3 } from "node:os";
82961
- import { join as join23, resolve as resolve13 } from "node:path";
82962
- var stateRootSchema = external_exports.string().brand();
82963
- function readStateDirectory(environment = process.env) {
82964
- const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
82965
- return stateRootSchema.parse(
82966
- configured !== void 0 && configured.length > 0 ? resolve13(configured) : join23(homedir3(), ".mobius")
82967
- );
82968
- }
82969
-
82970
82970
  // src/engine/runtime/config.ts
82971
82971
  var RuntimeLocalContext = class {
82972
- environment;
82972
+ agentLaunchEnvironment;
82973
82973
  stateDirectory;
82974
- constructor(stateDirectory, environment = process.env) {
82975
- this.stateDirectory = resolve14(stateDirectory);
82976
- this.environment = Object.freeze({ ...environment });
82974
+ maxAcpProcesses;
82975
+ constructor(stateDirectory, agentLaunchEnvironment, maxAcpProcesses = 1e3) {
82976
+ this.stateDirectory = resolve13(stateDirectory);
82977
+ this.agentLaunchEnvironment = Object.freeze({ ...agentLaunchEnvironment });
82978
+ this.maxAcpProcesses = maxAcpProcesses;
82977
82979
  }
82978
82980
  };
82979
82981
  function withRuntimeEnvironment(agent, environment) {
@@ -82996,8 +82998,10 @@ var OpaqueRuntimeReconnectTarget = class extends RuntimeReconnectTarget {
82996
82998
  this.commandArgument = `--connection ${connectionId2}`;
82997
82999
  }
82998
83000
  };
82999
- function createRuntimeConfig(connection, dependencies = new RuntimeAgentDependencies([]), localContext = new RuntimeLocalContext(readStateDirectory(), process.env), reconnectTarget = null, resolveAgent, rediscoverAgents) {
83000
- const runtimeAgents = dependencies.agents.map((agent) => withRuntimeEnvironment(agent, localContext.environment));
83001
+ function createRuntimeConfig(connection, dependencies, localContext, reconnectTarget = null, resolveAgent, rediscoverAgents) {
83002
+ const runtimeAgents = dependencies.agents.map(
83003
+ (agent) => withRuntimeEnvironment(agent, localContext.agentLaunchEnvironment)
83004
+ );
83001
83005
  return {
83002
83006
  adapters: dependencies.adapters,
83003
83007
  agents: runtimeAgents,
@@ -83039,7 +83043,7 @@ function createCatalogAgentResolver(discover, readConfig, publish) {
83039
83043
  signal.throwIfAborted();
83040
83044
  const inventory = await discover(signal);
83041
83045
  signal.throwIfAborted();
83042
- const rediscovered = inventory.readyAgents().filter((ready) => ready.id === agent.id).map((ready) => withRuntimeEnvironment(ready, config2.localContext.environment));
83046
+ const rediscovered = inventory.readyAgents().filter((ready) => ready.id === agent.id).map((ready) => withRuntimeEnvironment(ready, config2.localContext.agentLaunchEnvironment));
83043
83047
  await config2.catalog.replaceAndPublish(
83044
83048
  (current) => {
83045
83049
  if (!current.some((entry) => entry.id === agent.id)) {
@@ -83070,51 +83074,35 @@ async function unchangedIdentity(agent, signal) {
83070
83074
 
83071
83075
  // src/engine/runtime/connection/runtime-installation-store.ts
83072
83076
  import { randomUUID as randomUUID13 } from "node:crypto";
83073
- import { resolve as resolve15 } from "node:path";
83077
+ import { resolve as resolve14 } from "node:path";
83074
83078
 
83075
83079
  // src/engine/storage/installation/installation-files.ts
83076
83080
  import { createHash as createHash5, randomUUID as randomUUID12 } from "node:crypto";
83077
83081
  import { mkdir as mkdir4, open as open5, readdir as readdir5, rename as rename3, unlink as unlink3, writeFile } from "node:fs/promises";
83078
- import { dirname as dirname9, join as join25 } from "node:path";
83082
+ import { dirname as dirname9, join as join23 } from "node:path";
83079
83083
 
83080
83084
  // src/engine/util/node-error.ts
83081
83085
  function isNodeError(error62, code) {
83082
83086
  return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
83083
83087
  }
83084
83088
 
83085
- // src/engine/storage/state-root-layout.ts
83086
- var STATE_ROOT_LAYOUT = Object.freeze({
83087
- /** Names the version whose data is current. */
83088
- currentData: "current-data.txt",
83089
- /** Applications' installations: `installations/<application>/<installation>`. */
83090
- installations: "installations",
83091
- /** Managed CLI releases: `npm/<version>`. */
83092
- releases: "npm",
83093
- /** Each CLI version's data: `versions/<version>`. */
83094
- versions: "versions"
83095
- });
83096
- var STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
83097
-
83098
83089
  // src/engine/storage/installation/installation-files.ts
83099
83090
  var MAXIMUM_FILE_BYTES = 16 * 1024;
83100
- function applicationDirectory(root, applicationId) {
83101
- return join25(root, STATE_ROOT_LAYOUT.installations, applicationId);
83102
- }
83103
- function installationPointerPath(applicationDirectory2) {
83104
- return join25(applicationDirectory2, "current.json");
83091
+ function installationPointerPath(engineDataDir) {
83092
+ return join23(engineDataDir, "current.json");
83105
83093
  }
83106
83094
  var installationDirectorySchema = external_exports.string().brand();
83107
- function installationDirectory(applicationDirectory2, installationId2) {
83108
- return installationDirectorySchema.parse(join25(applicationDirectory2, installationId2));
83095
+ function installationDirectory(engineDataDir, installationId2) {
83096
+ return installationDirectorySchema.parse(join23(engineDataDir, installationId2));
83109
83097
  }
83110
83098
  function connectionDirectory(installationDirectory2) {
83111
- return join25(installationDirectory2, "connections");
83099
+ return join23(installationDirectory2, "connections");
83112
83100
  }
83113
83101
  function connectionFilePath(connectionDirectory2, connectionId2) {
83114
- return join25(connectionDirectory2, `${connectionId2}.json`);
83102
+ return join23(connectionDirectory2, `${connectionId2}.json`);
83115
83103
  }
83116
83104
  function channelIndexFilePath(installationDirectory2, channelId) {
83117
- return join25(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83105
+ return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83118
83106
  }
83119
83107
  async function readInstallationFile(path7) {
83120
83108
  let handle;
@@ -83136,7 +83124,7 @@ async function readInstallationFile(path7) {
83136
83124
  async function writeInstallationFile(path7, text2, signal) {
83137
83125
  signal.throwIfAborted();
83138
83126
  const directory = dirname9(path7);
83139
- const temporaryPath = join25(directory, `.${randomUUID12()}.tmp`);
83127
+ const temporaryPath = join23(directory, `.${randomUUID12()}.tmp`);
83140
83128
  try {
83141
83129
  await mkdir4(directory, { mode: 448, recursive: true });
83142
83130
  signal.throwIfAborted();
@@ -83174,7 +83162,6 @@ var VerifiedRuntimeConnection = class {
83174
83162
  kind = "verified";
83175
83163
  activation;
83176
83164
  appId;
83177
- applicationId;
83178
83165
  channelId;
83179
83166
  connectionId;
83180
83167
  defaultWorkspace;
@@ -83183,9 +83170,8 @@ var VerifiedRuntimeConnection = class {
83183
83170
  relayOrigin;
83184
83171
  runtimeCredential;
83185
83172
  runtimeId;
83186
- constructor(activation, applicationId, appId, installationId2, connectionId2, channelId, defaultWorkspace, pairingId, relayOrigin, runtimeCredential2, runtimeId) {
83173
+ constructor(activation, appId, installationId2, connectionId2, channelId, defaultWorkspace, pairingId, relayOrigin, runtimeCredential2, runtimeId) {
83187
83174
  this.activation = activation;
83188
- this.applicationId = applicationId;
83189
83175
  this.appId = appId;
83190
83176
  this.channelId = channelId;
83191
83177
  this.connectionId = connectionId2;
@@ -83199,22 +83185,14 @@ var VerifiedRuntimeConnection = class {
83199
83185
  };
83200
83186
 
83201
83187
  // src/engine/runtime/connection/runtime-installation-store.ts
83202
- var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
83203
83188
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
83204
83189
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
83205
83190
  var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
83206
83191
  var INSTALLATION_POINTER_KEYS = ["installationId", "version"];
83207
- var CHANNEL_INDEX_KEYS = [
83208
- "applicationId",
83209
- "channelId",
83210
- "connectionId",
83211
- "installationId",
83212
- "version"
83213
- ];
83192
+ var CHANNEL_INDEX_KEYS = ["channelId", "connectionId", "installationId", "version"];
83214
83193
  var VERIFIED_CONNECTION_KEYS = [
83215
83194
  "activation",
83216
83195
  "appId",
83217
- "applicationId",
83218
83196
  "channelId",
83219
83197
  "connectionId",
83220
83198
  "defaultWorkspace",
@@ -83241,12 +83219,6 @@ function hasExactKeys(value, expectedKeys) {
83241
83219
  const keys = Object.keys(value);
83242
83220
  return keys.length === expectedKeys.length && expectedKeys.every((key) => Object.hasOwn(value, key));
83243
83221
  }
83244
- function validateApplicationId(value) {
83245
- if (!APPLICATION_ID_PATTERN.test(value)) {
83246
- throw new RuntimeInstallationStoreError("invalid_application_id", "The application ID is invalid");
83247
- }
83248
- return value;
83249
- }
83250
83222
  function validateRemoteAppId(value) {
83251
83223
  if (!isIdentifier(value)) {
83252
83224
  throw new RuntimeInstallationStoreError("invalid_app_id", "The remote App ID is invalid");
@@ -83310,29 +83282,33 @@ function decodeInstallationPointer(value) {
83310
83282
  }
83311
83283
  return { installationId: validateInstallationId(storedInstallationId) };
83312
83284
  }
83313
- function decodeChannelIndex(value) {
83314
- if (!isRecord8(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
83285
+ function retainedFields(value, keys) {
83286
+ return Object.fromEntries(keys.filter((key) => Object.hasOwn(value, key)).map((key) => [key, value[key]]));
83287
+ }
83288
+ function decodeChannelIndex(input2) {
83289
+ if (!isRecord8(input2)) {
83290
+ throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83291
+ }
83292
+ const value = input2["version"] === 1 ? retainedFields(input2, CHANNEL_INDEX_KEYS) : input2;
83293
+ if (!hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1 && value["version"] !== 2) {
83315
83294
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83316
83295
  }
83317
- const applicationId = value["applicationId"];
83318
83296
  const channelId = value["channelId"];
83319
83297
  const connectionId2 = value["connectionId"];
83320
83298
  const storedInstallationId = value["installationId"];
83321
- if (typeof applicationId !== "string" || typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof storedInstallationId !== "string") {
83299
+ if (typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof storedInstallationId !== "string") {
83322
83300
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83323
83301
  }
83324
83302
  return {
83325
- applicationId: validateApplicationId(applicationId),
83326
83303
  channelId: validateIdentifier(channelId, "invalid_connection"),
83327
83304
  connectionId: validateConnectionId(connectionId2),
83328
83305
  installationId: validateInstallationId(storedInstallationId)
83329
83306
  };
83330
83307
  }
83331
83308
  function decodeVerifiedConnection(value) {
83332
- if (!hasExactKeys(value, VERIFIED_CONNECTION_KEYS) || value["version"] !== 5 || value["kind"] !== "verified") {
83309
+ if (!hasExactKeys(value, VERIFIED_CONNECTION_KEYS) || value["version"] !== 5 && value["version"] !== 6 || value["kind"] !== "verified") {
83333
83310
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83334
83311
  }
83335
- const applicationId = value["applicationId"];
83336
83312
  const activation = value["activation"];
83337
83313
  const appId = value["appId"];
83338
83314
  const channelId = value["channelId"];
@@ -83343,12 +83319,11 @@ function decodeVerifiedConnection(value) {
83343
83319
  const relayOrigin = value["relayOrigin"];
83344
83320
  const runtimeCredential2 = value["runtimeCredential"];
83345
83321
  const runtimeId = value["runtimeId"];
83346
- if (typeof applicationId !== "string" || activation !== "active" && activation !== "stopped" || typeof appId !== "string" || typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof defaultWorkspace !== "string" || typeof storedInstallationId !== "string" || typeof pairingId !== "string" || typeof relayOrigin !== "string" || typeof runtimeCredential2 !== "string" || typeof runtimeId !== "string") {
83322
+ if (activation !== "active" && activation !== "stopped" || typeof appId !== "string" || typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof defaultWorkspace !== "string" || typeof storedInstallationId !== "string" || typeof pairingId !== "string" || typeof relayOrigin !== "string" || typeof runtimeCredential2 !== "string" || typeof runtimeId !== "string") {
83347
83323
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83348
83324
  }
83349
83325
  return new VerifiedRuntimeConnection(
83350
83326
  activation,
83351
- validateApplicationId(applicationId),
83352
83327
  validateRemoteAppId(appId),
83353
83328
  validateInstallationId(storedInstallationId),
83354
83329
  validateConnectionId(connectionId2),
@@ -83364,7 +83339,7 @@ function decodeConnection(value) {
83364
83339
  if (!isRecord8(value)) {
83365
83340
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83366
83341
  }
83367
- return decodeVerifiedConnection(value);
83342
+ return decodeVerifiedConnection(value["version"] === 5 ? retainedFields(value, VERIFIED_CONNECTION_KEYS) : value);
83368
83343
  }
83369
83344
  async function readJsonFile2(path7, signal, missingCode) {
83370
83345
  signal.throwIfAborted();
@@ -83408,25 +83383,20 @@ async function writeJsonAtomically(path7, value, signal) {
83408
83383
  }
83409
83384
  }
83410
83385
  var RuntimeInstallationStore = class _RuntimeInstallationStore {
83411
- applicationId;
83412
83386
  installationId;
83413
83387
  stateDirectory;
83414
83388
  #connectionDirectory;
83415
- constructor(applicationId, installationId2, stateDirectory) {
83416
- this.applicationId = applicationId;
83389
+ constructor(installationId2, stateDirectory) {
83417
83390
  this.installationId = installationId2;
83418
83391
  this.stateDirectory = stateDirectory;
83419
83392
  this.#connectionDirectory = connectionDirectory(stateDirectory);
83420
83393
  }
83421
- static open = async (options, signal) => {
83394
+ static open = async (engineDataDir, signal) => {
83422
83395
  signal.throwIfAborted();
83423
- const applicationId = validateApplicationId(options.applicationId);
83424
- const rootDirectory = resolve15(options.stateDirectory);
83425
- const applicationDirectory2 = applicationDirectory(rootDirectory, applicationId);
83396
+ const dataDirectory = resolve14(engineDataDir);
83426
83397
  try {
83427
- await ensurePrivateDirectory(rootDirectory);
83428
- await validateLocalPath(rootDirectory, true, true, signal);
83429
- await ensurePrivateDirectory(applicationDirectory2);
83398
+ await ensurePrivateDirectory(dataDirectory);
83399
+ await validateLocalPath(dataDirectory, true, true, signal);
83430
83400
  } catch (cause) {
83431
83401
  throw new RuntimeInstallationStoreError(
83432
83402
  "installation_unavailable",
@@ -83436,8 +83406,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83436
83406
  }
83437
83407
  );
83438
83408
  }
83439
- const storedInstallationId = await readOrCreateInstallationId(applicationDirectory2, signal);
83440
- const stateDirectory = installationDirectory(applicationDirectory2, storedInstallationId);
83409
+ const storedInstallationId = await readOrCreateInstallationId(dataDirectory, signal);
83410
+ const stateDirectory = installationDirectory(dataDirectory, storedInstallationId);
83441
83411
  try {
83442
83412
  await ensurePrivateDirectory(stateDirectory);
83443
83413
  } catch (cause) {
@@ -83450,15 +83420,18 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83450
83420
  );
83451
83421
  }
83452
83422
  signal.throwIfAborted();
83453
- return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
83423
+ return new _RuntimeInstallationStore(storedInstallationId, stateDirectory);
83454
83424
  };
83455
83425
  connectionPath = (connectionId2) => connectionFilePath(this.#connectionDirectory, validateConnectionId(connectionId2));
83456
83426
  channelIndexPath = (channelId) => channelIndexFilePath(this.stateDirectory, validateIdentifier(channelId, "invalid_channel_id"));
83457
83427
  readConnection = async (connectionId2, signal) => {
83458
- const stored = decodeConnection(
83428
+ return this.decodeOwnedConnection(
83459
83429
  await readJsonFile2(this.connectionPath(connectionId2), signal, "connection_not_found")
83460
83430
  );
83461
- if (stored.applicationId !== this.applicationId || stored.installationId !== this.installationId) {
83431
+ };
83432
+ decodeOwnedConnection = (record2) => {
83433
+ const stored = decodeConnection(record2);
83434
+ if (stored.installationId !== this.installationId) {
83462
83435
  throw new RuntimeInstallationStoreError(
83463
83436
  "connection_owner_mismatch",
83464
83437
  "The saved Runtime connection belongs to another installation"
@@ -83471,7 +83444,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83471
83444
  const index2 = decodeChannelIndex(
83472
83445
  await readJsonFile2(this.channelIndexPath(normalizedChannelId), signal, "connection_not_found")
83473
83446
  );
83474
- if (index2.applicationId !== this.applicationId || index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
83447
+ if (index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
83475
83448
  throw new RuntimeInstallationStoreError(
83476
83449
  "connection_owner_mismatch",
83477
83450
  "The saved Runtime connection belongs to another installation"
@@ -83482,7 +83455,6 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83482
83455
  saveConnection = async (input2, signal) => {
83483
83456
  const stored = new VerifiedRuntimeConnection(
83484
83457
  "active",
83485
- this.applicationId,
83486
83458
  validateRemoteAppId(input2.appId),
83487
83459
  this.installationId,
83488
83460
  connectionId(),
@@ -83513,11 +83485,10 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83513
83485
  await writeJsonAtomically(
83514
83486
  this.channelIndexPath(stored.channelId),
83515
83487
  {
83516
- applicationId: this.applicationId,
83517
83488
  channelId: stored.channelId,
83518
83489
  connectionId: stored.connectionId,
83519
83490
  installationId: this.installationId,
83520
- version: 1
83491
+ version: 2
83521
83492
  },
83522
83493
  signal
83523
83494
  );
@@ -83555,10 +83526,10 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83555
83526
  return connections.find((connection) => connection.pairingId === normalizedPairingId) ?? null;
83556
83527
  };
83557
83528
  setConnectionActivation = async (connectionId2, activation, signal) => {
83558
- const connection = await this.readConnection(connectionId2, signal);
83529
+ const record2 = await readJsonFile2(this.connectionPath(connectionId2), signal, "connection_not_found");
83530
+ const connection = this.decodeOwnedConnection(record2);
83559
83531
  const updated = new VerifiedRuntimeConnection(
83560
83532
  activation,
83561
- connection.applicationId,
83562
83533
  connection.appId,
83563
83534
  connection.installationId,
83564
83535
  connection.connectionId,
@@ -83569,7 +83540,11 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83569
83540
  connection.runtimeCredential,
83570
83541
  connection.runtimeId
83571
83542
  );
83572
- await this.overwriteConnection(updated, signal);
83543
+ if (isRecord8(record2) && record2["version"] === 5) {
83544
+ await writeJsonAtomically(this.connectionPath(connectionId2), { ...record2, activation }, signal);
83545
+ } else {
83546
+ await this.overwriteConnection(updated, signal);
83547
+ }
83573
83548
  return updated;
83574
83549
  };
83575
83550
  removeConnection = async (connectionId2, signal) => {
@@ -83597,7 +83572,6 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83597
83572
  connectionPath,
83598
83573
  {
83599
83574
  activation: connection.activation,
83600
- applicationId: connection.applicationId,
83601
83575
  appId: connection.appId,
83602
83576
  channelId: connection.channelId,
83603
83577
  connectionId: connection.connectionId,
@@ -83608,14 +83582,14 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83608
83582
  relayOrigin: connection.relayOrigin.toString(),
83609
83583
  runtimeCredential: connection.runtimeCredential,
83610
83584
  runtimeId: connection.runtimeId,
83611
- version: 5
83585
+ version: 6
83612
83586
  },
83613
83587
  signal
83614
83588
  );
83615
83589
  };
83616
83590
  };
83617
- async function readOrCreateInstallationId(applicationDirectory2, signal) {
83618
- const pointerPath = installationPointerPath(applicationDirectory2);
83591
+ async function readOrCreateInstallationId(engineDataDir, signal) {
83592
+ const pointerPath = installationPointerPath(engineDataDir);
83619
83593
  try {
83620
83594
  return decodeInstallationPointer(await readJsonFile2(pointerPath, signal, "installation_not_found")).installationId;
83621
83595
  } catch (cause) {
@@ -83641,243 +83615,25 @@ async function readOrCreateInstallationId(applicationDirectory2, signal) {
83641
83615
  return decodeInstallationPointer(await readJsonFile2(pointerPath, signal, "installation_not_found")).installationId;
83642
83616
  }
83643
83617
  }
83644
- async function openRuntimeInstallationStore(options, signal) {
83645
- return await RuntimeInstallationStore.open(options, signal);
83618
+ async function openRuntimeInstallationStore(engineDataDir, signal) {
83619
+ return await RuntimeInstallationStore.open(engineDataDir, signal);
83646
83620
  }
83647
83621
 
83648
- // src/daemon/pairing/pair-local-machine.ts
83649
- var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
83650
- var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
83651
- var TOKEN_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
83652
- var CLAIM_RESPONSE_KEYS = ["appId", "channelId", "daemonToken", "runtimeId"];
83653
- var REDEEM_RESPONSE_KEYS = ["appId", "channelId", "runtimeCredential", "runtimeId"];
83654
- var PairingClientError = class extends Error {
83655
- code;
83656
- constructor(code, message, options = {}) {
83657
- super(message, options);
83658
- this.code = code;
83659
- this.name = "PairingClientError";
83660
- }
83661
- };
83662
- function hasExactKeys2(value, expectedKeys) {
83663
- const keys = Object.keys(value);
83664
- return keys.length === expectedKeys.length && expectedKeys.every((key) => Object.hasOwn(value, key));
83665
- }
83666
- function parseRelayOrigin2(value) {
83667
- let url2;
83668
- try {
83669
- url2 = new URL(value);
83670
- } catch (error62) {
83671
- throw new PairingClientError("invalid_relay_url", "The relay URL is invalid", { cause: error62 });
83672
- }
83673
- if (url2.protocol !== "https:" && url2.protocol !== "http:") {
83674
- throw new PairingClientError("invalid_relay_url", "The relay URL must use http or https");
83675
- }
83676
- if (url2.username.length > 0 || url2.password.length > 0) {
83677
- throw new PairingClientError("invalid_relay_url", "The relay URL cannot contain credentials");
83678
- }
83679
- if (url2.protocol === "http:" && url2.hostname !== "127.0.0.1" && url2.hostname !== "localhost") {
83680
- throw new PairingClientError("invalid_relay_url", "A remote relay must use https");
83681
- }
83682
- url2.hash = "";
83683
- url2.pathname = "/";
83684
- url2.search = "";
83685
- return url2;
83686
- }
83687
- function parsePairingCode(value) {
83688
- const code = value.trim().toUpperCase();
83689
- if (!PAIRING_CODE_PATTERN.test(code)) {
83690
- throw new PairingClientError(
83691
- "invalid_pairing_code",
83692
- "The pairing code must match the code shown in the browser"
83693
- );
83694
- }
83695
- return code;
83696
- }
83697
- function validatePairingId(value) {
83698
- if (!isIdentifier(value)) {
83699
- throw new PairingClientError("invalid_pairing_id", "The Runtime pairing ID is invalid");
83700
- }
83701
- return value;
83702
- }
83703
- async function resolveDefaultWorkspace(path7) {
83704
- const requestedWorkspace = resolve16(path7);
83705
- let defaultWorkspace;
83706
- try {
83707
- defaultWorkspace = await ensureCanonicalDirectory(requestedWorkspace);
83708
- } catch (error62) {
83709
- throw new PairingClientError("invalid_workspace", "The default workspace cannot be resolved", { cause: error62 });
83710
- }
83711
- if (defaultWorkspace === null) {
83712
- throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
83713
- }
83714
- return defaultWorkspace;
83715
- }
83716
- async function readJsonResponse(response) {
83717
- if (response.headers.get("cf-mitigated") === "challenge") {
83718
- throw new PairingClientError(
83719
- "relay_challenge",
83720
- "Cloudflare is protecting this temporary preview. Claim the deployment or use an authenticated deployment, then pair again"
83721
- );
83722
- }
83723
- const encoded = await response.text();
83724
- try {
83725
- return JSON.parse(encoded);
83726
- } catch (error62) {
83727
- throw new PairingClientError("invalid_relay_response", "The relay returned an invalid response", {
83728
- cause: error62
83729
- });
83730
- }
83731
- }
83732
- function readRelayError(value) {
83733
- if (isRecord3(value)) {
83734
- const error62 = value["error"];
83735
- if (isRecord3(error62)) {
83736
- const code = error62["code"];
83737
- const message = error62["message"];
83738
- if (typeof code === "string" && typeof message === "string") {
83739
- return new PairingClientError(code, message);
83740
- }
83741
- }
83742
- }
83743
- return new PairingClientError("pairing_failed", "The relay could not pair this machine");
83744
- }
83745
- function decodePairingResponse(value, credentialField, expectedKeys) {
83746
- if (!isRecord3(value) || !hasExactKeys2(value, expectedKeys)) {
83747
- throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
83748
- }
83749
- const appId = value["appId"];
83750
- const channelId = value["channelId"];
83751
- const runtimeCredential2 = value[credentialField];
83752
- const runtimeId = value["runtimeId"];
83753
- if (typeof appId !== "string" || !isIdentifier(appId) || typeof channelId !== "string" || !isIdentifier(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN.test(runtimeCredential2) || typeof runtimeId !== "string" || !isIdentifier(runtimeId)) {
83754
- throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
83755
- }
83756
- return { appId, channelId, runtimeCredential: runtimeCredential2, runtimeId };
83757
- }
83758
- async function claimPairing(options, defaultWorkspace, localAgents, signal) {
83759
- const agents = localAgents.map((agent) => ({
83760
- agentPath: agent.agentIdentity.requestedPath,
83761
- agentVersion: agent.agentVersion,
83762
- agentSettingsDiscovery: true,
83763
- capabilities: agent.capabilities,
83764
- id: agent.id,
83765
- label: agent.label,
83766
- sessionTurnConfiguration: true
83767
- }));
83768
- const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
83769
- let response;
83770
- try {
83771
- response = await fetch3(endpoint, {
83772
- body: JSON.stringify({
83773
- agents,
83774
- machineName: hostname3(),
83775
- pairingCode: options.code,
83776
- workspaceName: basename6(defaultWorkspace) || "Local workspace"
83777
- }),
83778
- dispatcher: environmentProxyDispatcher,
83779
- headers: { "content-type": "application/json" },
83780
- method: "POST",
83781
- signal: AbortSignal.any([signal, AbortSignal.timeout(PAIRING_TIMEOUT_MILLISECONDS)])
83782
- });
83783
- } catch (error62) {
83784
- throw new PairingClientError("relay_unavailable", "The pairing relay could not be reached", { cause: error62 });
83785
- }
83786
- const value = await readJsonResponse(response);
83787
- if (!response.ok) {
83788
- throw readRelayError(value);
83789
- }
83790
- return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
83791
- }
83792
- function buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext) {
83793
- const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
83794
- relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
83795
- relayUrl.searchParams.set("token", connection.runtimeCredential);
83796
- const config2 = createRuntimeConfig(
83797
- {
83798
- defaultWorkspace,
83799
- channelId: connection.channelId,
83800
- relayUrl
83801
- },
83802
- new RuntimeAgentDependencies(inventory.readyAgents()),
83803
- localContext,
83804
- new OpaqueRuntimeReconnectTarget(connection.connectionId),
83805
- createCatalogAgentResolver(
83806
- (refreshSignal) => discoverLocalAgentInventory({
83807
- defaultWorkspace,
83808
- dataDirectory: localContext.stateDirectory,
83809
- environment: localContext.environment,
83810
- signal: refreshSignal
83811
- }),
83812
- () => config2,
83813
- publishAgentCatalog
83814
- ),
83815
- (refreshSignal) => discoverLocalAgentInventory({
83816
- defaultWorkspace,
83817
- dataDirectory: localContext.stateDirectory,
83818
- environment: localContext.environment,
83819
- signal: refreshSignal
83820
- }).then((inventory2) => inventory2.readyAgents())
83821
- );
83822
- return {
83823
- channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
83824
- connectionId: connection.connectionId,
83825
- config: config2,
83826
- connectionPath: installation.connectionPath(connection.connectionId)
83827
- };
83828
- }
83829
- async function pairRuntime(installation, options, signal, environment) {
83830
- const localContext = new RuntimeLocalContext(installation.stateDirectory, environment);
83831
- const defaultWorkspace = await resolveDefaultWorkspace(options.workspace);
83832
- const inventory = await discoverLocalAgentInventory({
83833
- defaultWorkspace,
83834
- dataDirectory: localContext.stateDirectory,
83835
- environment: localContext.environment,
83836
- signal
83837
- });
83838
- const claim2 = await claimPairing(options, defaultWorkspace, inventory.readyAgents(), signal);
83839
- const connection = await installation.saveConnection(
83840
- {
83841
- appId: claim2.appId,
83842
- channelId: claim2.channelId,
83843
- defaultWorkspace,
83844
- pairingId: options.pairingId,
83845
- relayOrigin: options.relayOrigin,
83846
- runtimeCredential: claim2.runtimeCredential,
83847
- runtimeId: claim2.runtimeId
83848
- },
83849
- signal
83850
- );
83851
- return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
83852
- }
83853
- async function pairMobiusRuntime(installation, options, signal, environment = process.env) {
83854
- return await pairRuntime(
83855
- installation,
83856
- {
83857
- code: parsePairingCode(options.pairingCode),
83858
- pairingId: validatePairingId(options.pairingId),
83859
- relayOrigin: parseRelayOrigin2(options.relayOrigin),
83860
- workspace: options.defaultWorkspace
83861
- },
83862
- signal,
83863
- environment
83864
- );
83865
- }
83866
- async function resumeRuntimeConnection(installation, connection, signal, environment) {
83867
- const localContext = new RuntimeLocalContext(installation.stateDirectory, environment);
83868
- const defaultWorkspace = await resolveDefaultWorkspace(connection.defaultWorkspace);
83869
- const inventory = await discoverLocalAgentInventory({
83870
- defaultWorkspace,
83871
- dataDirectory: localContext.stateDirectory,
83872
- environment: localContext.environment,
83873
- signal
83874
- });
83875
- return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
83876
- }
83877
- async function resumeMobiusRuntime(installation, connectionId2, signal, environment = process.env) {
83878
- const connection = await installation.readConnection(connectionId2, signal);
83879
- return await resumeRuntimeConnection(installation, connection, signal, environment);
83880
- }
83622
+ // src/storage/state-root-layout.ts
83623
+ var STATE_ROOT_LAYOUT = Object.freeze({
83624
+ /** Names the version whose data is current. */
83625
+ currentData: "current-data.txt",
83626
+ /** Applications' installations: `installations/<application>/<installation>`. */
83627
+ installations: "installations",
83628
+ /** Managed CLI releases: `npm/<version>`. */
83629
+ releases: "npm",
83630
+ /** Each CLI version's data: `versions/<version>`. */
83631
+ versions: "versions"
83632
+ });
83633
+ var STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
83634
+
83635
+ // src/storage/state-directory.ts
83636
+ var stateRootSchema = external_exports.string().brand();
83881
83637
 
83882
83638
  // src/engine/runtime/run.ts
83883
83639
  import { styleText } from "node:util";
@@ -87326,6 +87082,43 @@ var ExecutionReceipts = class {
87326
87082
  return { state: "expired" };
87327
87083
  }
87328
87084
  };
87085
+ /**
87086
+ * How the Session's most recent started command ended. Receipts keep admission order, or the
87087
+ * order they last changed after a restart; commands that never started (queued, or reserved for
87088
+ * cancellation) are not turns, unless a restart failed them before they could start. Undefined
87089
+ * while that command still runs, or when no turn is retained.
87090
+ */
87091
+ lastTurn = (sessionId) => {
87092
+ let last;
87093
+ for (const [commandId, receipt] of this.#executions) {
87094
+ if (receipt.sessionId !== sessionId) {
87095
+ continue;
87096
+ }
87097
+ const outcome2 = receipt.outcome === null ? void 0 : this.outcome(commandId);
87098
+ const failedBeforeStart = outcome2?.type === "lifecycle-metadata" && outcome2.payload.kind === "prompt.failed-before-start";
87099
+ if (receipt.started || failedBeforeStart) {
87100
+ last = commandId;
87101
+ }
87102
+ }
87103
+ const outcome = last === void 0 ? void 0 : this.outcome(last);
87104
+ if (last === void 0 || outcome?.type !== "lifecycle-metadata") {
87105
+ return void 0;
87106
+ }
87107
+ switch (outcome.payload.kind) {
87108
+ case "prompt.completed":
87109
+ return { commandId: last, state: "completed", stopReason: outcome.payload.stopReason };
87110
+ case "prompt.failed":
87111
+ case "prompt.failed-before-start":
87112
+ return {
87113
+ code: outcome.payload.code,
87114
+ commandId: last,
87115
+ message: outcome.payload.message,
87116
+ state: "failed"
87117
+ };
87118
+ default:
87119
+ return void 0;
87120
+ }
87121
+ };
87329
87122
  /** Reserves an unseen command for cancellation before a delayed prompt can claim its identity. */
87330
87123
  recordCancellationBeforeAdmission = (commandId, sessionId) => {
87331
87124
  const existing = this.#executions.get(commandId);
@@ -87503,8 +87296,8 @@ var RuntimeTurnActivity = class {
87503
87296
  #changed() {
87504
87297
  this.#changedAt = Date.now();
87505
87298
  if (this.count() === 0) {
87506
- for (const resolve18 of this.#idleWaiters) {
87507
- resolve18();
87299
+ for (const resolve17 of this.#idleWaiters) {
87300
+ resolve17();
87508
87301
  }
87509
87302
  this.#idleWaiters.clear();
87510
87303
  }
@@ -87514,14 +87307,14 @@ var RuntimeTurnActivity = class {
87514
87307
  if (this.count() === 0) {
87515
87308
  return Promise.resolve();
87516
87309
  }
87517
- return new Promise((resolve18, reject2) => {
87310
+ return new Promise((resolve17, reject2) => {
87518
87311
  const abort = () => {
87519
87312
  this.#idleWaiters.delete(idle);
87520
87313
  reject2(signal.reason);
87521
87314
  };
87522
87315
  const idle = () => {
87523
87316
  signal.removeEventListener("abort", abort);
87524
- resolve18();
87317
+ resolve17();
87525
87318
  };
87526
87319
  this.#idleWaiters.add(idle);
87527
87320
  signal.addEventListener("abort", abort, { once: true });
@@ -87651,7 +87444,7 @@ var ActiveRuntimeTurn = class {
87651
87444
  // src/engine/session/turn/session-execution.ts
87652
87445
  var waitForTurnCompletion = (turn, waitSignal) => {
87653
87446
  waitSignal.throwIfAborted();
87654
- return new Promise((resolve18, reject2) => {
87447
+ return new Promise((resolve17, reject2) => {
87655
87448
  let settled = false;
87656
87449
  const finish = (result) => {
87657
87450
  if (settled) {
@@ -87660,7 +87453,7 @@ var waitForTurnCompletion = (turn, waitSignal) => {
87660
87453
  settled = true;
87661
87454
  waitSignal.removeEventListener("abort", onAbort);
87662
87455
  if (result.kind === "completed") {
87663
- resolve18();
87456
+ resolve17();
87664
87457
  } else {
87665
87458
  reject2(result.error);
87666
87459
  }
@@ -87842,8 +87635,8 @@ var SessionTurns = class {
87842
87635
  };
87843
87636
 
87844
87637
  // src/engine/session/workspace/workspace-directory.ts
87845
- import { homedir as homedir4 } from "node:os";
87846
- import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute15, join as join27, normalize as normalize2, relative as relative2 } from "node:path";
87638
+ import { homedir as homedir3 } from "node:os";
87639
+ import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute15, join as join24, normalize as normalize2, relative as relative2 } from "node:path";
87847
87640
  var WorkspaceDirectoryListing = class {
87848
87641
  directoryId;
87849
87642
  directoryLabel;
@@ -87864,7 +87657,7 @@ function encodePath(path7) {
87864
87657
  return `path-${encoded}`;
87865
87658
  }
87866
87659
  function expandCurrentUserHome(path7) {
87867
- return path7.replace(/^~(?=$|\/|\\)/, homedir4());
87660
+ return path7.replace(/^~(?=$|\/|\\)/, homedir3());
87868
87661
  }
87869
87662
  function decodePath(value, prefix) {
87870
87663
  const encoded = value.slice(prefix.length);
@@ -87895,7 +87688,7 @@ var WorkspaceDirectoryService = class {
87895
87688
  return this.#defaultWorkspace;
87896
87689
  }
87897
87690
  if (id === "home") {
87898
- return homedir4();
87691
+ return homedir3();
87899
87692
  }
87900
87693
  if (id.startsWith("path-")) {
87901
87694
  const path7 = expandCurrentUserHome(decodePath(id, "path-"));
@@ -87930,7 +87723,7 @@ var WorkspaceDirectoryService = class {
87930
87723
  }
87931
87724
  };
87932
87725
  label = (path7) => {
87933
- const suffix = relative2(homedir4(), path7);
87726
+ const suffix = relative2(homedir3(), path7);
87934
87727
  return suffix === "" ? "~" : !isAbsolute15(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path7;
87935
87728
  };
87936
87729
  identify = async (bindingId, requestedPath2, signal) => {
@@ -87939,7 +87732,7 @@ var WorkspaceDirectoryService = class {
87939
87732
  return {
87940
87733
  path: path7,
87941
87734
  directoryId: encodePath(path7),
87942
- name: basename7(path7) || path7,
87735
+ name: basename6(path7) || path7,
87943
87736
  label: this.label(path7)
87944
87737
  };
87945
87738
  };
@@ -87965,7 +87758,7 @@ var WorkspaceDirectoryService = class {
87965
87758
  continue;
87966
87759
  }
87967
87760
  try {
87968
- const path7 = await this.resolvePath(join27(target, child.name), signal);
87761
+ const path7 = await this.resolvePath(join24(target, child.name), signal);
87969
87762
  entries.push({ directoryId: encodePath(path7), name: child.name });
87970
87763
  } catch (cause) {
87971
87764
  signal.throwIfAborted();
@@ -88094,7 +87887,12 @@ function buildSessionLayer(options) {
88094
87887
  (directory, index2) => directory === requestOptions.additionalDirectories[index2]
88095
87888
  );
88096
87889
  });
88097
- return request.deliveryCommandId === void 0 ? snapshot : { ...snapshot, command: operations.delivery(request.deliveryCommandId, request.targetSessionId) };
87890
+ const lastTurn = snapshot.turn === null ? operations.lastTurn(request.targetSessionId) : void 0;
87891
+ return {
87892
+ ...snapshot,
87893
+ ...request.deliveryCommandId === void 0 ? {} : { command: operations.delivery(request.deliveryCommandId, request.targetSessionId) },
87894
+ ...lastTurn === void 0 ? {} : { lastTurn }
87895
+ };
88098
87896
  }
88099
87897
  );
88100
87898
  const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
@@ -88116,12 +87914,12 @@ function buildSessionLayer(options) {
88116
87914
 
88117
87915
  // src/engine/session/content/external-content-store.ts
88118
87916
  import { createHash as createHash7 } from "node:crypto";
88119
- import { join as join29 } from "node:path";
87917
+ import { join as join26 } from "node:path";
88120
87918
 
88121
87919
  // src/engine/storage/files/scratch-directory.ts
88122
87920
  import { randomUUID as randomUUID17 } from "node:crypto";
88123
87921
  import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
88124
- import { dirname as dirname11, join as join28 } from "node:path";
87922
+ import { dirname as dirname11, join as join25 } from "node:path";
88125
87923
  async function atomicWrite(path7, bytes, signal) {
88126
87924
  const temporary = `${path7}.${randomUUID17()}.tmp`;
88127
87925
  try {
@@ -88135,7 +87933,7 @@ async function atomicWrite(path7, bytes, signal) {
88135
87933
  var ScratchDirectory = class {
88136
87934
  #root;
88137
87935
  constructor(parent) {
88138
- this.#root = join28(parent, randomUUID17());
87936
+ this.#root = join25(parent, randomUUID17());
88139
87937
  }
88140
87938
  /** Refreshes this directory's lease and removes sibling directories whose lease is older than `leaseMilliseconds`. */
88141
87939
  refreshLease = async (leaseMilliseconds) => {
@@ -88146,7 +87944,7 @@ var ScratchDirectory = class {
88146
87944
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
88147
87945
  continue;
88148
87946
  }
88149
- const path7 = join28(dirname11(this.#root), directory.name);
87947
+ const path7 = join25(dirname11(this.#root), directory.name);
88150
87948
  if (path7 === this.#root) {
88151
87949
  continue;
88152
87950
  }
@@ -88161,10 +87959,10 @@ var ScratchDirectory = class {
88161
87959
  };
88162
87960
  /** Writes `bytes` atomically to `<group>/<name>` with owner-only permissions and returns the path. */
88163
87961
  write = async (group, name2, bytes, signal) => {
88164
- const directory = join28(this.#root, group);
87962
+ const directory = join25(this.#root, group);
88165
87963
  await mkdir5(directory, { mode: 448, recursive: true });
88166
87964
  signal.throwIfAborted();
88167
- const path7 = join28(directory, name2);
87965
+ const path7 = join25(directory, name2);
88168
87966
  await atomicWrite(path7, bytes, signal);
88169
87967
  return path7;
88170
87968
  };
@@ -88211,7 +88009,7 @@ var LocalExternalContentStore = class {
88211
88009
  #expirationTimer;
88212
88010
  #cleanup = Promise.resolve();
88213
88011
  constructor(stateDirectory) {
88214
- this.#scratch = new ScratchDirectory(join29(stateDirectory, "tmp", "session-content"));
88012
+ this.#scratch = new ScratchDirectory(join26(stateDirectory, "tmp", "session-content"));
88215
88013
  this.#expirationTimer = setInterval(() => {
88216
88014
  void this.#expire().catch(() => void 0);
88217
88015
  }, 6e4);
@@ -88409,18 +88207,6 @@ async function waitForAcpProcessCapacity(completion, signal) {
88409
88207
  var DEFAULT_MAX_ACP_PROCESSES = 1e3;
88410
88208
  var MAX_CONCURRENT_STARTS = 8;
88411
88209
  var ACP_PROCESS_IDLE_TIMEOUT_MILLISECONDS = 2 * 60 * 60 * 1e3;
88412
- var MAX_ACP_PROCESSES_ENVIRONMENT_KEY = "MOBIUS_MAX_ACP_PROCESSES";
88413
- function resolveMaxAcpProcesses(environment) {
88414
- const configured = environment[MAX_ACP_PROCESSES_ENVIRONMENT_KEY];
88415
- if (configured === void 0 || configured === "") {
88416
- return DEFAULT_MAX_ACP_PROCESSES;
88417
- }
88418
- const parsed = Number(configured);
88419
- if (!Number.isInteger(parsed) || parsed < 1) {
88420
- throw new Error(`${MAX_ACP_PROCESSES_ENVIRONMENT_KEY} must be a positive integer`);
88421
- }
88422
- return parsed;
88423
- }
88424
88210
  var AgentProcessPool = class {
88425
88211
  #maxProcesses;
88426
88212
  #timer;
@@ -88594,11 +88380,11 @@ var AgentProcessPool = class {
88594
88380
  };
88595
88381
 
88596
88382
  // src/engine/runtime/observability/diagnostic-log.ts
88597
- import { join as join32 } from "node:path";
88383
+ import { join as join29 } from "node:path";
88598
88384
 
88599
88385
  // src/engine/storage/logs/bounded-log.ts
88600
88386
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync as renameSync2, statSync as statSync5, writeFileSync as writeFileSync2 } from "node:fs";
88601
- import { join as join30 } from "node:path";
88387
+ import { join as join27 } from "node:path";
88602
88388
  var BoundedLineLog = class {
88603
88389
  #path;
88604
88390
  #maximumBytes;
@@ -88607,7 +88393,7 @@ var BoundedLineLog = class {
88607
88393
  #onWriteFailure;
88608
88394
  constructor(directory, filename, maximumBytes, onWriteFailure = () => void 0) {
88609
88395
  this.#directory = directory;
88610
- this.#path = join30(directory, filename);
88396
+ this.#path = join27(directory, filename);
88611
88397
  this.#maximumBytes = maximumBytes;
88612
88398
  this.#onWriteFailure = onWriteFailure;
88613
88399
  }
@@ -88658,21 +88444,21 @@ var BoundedLineLog = class {
88658
88444
 
88659
88445
  // src/engine/storage/logs/log-files.ts
88660
88446
  import { readFileSync as readFileSync10 } from "node:fs";
88661
- import { join as join31, relative as relative3 } from "node:path";
88447
+ import { join as join28 } from "node:path";
88662
88448
  var DAEMON_LOG_FILENAME = "daemon.log";
88663
88449
  var WORKER_LIFECYCLE_LOG_FILENAME = "worker-lifecycle.log";
88664
88450
  function unhandledRejectionLogFilename(role) {
88665
88451
  return `unhandled-rejections-${role}.log`;
88666
88452
  }
88667
- function logDirectory(stateDirectory) {
88668
- return join31(stateDirectory, "logs");
88453
+ function logDirectory(dataDirectory) {
88454
+ return join28(dataDirectory, "logs");
88669
88455
  }
88670
- function processLogPaths(stateDirectory) {
88456
+ function processLogPaths(dataDirectory) {
88671
88457
  return [
88672
88458
  WORKER_LIFECYCLE_LOG_FILENAME,
88673
88459
  unhandledRejectionLogFilename("manager"),
88674
88460
  unhandledRejectionLogFilename("worker")
88675
- ].map((filename) => join31(logDirectory(stateDirectory), filename));
88461
+ ].map((filename) => join28(logDirectory(dataDirectory), filename));
88676
88462
  }
88677
88463
  function readLogText(path7) {
88678
88464
  try {
@@ -88728,7 +88514,7 @@ var RuntimeDiagnosticLog = class {
88728
88514
  this.#maximumBytes = maximumBytes;
88729
88515
  const processLogsDirectory = options.processLogsDirectory;
88730
88516
  this.#sources = [
88731
- { maximumBytes, path: join32(directory, DAEMON_LOG_FILENAME) },
88517
+ { maximumBytes, path: join29(directory, DAEMON_LOG_FILENAME) },
88732
88518
  // The process logs a Runtime does not own, but must read to explain its own deaths.
88733
88519
  ...processLogsDirectory === void 0 ? [] : processLogPaths(processLogsDirectory).map((path7) => ({ maximumBytes: null, path: path7 }))
88734
88520
  ];
@@ -88841,6 +88627,8 @@ function addFailureDetails(details, failure2) {
88841
88627
  }
88842
88628
  }
88843
88629
  var RelayConnectionDiagnostics = class {
88630
+ #lastSkippedLogAt = Number.NEGATIVE_INFINITY;
88631
+ #skippedCount = 0;
88844
88632
  #channelId;
88845
88633
  #localLog;
88846
88634
  #lastClosedEpoch = 0;
@@ -88915,6 +88703,16 @@ var RelayConnectionDiagnostics = class {
88915
88703
  );
88916
88704
  };
88917
88705
  daemonDiagnostic = (event, requestId, details, failure2) => {
88706
+ if (event === "protocol_message_discarded" || event === "content_frame_discarded" || event === "content_chunk_discarded" || event === "prompt_attachments_skipped") {
88707
+ this.#skippedCount += 1;
88708
+ const now = Date.now();
88709
+ if (now - this.#lastSkippedLogAt < 6e4) {
88710
+ return;
88711
+ }
88712
+ details = { ...details, skippedCount: this.#skippedCount.toString() };
88713
+ this.#lastSkippedLogAt = now;
88714
+ this.#skippedCount = 0;
88715
+ }
88918
88716
  const recordedDetails = { ...details };
88919
88717
  if (failure2 !== void 0) {
88920
88718
  addFailureDetails(recordedDetails, failure2);
@@ -88986,7 +88784,7 @@ async function refreshAgentCatalog(config2, discover, signal) {
88986
88784
  const readyAgents = await discover(signal);
88987
88785
  signal.throwIfAborted();
88988
88786
  return await config2.catalog.replaceAndPublish(
88989
- () => readyAgents.map((agent) => withRuntimeEnvironment(agent, config2.localContext.environment)),
88787
+ () => readyAgents.map((agent) => withRuntimeEnvironment(agent, config2.localContext.agentLaunchEnvironment)),
88990
88788
  (publishSignal) => publishAgentCatalog(config2, publishSignal),
88991
88789
  signal
88992
88790
  );
@@ -89711,7 +89509,7 @@ function createContentWriteCommands(context) {
89711
89509
  import { WebSocket as WebSocket5 } from "undici";
89712
89510
 
89713
89511
  // src/engine/session/content/session-files.ts
89714
- import { basename as basename8, extname as extname3, isAbsolute as isAbsolute16, join as join33, normalize as normalize3, resolve as resolve17 } from "node:path";
89512
+ import { basename as basename7, extname as extname3, isAbsolute as isAbsolute16, join as join30, normalize as normalize3, resolve as resolve15 } from "node:path";
89715
89513
  import { fileURLToPath as fileURLToPath2 } from "node:url";
89716
89514
  function requestedPath(value) {
89717
89515
  if (value.includes("\0")) {
@@ -89735,7 +89533,7 @@ async function resolveFile(value, workingDirectory, signal) {
89735
89533
  if (isAbsolute16(requested.path) && normalize3(requested.path) !== requested.path) {
89736
89534
  return null;
89737
89535
  }
89738
- const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join33(workingDirectory, requested.path), requested.path] : [resolve17(workingDirectory, requested.path)];
89536
+ const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join30(workingDirectory, requested.path), requested.path] : [resolve15(workingDirectory, requested.path)];
89739
89537
  for (const candidate of candidates) {
89740
89538
  if (!isAbsolute16(candidate) || normalize3(candidate) !== candidate) {
89741
89539
  continue;
@@ -89769,7 +89567,7 @@ async function streamLocalFile(command, send2, sendChunk, signal, workingDirecto
89769
89567
  kind: FILE_BEGIN_KIND,
89770
89568
  mediaType: external?.mediaType ?? raster?.mimeType ?? (extname3(target).toLowerCase() === ".svg" ? "image/svg+xml" : "application/octet-stream"),
89771
89569
  modifiedAt: before.modifiedAt.toISOString(),
89772
- name: external?.name ?? (basename8(target) || "file"),
89570
+ name: external?.name ?? (basename7(target) || "file"),
89773
89571
  requestId: command.requestId,
89774
89572
  sessionId: command.sessionId
89775
89573
  });
@@ -89820,7 +89618,7 @@ var fileReadCommand = {
89820
89618
  };
89821
89619
 
89822
89620
  // src/engine/session/workspace/resolve-session-directories.ts
89823
- import { basename as basename9 } from "node:path";
89621
+ import { basename as basename8 } from "node:path";
89824
89622
  var ResolvedSessionDirectories = class {
89825
89623
  additionalDirectories;
89826
89624
  additionalDirectoryEntries;
@@ -89848,7 +89646,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId, ad
89848
89646
  additionalDirectories.push(directory);
89849
89647
  additionalDirectoryEntries.push({
89850
89648
  directoryId: additionalDirectoryId,
89851
- name: basename9(directory)
89649
+ name: basename8(directory)
89852
89650
  });
89853
89651
  }
89854
89652
  return new ResolvedSessionDirectories(cwd, selection.label, additionalDirectories, additionalDirectoryEntries);
@@ -90190,13 +89988,13 @@ function createNativeSessionRequestHandler(dependencies) {
90190
89988
  operationSignal.throwIfAborted();
90191
89989
  const skipPrevious = command.action === "active-turn";
90192
89990
  if (previous.length > 0 && !skipPrevious) {
90193
- await new Promise((resolve18, reject2) => {
89991
+ await new Promise((resolve17, reject2) => {
90194
89992
  const onAbort = () => reject2(operationSignal.reason);
90195
89993
  operationSignal.addEventListener("abort", onAbort, { once: true });
90196
89994
  void Promise.all(previous.map((request) => request.completion)).then(
90197
89995
  () => {
90198
89996
  operationSignal.removeEventListener("abort", onAbort);
90199
- resolve18();
89997
+ resolve17();
90200
89998
  },
90201
89999
  (error62) => {
90202
90000
  operationSignal.removeEventListener("abort", onAbort);
@@ -90515,10 +90313,7 @@ async function resolvePromptArtifacts(read, attachments, signal) {
90515
90313
  }
90516
90314
  if (attachment.kind === "image") {
90517
90315
  if (bytes.byteLength > PROMPT_IMAGE_MAX_BYTES || images.length >= 8) {
90518
- throw new PromptArtifactError(
90519
- "artifact_too_large_for_agent",
90520
- "The prompt attachment exceeds the Agent image limit"
90521
- );
90316
+ continue;
90522
90317
  }
90523
90318
  images.push({
90524
90319
  data: Buffer.from(bytes).toString("base64"),
@@ -90528,28 +90323,17 @@ async function resolvePromptArtifacts(read, attachments, signal) {
90528
90323
  continue;
90529
90324
  }
90530
90325
  if (!isTextMediaType(attachment.mimeType)) {
90531
- throw new PromptArtifactError(
90532
- "artifact_media_type_unsupported",
90533
- "The Agent cannot consume this prompt attachment media type"
90534
- );
90326
+ continue;
90535
90327
  }
90536
90328
  if (bytes.byteLength > MAX_AGENT_RESOURCE_BYTE_LENGTH || resources.length >= 16) {
90537
- throw new PromptArtifactError(
90538
- "artifact_too_large_for_agent",
90539
- "The prompt attachment exceeds the Agent resource limit"
90540
- );
90329
+ continue;
90541
90330
  }
90542
90331
  let text2;
90543
90332
  try {
90544
90333
  text2 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
90545
- } catch (cause) {
90546
- throw new PromptArtifactError(
90547
- "artifact_encoding_invalid",
90548
- "The prompt attachment is not valid UTF-8 text",
90549
- {
90550
- cause
90551
- }
90552
- );
90334
+ } catch {
90335
+ signal.throwIfAborted();
90336
+ continue;
90553
90337
  }
90554
90338
  resources.push({ mimeType: attachment.mimeType, text: text2, type: "embedded", uri: attachment.uri });
90555
90339
  }
@@ -90641,6 +90425,13 @@ async function executePrompt({
90641
90425
  availability.disposition
90642
90426
  );
90643
90427
  const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
90428
+ const skipped = command.attachments.length - attachments.images.length - attachments.resources.length;
90429
+ if (skipped > 0) {
90430
+ reportFailure("prompt_attachments_skipped", command.commandId, { count: skipped.toString() });
90431
+ }
90432
+ if (command.prompt.trim().length === 0 && attachments.images.length === 0 && attachments.resources.length === 0) {
90433
+ throw new PromptArtifactError("prompt_attachments_unsupported", "No supported prompt content remains");
90434
+ }
90644
90435
  let stopReason;
90645
90436
  if (availability.disposition === SessionPromptDisposition.Steer) {
90646
90437
  await sessions.steerPrompt({
@@ -91240,7 +91031,21 @@ function createCommandRegistry(context) {
91240
91031
  }
91241
91032
  command.handle(context, message);
91242
91033
  },
91243
- dispatchChunk: (message) => contentWrites.receiveChunk(decodeContentChunkFrame(message)),
91034
+ dispatchChunk: (message) => {
91035
+ const frame = (() => {
91036
+ try {
91037
+ return decodeContentChunkFrame(message);
91038
+ } catch {
91039
+ context.diagnostics.daemonDiagnostic("content_frame_discarded", "unknown", {
91040
+ reason: "unsupported_frame"
91041
+ });
91042
+ return null;
91043
+ }
91044
+ })();
91045
+ if (frame !== null) {
91046
+ contentWrites.receiveChunk(frame);
91047
+ }
91048
+ },
91244
91049
  settle: async () => {
91245
91050
  await Promise.all([
91246
91051
  contentWrites.settle(),
@@ -91290,7 +91095,7 @@ var RelayConnectionError = class extends Error {
91290
91095
  };
91291
91096
  function connectRelay(url2, signal) {
91292
91097
  signal.throwIfAborted();
91293
- return new Promise((resolve18, reject2) => {
91098
+ return new Promise((resolve17, reject2) => {
91294
91099
  let dispatchController;
91295
91100
  const dispatcher = environmentProxyDispatcher.compose((dispatch) => (options, handler) => {
91296
91101
  const trackedHandler = Object.create(handler);
@@ -91376,7 +91181,7 @@ function connectRelay(url2, signal) {
91376
91181
  }
91377
91182
  finished = true;
91378
91183
  cleanup();
91379
- resolve18({ release, socket });
91184
+ resolve17({ release, socket });
91380
91185
  };
91381
91186
  function onTimeout() {
91382
91187
  fail(
@@ -91552,7 +91357,7 @@ async function runRelayConnection({
91552
91357
  }
91553
91358
  });
91554
91359
  try {
91555
- await new Promise((resolve18, reject2) => {
91360
+ await new Promise((resolve17, reject2) => {
91556
91361
  let finished = false;
91557
91362
  let ready = false;
91558
91363
  const cleanup = () => {
@@ -91570,7 +91375,7 @@ async function runRelayConnection({
91570
91375
  }
91571
91376
  finished = true;
91572
91377
  cleanup();
91573
- resolve18();
91378
+ resolve17();
91574
91379
  };
91575
91380
  const rejectConnection = (failure2) => {
91576
91381
  if (finished) {
@@ -91657,6 +91462,9 @@ async function runRelayConnection({
91657
91462
  try {
91658
91463
  const message = decodeKnownServiceToDaemonMessage(encoded);
91659
91464
  if (message === null) {
91465
+ diagnostics.daemonDiagnostic("protocol_message_discarded", "unknown", {
91466
+ reason: "unsupported_message"
91467
+ });
91660
91468
  return;
91661
91469
  }
91662
91470
  const kind = message.kind;
@@ -91879,12 +91687,12 @@ function waitForRelayRetry(signal, timer) {
91879
91687
  if (signal.aborted) {
91880
91688
  return Promise.resolve();
91881
91689
  }
91882
- return new Promise((resolve18) => {
91690
+ return new Promise((resolve17) => {
91883
91691
  const retry = timer.schedule(finish, RELAY_RECONNECT_DELAY_MILLISECONDS);
91884
91692
  function finish() {
91885
91693
  retry.cancel();
91886
91694
  signal.removeEventListener("abort", finish);
91887
- resolve18();
91695
+ resolve17();
91888
91696
  }
91889
91697
  signal.addEventListener("abort", finish, { once: true });
91890
91698
  });
@@ -91927,7 +91735,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
91927
91735
  );
91928
91736
  const publisher = new RuntimeSessionEventPublisher(timer);
91929
91737
  const externalContent = __using(_stack, new LocalExternalContentStore(stateDirectory), true);
91930
- const processes = new AgentProcessPool(resolveMaxAcpProcesses(config2.localContext.environment) ?? void 0, timer);
91738
+ const processes = new AgentProcessPool(config2.localContext.maxAcpProcesses, timer);
91931
91739
  const adapters = createRuntimeAdapterRegistry(
91932
91740
  config2.adapters,
91933
91741
  processes,
@@ -92129,6 +91937,261 @@ var MobiusRuntimeEngine = class {
92129
91937
  }
92130
91938
  };
92131
91939
  };
91940
+
91941
+ // src/daemon/config.ts
91942
+ function resolveMaxAcpProcesses(environment) {
91943
+ const configured = environment["MOBIUS_MAX_ACP_PROCESSES"];
91944
+ if (configured === void 0 || configured === "") {
91945
+ return 1e3;
91946
+ }
91947
+ const parsed = Number(configured);
91948
+ if (!Number.isInteger(parsed) || parsed < 1) {
91949
+ throw new Error("MOBIUS_MAX_ACP_PROCESSES must be a positive integer");
91950
+ }
91951
+ return parsed;
91952
+ }
91953
+
91954
+ // src/daemon/pairing/pair-local-machine.ts
91955
+ var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
91956
+ var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
91957
+ var TOKEN_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
91958
+ var CLAIM_RESPONSE_KEYS = ["appId", "channelId", "daemonToken", "runtimeId"];
91959
+ var REDEEM_RESPONSE_KEYS = ["appId", "channelId", "runtimeCredential", "runtimeId"];
91960
+ var PairingClientError = class extends Error {
91961
+ code;
91962
+ constructor(code, message, options = {}) {
91963
+ super(message, options);
91964
+ this.code = code;
91965
+ this.name = "PairingClientError";
91966
+ }
91967
+ };
91968
+ function hasExactKeys2(value, expectedKeys) {
91969
+ const keys = Object.keys(value);
91970
+ return keys.length === expectedKeys.length && expectedKeys.every((key) => Object.hasOwn(value, key));
91971
+ }
91972
+ function parseRelayOrigin2(value) {
91973
+ let url2;
91974
+ try {
91975
+ url2 = new URL(value);
91976
+ } catch (error62) {
91977
+ throw new PairingClientError("invalid_relay_url", "The relay URL is invalid", { cause: error62 });
91978
+ }
91979
+ if (url2.protocol !== "https:" && url2.protocol !== "http:") {
91980
+ throw new PairingClientError("invalid_relay_url", "The relay URL must use http or https");
91981
+ }
91982
+ if (url2.username.length > 0 || url2.password.length > 0) {
91983
+ throw new PairingClientError("invalid_relay_url", "The relay URL cannot contain credentials");
91984
+ }
91985
+ if (url2.protocol === "http:" && url2.hostname !== "127.0.0.1" && url2.hostname !== "localhost") {
91986
+ throw new PairingClientError("invalid_relay_url", "A remote relay must use https");
91987
+ }
91988
+ url2.hash = "";
91989
+ url2.pathname = "/";
91990
+ url2.search = "";
91991
+ return url2;
91992
+ }
91993
+ function parsePairingCode(value) {
91994
+ const code = value.trim().toUpperCase();
91995
+ if (!PAIRING_CODE_PATTERN.test(code)) {
91996
+ throw new PairingClientError(
91997
+ "invalid_pairing_code",
91998
+ "The pairing code must match the code shown in the browser"
91999
+ );
92000
+ }
92001
+ return code;
92002
+ }
92003
+ function validatePairingId(value) {
92004
+ if (!isIdentifier(value)) {
92005
+ throw new PairingClientError("invalid_pairing_id", "The Runtime pairing ID is invalid");
92006
+ }
92007
+ return value;
92008
+ }
92009
+ async function resolveDefaultWorkspace(path7) {
92010
+ const requestedWorkspace = resolve16(path7);
92011
+ let defaultWorkspace;
92012
+ try {
92013
+ defaultWorkspace = await ensureCanonicalDirectory(requestedWorkspace);
92014
+ } catch (error62) {
92015
+ throw new PairingClientError("invalid_workspace", "The default workspace cannot be resolved", { cause: error62 });
92016
+ }
92017
+ if (defaultWorkspace === null) {
92018
+ throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
92019
+ }
92020
+ return defaultWorkspace;
92021
+ }
92022
+ async function readJsonResponse(response) {
92023
+ if (response.headers.get("cf-mitigated") === "challenge") {
92024
+ throw new PairingClientError(
92025
+ "relay_challenge",
92026
+ "Cloudflare is protecting this temporary preview. Claim the deployment or use an authenticated deployment, then pair again"
92027
+ );
92028
+ }
92029
+ const encoded = await response.text();
92030
+ try {
92031
+ return JSON.parse(encoded);
92032
+ } catch (error62) {
92033
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid response", {
92034
+ cause: error62
92035
+ });
92036
+ }
92037
+ }
92038
+ function readRelayError(value) {
92039
+ if (isRecord3(value)) {
92040
+ const error62 = value["error"];
92041
+ if (isRecord3(error62)) {
92042
+ const code = error62["code"];
92043
+ const message = error62["message"];
92044
+ if (typeof code === "string" && typeof message === "string") {
92045
+ return new PairingClientError(code, message);
92046
+ }
92047
+ }
92048
+ }
92049
+ return new PairingClientError("pairing_failed", "The relay could not pair this machine");
92050
+ }
92051
+ function decodePairingResponse(value, credentialField, expectedKeys) {
92052
+ if (!isRecord3(value) || !hasExactKeys2(value, expectedKeys)) {
92053
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
92054
+ }
92055
+ const appId = value["appId"];
92056
+ const channelId = value["channelId"];
92057
+ const runtimeCredential2 = value[credentialField];
92058
+ const runtimeId = value["runtimeId"];
92059
+ if (typeof appId !== "string" || !isIdentifier(appId) || typeof channelId !== "string" || !isIdentifier(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN.test(runtimeCredential2) || typeof runtimeId !== "string" || !isIdentifier(runtimeId)) {
92060
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
92061
+ }
92062
+ return { appId, channelId, runtimeCredential: runtimeCredential2, runtimeId };
92063
+ }
92064
+ async function claimPairing(options, defaultWorkspace, localAgents, signal) {
92065
+ const agents = localAgents.map((agent) => ({
92066
+ agentPath: agent.agentIdentity.requestedPath,
92067
+ agentVersion: agent.agentVersion,
92068
+ agentSettingsDiscovery: true,
92069
+ capabilities: agent.capabilities,
92070
+ id: agent.id,
92071
+ label: agent.label,
92072
+ sessionTurnConfiguration: true
92073
+ }));
92074
+ const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
92075
+ let response;
92076
+ try {
92077
+ response = await fetch3(endpoint, {
92078
+ body: JSON.stringify({
92079
+ agents,
92080
+ machineName: hostname3(),
92081
+ pairingCode: options.code,
92082
+ workspaceName: basename9(defaultWorkspace) || "Local workspace"
92083
+ }),
92084
+ dispatcher: environmentProxyDispatcher,
92085
+ headers: { "content-type": "application/json" },
92086
+ method: "POST",
92087
+ signal: AbortSignal.any([signal, AbortSignal.timeout(PAIRING_TIMEOUT_MILLISECONDS)])
92088
+ });
92089
+ } catch (error62) {
92090
+ throw new PairingClientError("relay_unavailable", "The pairing relay could not be reached", { cause: error62 });
92091
+ }
92092
+ const value = await readJsonResponse(response);
92093
+ if (!response.ok) {
92094
+ throw readRelayError(value);
92095
+ }
92096
+ return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
92097
+ }
92098
+ function buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext) {
92099
+ const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
92100
+ relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
92101
+ relayUrl.searchParams.set("token", connection.runtimeCredential);
92102
+ const config2 = createRuntimeConfig(
92103
+ {
92104
+ defaultWorkspace,
92105
+ channelId: connection.channelId,
92106
+ relayUrl
92107
+ },
92108
+ new RuntimeAgentDependencies(inventory.readyAgents()),
92109
+ localContext,
92110
+ new OpaqueRuntimeReconnectTarget(connection.connectionId),
92111
+ createCatalogAgentResolver(
92112
+ (refreshSignal) => discoverLocalAgentInventory({
92113
+ defaultWorkspace,
92114
+ dataDirectory: localContext.stateDirectory,
92115
+ environment: localContext.agentLaunchEnvironment,
92116
+ signal: refreshSignal
92117
+ }),
92118
+ () => config2,
92119
+ publishAgentCatalog
92120
+ ),
92121
+ (refreshSignal) => discoverLocalAgentInventory({
92122
+ defaultWorkspace,
92123
+ dataDirectory: localContext.stateDirectory,
92124
+ environment: localContext.agentLaunchEnvironment,
92125
+ signal: refreshSignal
92126
+ }).then((inventory2) => inventory2.readyAgents())
92127
+ );
92128
+ return {
92129
+ channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
92130
+ connectionId: connection.connectionId,
92131
+ config: config2,
92132
+ connectionPath: installation.connectionPath(connection.connectionId)
92133
+ };
92134
+ }
92135
+ async function pairRuntime(installation, options, signal, environment) {
92136
+ const localContext = new RuntimeLocalContext(
92137
+ installation.stateDirectory,
92138
+ environment,
92139
+ resolveMaxAcpProcesses(environment)
92140
+ );
92141
+ const defaultWorkspace = await resolveDefaultWorkspace(options.workspace);
92142
+ const inventory = await discoverLocalAgentInventory({
92143
+ defaultWorkspace,
92144
+ dataDirectory: localContext.stateDirectory,
92145
+ environment: localContext.agentLaunchEnvironment,
92146
+ signal
92147
+ });
92148
+ const claim2 = await claimPairing(options, defaultWorkspace, inventory.readyAgents(), signal);
92149
+ const connection = await installation.saveConnection(
92150
+ {
92151
+ appId: claim2.appId,
92152
+ channelId: claim2.channelId,
92153
+ defaultWorkspace,
92154
+ pairingId: options.pairingId,
92155
+ relayOrigin: options.relayOrigin,
92156
+ runtimeCredential: claim2.runtimeCredential,
92157
+ runtimeId: claim2.runtimeId
92158
+ },
92159
+ signal
92160
+ );
92161
+ return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
92162
+ }
92163
+ async function pairMobiusRuntime(installation, options, signal, environment = process.env) {
92164
+ return await pairRuntime(
92165
+ installation,
92166
+ {
92167
+ code: parsePairingCode(options.pairingCode),
92168
+ pairingId: validatePairingId(options.pairingId),
92169
+ relayOrigin: parseRelayOrigin2(options.relayOrigin),
92170
+ workspace: options.defaultWorkspace
92171
+ },
92172
+ signal,
92173
+ environment
92174
+ );
92175
+ }
92176
+ async function resumeRuntimeConnection(installation, connection, signal, environment) {
92177
+ const localContext = new RuntimeLocalContext(
92178
+ installation.stateDirectory,
92179
+ environment,
92180
+ resolveMaxAcpProcesses(environment)
92181
+ );
92182
+ const defaultWorkspace = await resolveDefaultWorkspace(connection.defaultWorkspace);
92183
+ const inventory = await discoverLocalAgentInventory({
92184
+ defaultWorkspace,
92185
+ dataDirectory: localContext.stateDirectory,
92186
+ environment: localContext.agentLaunchEnvironment,
92187
+ signal
92188
+ });
92189
+ return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
92190
+ }
92191
+ async function resumeMobiusRuntime(installation, connectionId2, signal, environment = process.env) {
92192
+ const connection = await installation.readConnection(connectionId2, signal);
92193
+ return await resumeRuntimeConnection(installation, connection, signal, environment);
92194
+ }
92132
92195
  export {
92133
92196
  MobiusRuntimeEngine,
92134
92197
  RuntimeRelayRevokedError,