@moxt-ai/mobius 0.0.344 → 0.0.345

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 (152) 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 +10089 -10034
  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/process/agent-process-pool.d.ts +0 -1
  81. package/dist/engine/session/process/agent-process-pool.d.ts.map +1 -1
  82. package/dist/engine/session/process/agent-process-pool.js +0 -14
  83. package/dist/engine/session/process/agent-process-pool.js.map +1 -1
  84. package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
  85. package/dist/engine/session/prompt/execute-prompt.js +10 -1
  86. package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
  87. package/dist/engine/session/prompt/prompt-artifacts.d.ts.map +1 -1
  88. package/dist/engine/session/prompt/prompt-artifacts.js +6 -7
  89. package/dist/engine/session/prompt/prompt-artifacts.js.map +1 -1
  90. package/dist/engine/storage/installation/installation-files.d.ts +3 -4
  91. package/dist/engine/storage/installation/installation-files.d.ts.map +1 -1
  92. package/dist/engine/storage/installation/installation-files.js +5 -9
  93. package/dist/engine/storage/installation/installation-files.js.map +1 -1
  94. package/dist/engine/storage/logs/log-files.d.ts +2 -26
  95. package/dist/engine/storage/logs/log-files.d.ts.map +1 -1
  96. package/dist/engine/storage/logs/log-files.js +5 -128
  97. package/dist/engine/storage/logs/log-files.js.map +1 -1
  98. package/dist/engine.js +479 -469
  99. package/dist/engine.js.map +4 -4
  100. package/dist/{engine/storage → storage}/daemon/control-token.d.ts +1 -1
  101. package/dist/storage/daemon/control-token.d.ts.map +1 -0
  102. package/dist/{engine/storage → storage}/daemon/control-token.js +1 -1
  103. package/dist/storage/daemon/control-token.js.map +1 -0
  104. package/dist/{engine/storage → storage}/daemon/manager-lock.d.ts +1 -1
  105. package/dist/storage/daemon/manager-lock.d.ts.map +1 -0
  106. package/dist/{engine/storage → storage}/daemon/manager-lock.js +1 -1
  107. package/dist/storage/daemon/manager-lock.js.map +1 -0
  108. package/dist/storage/daemon/release-files.d.ts.map +1 -0
  109. package/dist/storage/daemon/release-files.js.map +1 -0
  110. package/dist/{engine/storage → storage}/daemon/version-data.d.ts +2 -0
  111. package/dist/storage/daemon/version-data.d.ts.map +1 -0
  112. package/dist/{engine/storage → storage}/daemon/version-data.js +17 -2
  113. package/dist/storage/daemon/version-data.js.map +1 -0
  114. package/dist/storage/files/output-file.d.ts.map +1 -0
  115. package/dist/{engine/storage → storage}/files/output-file.js +1 -1
  116. package/dist/storage/files/output-file.js.map +1 -0
  117. package/dist/storage/logs/log-files.d.ts +24 -0
  118. package/dist/storage/logs/log-files.d.ts.map +1 -0
  119. package/dist/storage/logs/log-files.js +122 -0
  120. package/dist/storage/logs/log-files.js.map +1 -0
  121. package/dist/storage/state-directory.d.ts.map +1 -0
  122. package/dist/storage/state-directory.js.map +1 -0
  123. package/dist/storage/state-root-layout.d.ts.map +1 -0
  124. package/dist/storage/state-root-layout.js.map +1 -0
  125. package/dist/storage/state-root.d.ts.map +1 -0
  126. package/dist/{engine/storage → storage}/state-root.js +1 -1
  127. package/dist/storage/state-root.js.map +1 -0
  128. package/package.json +1 -1
  129. package/dist/engine/storage/daemon/control-token.d.ts.map +0 -1
  130. package/dist/engine/storage/daemon/control-token.js.map +0 -1
  131. package/dist/engine/storage/daemon/manager-lock.d.ts.map +0 -1
  132. package/dist/engine/storage/daemon/manager-lock.js.map +0 -1
  133. package/dist/engine/storage/daemon/release-files.d.ts.map +0 -1
  134. package/dist/engine/storage/daemon/release-files.js.map +0 -1
  135. package/dist/engine/storage/daemon/version-data.d.ts.map +0 -1
  136. package/dist/engine/storage/daemon/version-data.js.map +0 -1
  137. package/dist/engine/storage/files/output-file.d.ts.map +0 -1
  138. package/dist/engine/storage/files/output-file.js.map +0 -1
  139. package/dist/engine/storage/state-directory.d.ts.map +0 -1
  140. package/dist/engine/storage/state-directory.js.map +0 -1
  141. package/dist/engine/storage/state-root-layout.d.ts.map +0 -1
  142. package/dist/engine/storage/state-root-layout.js.map +0 -1
  143. package/dist/engine/storage/state-root.d.ts.map +0 -1
  144. package/dist/engine/storage/state-root.js.map +0 -1
  145. /package/dist/{engine/storage → storage}/daemon/release-files.d.ts +0 -0
  146. /package/dist/{engine/storage → storage}/daemon/release-files.js +0 -0
  147. /package/dist/{engine/storage → storage}/files/output-file.d.ts +0 -0
  148. /package/dist/{engine/storage → storage}/state-directory.d.ts +0 -0
  149. /package/dist/{engine/storage → storage}/state-directory.js +0 -0
  150. /package/dist/{engine/storage → storage}/state-root-layout.d.ts +0 -0
  151. /package/dist/{engine/storage → storage}/state-root-layout.js +0 -0
  152. /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
  });
@@ -21762,12 +21762,12 @@ var serviceToDaemonSignatures = {
21762
21762
  };
21763
21763
  var serviceToDaemonRegistry = serviceToDaemonSignatures;
21764
21764
  function decodeKnownServiceToDaemonMessage(encoded) {
21765
- const kind = decodeMessageKind(encoded);
21766
- const signature = serviceToDaemonRegistry[kind];
21767
- if (signature === void 0) {
21768
- return null;
21769
- }
21770
21765
  try {
21766
+ const kind = decodeMessageKind(encoded);
21767
+ const signature = serviceToDaemonRegistry[kind];
21768
+ if (signature === void 0) {
21769
+ return null;
21770
+ }
21771
21771
  return signature.decoder(encoded);
21772
21772
  } catch {
21773
21773
  return null;
@@ -21911,7 +21911,7 @@ import { fetch as fetch3 } from "undici";
21911
21911
  // package.json
21912
21912
  var package_default = {
21913
21913
  name: "@moxt-ai/mobius",
21914
- version: "0.0.344",
21914
+ version: "0.0.345",
21915
21915
  description: "Mobius CLI for pairing and running local AI agent services.",
21916
21916
  type: "module",
21917
21917
  bin: {
@@ -58990,11 +58990,11 @@ var Pushable = class {
58990
58990
  done = false;
58991
58991
  push(item) {
58992
58992
  if (this.resolvers.length > 0) {
58993
- const resolve18 = this.resolvers.shift();
58994
- if (resolve18 === void 0) {
58993
+ const resolve17 = this.resolvers.shift();
58994
+ if (resolve17 === void 0) {
58995
58995
  return;
58996
58996
  }
58997
- resolve18({ value: item, done: false });
58997
+ resolve17({ value: item, done: false });
58998
58998
  } else {
58999
58999
  this.queue.push(item);
59000
59000
  }
@@ -59002,8 +59002,8 @@ var Pushable = class {
59002
59002
  end() {
59003
59003
  this.done = true;
59004
59004
  while (this.resolvers.length > 0) {
59005
- const resolve18 = this.resolvers.shift();
59006
- resolve18?.({ done: true, value: void 0 });
59005
+ const resolve17 = this.resolvers.shift();
59006
+ resolve17?.({ done: true, value: void 0 });
59007
59007
  }
59008
59008
  }
59009
59009
  [Symbol.asyncIterator]() {
@@ -59019,8 +59019,8 @@ var Pushable = class {
59019
59019
  if (this.done) {
59020
59020
  return Promise.resolve({ done: true, value: void 0 });
59021
59021
  }
59022
- return new Promise((resolve18) => {
59023
- this.resolvers.push(resolve18);
59022
+ return new Promise((resolve17) => {
59023
+ this.resolvers.push(resolve17);
59024
59024
  });
59025
59025
  }
59026
59026
  };
@@ -59038,14 +59038,14 @@ function unreachable(value, logger = console) {
59038
59038
  async function withDeadline(signal, timeoutMilliseconds, operation) {
59039
59039
  const deadline = AbortSignal.any([signal, AbortSignal.timeout(timeoutMilliseconds)]);
59040
59040
  deadline.throwIfAborted();
59041
- return await new Promise((resolve18, reject2) => {
59041
+ return await new Promise((resolve17, reject2) => {
59042
59042
  const settle2 = (callback) => {
59043
59043
  deadline.removeEventListener("abort", onAbort);
59044
59044
  callback();
59045
59045
  };
59046
59046
  const onAbort = () => settle2(() => reject2(deadline.reason));
59047
59047
  deadline.addEventListener("abort", onAbort, { once: true });
59048
- operation().then((value) => settle2(() => resolve18(value)), (error62) => settle2(() => reject2(error62)));
59048
+ operation().then((value) => settle2(() => resolve17(value)), (error62) => settle2(() => reject2(error62)));
59049
59049
  });
59050
59050
  }
59051
59051
  var environmentChain = Promise.resolve();
@@ -59588,8 +59588,8 @@ function inputPath(context, key) {
59588
59588
  return plainString(context.input[key]);
59589
59589
  }
59590
59590
  function isInside(directory, candidate) {
59591
- const relative4 = path.relative(path.resolve(directory), path.resolve(candidate));
59592
- return relative4 === "" || !relative4.startsWith(`..${path.sep}`) && relative4 !== "..";
59591
+ const relative3 = path.relative(path.resolve(directory), path.resolve(candidate));
59592
+ return relative3 === "" || !relative3.startsWith(`..${path.sep}`) && relative3 !== "..";
59593
59593
  }
59594
59594
  function hasSessionAllowRuleFor(changeSet, toolName) {
59595
59595
  return !!changeSet?.updates.some((update) => update.type === "addRules" && update.destination === "session" && update.behavior === "allow" && update.rules.some((rule) => rule.toolName === toolName));
@@ -61738,14 +61738,14 @@ function waitUnlessAborted(milliseconds, signal) {
61738
61738
  if (signal.aborted) {
61739
61739
  return Promise.resolve(false);
61740
61740
  }
61741
- return new Promise((resolve18) => {
61741
+ return new Promise((resolve17) => {
61742
61742
  const timer = setTimeout(() => {
61743
61743
  signal.removeEventListener("abort", onAbort);
61744
- resolve18(true);
61744
+ resolve17(true);
61745
61745
  }, milliseconds);
61746
61746
  const onAbort = () => {
61747
61747
  clearTimeout(timer);
61748
- resolve18(false);
61748
+ resolve17(false);
61749
61749
  };
61750
61750
  signal.addEventListener("abort", onAbort, { once: true });
61751
61751
  });
@@ -61991,7 +61991,7 @@ var ClientConnection = class {
61991
61991
  }
61992
61992
  };
61993
61993
  function raceWithAbort(operation, signal) {
61994
- return new Promise((resolve18, reject2) => {
61994
+ return new Promise((resolve17, reject2) => {
61995
61995
  const cleanup = () => signal.removeEventListener("abort", onAbort);
61996
61996
  const onAbort = () => {
61997
61997
  cleanup();
@@ -62003,7 +62003,7 @@ function raceWithAbort(operation, signal) {
62003
62003
  }
62004
62004
  void operation.then((value) => {
62005
62005
  cleanup();
62006
- resolve18(value);
62006
+ resolve17(value);
62007
62007
  }, (error62) => {
62008
62008
  cleanup();
62009
62009
  reject2(error62);
@@ -62586,12 +62586,12 @@ var ClaudeAcpAgent = class {
62586
62586
  }
62587
62587
  };
62588
62588
  let completeTurn;
62589
- turn.completion = new Promise((resolve18) => {
62590
- completeTurn = resolve18;
62589
+ turn.completion = new Promise((resolve17) => {
62590
+ completeTurn = resolve17;
62591
62591
  });
62592
- const response = new Promise((resolve18, reject2) => {
62592
+ const response = new Promise((resolve17, reject2) => {
62593
62593
  turn.resolve = (result) => {
62594
- resolve18(result);
62594
+ resolve17(result);
62595
62595
  completeTurn();
62596
62596
  };
62597
62597
  turn.reject = (error62) => {
@@ -63006,8 +63006,8 @@ var ClaudeAcpAgent = class {
63006
63006
  pendingNext ??= session.query.next().then((result) => ({ kind: "message", result }));
63007
63007
  const nextMessage = pendingNext;
63008
63008
  let onAbort;
63009
- const abortRace = new Promise((resolve18) => {
63010
- onAbort = () => resolve18("abort");
63009
+ const abortRace = new Promise((resolve17) => {
63010
+ onAbort = () => resolve17("abort");
63011
63011
  cancelController.signal.addEventListener("abort", onAbort, { once: true });
63012
63012
  });
63013
63013
  const raced = await Promise.race([nextMessage, abortRace]);
@@ -70594,10 +70594,10 @@ var PiRpcProcess = class _PiRpcProcess {
70594
70594
  shell: shouldUseShellForPiCommand(cmd)
70595
70595
  });
70596
70596
  try {
70597
- await new Promise((resolve18, reject2) => {
70597
+ await new Promise((resolve17, reject2) => {
70598
70598
  const onSpawn = () => {
70599
70599
  cleanup();
70600
- resolve18();
70600
+ resolve17();
70601
70601
  };
70602
70602
  const onError = (err) => {
70603
70603
  cleanup();
@@ -70799,7 +70799,7 @@ var PiRpcProcess = class _PiRpcProcess {
70799
70799
  const timeoutMs = opts?.timeoutMs;
70800
70800
  const line = `${JSON.stringify(withId)}
70801
70801
  `;
70802
- return new Promise((resolve18, reject2) => {
70802
+ return new Promise((resolve17, reject2) => {
70803
70803
  const signal = opts?.signal;
70804
70804
  if (signal?.aborted === true) {
70805
70805
  reject2(signal.reason);
@@ -70821,7 +70821,7 @@ var PiRpcProcess = class _PiRpcProcess {
70821
70821
  this.pending.set(id, {
70822
70822
  resolve: (res) => {
70823
70823
  drop();
70824
- resolve18(res);
70824
+ resolve17(res);
70825
70825
  },
70826
70826
  reject: (error62) => {
70827
70827
  drop();
@@ -70854,14 +70854,14 @@ var PiRpcProcess = class _PiRpcProcess {
70854
70854
  });
70855
70855
  }
70856
70856
  writeLine(line) {
70857
- return new Promise((resolve18, reject2) => {
70857
+ return new Promise((resolve17, reject2) => {
70858
70858
  try {
70859
70859
  this.child.stdin.write(line, (error62) => {
70860
70860
  if (error62) {
70861
70861
  reject2(error62);
70862
70862
  return;
70863
70863
  }
70864
- resolve18();
70864
+ resolve17();
70865
70865
  });
70866
70866
  } catch (error62) {
70867
70867
  reject2(error62);
@@ -72132,8 +72132,8 @@ var PiAcpSession = class {
72132
72132
  }
72133
72133
  async prompt(message, images = []) {
72134
72134
  const expandedMessage = expandSlashCommand(message, this.fileCommands);
72135
- const turnPromise = new Promise((resolve18, reject2) => {
72136
- const queued = { message: expandedMessage, images, resolve: resolve18, reject: reject2 };
72135
+ const turnPromise = new Promise((resolve17, reject2) => {
72136
+ const queued = { message: expandedMessage, images, resolve: resolve17, reject: reject2 };
72137
72137
  if (this.pendingTurn) {
72138
72138
  this.turnQueue.push(queued);
72139
72139
  this.emit({
@@ -75100,8 +75100,8 @@ var AdapterRegistry = class {
75100
75100
  #resolve;
75101
75101
  #dependencies;
75102
75102
  #adapters = /* @__PURE__ */ new Map();
75103
- constructor(resolve18, dependencies) {
75104
- this.#resolve = resolve18;
75103
+ constructor(resolve17, dependencies) {
75104
+ this.#resolve = resolve17;
75105
75105
  this.#dependencies = dependencies;
75106
75106
  }
75107
75107
  resolve = (agent) => {
@@ -76093,14 +76093,14 @@ function mergeTextChunk(previous, incoming) {
76093
76093
  var SessionEventHistoryProjection = class {
76094
76094
  #toolCallEventIds = /* @__PURE__ */ new Map();
76095
76095
  #latestEvent = null;
76096
- apply = (liveEvent2, resolve18) => {
76096
+ apply = (liveEvent2, resolve17) => {
76097
76097
  if (liveEvent2.type === "lifecycle-metadata") {
76098
76098
  this.#latestEvent = null;
76099
76099
  return { kind: "skip" };
76100
76100
  }
76101
76101
  if (liveEvent2.type === "acp" && liveEvent2.payload.sessionUpdate === "tool_call_update") {
76102
76102
  const targetEventId = this.#toolCallEventIds.get(liveEvent2.payload.toolCallId);
76103
- const current = targetEventId === void 0 ? void 0 : resolve18([targetEventId]).get(targetEventId);
76103
+ const current = targetEventId === void 0 ? void 0 : resolve17([targetEventId]).get(targetEventId);
76104
76104
  if (current?.type === "acp" && (current.payload.sessionUpdate === "tool_call" || current.payload.sessionUpdate === "tool_call_update")) {
76105
76105
  return this.#replace(
76106
76106
  current,
@@ -76124,12 +76124,12 @@ var SessionEventHistoryProjection = class {
76124
76124
  * The projected tool call announced with this identifier, in its current
76125
76125
  * merged form, or `undefined` when the projection has not recorded one.
76126
76126
  */
76127
- getToolCall = (toolCallId, resolve18) => {
76127
+ getToolCall = (toolCallId, resolve17) => {
76128
76128
  const eventId = this.#toolCallEventIds.get(toolCallId);
76129
76129
  if (eventId === void 0) {
76130
76130
  return void 0;
76131
76131
  }
76132
- const event = resolve18([eventId]).get(eventId);
76132
+ const event = resolve17([eventId]).get(eventId);
76133
76133
  if (event?.type === "acp" && (event.payload.sessionUpdate === "tool_call" || event.payload.sessionUpdate === "tool_call_update")) {
76134
76134
  return event.payload;
76135
76135
  }
@@ -76189,8 +76189,8 @@ var SessionEvents = class {
76189
76189
  this.sessionGenerationId = sessionGenerationId;
76190
76190
  this.#projection = new SessionEventHistoryProjection();
76191
76191
  }
76192
- apply = (event, resolve18) => {
76193
- const projected = this.#projection.apply(event, resolve18);
76192
+ apply = (event, resolve17) => {
76193
+ const projected = this.#projection.apply(event, resolve17);
76194
76194
  this.#throughPosition = event.position;
76195
76195
  if (projected.kind === "skip") {
76196
76196
  return;
@@ -76217,7 +76217,7 @@ var SessionEvents = class {
76217
76217
  return this.#cachedItemsByEventId.size;
76218
76218
  }
76219
76219
  /** The projected tool call for this identifier, materializing it if needed. */
76220
- toolCall = (toolCallId, resolve18) => this.#projection.getToolCall(toolCallId, resolve18);
76220
+ toolCall = (toolCallId, resolve17) => this.#projection.getToolCall(toolCallId, resolve17);
76221
76221
  endIndex = (cursor) => {
76222
76222
  if (cursor === null) {
76223
76223
  return this.#eventIds.length;
@@ -77571,7 +77571,7 @@ function sql(strings, ...params) {
77571
77571
  return new SQL([new StringChunk(str)]);
77572
77572
  }
77573
77573
  _sql.raw = raw;
77574
- function join34(chunks, separator) {
77574
+ function join32(chunks, separator) {
77575
77575
  const result = [];
77576
77576
  for (const [i, chunk] of chunks.entries()) {
77577
77577
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -77579,7 +77579,7 @@ function sql(strings, ...params) {
77579
77579
  }
77580
77580
  return new SQL(result);
77581
77581
  }
77582
- _sql.join = join34;
77582
+ _sql.join = join32;
77583
77583
  function identifier2(value) {
77584
77584
  return new Name(value);
77585
77585
  }
@@ -79300,7 +79300,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
79300
79300
  const baseTableName = this.tableName;
79301
79301
  const tableName = getTableLikeName(table);
79302
79302
  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`);
79303
+ if (typeof tableName === "string" && this.config.joins?.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
79304
79304
  if (!this.isPartialSelect) {
79305
79305
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
79306
79306
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -80846,7 +80846,7 @@ var SQLiteDialect = class {
80846
80846
  if (!joins2) return;
80847
80847
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
80848
80848
  if (!withEntries.length) return;
80849
- return sql.join(withEntries.map(([k2, join34]) => {
80849
+ return sql.join(withEntries.map(([k2, join32]) => {
80850
80850
  const relation = tableConfig.relations[k2];
80851
80851
  const isSingle2 = is(relation, One2);
80852
80852
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -80857,7 +80857,7 @@ var SQLiteDialect = class {
80857
80857
  table: targetTable,
80858
80858
  mode: isSingle2 ? "first" : "many",
80859
80859
  schema,
80860
- queryConfig: join34,
80860
+ queryConfig: join32,
80861
80861
  tableConfig: schema[relation.targetTableName],
80862
80862
  relationWhere: filter,
80863
80863
  isNested: true,
@@ -80871,7 +80871,7 @@ var SQLiteDialect = class {
80871
80871
  key: k2,
80872
80872
  selection: innerQuery.selection,
80873
80873
  isArray: !isSingle2,
80874
- isOptional: (relation.optional ?? false) || join34 !== true && !!join34.where
80874
+ isOptional: (relation.optional ?? false) || join32 !== true && !!join32.where
80875
80875
  });
80876
80876
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
80877
80877
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -81225,7 +81225,7 @@ var SQLiteUpdateBase = class {
81225
81225
  createJoin(joinType) {
81226
81226
  return ((table, on2) => {
81227
81227
  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`);
81228
+ if (typeof tableName === "string" && this.config.joins.some((join32) => join32.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
81229
81229
  if (typeof on2 === "function") {
81230
81230
  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
81231
  on2 = on2(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -82885,7 +82885,7 @@ async function publishAgentCatalog(config2, signal) {
82885
82885
  }
82886
82886
 
82887
82887
  // src/engine/runtime/config.ts
82888
- import { join as join24, resolve as resolve14 } from "node:path";
82888
+ import { resolve as resolve13 } from "node:path";
82889
82889
 
82890
82890
  // src/engine/util/serial-task-queue.ts
82891
82891
  var SerialTaskQueue = class {
@@ -82956,24 +82956,15 @@ var LocalAgentCatalog = class {
82956
82956
  };
82957
82957
  };
82958
82958
 
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
82959
  // src/engine/runtime/config.ts
82971
82960
  var RuntimeLocalContext = class {
82972
- environment;
82961
+ agentLaunchEnvironment;
82973
82962
  stateDirectory;
82974
- constructor(stateDirectory, environment = process.env) {
82975
- this.stateDirectory = resolve14(stateDirectory);
82976
- this.environment = Object.freeze({ ...environment });
82963
+ maxAcpProcesses;
82964
+ constructor(stateDirectory, agentLaunchEnvironment, maxAcpProcesses = 1e3) {
82965
+ this.stateDirectory = resolve13(stateDirectory);
82966
+ this.agentLaunchEnvironment = Object.freeze({ ...agentLaunchEnvironment });
82967
+ this.maxAcpProcesses = maxAcpProcesses;
82977
82968
  }
82978
82969
  };
82979
82970
  function withRuntimeEnvironment(agent, environment) {
@@ -82996,8 +82987,10 @@ var OpaqueRuntimeReconnectTarget = class extends RuntimeReconnectTarget {
82996
82987
  this.commandArgument = `--connection ${connectionId2}`;
82997
82988
  }
82998
82989
  };
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));
82990
+ function createRuntimeConfig(connection, dependencies, localContext, reconnectTarget = null, resolveAgent, rediscoverAgents) {
82991
+ const runtimeAgents = dependencies.agents.map(
82992
+ (agent) => withRuntimeEnvironment(agent, localContext.agentLaunchEnvironment)
82993
+ );
83001
82994
  return {
83002
82995
  adapters: dependencies.adapters,
83003
82996
  agents: runtimeAgents,
@@ -83039,7 +83032,7 @@ function createCatalogAgentResolver(discover, readConfig, publish) {
83039
83032
  signal.throwIfAborted();
83040
83033
  const inventory = await discover(signal);
83041
83034
  signal.throwIfAborted();
83042
- const rediscovered = inventory.readyAgents().filter((ready) => ready.id === agent.id).map((ready) => withRuntimeEnvironment(ready, config2.localContext.environment));
83035
+ const rediscovered = inventory.readyAgents().filter((ready) => ready.id === agent.id).map((ready) => withRuntimeEnvironment(ready, config2.localContext.agentLaunchEnvironment));
83043
83036
  await config2.catalog.replaceAndPublish(
83044
83037
  (current) => {
83045
83038
  if (!current.some((entry) => entry.id === agent.id)) {
@@ -83070,51 +83063,35 @@ async function unchangedIdentity(agent, signal) {
83070
83063
 
83071
83064
  // src/engine/runtime/connection/runtime-installation-store.ts
83072
83065
  import { randomUUID as randomUUID13 } from "node:crypto";
83073
- import { resolve as resolve15 } from "node:path";
83066
+ import { resolve as resolve14 } from "node:path";
83074
83067
 
83075
83068
  // src/engine/storage/installation/installation-files.ts
83076
83069
  import { createHash as createHash5, randomUUID as randomUUID12 } from "node:crypto";
83077
83070
  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";
83071
+ import { dirname as dirname9, join as join23 } from "node:path";
83079
83072
 
83080
83073
  // src/engine/util/node-error.ts
83081
83074
  function isNodeError(error62, code) {
83082
83075
  return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
83083
83076
  }
83084
83077
 
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
83078
  // src/engine/storage/installation/installation-files.ts
83099
83079
  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");
83080
+ function installationPointerPath(engineDataDir) {
83081
+ return join23(engineDataDir, "current.json");
83105
83082
  }
83106
83083
  var installationDirectorySchema = external_exports.string().brand();
83107
- function installationDirectory(applicationDirectory2, installationId2) {
83108
- return installationDirectorySchema.parse(join25(applicationDirectory2, installationId2));
83084
+ function installationDirectory(engineDataDir, installationId2) {
83085
+ return installationDirectorySchema.parse(join23(engineDataDir, installationId2));
83109
83086
  }
83110
83087
  function connectionDirectory(installationDirectory2) {
83111
- return join25(installationDirectory2, "connections");
83088
+ return join23(installationDirectory2, "connections");
83112
83089
  }
83113
83090
  function connectionFilePath(connectionDirectory2, connectionId2) {
83114
- return join25(connectionDirectory2, `${connectionId2}.json`);
83091
+ return join23(connectionDirectory2, `${connectionId2}.json`);
83115
83092
  }
83116
83093
  function channelIndexFilePath(installationDirectory2, channelId) {
83117
- return join25(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83094
+ return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
83118
83095
  }
83119
83096
  async function readInstallationFile(path7) {
83120
83097
  let handle;
@@ -83136,7 +83113,7 @@ async function readInstallationFile(path7) {
83136
83113
  async function writeInstallationFile(path7, text2, signal) {
83137
83114
  signal.throwIfAborted();
83138
83115
  const directory = dirname9(path7);
83139
- const temporaryPath = join25(directory, `.${randomUUID12()}.tmp`);
83116
+ const temporaryPath = join23(directory, `.${randomUUID12()}.tmp`);
83140
83117
  try {
83141
83118
  await mkdir4(directory, { mode: 448, recursive: true });
83142
83119
  signal.throwIfAborted();
@@ -83174,7 +83151,6 @@ var VerifiedRuntimeConnection = class {
83174
83151
  kind = "verified";
83175
83152
  activation;
83176
83153
  appId;
83177
- applicationId;
83178
83154
  channelId;
83179
83155
  connectionId;
83180
83156
  defaultWorkspace;
@@ -83183,9 +83159,8 @@ var VerifiedRuntimeConnection = class {
83183
83159
  relayOrigin;
83184
83160
  runtimeCredential;
83185
83161
  runtimeId;
83186
- constructor(activation, applicationId, appId, installationId2, connectionId2, channelId, defaultWorkspace, pairingId, relayOrigin, runtimeCredential2, runtimeId) {
83162
+ constructor(activation, appId, installationId2, connectionId2, channelId, defaultWorkspace, pairingId, relayOrigin, runtimeCredential2, runtimeId) {
83187
83163
  this.activation = activation;
83188
- this.applicationId = applicationId;
83189
83164
  this.appId = appId;
83190
83165
  this.channelId = channelId;
83191
83166
  this.connectionId = connectionId2;
@@ -83199,22 +83174,14 @@ var VerifiedRuntimeConnection = class {
83199
83174
  };
83200
83175
 
83201
83176
  // src/engine/runtime/connection/runtime-installation-store.ts
83202
- var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
83203
83177
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
83204
83178
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
83205
83179
  var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
83206
83180
  var INSTALLATION_POINTER_KEYS = ["installationId", "version"];
83207
- var CHANNEL_INDEX_KEYS = [
83208
- "applicationId",
83209
- "channelId",
83210
- "connectionId",
83211
- "installationId",
83212
- "version"
83213
- ];
83181
+ var CHANNEL_INDEX_KEYS = ["channelId", "connectionId", "installationId", "version"];
83214
83182
  var VERIFIED_CONNECTION_KEYS = [
83215
83183
  "activation",
83216
83184
  "appId",
83217
- "applicationId",
83218
83185
  "channelId",
83219
83186
  "connectionId",
83220
83187
  "defaultWorkspace",
@@ -83241,12 +83208,6 @@ function hasExactKeys(value, expectedKeys) {
83241
83208
  const keys = Object.keys(value);
83242
83209
  return keys.length === expectedKeys.length && expectedKeys.every((key) => Object.hasOwn(value, key));
83243
83210
  }
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
83211
  function validateRemoteAppId(value) {
83251
83212
  if (!isIdentifier(value)) {
83252
83213
  throw new RuntimeInstallationStoreError("invalid_app_id", "The remote App ID is invalid");
@@ -83310,29 +83271,33 @@ function decodeInstallationPointer(value) {
83310
83271
  }
83311
83272
  return { installationId: validateInstallationId(storedInstallationId) };
83312
83273
  }
83313
- function decodeChannelIndex(value) {
83314
- if (!isRecord8(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
83274
+ function retainedFields(value, keys) {
83275
+ return Object.fromEntries(keys.filter((key) => Object.hasOwn(value, key)).map((key) => [key, value[key]]));
83276
+ }
83277
+ function decodeChannelIndex(input2) {
83278
+ if (!isRecord8(input2)) {
83279
+ throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83280
+ }
83281
+ const value = input2["version"] === 1 ? retainedFields(input2, CHANNEL_INDEX_KEYS) : input2;
83282
+ if (!hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1 && value["version"] !== 2) {
83315
83283
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83316
83284
  }
83317
- const applicationId = value["applicationId"];
83318
83285
  const channelId = value["channelId"];
83319
83286
  const connectionId2 = value["connectionId"];
83320
83287
  const storedInstallationId = value["installationId"];
83321
- if (typeof applicationId !== "string" || typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof storedInstallationId !== "string") {
83288
+ if (typeof channelId !== "string" || typeof connectionId2 !== "string" || typeof storedInstallationId !== "string") {
83322
83289
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83323
83290
  }
83324
83291
  return {
83325
- applicationId: validateApplicationId(applicationId),
83326
83292
  channelId: validateIdentifier(channelId, "invalid_connection"),
83327
83293
  connectionId: validateConnectionId(connectionId2),
83328
83294
  installationId: validateInstallationId(storedInstallationId)
83329
83295
  };
83330
83296
  }
83331
83297
  function decodeVerifiedConnection(value) {
83332
- if (!hasExactKeys(value, VERIFIED_CONNECTION_KEYS) || value["version"] !== 5 || value["kind"] !== "verified") {
83298
+ if (!hasExactKeys(value, VERIFIED_CONNECTION_KEYS) || value["version"] !== 5 && value["version"] !== 6 || value["kind"] !== "verified") {
83333
83299
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83334
83300
  }
83335
- const applicationId = value["applicationId"];
83336
83301
  const activation = value["activation"];
83337
83302
  const appId = value["appId"];
83338
83303
  const channelId = value["channelId"];
@@ -83343,12 +83308,11 @@ function decodeVerifiedConnection(value) {
83343
83308
  const relayOrigin = value["relayOrigin"];
83344
83309
  const runtimeCredential2 = value["runtimeCredential"];
83345
83310
  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") {
83311
+ 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
83312
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83348
83313
  }
83349
83314
  return new VerifiedRuntimeConnection(
83350
83315
  activation,
83351
- validateApplicationId(applicationId),
83352
83316
  validateRemoteAppId(appId),
83353
83317
  validateInstallationId(storedInstallationId),
83354
83318
  validateConnectionId(connectionId2),
@@ -83364,7 +83328,7 @@ function decodeConnection(value) {
83364
83328
  if (!isRecord8(value)) {
83365
83329
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
83366
83330
  }
83367
- return decodeVerifiedConnection(value);
83331
+ return decodeVerifiedConnection(value["version"] === 5 ? retainedFields(value, VERIFIED_CONNECTION_KEYS) : value);
83368
83332
  }
83369
83333
  async function readJsonFile2(path7, signal, missingCode) {
83370
83334
  signal.throwIfAborted();
@@ -83408,25 +83372,20 @@ async function writeJsonAtomically(path7, value, signal) {
83408
83372
  }
83409
83373
  }
83410
83374
  var RuntimeInstallationStore = class _RuntimeInstallationStore {
83411
- applicationId;
83412
83375
  installationId;
83413
83376
  stateDirectory;
83414
83377
  #connectionDirectory;
83415
- constructor(applicationId, installationId2, stateDirectory) {
83416
- this.applicationId = applicationId;
83378
+ constructor(installationId2, stateDirectory) {
83417
83379
  this.installationId = installationId2;
83418
83380
  this.stateDirectory = stateDirectory;
83419
83381
  this.#connectionDirectory = connectionDirectory(stateDirectory);
83420
83382
  }
83421
- static open = async (options, signal) => {
83383
+ static open = async (engineDataDir, signal) => {
83422
83384
  signal.throwIfAborted();
83423
- const applicationId = validateApplicationId(options.applicationId);
83424
- const rootDirectory = resolve15(options.stateDirectory);
83425
- const applicationDirectory2 = applicationDirectory(rootDirectory, applicationId);
83385
+ const dataDirectory = resolve14(engineDataDir);
83426
83386
  try {
83427
- await ensurePrivateDirectory(rootDirectory);
83428
- await validateLocalPath(rootDirectory, true, true, signal);
83429
- await ensurePrivateDirectory(applicationDirectory2);
83387
+ await ensurePrivateDirectory(dataDirectory);
83388
+ await validateLocalPath(dataDirectory, true, true, signal);
83430
83389
  } catch (cause) {
83431
83390
  throw new RuntimeInstallationStoreError(
83432
83391
  "installation_unavailable",
@@ -83436,8 +83395,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83436
83395
  }
83437
83396
  );
83438
83397
  }
83439
- const storedInstallationId = await readOrCreateInstallationId(applicationDirectory2, signal);
83440
- const stateDirectory = installationDirectory(applicationDirectory2, storedInstallationId);
83398
+ const storedInstallationId = await readOrCreateInstallationId(dataDirectory, signal);
83399
+ const stateDirectory = installationDirectory(dataDirectory, storedInstallationId);
83441
83400
  try {
83442
83401
  await ensurePrivateDirectory(stateDirectory);
83443
83402
  } catch (cause) {
@@ -83450,15 +83409,18 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83450
83409
  );
83451
83410
  }
83452
83411
  signal.throwIfAborted();
83453
- return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
83412
+ return new _RuntimeInstallationStore(storedInstallationId, stateDirectory);
83454
83413
  };
83455
83414
  connectionPath = (connectionId2) => connectionFilePath(this.#connectionDirectory, validateConnectionId(connectionId2));
83456
83415
  channelIndexPath = (channelId) => channelIndexFilePath(this.stateDirectory, validateIdentifier(channelId, "invalid_channel_id"));
83457
83416
  readConnection = async (connectionId2, signal) => {
83458
- const stored = decodeConnection(
83417
+ return this.decodeOwnedConnection(
83459
83418
  await readJsonFile2(this.connectionPath(connectionId2), signal, "connection_not_found")
83460
83419
  );
83461
- if (stored.applicationId !== this.applicationId || stored.installationId !== this.installationId) {
83420
+ };
83421
+ decodeOwnedConnection = (record2) => {
83422
+ const stored = decodeConnection(record2);
83423
+ if (stored.installationId !== this.installationId) {
83462
83424
  throw new RuntimeInstallationStoreError(
83463
83425
  "connection_owner_mismatch",
83464
83426
  "The saved Runtime connection belongs to another installation"
@@ -83471,7 +83433,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83471
83433
  const index2 = decodeChannelIndex(
83472
83434
  await readJsonFile2(this.channelIndexPath(normalizedChannelId), signal, "connection_not_found")
83473
83435
  );
83474
- if (index2.applicationId !== this.applicationId || index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
83436
+ if (index2.installationId !== this.installationId || index2.channelId !== normalizedChannelId) {
83475
83437
  throw new RuntimeInstallationStoreError(
83476
83438
  "connection_owner_mismatch",
83477
83439
  "The saved Runtime connection belongs to another installation"
@@ -83482,7 +83444,6 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83482
83444
  saveConnection = async (input2, signal) => {
83483
83445
  const stored = new VerifiedRuntimeConnection(
83484
83446
  "active",
83485
- this.applicationId,
83486
83447
  validateRemoteAppId(input2.appId),
83487
83448
  this.installationId,
83488
83449
  connectionId(),
@@ -83513,11 +83474,10 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83513
83474
  await writeJsonAtomically(
83514
83475
  this.channelIndexPath(stored.channelId),
83515
83476
  {
83516
- applicationId: this.applicationId,
83517
83477
  channelId: stored.channelId,
83518
83478
  connectionId: stored.connectionId,
83519
83479
  installationId: this.installationId,
83520
- version: 1
83480
+ version: 2
83521
83481
  },
83522
83482
  signal
83523
83483
  );
@@ -83555,10 +83515,10 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83555
83515
  return connections.find((connection) => connection.pairingId === normalizedPairingId) ?? null;
83556
83516
  };
83557
83517
  setConnectionActivation = async (connectionId2, activation, signal) => {
83558
- const connection = await this.readConnection(connectionId2, signal);
83518
+ const record2 = await readJsonFile2(this.connectionPath(connectionId2), signal, "connection_not_found");
83519
+ const connection = this.decodeOwnedConnection(record2);
83559
83520
  const updated = new VerifiedRuntimeConnection(
83560
83521
  activation,
83561
- connection.applicationId,
83562
83522
  connection.appId,
83563
83523
  connection.installationId,
83564
83524
  connection.connectionId,
@@ -83569,7 +83529,11 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83569
83529
  connection.runtimeCredential,
83570
83530
  connection.runtimeId
83571
83531
  );
83572
- await this.overwriteConnection(updated, signal);
83532
+ if (isRecord8(record2) && record2["version"] === 5) {
83533
+ await writeJsonAtomically(this.connectionPath(connectionId2), { ...record2, activation }, signal);
83534
+ } else {
83535
+ await this.overwriteConnection(updated, signal);
83536
+ }
83573
83537
  return updated;
83574
83538
  };
83575
83539
  removeConnection = async (connectionId2, signal) => {
@@ -83597,7 +83561,6 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83597
83561
  connectionPath,
83598
83562
  {
83599
83563
  activation: connection.activation,
83600
- applicationId: connection.applicationId,
83601
83564
  appId: connection.appId,
83602
83565
  channelId: connection.channelId,
83603
83566
  connectionId: connection.connectionId,
@@ -83608,14 +83571,14 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
83608
83571
  relayOrigin: connection.relayOrigin.toString(),
83609
83572
  runtimeCredential: connection.runtimeCredential,
83610
83573
  runtimeId: connection.runtimeId,
83611
- version: 5
83574
+ version: 6
83612
83575
  },
83613
83576
  signal
83614
83577
  );
83615
83578
  };
83616
83579
  };
83617
- async function readOrCreateInstallationId(applicationDirectory2, signal) {
83618
- const pointerPath = installationPointerPath(applicationDirectory2);
83580
+ async function readOrCreateInstallationId(engineDataDir, signal) {
83581
+ const pointerPath = installationPointerPath(engineDataDir);
83619
83582
  try {
83620
83583
  return decodeInstallationPointer(await readJsonFile2(pointerPath, signal, "installation_not_found")).installationId;
83621
83584
  } catch (cause) {
@@ -83641,243 +83604,25 @@ async function readOrCreateInstallationId(applicationDirectory2, signal) {
83641
83604
  return decodeInstallationPointer(await readJsonFile2(pointerPath, signal, "installation_not_found")).installationId;
83642
83605
  }
83643
83606
  }
83644
- async function openRuntimeInstallationStore(options, signal) {
83645
- return await RuntimeInstallationStore.open(options, signal);
83607
+ async function openRuntimeInstallationStore(engineDataDir, signal) {
83608
+ return await RuntimeInstallationStore.open(engineDataDir, signal);
83646
83609
  }
83647
83610
 
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
- }
83611
+ // src/storage/state-root-layout.ts
83612
+ var STATE_ROOT_LAYOUT = Object.freeze({
83613
+ /** Names the version whose data is current. */
83614
+ currentData: "current-data.txt",
83615
+ /** Applications' installations: `installations/<application>/<installation>`. */
83616
+ installations: "installations",
83617
+ /** Managed CLI releases: `npm/<version>`. */
83618
+ releases: "npm",
83619
+ /** Each CLI version's data: `versions/<version>`. */
83620
+ versions: "versions"
83621
+ });
83622
+ var STATE_ROOT_ENTRY_NAMES = new Set(Object.values(STATE_ROOT_LAYOUT));
83623
+
83624
+ // src/storage/state-directory.ts
83625
+ var stateRootSchema = external_exports.string().brand();
83881
83626
 
83882
83627
  // src/engine/runtime/run.ts
83883
83628
  import { styleText } from "node:util";
@@ -87503,8 +87248,8 @@ var RuntimeTurnActivity = class {
87503
87248
  #changed() {
87504
87249
  this.#changedAt = Date.now();
87505
87250
  if (this.count() === 0) {
87506
- for (const resolve18 of this.#idleWaiters) {
87507
- resolve18();
87251
+ for (const resolve17 of this.#idleWaiters) {
87252
+ resolve17();
87508
87253
  }
87509
87254
  this.#idleWaiters.clear();
87510
87255
  }
@@ -87514,14 +87259,14 @@ var RuntimeTurnActivity = class {
87514
87259
  if (this.count() === 0) {
87515
87260
  return Promise.resolve();
87516
87261
  }
87517
- return new Promise((resolve18, reject2) => {
87262
+ return new Promise((resolve17, reject2) => {
87518
87263
  const abort = () => {
87519
87264
  this.#idleWaiters.delete(idle);
87520
87265
  reject2(signal.reason);
87521
87266
  };
87522
87267
  const idle = () => {
87523
87268
  signal.removeEventListener("abort", abort);
87524
- resolve18();
87269
+ resolve17();
87525
87270
  };
87526
87271
  this.#idleWaiters.add(idle);
87527
87272
  signal.addEventListener("abort", abort, { once: true });
@@ -87651,7 +87396,7 @@ var ActiveRuntimeTurn = class {
87651
87396
  // src/engine/session/turn/session-execution.ts
87652
87397
  var waitForTurnCompletion = (turn, waitSignal) => {
87653
87398
  waitSignal.throwIfAborted();
87654
- return new Promise((resolve18, reject2) => {
87399
+ return new Promise((resolve17, reject2) => {
87655
87400
  let settled = false;
87656
87401
  const finish = (result) => {
87657
87402
  if (settled) {
@@ -87660,7 +87405,7 @@ var waitForTurnCompletion = (turn, waitSignal) => {
87660
87405
  settled = true;
87661
87406
  waitSignal.removeEventListener("abort", onAbort);
87662
87407
  if (result.kind === "completed") {
87663
- resolve18();
87408
+ resolve17();
87664
87409
  } else {
87665
87410
  reject2(result.error);
87666
87411
  }
@@ -87842,8 +87587,8 @@ var SessionTurns = class {
87842
87587
  };
87843
87588
 
87844
87589
  // 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";
87590
+ import { homedir as homedir3 } from "node:os";
87591
+ import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute15, join as join24, normalize as normalize2, relative as relative2 } from "node:path";
87847
87592
  var WorkspaceDirectoryListing = class {
87848
87593
  directoryId;
87849
87594
  directoryLabel;
@@ -87864,7 +87609,7 @@ function encodePath(path7) {
87864
87609
  return `path-${encoded}`;
87865
87610
  }
87866
87611
  function expandCurrentUserHome(path7) {
87867
- return path7.replace(/^~(?=$|\/|\\)/, homedir4());
87612
+ return path7.replace(/^~(?=$|\/|\\)/, homedir3());
87868
87613
  }
87869
87614
  function decodePath(value, prefix) {
87870
87615
  const encoded = value.slice(prefix.length);
@@ -87895,7 +87640,7 @@ var WorkspaceDirectoryService = class {
87895
87640
  return this.#defaultWorkspace;
87896
87641
  }
87897
87642
  if (id === "home") {
87898
- return homedir4();
87643
+ return homedir3();
87899
87644
  }
87900
87645
  if (id.startsWith("path-")) {
87901
87646
  const path7 = expandCurrentUserHome(decodePath(id, "path-"));
@@ -87930,7 +87675,7 @@ var WorkspaceDirectoryService = class {
87930
87675
  }
87931
87676
  };
87932
87677
  label = (path7) => {
87933
- const suffix = relative2(homedir4(), path7);
87678
+ const suffix = relative2(homedir3(), path7);
87934
87679
  return suffix === "" ? "~" : !isAbsolute15(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path7;
87935
87680
  };
87936
87681
  identify = async (bindingId, requestedPath2, signal) => {
@@ -87939,7 +87684,7 @@ var WorkspaceDirectoryService = class {
87939
87684
  return {
87940
87685
  path: path7,
87941
87686
  directoryId: encodePath(path7),
87942
- name: basename7(path7) || path7,
87687
+ name: basename6(path7) || path7,
87943
87688
  label: this.label(path7)
87944
87689
  };
87945
87690
  };
@@ -87965,7 +87710,7 @@ var WorkspaceDirectoryService = class {
87965
87710
  continue;
87966
87711
  }
87967
87712
  try {
87968
- const path7 = await this.resolvePath(join27(target, child.name), signal);
87713
+ const path7 = await this.resolvePath(join24(target, child.name), signal);
87969
87714
  entries.push({ directoryId: encodePath(path7), name: child.name });
87970
87715
  } catch (cause) {
87971
87716
  signal.throwIfAborted();
@@ -88116,12 +87861,12 @@ function buildSessionLayer(options) {
88116
87861
 
88117
87862
  // src/engine/session/content/external-content-store.ts
88118
87863
  import { createHash as createHash7 } from "node:crypto";
88119
- import { join as join29 } from "node:path";
87864
+ import { join as join26 } from "node:path";
88120
87865
 
88121
87866
  // src/engine/storage/files/scratch-directory.ts
88122
87867
  import { randomUUID as randomUUID17 } from "node:crypto";
88123
87868
  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";
87869
+ import { dirname as dirname11, join as join25 } from "node:path";
88125
87870
  async function atomicWrite(path7, bytes, signal) {
88126
87871
  const temporary = `${path7}.${randomUUID17()}.tmp`;
88127
87872
  try {
@@ -88135,7 +87880,7 @@ async function atomicWrite(path7, bytes, signal) {
88135
87880
  var ScratchDirectory = class {
88136
87881
  #root;
88137
87882
  constructor(parent) {
88138
- this.#root = join28(parent, randomUUID17());
87883
+ this.#root = join25(parent, randomUUID17());
88139
87884
  }
88140
87885
  /** Refreshes this directory's lease and removes sibling directories whose lease is older than `leaseMilliseconds`. */
88141
87886
  refreshLease = async (leaseMilliseconds) => {
@@ -88146,7 +87891,7 @@ var ScratchDirectory = class {
88146
87891
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
88147
87892
  continue;
88148
87893
  }
88149
- const path7 = join28(dirname11(this.#root), directory.name);
87894
+ const path7 = join25(dirname11(this.#root), directory.name);
88150
87895
  if (path7 === this.#root) {
88151
87896
  continue;
88152
87897
  }
@@ -88161,10 +87906,10 @@ var ScratchDirectory = class {
88161
87906
  };
88162
87907
  /** Writes `bytes` atomically to `<group>/<name>` with owner-only permissions and returns the path. */
88163
87908
  write = async (group, name2, bytes, signal) => {
88164
- const directory = join28(this.#root, group);
87909
+ const directory = join25(this.#root, group);
88165
87910
  await mkdir5(directory, { mode: 448, recursive: true });
88166
87911
  signal.throwIfAborted();
88167
- const path7 = join28(directory, name2);
87912
+ const path7 = join25(directory, name2);
88168
87913
  await atomicWrite(path7, bytes, signal);
88169
87914
  return path7;
88170
87915
  };
@@ -88211,7 +87956,7 @@ var LocalExternalContentStore = class {
88211
87956
  #expirationTimer;
88212
87957
  #cleanup = Promise.resolve();
88213
87958
  constructor(stateDirectory) {
88214
- this.#scratch = new ScratchDirectory(join29(stateDirectory, "tmp", "session-content"));
87959
+ this.#scratch = new ScratchDirectory(join26(stateDirectory, "tmp", "session-content"));
88215
87960
  this.#expirationTimer = setInterval(() => {
88216
87961
  void this.#expire().catch(() => void 0);
88217
87962
  }, 6e4);
@@ -88409,18 +88154,6 @@ async function waitForAcpProcessCapacity(completion, signal) {
88409
88154
  var DEFAULT_MAX_ACP_PROCESSES = 1e3;
88410
88155
  var MAX_CONCURRENT_STARTS = 8;
88411
88156
  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
88157
  var AgentProcessPool = class {
88425
88158
  #maxProcesses;
88426
88159
  #timer;
@@ -88594,11 +88327,11 @@ var AgentProcessPool = class {
88594
88327
  };
88595
88328
 
88596
88329
  // src/engine/runtime/observability/diagnostic-log.ts
88597
- import { join as join32 } from "node:path";
88330
+ import { join as join29 } from "node:path";
88598
88331
 
88599
88332
  // src/engine/storage/logs/bounded-log.ts
88600
88333
  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";
88334
+ import { join as join27 } from "node:path";
88602
88335
  var BoundedLineLog = class {
88603
88336
  #path;
88604
88337
  #maximumBytes;
@@ -88607,7 +88340,7 @@ var BoundedLineLog = class {
88607
88340
  #onWriteFailure;
88608
88341
  constructor(directory, filename, maximumBytes, onWriteFailure = () => void 0) {
88609
88342
  this.#directory = directory;
88610
- this.#path = join30(directory, filename);
88343
+ this.#path = join27(directory, filename);
88611
88344
  this.#maximumBytes = maximumBytes;
88612
88345
  this.#onWriteFailure = onWriteFailure;
88613
88346
  }
@@ -88658,21 +88391,21 @@ var BoundedLineLog = class {
88658
88391
 
88659
88392
  // src/engine/storage/logs/log-files.ts
88660
88393
  import { readFileSync as readFileSync10 } from "node:fs";
88661
- import { join as join31, relative as relative3 } from "node:path";
88394
+ import { join as join28 } from "node:path";
88662
88395
  var DAEMON_LOG_FILENAME = "daemon.log";
88663
88396
  var WORKER_LIFECYCLE_LOG_FILENAME = "worker-lifecycle.log";
88664
88397
  function unhandledRejectionLogFilename(role) {
88665
88398
  return `unhandled-rejections-${role}.log`;
88666
88399
  }
88667
- function logDirectory(stateDirectory) {
88668
- return join31(stateDirectory, "logs");
88400
+ function logDirectory(dataDirectory) {
88401
+ return join28(dataDirectory, "logs");
88669
88402
  }
88670
- function processLogPaths(stateDirectory) {
88403
+ function processLogPaths(dataDirectory) {
88671
88404
  return [
88672
88405
  WORKER_LIFECYCLE_LOG_FILENAME,
88673
88406
  unhandledRejectionLogFilename("manager"),
88674
88407
  unhandledRejectionLogFilename("worker")
88675
- ].map((filename) => join31(logDirectory(stateDirectory), filename));
88408
+ ].map((filename) => join28(logDirectory(dataDirectory), filename));
88676
88409
  }
88677
88410
  function readLogText(path7) {
88678
88411
  try {
@@ -88728,7 +88461,7 @@ var RuntimeDiagnosticLog = class {
88728
88461
  this.#maximumBytes = maximumBytes;
88729
88462
  const processLogsDirectory = options.processLogsDirectory;
88730
88463
  this.#sources = [
88731
- { maximumBytes, path: join32(directory, DAEMON_LOG_FILENAME) },
88464
+ { maximumBytes, path: join29(directory, DAEMON_LOG_FILENAME) },
88732
88465
  // The process logs a Runtime does not own, but must read to explain its own deaths.
88733
88466
  ...processLogsDirectory === void 0 ? [] : processLogPaths(processLogsDirectory).map((path7) => ({ maximumBytes: null, path: path7 }))
88734
88467
  ];
@@ -88841,6 +88574,8 @@ function addFailureDetails(details, failure2) {
88841
88574
  }
88842
88575
  }
88843
88576
  var RelayConnectionDiagnostics = class {
88577
+ #lastSkippedLogAt = Number.NEGATIVE_INFINITY;
88578
+ #skippedCount = 0;
88844
88579
  #channelId;
88845
88580
  #localLog;
88846
88581
  #lastClosedEpoch = 0;
@@ -88915,6 +88650,16 @@ var RelayConnectionDiagnostics = class {
88915
88650
  );
88916
88651
  };
88917
88652
  daemonDiagnostic = (event, requestId, details, failure2) => {
88653
+ if (event === "protocol_message_discarded" || event === "content_frame_discarded" || event === "content_chunk_discarded" || event === "prompt_attachments_skipped") {
88654
+ this.#skippedCount += 1;
88655
+ const now = Date.now();
88656
+ if (now - this.#lastSkippedLogAt < 6e4) {
88657
+ return;
88658
+ }
88659
+ details = { ...details, skippedCount: this.#skippedCount.toString() };
88660
+ this.#lastSkippedLogAt = now;
88661
+ this.#skippedCount = 0;
88662
+ }
88918
88663
  const recordedDetails = { ...details };
88919
88664
  if (failure2 !== void 0) {
88920
88665
  addFailureDetails(recordedDetails, failure2);
@@ -88986,7 +88731,7 @@ async function refreshAgentCatalog(config2, discover, signal) {
88986
88731
  const readyAgents = await discover(signal);
88987
88732
  signal.throwIfAborted();
88988
88733
  return await config2.catalog.replaceAndPublish(
88989
- () => readyAgents.map((agent) => withRuntimeEnvironment(agent, config2.localContext.environment)),
88734
+ () => readyAgents.map((agent) => withRuntimeEnvironment(agent, config2.localContext.agentLaunchEnvironment)),
88990
88735
  (publishSignal) => publishAgentCatalog(config2, publishSignal),
88991
88736
  signal
88992
88737
  );
@@ -89711,7 +89456,7 @@ function createContentWriteCommands(context) {
89711
89456
  import { WebSocket as WebSocket5 } from "undici";
89712
89457
 
89713
89458
  // 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";
89459
+ import { basename as basename7, extname as extname3, isAbsolute as isAbsolute16, join as join30, normalize as normalize3, resolve as resolve15 } from "node:path";
89715
89460
  import { fileURLToPath as fileURLToPath2 } from "node:url";
89716
89461
  function requestedPath(value) {
89717
89462
  if (value.includes("\0")) {
@@ -89735,7 +89480,7 @@ async function resolveFile(value, workingDirectory, signal) {
89735
89480
  if (isAbsolute16(requested.path) && normalize3(requested.path) !== requested.path) {
89736
89481
  return null;
89737
89482
  }
89738
- const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join33(workingDirectory, requested.path), requested.path] : [resolve17(workingDirectory, requested.path)];
89483
+ const candidates = requested.explicitUrl || workingDirectory === null ? [requested.path] : isAbsolute16(requested.path) ? [join30(workingDirectory, requested.path), requested.path] : [resolve15(workingDirectory, requested.path)];
89739
89484
  for (const candidate of candidates) {
89740
89485
  if (!isAbsolute16(candidate) || normalize3(candidate) !== candidate) {
89741
89486
  continue;
@@ -89769,7 +89514,7 @@ async function streamLocalFile(command, send2, sendChunk, signal, workingDirecto
89769
89514
  kind: FILE_BEGIN_KIND,
89770
89515
  mediaType: external?.mediaType ?? raster?.mimeType ?? (extname3(target).toLowerCase() === ".svg" ? "image/svg+xml" : "application/octet-stream"),
89771
89516
  modifiedAt: before.modifiedAt.toISOString(),
89772
- name: external?.name ?? (basename8(target) || "file"),
89517
+ name: external?.name ?? (basename7(target) || "file"),
89773
89518
  requestId: command.requestId,
89774
89519
  sessionId: command.sessionId
89775
89520
  });
@@ -89820,7 +89565,7 @@ var fileReadCommand = {
89820
89565
  };
89821
89566
 
89822
89567
  // src/engine/session/workspace/resolve-session-directories.ts
89823
- import { basename as basename9 } from "node:path";
89568
+ import { basename as basename8 } from "node:path";
89824
89569
  var ResolvedSessionDirectories = class {
89825
89570
  additionalDirectories;
89826
89571
  additionalDirectoryEntries;
@@ -89848,7 +89593,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId, ad
89848
89593
  additionalDirectories.push(directory);
89849
89594
  additionalDirectoryEntries.push({
89850
89595
  directoryId: additionalDirectoryId,
89851
- name: basename9(directory)
89596
+ name: basename8(directory)
89852
89597
  });
89853
89598
  }
89854
89599
  return new ResolvedSessionDirectories(cwd, selection.label, additionalDirectories, additionalDirectoryEntries);
@@ -90190,13 +89935,13 @@ function createNativeSessionRequestHandler(dependencies) {
90190
89935
  operationSignal.throwIfAborted();
90191
89936
  const skipPrevious = command.action === "active-turn";
90192
89937
  if (previous.length > 0 && !skipPrevious) {
90193
- await new Promise((resolve18, reject2) => {
89938
+ await new Promise((resolve17, reject2) => {
90194
89939
  const onAbort = () => reject2(operationSignal.reason);
90195
89940
  operationSignal.addEventListener("abort", onAbort, { once: true });
90196
89941
  void Promise.all(previous.map((request) => request.completion)).then(
90197
89942
  () => {
90198
89943
  operationSignal.removeEventListener("abort", onAbort);
90199
- resolve18();
89944
+ resolve17();
90200
89945
  },
90201
89946
  (error62) => {
90202
89947
  operationSignal.removeEventListener("abort", onAbort);
@@ -90515,10 +90260,7 @@ async function resolvePromptArtifacts(read, attachments, signal) {
90515
90260
  }
90516
90261
  if (attachment.kind === "image") {
90517
90262
  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
- );
90263
+ continue;
90522
90264
  }
90523
90265
  images.push({
90524
90266
  data: Buffer.from(bytes).toString("base64"),
@@ -90528,28 +90270,17 @@ async function resolvePromptArtifacts(read, attachments, signal) {
90528
90270
  continue;
90529
90271
  }
90530
90272
  if (!isTextMediaType(attachment.mimeType)) {
90531
- throw new PromptArtifactError(
90532
- "artifact_media_type_unsupported",
90533
- "The Agent cannot consume this prompt attachment media type"
90534
- );
90273
+ continue;
90535
90274
  }
90536
90275
  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
- );
90276
+ continue;
90541
90277
  }
90542
90278
  let text2;
90543
90279
  try {
90544
90280
  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
- );
90281
+ } catch {
90282
+ signal.throwIfAborted();
90283
+ continue;
90553
90284
  }
90554
90285
  resources.push({ mimeType: attachment.mimeType, text: text2, type: "embedded", uri: attachment.uri });
90555
90286
  }
@@ -90641,6 +90372,13 @@ async function executePrompt({
90641
90372
  availability.disposition
90642
90373
  );
90643
90374
  const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
90375
+ const skipped = command.attachments.length - attachments.images.length - attachments.resources.length;
90376
+ if (skipped > 0) {
90377
+ reportFailure("prompt_attachments_skipped", command.commandId, { count: skipped.toString() });
90378
+ }
90379
+ if (command.prompt.trim().length === 0 && attachments.images.length === 0 && attachments.resources.length === 0) {
90380
+ throw new PromptArtifactError("prompt_attachments_unsupported", "No supported prompt content remains");
90381
+ }
90644
90382
  let stopReason;
90645
90383
  if (availability.disposition === SessionPromptDisposition.Steer) {
90646
90384
  await sessions.steerPrompt({
@@ -91240,7 +90978,21 @@ function createCommandRegistry(context) {
91240
90978
  }
91241
90979
  command.handle(context, message);
91242
90980
  },
91243
- dispatchChunk: (message) => contentWrites.receiveChunk(decodeContentChunkFrame(message)),
90981
+ dispatchChunk: (message) => {
90982
+ const frame = (() => {
90983
+ try {
90984
+ return decodeContentChunkFrame(message);
90985
+ } catch {
90986
+ context.diagnostics.daemonDiagnostic("content_frame_discarded", "unknown", {
90987
+ reason: "unsupported_frame"
90988
+ });
90989
+ return null;
90990
+ }
90991
+ })();
90992
+ if (frame !== null) {
90993
+ contentWrites.receiveChunk(frame);
90994
+ }
90995
+ },
91244
90996
  settle: async () => {
91245
90997
  await Promise.all([
91246
90998
  contentWrites.settle(),
@@ -91290,7 +91042,7 @@ var RelayConnectionError = class extends Error {
91290
91042
  };
91291
91043
  function connectRelay(url2, signal) {
91292
91044
  signal.throwIfAborted();
91293
- return new Promise((resolve18, reject2) => {
91045
+ return new Promise((resolve17, reject2) => {
91294
91046
  let dispatchController;
91295
91047
  const dispatcher = environmentProxyDispatcher.compose((dispatch) => (options, handler) => {
91296
91048
  const trackedHandler = Object.create(handler);
@@ -91376,7 +91128,7 @@ function connectRelay(url2, signal) {
91376
91128
  }
91377
91129
  finished = true;
91378
91130
  cleanup();
91379
- resolve18({ release, socket });
91131
+ resolve17({ release, socket });
91380
91132
  };
91381
91133
  function onTimeout() {
91382
91134
  fail(
@@ -91552,7 +91304,7 @@ async function runRelayConnection({
91552
91304
  }
91553
91305
  });
91554
91306
  try {
91555
- await new Promise((resolve18, reject2) => {
91307
+ await new Promise((resolve17, reject2) => {
91556
91308
  let finished = false;
91557
91309
  let ready = false;
91558
91310
  const cleanup = () => {
@@ -91570,7 +91322,7 @@ async function runRelayConnection({
91570
91322
  }
91571
91323
  finished = true;
91572
91324
  cleanup();
91573
- resolve18();
91325
+ resolve17();
91574
91326
  };
91575
91327
  const rejectConnection = (failure2) => {
91576
91328
  if (finished) {
@@ -91657,6 +91409,9 @@ async function runRelayConnection({
91657
91409
  try {
91658
91410
  const message = decodeKnownServiceToDaemonMessage(encoded);
91659
91411
  if (message === null) {
91412
+ diagnostics.daemonDiagnostic("protocol_message_discarded", "unknown", {
91413
+ reason: "unsupported_message"
91414
+ });
91660
91415
  return;
91661
91416
  }
91662
91417
  const kind = message.kind;
@@ -91879,12 +91634,12 @@ function waitForRelayRetry(signal, timer) {
91879
91634
  if (signal.aborted) {
91880
91635
  return Promise.resolve();
91881
91636
  }
91882
- return new Promise((resolve18) => {
91637
+ return new Promise((resolve17) => {
91883
91638
  const retry = timer.schedule(finish, RELAY_RECONNECT_DELAY_MILLISECONDS);
91884
91639
  function finish() {
91885
91640
  retry.cancel();
91886
91641
  signal.removeEventListener("abort", finish);
91887
- resolve18();
91642
+ resolve17();
91888
91643
  }
91889
91644
  signal.addEventListener("abort", finish, { once: true });
91890
91645
  });
@@ -91927,7 +91682,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
91927
91682
  );
91928
91683
  const publisher = new RuntimeSessionEventPublisher(timer);
91929
91684
  const externalContent = __using(_stack, new LocalExternalContentStore(stateDirectory), true);
91930
- const processes = new AgentProcessPool(resolveMaxAcpProcesses(config2.localContext.environment) ?? void 0, timer);
91685
+ const processes = new AgentProcessPool(config2.localContext.maxAcpProcesses, timer);
91931
91686
  const adapters = createRuntimeAdapterRegistry(
91932
91687
  config2.adapters,
91933
91688
  processes,
@@ -92129,6 +91884,261 @@ var MobiusRuntimeEngine = class {
92129
91884
  }
92130
91885
  };
92131
91886
  };
91887
+
91888
+ // src/daemon/config.ts
91889
+ function resolveMaxAcpProcesses(environment) {
91890
+ const configured = environment["MOBIUS_MAX_ACP_PROCESSES"];
91891
+ if (configured === void 0 || configured === "") {
91892
+ return 1e3;
91893
+ }
91894
+ const parsed = Number(configured);
91895
+ if (!Number.isInteger(parsed) || parsed < 1) {
91896
+ throw new Error("MOBIUS_MAX_ACP_PROCESSES must be a positive integer");
91897
+ }
91898
+ return parsed;
91899
+ }
91900
+
91901
+ // src/daemon/pairing/pair-local-machine.ts
91902
+ var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
91903
+ var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
91904
+ var TOKEN_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
91905
+ var CLAIM_RESPONSE_KEYS = ["appId", "channelId", "daemonToken", "runtimeId"];
91906
+ var REDEEM_RESPONSE_KEYS = ["appId", "channelId", "runtimeCredential", "runtimeId"];
91907
+ var PairingClientError = class extends Error {
91908
+ code;
91909
+ constructor(code, message, options = {}) {
91910
+ super(message, options);
91911
+ this.code = code;
91912
+ this.name = "PairingClientError";
91913
+ }
91914
+ };
91915
+ function hasExactKeys2(value, expectedKeys) {
91916
+ const keys = Object.keys(value);
91917
+ return keys.length === expectedKeys.length && expectedKeys.every((key) => Object.hasOwn(value, key));
91918
+ }
91919
+ function parseRelayOrigin2(value) {
91920
+ let url2;
91921
+ try {
91922
+ url2 = new URL(value);
91923
+ } catch (error62) {
91924
+ throw new PairingClientError("invalid_relay_url", "The relay URL is invalid", { cause: error62 });
91925
+ }
91926
+ if (url2.protocol !== "https:" && url2.protocol !== "http:") {
91927
+ throw new PairingClientError("invalid_relay_url", "The relay URL must use http or https");
91928
+ }
91929
+ if (url2.username.length > 0 || url2.password.length > 0) {
91930
+ throw new PairingClientError("invalid_relay_url", "The relay URL cannot contain credentials");
91931
+ }
91932
+ if (url2.protocol === "http:" && url2.hostname !== "127.0.0.1" && url2.hostname !== "localhost") {
91933
+ throw new PairingClientError("invalid_relay_url", "A remote relay must use https");
91934
+ }
91935
+ url2.hash = "";
91936
+ url2.pathname = "/";
91937
+ url2.search = "";
91938
+ return url2;
91939
+ }
91940
+ function parsePairingCode(value) {
91941
+ const code = value.trim().toUpperCase();
91942
+ if (!PAIRING_CODE_PATTERN.test(code)) {
91943
+ throw new PairingClientError(
91944
+ "invalid_pairing_code",
91945
+ "The pairing code must match the code shown in the browser"
91946
+ );
91947
+ }
91948
+ return code;
91949
+ }
91950
+ function validatePairingId(value) {
91951
+ if (!isIdentifier(value)) {
91952
+ throw new PairingClientError("invalid_pairing_id", "The Runtime pairing ID is invalid");
91953
+ }
91954
+ return value;
91955
+ }
91956
+ async function resolveDefaultWorkspace(path7) {
91957
+ const requestedWorkspace = resolve16(path7);
91958
+ let defaultWorkspace;
91959
+ try {
91960
+ defaultWorkspace = await ensureCanonicalDirectory(requestedWorkspace);
91961
+ } catch (error62) {
91962
+ throw new PairingClientError("invalid_workspace", "The default workspace cannot be resolved", { cause: error62 });
91963
+ }
91964
+ if (defaultWorkspace === null) {
91965
+ throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
91966
+ }
91967
+ return defaultWorkspace;
91968
+ }
91969
+ async function readJsonResponse(response) {
91970
+ if (response.headers.get("cf-mitigated") === "challenge") {
91971
+ throw new PairingClientError(
91972
+ "relay_challenge",
91973
+ "Cloudflare is protecting this temporary preview. Claim the deployment or use an authenticated deployment, then pair again"
91974
+ );
91975
+ }
91976
+ const encoded = await response.text();
91977
+ try {
91978
+ return JSON.parse(encoded);
91979
+ } catch (error62) {
91980
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid response", {
91981
+ cause: error62
91982
+ });
91983
+ }
91984
+ }
91985
+ function readRelayError(value) {
91986
+ if (isRecord3(value)) {
91987
+ const error62 = value["error"];
91988
+ if (isRecord3(error62)) {
91989
+ const code = error62["code"];
91990
+ const message = error62["message"];
91991
+ if (typeof code === "string" && typeof message === "string") {
91992
+ return new PairingClientError(code, message);
91993
+ }
91994
+ }
91995
+ }
91996
+ return new PairingClientError("pairing_failed", "The relay could not pair this machine");
91997
+ }
91998
+ function decodePairingResponse(value, credentialField, expectedKeys) {
91999
+ if (!isRecord3(value) || !hasExactKeys2(value, expectedKeys)) {
92000
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
92001
+ }
92002
+ const appId = value["appId"];
92003
+ const channelId = value["channelId"];
92004
+ const runtimeCredential2 = value[credentialField];
92005
+ const runtimeId = value["runtimeId"];
92006
+ if (typeof appId !== "string" || !isIdentifier(appId) || typeof channelId !== "string" || !isIdentifier(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN.test(runtimeCredential2) || typeof runtimeId !== "string" || !isIdentifier(runtimeId)) {
92007
+ throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
92008
+ }
92009
+ return { appId, channelId, runtimeCredential: runtimeCredential2, runtimeId };
92010
+ }
92011
+ async function claimPairing(options, defaultWorkspace, localAgents, signal) {
92012
+ const agents = localAgents.map((agent) => ({
92013
+ agentPath: agent.agentIdentity.requestedPath,
92014
+ agentVersion: agent.agentVersion,
92015
+ agentSettingsDiscovery: true,
92016
+ capabilities: agent.capabilities,
92017
+ id: agent.id,
92018
+ label: agent.label,
92019
+ sessionTurnConfiguration: true
92020
+ }));
92021
+ const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
92022
+ let response;
92023
+ try {
92024
+ response = await fetch3(endpoint, {
92025
+ body: JSON.stringify({
92026
+ agents,
92027
+ machineName: hostname3(),
92028
+ pairingCode: options.code,
92029
+ workspaceName: basename9(defaultWorkspace) || "Local workspace"
92030
+ }),
92031
+ dispatcher: environmentProxyDispatcher,
92032
+ headers: { "content-type": "application/json" },
92033
+ method: "POST",
92034
+ signal: AbortSignal.any([signal, AbortSignal.timeout(PAIRING_TIMEOUT_MILLISECONDS)])
92035
+ });
92036
+ } catch (error62) {
92037
+ throw new PairingClientError("relay_unavailable", "The pairing relay could not be reached", { cause: error62 });
92038
+ }
92039
+ const value = await readJsonResponse(response);
92040
+ if (!response.ok) {
92041
+ throw readRelayError(value);
92042
+ }
92043
+ return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
92044
+ }
92045
+ function buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext) {
92046
+ const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
92047
+ relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
92048
+ relayUrl.searchParams.set("token", connection.runtimeCredential);
92049
+ const config2 = createRuntimeConfig(
92050
+ {
92051
+ defaultWorkspace,
92052
+ channelId: connection.channelId,
92053
+ relayUrl
92054
+ },
92055
+ new RuntimeAgentDependencies(inventory.readyAgents()),
92056
+ localContext,
92057
+ new OpaqueRuntimeReconnectTarget(connection.connectionId),
92058
+ createCatalogAgentResolver(
92059
+ (refreshSignal) => discoverLocalAgentInventory({
92060
+ defaultWorkspace,
92061
+ dataDirectory: localContext.stateDirectory,
92062
+ environment: localContext.agentLaunchEnvironment,
92063
+ signal: refreshSignal
92064
+ }),
92065
+ () => config2,
92066
+ publishAgentCatalog
92067
+ ),
92068
+ (refreshSignal) => discoverLocalAgentInventory({
92069
+ defaultWorkspace,
92070
+ dataDirectory: localContext.stateDirectory,
92071
+ environment: localContext.agentLaunchEnvironment,
92072
+ signal: refreshSignal
92073
+ }).then((inventory2) => inventory2.readyAgents())
92074
+ );
92075
+ return {
92076
+ channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
92077
+ connectionId: connection.connectionId,
92078
+ config: config2,
92079
+ connectionPath: installation.connectionPath(connection.connectionId)
92080
+ };
92081
+ }
92082
+ async function pairRuntime(installation, options, signal, environment) {
92083
+ const localContext = new RuntimeLocalContext(
92084
+ installation.stateDirectory,
92085
+ environment,
92086
+ resolveMaxAcpProcesses(environment)
92087
+ );
92088
+ const defaultWorkspace = await resolveDefaultWorkspace(options.workspace);
92089
+ const inventory = await discoverLocalAgentInventory({
92090
+ defaultWorkspace,
92091
+ dataDirectory: localContext.stateDirectory,
92092
+ environment: localContext.agentLaunchEnvironment,
92093
+ signal
92094
+ });
92095
+ const claim2 = await claimPairing(options, defaultWorkspace, inventory.readyAgents(), signal);
92096
+ const connection = await installation.saveConnection(
92097
+ {
92098
+ appId: claim2.appId,
92099
+ channelId: claim2.channelId,
92100
+ defaultWorkspace,
92101
+ pairingId: options.pairingId,
92102
+ relayOrigin: options.relayOrigin,
92103
+ runtimeCredential: claim2.runtimeCredential,
92104
+ runtimeId: claim2.runtimeId
92105
+ },
92106
+ signal
92107
+ );
92108
+ return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
92109
+ }
92110
+ async function pairMobiusRuntime(installation, options, signal, environment = process.env) {
92111
+ return await pairRuntime(
92112
+ installation,
92113
+ {
92114
+ code: parsePairingCode(options.pairingCode),
92115
+ pairingId: validatePairingId(options.pairingId),
92116
+ relayOrigin: parseRelayOrigin2(options.relayOrigin),
92117
+ workspace: options.defaultWorkspace
92118
+ },
92119
+ signal,
92120
+ environment
92121
+ );
92122
+ }
92123
+ async function resumeRuntimeConnection(installation, connection, signal, environment) {
92124
+ const localContext = new RuntimeLocalContext(
92125
+ installation.stateDirectory,
92126
+ environment,
92127
+ resolveMaxAcpProcesses(environment)
92128
+ );
92129
+ const defaultWorkspace = await resolveDefaultWorkspace(connection.defaultWorkspace);
92130
+ const inventory = await discoverLocalAgentInventory({
92131
+ defaultWorkspace,
92132
+ dataDirectory: localContext.stateDirectory,
92133
+ environment: localContext.agentLaunchEnvironment,
92134
+ signal
92135
+ });
92136
+ return buildPairedRuntime(installation, connection, defaultWorkspace, inventory, localContext);
92137
+ }
92138
+ async function resumeMobiusRuntime(installation, connectionId2, signal, environment = process.env) {
92139
+ const connection = await installation.readConnection(connectionId2, signal);
92140
+ return await resumeRuntimeConnection(installation, connection, signal, environment);
92141
+ }
92132
92142
  export {
92133
92143
  MobiusRuntimeEngine,
92134
92144
  RuntimeRelayRevokedError,