@moxt-ai/mobius 0.0.193 → 0.0.194

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 (74) hide show
  1. package/dist/acp/agent-runtime-manager.js +1 -1
  2. package/dist/acp/agent-runtime-manager.js.map +1 -1
  3. package/dist/acp/agent-session.js +2 -2
  4. package/dist/acp/agent-session.js.map +1 -1
  5. package/dist/acp/native-session.d.ts +1 -0
  6. package/dist/acp/native-session.d.ts.map +1 -1
  7. package/dist/agent-catalog/agents/workbuddy-agent.d.ts.map +1 -1
  8. package/dist/agent-catalog/agents/workbuddy-agent.js +5 -19
  9. package/dist/agent-catalog/agents/workbuddy-agent.js.map +1 -1
  10. package/dist/agent-catalog/discover-agent-settings.d.ts.map +1 -1
  11. package/dist/agent-catalog/discover-agent-settings.js +2 -1
  12. package/dist/agent-catalog/discover-agent-settings.js.map +1 -1
  13. package/dist/agent-catalog/resolve-catalog-agent.d.ts +15 -0
  14. package/dist/agent-catalog/resolve-catalog-agent.d.ts.map +1 -0
  15. package/dist/agent-catalog/resolve-catalog-agent.js +65 -0
  16. package/dist/agent-catalog/resolve-catalog-agent.js.map +1 -0
  17. package/dist/agent-installation/grok-managed-package.d.ts.map +1 -1
  18. package/dist/agent-installation/grok-managed-package.js +5 -16
  19. package/dist/agent-installation/grok-managed-package.js.map +1 -1
  20. package/dist/agent-installation/opencode-managed-release.d.ts.map +1 -1
  21. package/dist/agent-installation/opencode-managed-release.js +9 -16
  22. package/dist/agent-installation/opencode-managed-release.js.map +1 -1
  23. package/dist/cli.js +862 -748
  24. package/dist/cli.js.map +4 -4
  25. package/dist/config.d.ts +7 -1
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +2 -1
  28. package/dist/config.js.map +1 -1
  29. package/dist/daemon-history-commands.d.ts.map +1 -1
  30. package/dist/daemon-history-commands.js +3 -2
  31. package/dist/daemon-history-commands.js.map +1 -1
  32. package/dist/daemon-prompt-executor.d.ts.map +1 -1
  33. package/dist/daemon-prompt-executor.js +2 -1
  34. package/dist/daemon-prompt-executor.js.map +1 -1
  35. package/dist/daemon-session-commands.d.ts +2 -1
  36. package/dist/daemon-session-commands.d.ts.map +1 -1
  37. package/dist/daemon-session-commands.js +6 -2
  38. package/dist/daemon-session-commands.js.map +1 -1
  39. package/dist/index.js +867 -744
  40. package/dist/index.js.map +4 -4
  41. package/dist/native-sessions/service.d.ts.map +1 -1
  42. package/dist/native-sessions/service.js +5 -2
  43. package/dist/native-sessions/service.js.map +1 -1
  44. package/dist/pairing/pair-local-machine.d.ts.map +1 -1
  45. package/dist/pairing/pair-local-machine.js +12 -5
  46. package/dist/pairing/pair-local-machine.js.map +1 -1
  47. package/dist/platform/contracts.d.ts +26 -0
  48. package/dist/platform/contracts.d.ts.map +1 -0
  49. package/dist/platform/contracts.js +2 -0
  50. package/dist/platform/contracts.js.map +1 -0
  51. package/dist/platform/index.d.ts +3 -0
  52. package/dist/platform/index.d.ts.map +1 -0
  53. package/dist/platform/index.js +21 -0
  54. package/dist/platform/index.js.map +1 -0
  55. package/dist/platform/linux.d.ts +3 -0
  56. package/dist/platform/linux.d.ts.map +1 -0
  57. package/dist/platform/linux.js +146 -0
  58. package/dist/platform/linux.js.map +1 -0
  59. package/dist/platform/macos.d.ts +3 -0
  60. package/dist/platform/macos.d.ts.map +1 -0
  61. package/dist/platform/macos.js +49 -0
  62. package/dist/platform/macos.js.map +1 -0
  63. package/dist/platform/posix.d.ts +4 -0
  64. package/dist/platform/posix.d.ts.map +1 -0
  65. package/dist/platform/posix.js +47 -0
  66. package/dist/platform/posix.js.map +1 -0
  67. package/dist/process/executable.d.ts +2 -4
  68. package/dist/process/executable.d.ts.map +1 -1
  69. package/dist/process/executable.js +11 -166
  70. package/dist/process/executable.js.map +1 -1
  71. package/dist/runtime.d.ts.map +1 -1
  72. package/dist/runtime.js +885 -762
  73. package/dist/runtime.js.map +4 -4
  74. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
32
32
  })).onNotification("cursor/update_todos", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/task", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/generate_image", discardExtensionParams, async () => Promise.resolve());
33
33
 
34
34
  // src/config.ts
35
- import { join as join3, resolve as resolve3 } from "node:path";
35
+ import { join as join5, resolve as resolve3 } from "node:path";
36
36
 
37
37
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
38
38
  var external_exports = {};
@@ -21822,15 +21822,266 @@ function normalizeAcpCapabilities(initialized) {
21822
21822
  }
21823
21823
 
21824
21824
  // src/process/executable.ts
21825
- import { execFile, spawn } from "node:child_process";
21825
+ import { spawn } from "node:child_process";
21826
+ import { constants as constants2 } from "node:fs";
21827
+ import { access as access2, realpath as realpath2, stat as stat2 } from "node:fs/promises";
21828
+ import { join as join3, resolve } from "node:path";
21829
+
21830
+ // src/platform/linux.ts
21826
21831
  import { constants, readdirSync, readFileSync } from "node:fs";
21827
21832
  import { access, readdir, readFile, realpath, stat } from "node:fs/promises";
21828
- import { join, resolve } from "node:path";
21833
+ import { join } from "node:path";
21834
+
21835
+ // src/platform/posix.ts
21836
+ import { execFile } from "node:child_process";
21837
+ var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21838
+ var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21839
+ function parseProcessTable(output2) {
21840
+ const entries = [];
21841
+ for (const line of output2.split("\n")) {
21842
+ const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21843
+ if (groups === void 0) {
21844
+ continue;
21845
+ }
21846
+ const processId = Number(groups["pid"]);
21847
+ const parentProcessId = Number(groups["ppid"]);
21848
+ const processGroupId = Number(groups["pgid"]);
21849
+ if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21850
+ continue;
21851
+ }
21852
+ entries.push({ parentProcessId, processGroupId, processId });
21853
+ }
21854
+ return entries;
21855
+ }
21856
+ function readProcessTableWithPs(executable) {
21857
+ return new Promise((resolveTable) => {
21858
+ execFile(
21859
+ executable,
21860
+ ["-axo", "pid=,ppid=,pgid="],
21861
+ {
21862
+ encoding: "utf8",
21863
+ maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
21864
+ signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
21865
+ timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
21866
+ },
21867
+ (error62, stdout) => {
21868
+ resolveTable(error62 === null ? parseProcessTable(stdout) : []);
21869
+ }
21870
+ );
21871
+ });
21872
+ }
21873
+ function processExists(processId) {
21874
+ try {
21875
+ process.kill(processId, 0);
21876
+ return true;
21877
+ } catch {
21878
+ return false;
21879
+ }
21880
+ }
21881
+
21882
+ // src/platform/linux.ts
21883
+ function appendLinuxProcessTableEntry(entries, processId, encoded) {
21884
+ const closingParenthesis = encoded.lastIndexOf(")");
21885
+ if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21886
+ return;
21887
+ }
21888
+ const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21889
+ const parentProcessId = Number(fields[1]);
21890
+ const processGroupId = Number(fields[2]);
21891
+ if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21892
+ return;
21893
+ }
21894
+ entries.push({ parentProcessId, processGroupId, processId });
21895
+ }
21896
+ async function readLinuxProcessTable() {
21897
+ const entries = [];
21898
+ try {
21899
+ const directories = await readdir("/proc", { withFileTypes: true });
21900
+ for (const directory of directories) {
21901
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21902
+ continue;
21903
+ }
21904
+ const processId = Number(directory.name);
21905
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21906
+ continue;
21907
+ }
21908
+ try {
21909
+ appendLinuxProcessTableEntry(
21910
+ entries,
21911
+ processId,
21912
+ await readFile(join("/proc", directory.name, "stat"), "utf8")
21913
+ );
21914
+ } catch {
21915
+ }
21916
+ }
21917
+ } catch {
21918
+ }
21919
+ return entries;
21920
+ }
21921
+ function readLinuxProcessTableSynchronously() {
21922
+ const entries = [];
21923
+ try {
21924
+ const directories = readdirSync("/proc", { withFileTypes: true });
21925
+ for (const directory of directories) {
21926
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21927
+ continue;
21928
+ }
21929
+ const processId = Number(directory.name);
21930
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21931
+ continue;
21932
+ }
21933
+ try {
21934
+ appendLinuxProcessTableEntry(
21935
+ entries,
21936
+ processId,
21937
+ readFileSync(join("/proc", directory.name, "stat"), "utf8")
21938
+ );
21939
+ } catch {
21940
+ }
21941
+ }
21942
+ } catch {
21943
+ }
21944
+ return entries;
21945
+ }
21946
+ async function readLinuxProcessTableWithFallback() {
21947
+ const procfsEntries = await readLinuxProcessTable();
21948
+ if (procfsEntries.length > 0) {
21949
+ return procfsEntries;
21950
+ }
21951
+ for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
21952
+ try {
21953
+ const resolvedPath = await realpath(candidate);
21954
+ if (!(await stat(resolvedPath)).isFile()) {
21955
+ continue;
21956
+ }
21957
+ await access(resolvedPath, constants.X_OK);
21958
+ } catch {
21959
+ continue;
21960
+ }
21961
+ const entries = await readProcessTableWithPs(candidate);
21962
+ if (entries.length > 0) {
21963
+ return entries;
21964
+ }
21965
+ }
21966
+ return [];
21967
+ }
21968
+ function processExists2(processId) {
21969
+ try {
21970
+ const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
21971
+ const closingParenthesis = encoded.lastIndexOf(")");
21972
+ if (closingParenthesis >= 0) {
21973
+ const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
21974
+ if (processState === "Z" || processState === "X") {
21975
+ return false;
21976
+ }
21977
+ }
21978
+ } catch {
21979
+ }
21980
+ return processExists(processId);
21981
+ }
21982
+ var linuxPlatform = {
21983
+ readProcessTable: readLinuxProcessTableWithFallback,
21984
+ readProcessTableSynchronously: readLinuxProcessTableSynchronously,
21985
+ processExists: processExists2,
21986
+ workBuddyExecutablePaths: () => [],
21987
+ openCodeArchives: {
21988
+ arm64: {
21989
+ asset: "opencode-linux-arm64.tar.gz",
21990
+ sha256: "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
21991
+ format: "tar.gz"
21992
+ },
21993
+ x64: {
21994
+ asset: "opencode-linux-x64.tar.gz",
21995
+ sha256: "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
21996
+ format: "tar.gz"
21997
+ }
21998
+ },
21999
+ grokDependencies: {
22000
+ arm64: {
22001
+ name: "@xai-official/grok-linux-arm64",
22002
+ integrity: "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
22003
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
22004
+ },
22005
+ x64: {
22006
+ name: "@xai-official/grok-linux-x64",
22007
+ integrity: "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
22008
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
22009
+ }
22010
+ }
22011
+ };
22012
+
22013
+ // src/platform/macos.ts
22014
+ import { isAbsolute, join as join2 } from "node:path";
22015
+ var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
22016
+ "WorkBuddy.app",
22017
+ "Contents",
22018
+ "Resources",
22019
+ "app.asar.unpacked",
22020
+ "cli",
22021
+ "bin",
22022
+ "codebuddy"
22023
+ ]);
22024
+ var macosPlatform = {
22025
+ readProcessTable: () => readProcessTableWithPs("/bin/ps"),
22026
+ readProcessTableSynchronously: () => [],
22027
+ processExists,
22028
+ workBuddyExecutablePaths: (environment) => {
22029
+ const paths = [join2("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
22030
+ const homeDirectory = environment["HOME"];
22031
+ if (homeDirectory !== void 0 && isAbsolute(homeDirectory)) {
22032
+ paths.unshift(join2(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
22033
+ }
22034
+ return paths;
22035
+ },
22036
+ openCodeArchives: {
22037
+ arm64: {
22038
+ asset: "opencode-darwin-arm64.zip",
22039
+ sha256: "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
22040
+ format: "zip"
22041
+ },
22042
+ x64: {
22043
+ asset: "opencode-darwin-x64.zip",
22044
+ sha256: "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
22045
+ format: "zip"
22046
+ }
22047
+ },
22048
+ grokDependencies: {
22049
+ arm64: {
22050
+ name: "@xai-official/grok-darwin-arm64",
22051
+ integrity: "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
22052
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
22053
+ },
22054
+ x64: {
22055
+ name: "@xai-official/grok-darwin-x64",
22056
+ integrity: "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
22057
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
22058
+ }
22059
+ }
22060
+ };
22061
+
22062
+ // src/platform/index.ts
22063
+ var fallbackPlatform = {
22064
+ readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
22065
+ readProcessTableSynchronously: () => [],
22066
+ processExists,
22067
+ workBuddyExecutablePaths: () => [],
22068
+ openCodeArchives: {},
22069
+ grokDependencies: {}
22070
+ };
22071
+ var platforms = /* @__PURE__ */ new Map([
22072
+ ["linux", linuxPlatform],
22073
+ ["darwin", macosPlatform],
22074
+ ["win32", { ...fallbackPlatform, readProcessTable: () => Promise.resolve([]) }]
22075
+ ]);
22076
+ function platformSupportFor(platform) {
22077
+ return platforms.get(platform) ?? fallbackPlatform;
22078
+ }
22079
+
22080
+ // src/process/executable.ts
22081
+ var hostPlatform = platformSupportFor(process.platform);
21829
22082
  var DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024;
21830
22083
  var PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS = 1e3;
21831
22084
  var PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS = 5e3;
21832
- var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21833
- var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21834
22085
  var PROCESS_EXIT_CHECK_ATTEMPTS = 16;
21835
22086
  var GRACEFUL_STOP_SIGNAL = 15;
21836
22087
  var FORCED_STOP_SIGNAL = 9;
@@ -21889,13 +22140,13 @@ function executableExtensions(executableName, environment, platform) {
21889
22140
  async function resolveExecutablePath(requestedPath2, platform = process.platform) {
21890
22141
  const absoluteRequestedPath = resolve(requestedPath2);
21891
22142
  try {
21892
- const resolvedPath = await realpath(absoluteRequestedPath);
21893
- const metadata = await stat(resolvedPath);
22143
+ const resolvedPath = await realpath2(absoluteRequestedPath);
22144
+ const metadata = await stat2(resolvedPath);
21894
22145
  if (!metadata.isFile()) {
21895
22146
  return null;
21896
22147
  }
21897
22148
  if (platform !== "win32") {
21898
- await access(resolvedPath, constants.X_OK);
22149
+ await access2(resolvedPath, constants2.X_OK);
21899
22150
  }
21900
22151
  return new ResolvedExecutable(
21901
22152
  new ExecutableIdentity(
@@ -21920,7 +22171,7 @@ async function findExecutableOnPath(executableName, environment, platform = proc
21920
22171
  continue;
21921
22172
  }
21922
22173
  for (const extension of extensions) {
21923
- const requestedPath2 = resolve(join(entry, `${executableName}${extension}`));
22174
+ const requestedPath2 = resolve(join3(entry, `${executableName}${extension}`));
21924
22175
  const executable = await resolveExecutablePath(requestedPath2, platform);
21925
22176
  if (executable !== null) {
21926
22177
  return executable;
@@ -21941,128 +22192,8 @@ function appendBounded(chunks, chunk, currentBytes, limitBytes) {
21941
22192
  chunks.push(chunk);
21942
22193
  return nextBytes;
21943
22194
  }
21944
- function parseProcessTable(output2) {
21945
- const entries = [];
21946
- for (const line of output2.split("\n")) {
21947
- const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21948
- if (groups === void 0) {
21949
- continue;
21950
- }
21951
- const processId = Number(groups["pid"]);
21952
- const parentProcessId = Number(groups["ppid"]);
21953
- const processGroupId = Number(groups["pgid"]);
21954
- if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21955
- continue;
21956
- }
21957
- entries.push({ parentProcessId, processGroupId, processId });
21958
- }
21959
- return entries;
21960
- }
21961
- function appendLinuxProcessTableEntry(entries, processId, encoded) {
21962
- const closingParenthesis = encoded.lastIndexOf(")");
21963
- if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21964
- return;
21965
- }
21966
- const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21967
- const parentProcessId = Number(fields[1]);
21968
- const processGroupId = Number(fields[2]);
21969
- if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21970
- return;
21971
- }
21972
- entries.push({ parentProcessId, processGroupId, processId });
21973
- }
21974
- async function readLinuxProcessTable() {
21975
- const entries = [];
21976
- try {
21977
- const directories = await readdir("/proc", { withFileTypes: true });
21978
- for (const directory of directories) {
21979
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21980
- continue;
21981
- }
21982
- const processId = Number(directory.name);
21983
- if (!Number.isSafeInteger(processId) || processId <= 0) {
21984
- continue;
21985
- }
21986
- try {
21987
- appendLinuxProcessTableEntry(
21988
- entries,
21989
- processId,
21990
- await readFile(join("/proc", directory.name, "stat"), "utf8")
21991
- );
21992
- } catch {
21993
- }
21994
- }
21995
- } catch {
21996
- }
21997
- return entries;
21998
- }
21999
- function readLinuxProcessTableSynchronously() {
22000
- const entries = [];
22001
- try {
22002
- const directories = readdirSync("/proc", { withFileTypes: true });
22003
- for (const directory of directories) {
22004
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
22005
- continue;
22006
- }
22007
- const processId = Number(directory.name);
22008
- if (!Number.isSafeInteger(processId) || processId <= 0) {
22009
- continue;
22010
- }
22011
- try {
22012
- appendLinuxProcessTableEntry(
22013
- entries,
22014
- processId,
22015
- readFileSync(join("/proc", directory.name, "stat"), "utf8")
22016
- );
22017
- } catch {
22018
- }
22019
- }
22020
- } catch {
22021
- }
22022
- return entries;
22023
- }
22024
- function readProcessTableWithPs(executable) {
22025
- return new Promise((resolveTable) => {
22026
- execFile(
22027
- executable,
22028
- ["-axo", "pid=,ppid=,pgid="],
22029
- {
22030
- encoding: "utf8",
22031
- maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
22032
- signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
22033
- timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
22034
- },
22035
- (error62, stdout) => {
22036
- resolveTable(error62 === null ? parseProcessTable(stdout) : []);
22037
- }
22038
- );
22039
- });
22040
- }
22041
- async function readLinuxProcessTableWithFallback() {
22042
- const procfsEntries = await readLinuxProcessTable();
22043
- if (procfsEntries.length > 0) {
22044
- return procfsEntries;
22045
- }
22046
- for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
22047
- const executable = await resolveExecutablePath(candidate);
22048
- if (executable === null) {
22049
- continue;
22050
- }
22051
- const entries = await readProcessTableWithPs(executable.identity.requestedPath);
22052
- if (entries.length > 0) {
22053
- return entries;
22054
- }
22055
- }
22056
- return [];
22057
- }
22058
22195
  function readProcessTable() {
22059
- if (process.platform === "win32") {
22060
- return Promise.resolve([]);
22061
- }
22062
- if (process.platform === "linux") {
22063
- return readLinuxProcessTableWithFallback();
22064
- }
22065
- return readProcessTableWithPs(process.platform === "darwin" ? "/bin/ps" : "/usr/bin/ps");
22196
+ return hostPlatform.readProcessTable();
22066
22197
  }
22067
22198
  function selectProcessTree(entries, rootProcessId) {
22068
22199
  const processIds = /* @__PURE__ */ new Set([rootProcessId]);
@@ -22099,11 +22230,9 @@ async function captureProcessTree(child2) {
22099
22230
  if (process.platform === "win32" || child2.pid === void 0) {
22100
22231
  return [];
22101
22232
  }
22102
- if (process.platform === "linux") {
22103
- const procfsEntries = readLinuxProcessTableSynchronously();
22104
- if (procfsEntries.length > 0) {
22105
- return selectProcessTree(procfsEntries, child2.pid);
22106
- }
22233
+ const entries = hostPlatform.readProcessTableSynchronously();
22234
+ if (entries.length > 0) {
22235
+ return selectProcessTree(entries, child2.pid);
22107
22236
  }
22108
22237
  return selectProcessTree(await readProcessTable(), child2.pid);
22109
22238
  }
@@ -22131,36 +22260,15 @@ function signalCapturedProcessGroups(processes, rootProcessId, signal) {
22131
22260
  }
22132
22261
  }
22133
22262
  }
22134
- function processExists(processId) {
22135
- if (process.platform === "linux") {
22136
- try {
22137
- const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
22138
- const closingParenthesis = encoded.lastIndexOf(")");
22139
- if (closingParenthesis >= 0) {
22140
- const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
22141
- if (processState === "Z" || processState === "X") {
22142
- return false;
22143
- }
22144
- }
22145
- } catch {
22146
- }
22147
- }
22148
- try {
22149
- process.kill(processId, 0);
22150
- return true;
22151
- } catch {
22152
- return false;
22153
- }
22154
- }
22155
22263
  async function waitForCapturedProcessesExit(processes, rootProcessId) {
22156
22264
  const processIds = processes.map((identity2) => identity2.processId).filter((processId) => processId !== rootProcessId);
22157
22265
  for (let attempt = 0; attempt < PROCESS_EXIT_CHECK_ATTEMPTS; attempt += 1) {
22158
- if (processIds.every((processId) => !processExists(processId))) {
22266
+ if (processIds.every((processId) => !hostPlatform.processExists(processId))) {
22159
22267
  return true;
22160
22268
  }
22161
22269
  await readProcessTable();
22162
22270
  }
22163
- return processIds.every((processId) => !processExists(processId));
22271
+ return processIds.every((processId) => !hostPlatform.processExists(processId));
22164
22272
  }
22165
22273
  function terminateProcess(child2) {
22166
22274
  if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
@@ -22508,19 +22616,19 @@ var LocalAgentCatalog = class {
22508
22616
 
22509
22617
  // src/storage/state-directory.ts
22510
22618
  import { homedir } from "node:os";
22511
- import { join as join2, resolve as resolve2 } from "node:path";
22619
+ import { join as join4, resolve as resolve2 } from "node:path";
22512
22620
  function readStateDirectory(environment = process.env) {
22513
22621
  const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
22514
22622
  if (configured !== void 0 && configured.length > 0) {
22515
22623
  return resolve2(configured);
22516
22624
  }
22517
- return join2(homedir(), ".mobius");
22625
+ return join4(homedir(), ".mobius");
22518
22626
  }
22519
22627
 
22520
22628
  // src/config.ts
22521
22629
  function loadDefaultWorkspace(environment = process.env) {
22522
22630
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
22523
- return configuredWorkspace ?? join3(readStateDirectory(environment), "workspace");
22631
+ return configuredWorkspace ?? join5(readStateDirectory(environment), "workspace");
22524
22632
  }
22525
22633
  var DaemonLocalContext = class {
22526
22634
  environment;
@@ -22550,7 +22658,7 @@ var OpaqueDaemonReconnectTarget = class extends DaemonReconnectTarget {
22550
22658
  this.commandArgument = `--connection ${connectionId2}`;
22551
22659
  }
22552
22660
  };
22553
- function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null) {
22661
+ function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null, resolveAgent) {
22554
22662
  const daemonAgents = agents.map((agent) => withDaemonEnvironment(agent, localContext.environment));
22555
22663
  return {
22556
22664
  agents: daemonAgents,
@@ -22561,7 +22669,8 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
22561
22669
  installableAgents,
22562
22670
  localContext,
22563
22671
  reconnectTarget,
22564
- relayUrl: connection.relayUrl
22672
+ relayUrl: connection.relayUrl,
22673
+ ...resolveAgent === void 0 ? {} : { resolveAgent }
22565
22674
  };
22566
22675
  }
22567
22676
  function loadDaemonConfig() {
@@ -22695,8 +22804,8 @@ import {
22695
22804
  } from "@agentclientprotocol/sdk";
22696
22805
 
22697
22806
  // src/authorization/local-raster.ts
22698
- import { open as open2, readFile as readFile2, realpath as realpath2, stat as stat2 } from "node:fs/promises";
22699
- import { basename, isAbsolute, normalize } from "node:path";
22807
+ import { open as open2, readFile as readFile2, realpath as realpath3, stat as stat3 } from "node:fs/promises";
22808
+ import { basename, isAbsolute as isAbsolute2, normalize } from "node:path";
22700
22809
  import { fileURLToPath } from "node:url";
22701
22810
  var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
22702
22811
  var MAX_INLINE_RASTER_BYTES = 3e6;
@@ -22762,13 +22871,13 @@ function readInlineRaster(data, name2 = "Image") {
22762
22871
  }
22763
22872
  async function resolveCanonicalPath(requested, signal) {
22764
22873
  signal.throwIfAborted();
22765
- if (!isAbsolute(requested) || requested.includes("\0") || normalize(requested) !== requested) {
22874
+ if (!isAbsolute2(requested) || requested.includes("\0") || normalize(requested) !== requested) {
22766
22875
  return null;
22767
22876
  }
22768
22877
  try {
22769
- const target = await realpath2(requested);
22878
+ const target = await realpath3(requested);
22770
22879
  signal.throwIfAborted();
22771
- if (!isAbsolute(target) || normalize(target) !== target) {
22880
+ if (!isAbsolute2(target) || normalize(target) !== target) {
22772
22881
  return null;
22773
22882
  }
22774
22883
  return target;
@@ -22814,7 +22923,7 @@ async function readLocalRaster(uri, signal) {
22814
22923
  if (target === null) {
22815
22924
  return null;
22816
22925
  }
22817
- const targetMetadata = await stat2(target);
22926
+ const targetMetadata = await stat3(target);
22818
22927
  signal.throwIfAborted();
22819
22928
  if (!targetMetadata.isFile() || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
22820
22929
  return null;
@@ -25646,7 +25755,7 @@ function sql(strings, ...params) {
25646
25755
  return new SQL([new StringChunk(str)]);
25647
25756
  }
25648
25757
  _sql.raw = raw;
25649
- function join20(chunks, separator) {
25758
+ function join22(chunks, separator) {
25650
25759
  const result = [];
25651
25760
  for (const [i, chunk] of chunks.entries()) {
25652
25761
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -25654,7 +25763,7 @@ function sql(strings, ...params) {
25654
25763
  }
25655
25764
  return new SQL(result);
25656
25765
  }
25657
- _sql.join = join20;
25766
+ _sql.join = join22;
25658
25767
  function identifier2(value) {
25659
25768
  return new Name(value);
25660
25769
  }
@@ -27799,7 +27908,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
27799
27908
  const baseTableName = this.tableName;
27800
27909
  const tableName = getTableLikeName(table);
27801
27910
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
27802
- if (typeof tableName === "string" && this.config.joins?.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
27911
+ if (typeof tableName === "string" && this.config.joins?.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
27803
27912
  if (!this.isPartialSelect) {
27804
27913
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
27805
27914
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -28638,7 +28747,7 @@ var SQLiteDialect = class {
28638
28747
  if (!joins2) return;
28639
28748
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
28640
28749
  if (!withEntries.length) return;
28641
- return sql.join(withEntries.map(([k, join20]) => {
28750
+ return sql.join(withEntries.map(([k, join22]) => {
28642
28751
  const relation = tableConfig.relations[k];
28643
28752
  const isSingle2 = is(relation, One);
28644
28753
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -28649,7 +28758,7 @@ var SQLiteDialect = class {
28649
28758
  table: targetTable,
28650
28759
  mode: isSingle2 ? "first" : "many",
28651
28760
  schema,
28652
- queryConfig: join20,
28761
+ queryConfig: join22,
28653
28762
  tableConfig: schema[relation.targetTableName],
28654
28763
  relationWhere: filter,
28655
28764
  isNested: true,
@@ -28663,7 +28772,7 @@ var SQLiteDialect = class {
28663
28772
  key: k,
28664
28773
  selection: innerQuery.selection,
28665
28774
  isArray: !isSingle2,
28666
- isOptional: (relation.optional ?? false) || join20 !== true && !!join20.where
28775
+ isOptional: (relation.optional ?? false) || join22 !== true && !!join22.where
28667
28776
  });
28668
28777
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
28669
28778
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -29279,7 +29388,7 @@ var SQLiteUpdateBase = class {
29279
29388
  createJoin(joinType) {
29280
29389
  return ((table, on) => {
29281
29390
  const tableName = getTableLikeName(table);
29282
- if (typeof tableName === "string" && this.config.joins.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29391
+ if (typeof tableName === "string" && this.config.joins.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29283
29392
  if (typeof on === "function") {
29284
29393
  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;
29285
29394
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -30685,7 +30794,7 @@ var AgentSession = class _AgentSession {
30685
30794
  );
30686
30795
  }
30687
30796
  initialize = async (signal, recovery, origin) => {
30688
- if (origin?.kind === "fork") {
30797
+ if (origin !== void 0) {
30689
30798
  this.#sessionTitle = origin.title;
30690
30799
  }
30691
30800
  await this.#initializeAgent(signal);
@@ -30699,7 +30808,7 @@ var AgentSession = class _AgentSession {
30699
30808
  this.#cwd,
30700
30809
  this.#additionalDirectories,
30701
30810
  true,
30702
- ""
30811
+ origin.title
30703
30812
  )
30704
30813
  ) : this.#store.read(this.#mobiusSessionId)
30705
30814
  );
@@ -31938,8 +32047,8 @@ var AcpContentExternalizer = class {
31938
32047
 
31939
32048
  // src/external-content/local-external-content-store.ts
31940
32049
  import { createHash, randomUUID as randomUUID2 } from "node:crypto";
31941
- import { lstat, mkdir, readdir as readdir2, realpath as realpath3, rename, rm, stat as stat3, utimes, writeFile } from "node:fs/promises";
31942
- import { dirname, join as join4 } from "node:path";
32050
+ import { lstat, mkdir, readdir as readdir2, realpath as realpath4, rename, rm, stat as stat4, utimes, writeFile } from "node:fs/promises";
32051
+ import { dirname, join as join6 } from "node:path";
31943
32052
  var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
31944
32053
  var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
31945
32054
  var metadataSchema2 = external_exports.strictObject({
@@ -31975,7 +32084,7 @@ var LocalExternalContentStore = class {
31975
32084
  #expirationTimer;
31976
32085
  #cleanup = Promise.resolve();
31977
32086
  constructor(stateDirectory) {
31978
- this.#root = join4(stateDirectory, "tmp", "session-content", randomUUID2());
32087
+ this.#root = join6(stateDirectory, "tmp", "session-content", randomUUID2());
31979
32088
  this.#expirationTimer = setInterval(() => {
31980
32089
  void this.#expire().catch(() => void 0);
31981
32090
  }, 6e4);
@@ -31990,11 +32099,11 @@ var LocalExternalContentStore = class {
31990
32099
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
31991
32100
  continue;
31992
32101
  }
31993
- const path2 = join4(dirname(this.#root), directory.name);
32102
+ const path2 = join6(dirname(this.#root), directory.name);
31994
32103
  if (path2 === this.#root) {
31995
32104
  continue;
31996
32105
  }
31997
- const modified = await stat3(path2).then(
32106
+ const modified = await stat4(path2).then(
31998
32107
  (entry) => entry.mtimeMs,
31999
32108
  () => Date.now()
32000
32109
  );
@@ -32040,10 +32149,10 @@ var LocalExternalContentStore = class {
32040
32149
  }
32041
32150
  await this.#expire();
32042
32151
  active.throwIfAborted();
32043
- const directory = join4(this.#root, kind);
32152
+ const directory = join6(this.#root, kind);
32044
32153
  await mkdir(directory, { mode: 448, recursive: true });
32045
32154
  active.throwIfAborted();
32046
- const path2 = join4(directory, key);
32155
+ const path2 = join6(directory, key);
32047
32156
  const write = atomicWrite(path2, bytes, active);
32048
32157
  await write;
32049
32158
  active.throwIfAborted();
@@ -32076,8 +32185,8 @@ var LocalExternalContentStore = class {
32076
32185
  }
32077
32186
  try {
32078
32187
  const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
32079
- realpath3(dirname(entry.path)),
32080
- realpath3(entry.path),
32188
+ realpath4(dirname(entry.path)),
32189
+ realpath4(entry.path),
32081
32190
  lstat(entry.path)
32082
32191
  ]);
32083
32192
  signal.throwIfAborted();
@@ -32515,7 +32624,7 @@ var AgentRuntimeManager = class {
32515
32624
  return await this.#startRetainedSessionProcess(
32516
32625
  options,
32517
32626
  async () => await AgentSession.start(
32518
- options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId } } : options,
32627
+ options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId, title: "" } } : options,
32519
32628
  recovery,
32520
32629
  () => this.#observer,
32521
32630
  this.#store,
@@ -33174,10 +33283,10 @@ var LocalAuthorizationError = class extends Error {
33174
33283
  };
33175
33284
 
33176
33285
  // src/pairing/pair-local-machine.ts
33177
- import { mkdir as mkdir6, realpath as realpath8, stat as stat7 } from "node:fs/promises";
33286
+ import { mkdir as mkdir6, realpath as realpath9, stat as stat8 } from "node:fs/promises";
33178
33287
  import { hostname as hostname3 } from "node:os";
33179
33288
  import { basename as basename3, resolve as resolve5 } from "node:path";
33180
- import { fetch as fetch2 } from "undici";
33289
+ import { fetch as fetch3 } from "undici";
33181
33290
 
33182
33291
  // src/agent-catalog/agent-discovery.ts
33183
33292
  var AgentDiscovery = class {
@@ -33319,8 +33428,8 @@ var LocalAgentInventory = class {
33319
33428
  };
33320
33429
 
33321
33430
  // src/agent-installation/managed-npm-package.ts
33322
- import { mkdir as mkdir2, mkdtemp, open as open3, realpath as realpath4, rename as rename2, rm as rm2, stat as stat4 } from "node:fs/promises";
33323
- import { delimiter, dirname as dirname2, isAbsolute as isAbsolute2, join as join5, relative, sep } from "node:path";
33431
+ import { mkdir as mkdir2, mkdtemp, open as open3, realpath as realpath5, rename as rename2, rm as rm2, stat as stat5 } from "node:fs/promises";
33432
+ import { delimiter, dirname as dirname2, isAbsolute as isAbsolute3, join as join7, relative, sep } from "node:path";
33324
33433
  var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
33325
33434
  var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
33326
33435
  var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
@@ -33371,11 +33480,11 @@ function isRecord7(value) {
33371
33480
  return typeof value === "object" && value !== null && !Array.isArray(value);
33372
33481
  }
33373
33482
  function packagePath(root, packageName) {
33374
- return join5(root, "node_modules", ...packageName.split("/"));
33483
+ return join7(root, "node_modules", ...packageName.split("/"));
33375
33484
  }
33376
33485
  function isContainedPath(root, candidate) {
33377
33486
  const difference = relative(root, candidate);
33378
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute2(difference);
33487
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute3(difference);
33379
33488
  }
33380
33489
  async function readJsonRecord(path2, maximumBytes) {
33381
33490
  try {
@@ -33476,14 +33585,14 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
33476
33585
  }
33477
33586
  }
33478
33587
  async function verifyRequiredDependency(rootPath, lock, definition) {
33479
- const dependencyRoot = await realpath4(packagePath(rootPath, definition.packageName));
33588
+ const dependencyRoot = await realpath5(packagePath(rootPath, definition.packageName));
33480
33589
  if (!isContainedPath(rootPath, dependencyRoot)) {
33481
33590
  throw new ManagedNpmPackageError(
33482
33591
  "managed_package_verification_failed",
33483
33592
  "The required managed npm dependency escaped its private cache"
33484
33593
  );
33485
33594
  }
33486
- const metadata = await readJsonRecord(join5(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33595
+ const metadata = await readJsonRecord(join7(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33487
33596
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
33488
33597
  throw new ManagedNpmPackageError(
33489
33598
  "managed_package_verification_failed",
@@ -33505,15 +33614,15 @@ async function validateManagedNpmPackage(root, definition) {
33505
33614
  }
33506
33615
  }
33507
33616
  async function validateManagedNpmPackageContents(root, definition) {
33508
- const rootPath = await realpath4(root);
33509
- const packageRoot = await realpath4(packagePath(rootPath, definition.packageName));
33617
+ const rootPath = await realpath5(root);
33618
+ const packageRoot = await realpath5(packagePath(rootPath, definition.packageName));
33510
33619
  if (!isContainedPath(rootPath, packageRoot)) {
33511
33620
  throw new ManagedNpmPackageError(
33512
33621
  "managed_package_verification_failed",
33513
33622
  "The managed npm package escaped its private cache"
33514
33623
  );
33515
33624
  }
33516
- const metadata = await readJsonRecord(join5(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33625
+ const metadata = await readJsonRecord(join7(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33517
33626
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
33518
33627
  throw new ManagedNpmPackageError(
33519
33628
  "managed_package_verification_failed",
@@ -33521,14 +33630,14 @@ async function validateManagedNpmPackageContents(root, definition) {
33521
33630
  );
33522
33631
  }
33523
33632
  if (definition instanceof SriManagedNpmPackageDefinition) {
33524
- const lock = await readJsonRecord(join5(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
33633
+ const lock = await readJsonRecord(join7(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
33525
33634
  verifyPackageLockEntry(lock, definition, definition.verifyDependencyClosure);
33526
33635
  for (const dependency of definition.requiredDependencies) {
33527
33636
  await verifyRequiredDependency(rootPath, lock, dependency);
33528
33637
  }
33529
33638
  }
33530
33639
  const declaredBin = readBinPath(metadata, definition.executableName);
33531
- const executable = await resolveExecutablePath(join5(packageRoot, declaredBin));
33640
+ const executable = await resolveExecutablePath(join7(packageRoot, declaredBin));
33532
33641
  if (executable === null || !isContainedPath(rootPath, executable.path)) {
33533
33642
  throw new ManagedNpmPackageError(
33534
33643
  "managed_package_verification_failed",
@@ -33541,7 +33650,7 @@ var ManagedNpmPackageInstaller = class {
33541
33650
  install = async (root, definition, environment, signal) => {
33542
33651
  signal.throwIfAborted();
33543
33652
  try {
33544
- const metadata = await stat4(root);
33653
+ const metadata = await stat5(root);
33545
33654
  if (metadata.isDirectory()) {
33546
33655
  return await validateManagedNpmPackage(root, definition);
33547
33656
  }
@@ -33552,7 +33661,7 @@ var ManagedNpmPackageInstaller = class {
33552
33661
  }
33553
33662
  const parent = dirname2(root);
33554
33663
  await mkdir2(parent, { mode: 448, recursive: true });
33555
- const staging = await mkdtemp(join5(parent, `.${definition.version}.staging-`));
33664
+ const staging = await mkdtemp(join7(parent, `.${definition.version}.staging-`));
33556
33665
  try {
33557
33666
  const npm = await findExecutableOnPath(process.platform === "win32" ? "npm.cmd" : "npm", environment);
33558
33667
  if (npm === null) {
@@ -33578,9 +33687,9 @@ var ManagedNpmPackageInstaller = class {
33578
33687
  `${definition.packageName}@${definition.version}`
33579
33688
  );
33580
33689
  const installEnvironment = {
33581
- HOME: join5(staging, "home"),
33690
+ HOME: join7(staging, "home"),
33582
33691
  NPM_CONFIG_AUDIT: "false",
33583
- NPM_CONFIG_CACHE: join5(staging, ".npm-cache"),
33692
+ NPM_CONFIG_CACHE: join7(staging, ".npm-cache"),
33584
33693
  NPM_CONFIG_FUND: "false",
33585
33694
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
33586
33695
  NPM_CONFIG_PACKAGE_LOCK: "true",
@@ -33602,8 +33711,8 @@ var ManagedNpmPackageInstaller = class {
33602
33711
  timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
33603
33712
  });
33604
33713
  await Promise.all([
33605
- rm2(join5(staging, ".npm-cache"), { force: true, recursive: true }),
33606
- rm2(join5(staging, "home"), { force: true, recursive: true })
33714
+ rm2(join7(staging, ".npm-cache"), { force: true, recursive: true }),
33715
+ rm2(join7(staging, "home"), { force: true, recursive: true })
33607
33716
  ]);
33608
33717
  await validateManagedNpmPackage(staging, definition);
33609
33718
  try {
@@ -33639,7 +33748,7 @@ var ManagedNpmPackageInstaller = class {
33639
33748
  };
33640
33749
 
33641
33750
  // src/agent-catalog/agent-specification.ts
33642
- import { join as join6 } from "node:path";
33751
+ import { join as join8 } from "node:path";
33643
33752
 
33644
33753
  // src/agent-catalog/version-output.ts
33645
33754
  function normalizeVersionOutput(output2) {
@@ -33662,7 +33771,7 @@ var LocalAgentSpecification = class {
33662
33771
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
33663
33772
  signal.throwIfAborted();
33664
33773
  const executable = await resolveExecutablePath(
33665
- join6(stateDirectory, ...this.managedAgentExecutablePath),
33774
+ join8(stateDirectory, ...this.managedAgentExecutablePath),
33666
33775
  platform
33667
33776
  );
33668
33777
  signal.throwIfAborted();
@@ -33760,7 +33869,7 @@ import {
33760
33869
  import { spawn as spawn3 } from "node:child_process";
33761
33870
 
33762
33871
  // src/acp/codex/app-server-protocol.ts
33763
- import { isAbsolute as isAbsolute3 } from "node:path";
33872
+ import { isAbsolute as isAbsolute4 } from "node:path";
33764
33873
  var boundedText = (maximum) => external_exports.string().max(maximum);
33765
33874
  var jsonValue = external_exports.lazy(() => external_exports.unknown());
33766
33875
  var requestIdSchema = external_exports.union([external_exports.number(), external_exports.string()]).refine((value) => typeof value === "number" || value.length <= 256);
@@ -33831,7 +33940,7 @@ var imageGenerationItemSchema = external_exports.object({
33831
33940
  });
33832
33941
  var threadItemSchema = external_exports.discriminatedUnion("type", [
33833
33942
  imageGenerationItemSchema,
33834
- external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute3) }),
33943
+ external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute4) }),
33835
33944
  external_exports.object({
33836
33945
  id: boundedText(256),
33837
33946
  text: boundedText(1e6),
@@ -35697,15 +35806,15 @@ var AgentProbeError = class extends Error {
35697
35806
  };
35698
35807
 
35699
35808
  // src/agent-catalog/agents/resolve-user-local-executable.ts
35700
- import { isAbsolute as isAbsolute4, join as join7 } from "node:path";
35809
+ import { isAbsolute as isAbsolute5, join as join9 } from "node:path";
35701
35810
  async function resolveUserLocalExecutable(executableName, context) {
35702
35811
  context.signal.throwIfAborted();
35703
35812
  const platform = context.platform ?? process.platform;
35704
35813
  const homeDirectory = context.environment["HOME"];
35705
- if (platform === "win32" || homeDirectory === void 0 || !isAbsolute4(homeDirectory)) {
35814
+ if (platform === "win32" || homeDirectory === void 0 || !isAbsolute5(homeDirectory)) {
35706
35815
  return [];
35707
35816
  }
35708
- const executable = await resolveExecutablePath(join7(homeDirectory, ".local", "bin", executableName), platform);
35817
+ const executable = await resolveExecutablePath(join9(homeDirectory, ".local", "bin", executableName), platform);
35709
35818
  context.signal.throwIfAborted();
35710
35819
  return executable === null ? [] : [executable];
35711
35820
  }
@@ -35794,8 +35903,8 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
35794
35903
  };
35795
35904
 
35796
35905
  // src/agent-catalog/agents/deepseek-harness-agent.ts
35797
- import { mkdir as mkdir3, realpath as realpath5, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
35798
- import { isAbsolute as isAbsolute5, join as join8, normalize as normalize2 } from "node:path";
35906
+ import { mkdir as mkdir3, realpath as realpath6, stat as stat6, writeFile as writeFile2 } from "node:fs/promises";
35907
+ import { isAbsolute as isAbsolute6, join as join10, normalize as normalize2 } from "node:path";
35799
35908
 
35800
35909
  // src/agent-installation/deepseek-managed-package.ts
35801
35910
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -35819,20 +35928,20 @@ var DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH = `# Managed by Mobius: pin the ACP brid
35819
35928
  model: deepseek-v4-flash-vision-exp
35820
35929
  `;
35821
35930
  async function prepareAgentHome(path2, imagePrompts) {
35822
- if (!isAbsolute5(path2) || normalize2(path2) !== path2) {
35931
+ if (!isAbsolute6(path2) || normalize2(path2) !== path2) {
35823
35932
  throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
35824
35933
  }
35825
35934
  try {
35826
35935
  if (imagePrompts) {
35827
35936
  await mkdir3(path2, { mode: 448, recursive: true });
35828
35937
  }
35829
- const resolved = await realpath5(path2);
35830
- const metadata = await stat5(resolved);
35938
+ const resolved = await realpath6(path2);
35939
+ const metadata = await stat6(resolved);
35831
35940
  if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
35832
35941
  throw new Error("Agent home is not a user-owned directory");
35833
35942
  }
35834
35943
  if (imagePrompts) {
35835
- await writeFile2(join8(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
35944
+ await writeFile2(join10(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
35836
35945
  mode: 384
35837
35946
  });
35838
35947
  }
@@ -35880,7 +35989,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
35880
35989
  context.signal
35881
35990
  );
35882
35991
  if (managed.path === agent.path) {
35883
- selectedHome = join8(readStateDirectory(context.environment), "agents", this.id, "home");
35992
+ selectedHome = join10(readStateDirectory(context.environment), "agents", this.id, "home");
35884
35993
  managedHome = true;
35885
35994
  }
35886
35995
  } catch {
@@ -35896,7 +36005,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
35896
36005
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
35897
36006
  signal.throwIfAborted();
35898
36007
  const executable = await validateManagedNpmPackage(
35899
- join8(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
36008
+ join10(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
35900
36009
  DEEPSEEK_HARNESS_PACKAGE
35901
36010
  );
35902
36011
  signal.throwIfAborted();
@@ -35950,8 +36059,8 @@ var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
35950
36059
  };
35951
36060
 
35952
36061
  // src/agent-catalog/agents/grok-build-agent.ts
35953
- import { realpath as realpath6 } from "node:fs/promises";
35954
- import { isAbsolute as isAbsolute6, join as join9, relative as relative2, sep as sep2 } from "node:path";
36062
+ import { realpath as realpath7 } from "node:fs/promises";
36063
+ import { isAbsolute as isAbsolute7, join as join11, relative as relative2, sep as sep2 } from "node:path";
35955
36064
  import {
35956
36065
  RequestError as RequestError2
35957
36066
  } from "@agentclientprotocol/sdk";
@@ -35974,50 +36083,25 @@ var GrokBuildManagedPackage = class extends SriManagedNpmPackageDefinition {
35974
36083
  this.requiredDependencies = Object.freeze([requiredDependency]);
35975
36084
  }
35976
36085
  };
35977
- var GROK_DARWIN_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
35978
- "@xai-official/grok-darwin-arm64",
35979
- GROK_BUILD_MANAGED_VERSION,
35980
- "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
35981
- "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
35982
- );
35983
- var GROK_DARWIN_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
35984
- "@xai-official/grok-darwin-x64",
35985
- GROK_BUILD_MANAGED_VERSION,
35986
- "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
35987
- "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
35988
- );
35989
- var GROK_LINUX_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
35990
- "@xai-official/grok-linux-arm64",
35991
- GROK_BUILD_MANAGED_VERSION,
35992
- "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
35993
- "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
35994
- );
35995
- var GROK_LINUX_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
35996
- "@xai-official/grok-linux-x64",
35997
- GROK_BUILD_MANAGED_VERSION,
35998
- "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
35999
- "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
36000
- );
36001
36086
  function grokBuildManagedPackage(platform, architecture) {
36002
- if (platform === "darwin" && architecture === "arm64") {
36003
- return new GrokBuildManagedPackage(GROK_DARWIN_ARM64_PACKAGE);
36004
- }
36005
- if (platform === "darwin" && architecture === "x64") {
36006
- return new GrokBuildManagedPackage(GROK_DARWIN_X64_PACKAGE);
36007
- }
36008
- if (platform === "linux" && architecture === "arm64") {
36009
- return new GrokBuildManagedPackage(GROK_LINUX_ARM64_PACKAGE);
36010
- }
36011
- if (platform === "linux" && architecture === "x64") {
36012
- return new GrokBuildManagedPackage(GROK_LINUX_X64_PACKAGE);
36087
+ const release = platformSupportFor(platform).grokDependencies[architecture];
36088
+ if (release === void 0) {
36089
+ throw new Error("Grok Build does not publish a package for this platform");
36013
36090
  }
36014
- throw new Error("Grok Build does not publish a package for this platform");
36091
+ return new GrokBuildManagedPackage(
36092
+ new SriManagedNpmDependencyDefinition(
36093
+ release.name,
36094
+ GROK_BUILD_MANAGED_VERSION,
36095
+ release.integrity,
36096
+ release.tarballUrl
36097
+ )
36098
+ );
36015
36099
  }
36016
36100
 
36017
36101
  // src/agent-catalog/agents/grok-build-agent.ts
36018
36102
  function isContainedPath2(root, candidate) {
36019
36103
  const difference = relative2(root, candidate);
36020
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute6(difference);
36104
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute7(difference);
36021
36105
  }
36022
36106
  var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36023
36107
  adapterVersion = GROK_BUILD_MANAGED_VERSION;
@@ -36046,8 +36130,8 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36046
36130
  );
36047
36131
  if (managed.path === agent.path) {
36048
36132
  return Object.freeze({
36049
- GROK_HOME: await realpath6(
36050
- join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
36133
+ GROK_HOME: await realpath7(
36134
+ join11(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
36051
36135
  )
36052
36136
  });
36053
36137
  }
@@ -36058,9 +36142,9 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36058
36142
  };
36059
36143
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
36060
36144
  signal.throwIfAborted();
36061
- const versionRoot = await realpath6(join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
36062
- await validateManagedNpmPackage(join9(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
36063
- const executable = await resolveExecutablePath(join9(versionRoot, "home", "bin", "grok"), platform);
36145
+ const versionRoot = await realpath7(join11(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
36146
+ await validateManagedNpmPackage(join11(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
36147
+ const executable = await resolveExecutablePath(join11(versionRoot, "home", "bin", "grok"), platform);
36064
36148
  signal.throwIfAborted();
36065
36149
  if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
36066
36150
  throw new AgentProbeError("managed_agent_invalid", "The managed Grok Build executable is invalid");
@@ -36160,13 +36244,13 @@ var OhMyPiAgentSpecification = class extends DirectAcpAgentDefinition {
36160
36244
  };
36161
36245
 
36162
36246
  // src/agent-catalog/agents/opencode-agent.ts
36163
- import { join as join11 } from "node:path";
36247
+ import { join as join13 } from "node:path";
36164
36248
 
36165
36249
  // src/agent-installation/managed-agent-archive.ts
36166
36250
  import { createHash as createHash3 } from "node:crypto";
36167
36251
  import { createReadStream } from "node:fs";
36168
- import { chmod, copyFile, mkdir as mkdir4, mkdtemp as mkdtemp2, open as open4, realpath as realpath7, rename as rename3, rm as rm3, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
36169
- import { delimiter as delimiter2, dirname as dirname3, isAbsolute as isAbsolute7, join as join10, relative as relative3, sep as sep3 } from "node:path";
36252
+ import { chmod, copyFile, mkdir as mkdir4, mkdtemp as mkdtemp2, open as open4, realpath as realpath8, rename as rename3, rm as rm3, stat as stat7, writeFile as writeFile3 } from "node:fs/promises";
36253
+ import { delimiter as delimiter2, dirname as dirname3, isAbsolute as isAbsolute8, join as join12, relative as relative3, sep as sep3 } from "node:path";
36170
36254
 
36171
36255
  // src/agent-installation/verified-download.ts
36172
36256
  import { fetch } from "undici";
@@ -36272,7 +36356,7 @@ function isRecord8(value) {
36272
36356
  }
36273
36357
  function isContainedPath3(root, candidate) {
36274
36358
  const difference = relative3(root, candidate);
36275
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute7(difference);
36359
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute8(difference);
36276
36360
  }
36277
36361
  async function hashFile(path2, signal) {
36278
36362
  signal.throwIfAborted();
@@ -36346,16 +36430,16 @@ async function readManifest(path2) {
36346
36430
  }
36347
36431
  async function validateManagedAgentArchive(root, definition, signal) {
36348
36432
  try {
36349
- const rootPath = await realpath7(root);
36350
- const rootMetadata = await stat6(rootPath);
36433
+ const rootPath = await realpath8(root);
36434
+ const rootMetadata = await stat7(rootPath);
36351
36435
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
36352
36436
  throw new Error("Managed Agent root is not user-owned");
36353
36437
  }
36354
- const manifest = await readManifest(join10(rootPath, "archive.json"));
36438
+ const manifest = await readManifest(join12(rootPath, "archive.json"));
36355
36439
  if (manifest["archiveSha256"] !== definition.archiveSha256 || manifest["archiveUrl"] !== definition.archiveUrl.toString() || manifest["version"] !== definition.version || typeof manifest["executableSha256"] !== "string") {
36356
36440
  throw new Error("Managed Agent archive identity is invalid");
36357
36441
  }
36358
- const executable = await resolveExecutablePath(join10(rootPath, "bin", definition.executableName));
36442
+ const executable = await resolveExecutablePath(join12(rootPath, "bin", definition.executableName));
36359
36443
  if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
36360
36444
  throw new Error("Managed Agent executable is invalid");
36361
36445
  }
@@ -36381,47 +36465,21 @@ function releaseUrl(asset) {
36381
36465
  return new URL(`https://github.com/anomalyco/opencode/releases/download/v${OPENCODE_MANAGED_VERSION}/${asset}`);
36382
36466
  }
36383
36467
  function openCodeManagedArchive(platform, architecture) {
36384
- if (platform === "darwin" && architecture === "arm64") {
36385
- const asset = "opencode-darwin-arm64.zip";
36386
- return new ZipManagedAgentArchiveDefinition(
36387
- OPENCODE_MANAGED_VERSION,
36388
- asset,
36389
- releaseUrl(asset),
36390
- "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
36391
- "opencode"
36392
- );
36393
- }
36394
- if (platform === "darwin" && architecture === "x64") {
36395
- const asset = "opencode-darwin-x64.zip";
36396
- return new ZipManagedAgentArchiveDefinition(
36397
- OPENCODE_MANAGED_VERSION,
36398
- asset,
36399
- releaseUrl(asset),
36400
- "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
36401
- "opencode"
36402
- );
36403
- }
36404
- if (platform === "linux" && architecture === "arm64") {
36405
- const asset = "opencode-linux-arm64.tar.gz";
36406
- return new TarGzipManagedAgentArchiveDefinition(
36407
- OPENCODE_MANAGED_VERSION,
36408
- asset,
36409
- releaseUrl(asset),
36410
- "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
36411
- "opencode"
36412
- );
36413
- }
36414
- if (platform === "linux" && architecture === "x64") {
36415
- const asset = "opencode-linux-x64.tar.gz";
36416
- return new TarGzipManagedAgentArchiveDefinition(
36417
- OPENCODE_MANAGED_VERSION,
36418
- asset,
36419
- releaseUrl(asset),
36420
- "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
36421
- "opencode"
36422
- );
36423
- }
36424
- throw new Error("OpenCode does not publish an approved archive for this platform");
36468
+ const release = platformSupportFor(platform).openCodeArchives[architecture];
36469
+ if (release === void 0) {
36470
+ throw new Error("OpenCode does not publish an approved archive for this platform");
36471
+ }
36472
+ const Definition = {
36473
+ zip: ZipManagedAgentArchiveDefinition,
36474
+ "tar.gz": TarGzipManagedAgentArchiveDefinition
36475
+ }[release.format];
36476
+ return new Definition(
36477
+ OPENCODE_MANAGED_VERSION,
36478
+ release.asset,
36479
+ releaseUrl(release.asset),
36480
+ release.sha256,
36481
+ "opencode"
36482
+ );
36425
36483
  }
36426
36484
 
36427
36485
  // src/agent-catalog/agents/opencode-agent.ts
@@ -36547,7 +36605,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
36547
36605
  return Object.freeze(environment);
36548
36606
  };
36549
36607
  resolveManagedAgent = async (stateDirectory, platform, signal) => await validateManagedAgentArchive(
36550
- join11(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
36608
+ join13(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
36551
36609
  openCodeManagedArchive(platform, process.arch),
36552
36610
  signal
36553
36611
  );
@@ -36565,7 +36623,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
36565
36623
  };
36566
36624
 
36567
36625
  // src/agent-catalog/agents/pi-agent.ts
36568
- import { join as join12 } from "node:path";
36626
+ import { join as join14 } from "node:path";
36569
36627
  import {
36570
36628
  methods as methods7
36571
36629
  } from "@agentclientprotocol/sdk";
@@ -36624,7 +36682,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
36624
36682
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
36625
36683
  signal.throwIfAborted();
36626
36684
  const executable = await validateManagedNpmPackage(
36627
- join12(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
36685
+ join14(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
36628
36686
  PI_AGENT_PACKAGE
36629
36687
  );
36630
36688
  signal.throwIfAborted();
@@ -36662,7 +36720,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
36662
36720
  };
36663
36721
 
36664
36722
  // src/agent-catalog/agents/workbuddy-agent.ts
36665
- import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
36723
+ import { join as join15 } from "node:path";
36666
36724
 
36667
36725
  // src/agent-installation/workbuddy-managed-package.ts
36668
36726
  var WORKBUDDY_MANAGED_VERSION = "2.146.0";
@@ -36680,15 +36738,6 @@ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
36680
36738
  );
36681
36739
 
36682
36740
  // src/agent-catalog/agents/workbuddy-agent.ts
36683
- var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
36684
- "WorkBuddy.app",
36685
- "Contents",
36686
- "Resources",
36687
- "app.asar.unpacked",
36688
- "cli",
36689
- "bin",
36690
- "codebuddy"
36691
- ]);
36692
36741
  var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36693
36742
  adapterVersion = WORKBUDDY_MANAGED_VERSION;
36694
36743
  authenticationCommand = () => "codebuddy";
@@ -36717,7 +36766,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36717
36766
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
36718
36767
  signal.throwIfAborted();
36719
36768
  const executable = await validateManagedNpmPackage(
36720
- join13(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
36769
+ join15(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
36721
36770
  WORKBUDDY_MANAGED_PACKAGE
36722
36771
  );
36723
36772
  signal.throwIfAborted();
@@ -36725,17 +36774,11 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36725
36774
  };
36726
36775
  resolveInstalledAgentExecutables = async (context) => {
36727
36776
  context.signal.throwIfAborted();
36728
- if ((context.platform ?? process.platform) !== "darwin") {
36729
- return [];
36730
- }
36731
- const requestedPaths = [join13("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
36732
- const homeDirectory = context.environment["HOME"];
36733
- if (homeDirectory !== void 0 && isAbsolute8(homeDirectory)) {
36734
- requestedPaths.unshift(join13(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
36735
- }
36777
+ const platform = context.platform ?? process.platform;
36778
+ const requestedPaths = platformSupportFor(platform).workBuddyExecutablePaths(context.environment);
36736
36779
  const executables = [];
36737
36780
  for (const requestedPath2 of requestedPaths) {
36738
- const executable = await resolveExecutablePath(requestedPath2, "darwin");
36781
+ const executable = await resolveExecutablePath(requestedPath2, platform);
36739
36782
  context.signal.throwIfAborted();
36740
36783
  if (executable !== null) {
36741
36784
  executables.push(executable);
@@ -37066,10 +37109,10 @@ function isAgentVersionSupported(reportedVersion, minimumSupportedVersion) {
37066
37109
  }
37067
37110
 
37068
37111
  // src/agent-catalog/executable-discovery.ts
37069
- import { isAbsolute as isAbsolute9, join as join15 } from "node:path";
37112
+ import { isAbsolute as isAbsolute9, join as join17 } from "node:path";
37070
37113
 
37071
37114
  // src/agent-installation/managed-adapter-installer.ts
37072
- import { join as join14 } from "node:path";
37115
+ import { join as join16 } from "node:path";
37073
37116
  var ManagedAdapterInstallError = class extends Error {
37074
37117
  code;
37075
37118
  constructor(code, message, options = {}) {
@@ -37126,7 +37169,7 @@ var ManagedAdapterInstaller = class {
37126
37169
  this.#stateDirectory = options.stateDirectory;
37127
37170
  }
37128
37171
  install = async (specification, signal) => {
37129
- const root = join14(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
37172
+ const root = join16(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
37130
37173
  try {
37131
37174
  return await this.#npmInstaller.install(
37132
37175
  root,
@@ -37160,7 +37203,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
37160
37203
  let managed;
37161
37204
  try {
37162
37205
  managed = await validateManagedAdapter(
37163
- join15(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
37206
+ join17(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
37164
37207
  specification
37165
37208
  );
37166
37209
  } catch {
@@ -37473,10 +37516,176 @@ async function discoverLocalAgentInventory(options) {
37473
37516
  return new LocalAgentInventory(results);
37474
37517
  }
37475
37518
 
37519
+ // src/agent-catalog/publish-agent-catalog.ts
37520
+ import { fetch as fetch2 } from "undici";
37521
+
37522
+ // src/relay-connection/runtime-authentication.ts
37523
+ function runtimeCredential(relayUrl) {
37524
+ return relayUrl.searchParams.get("token") ?? "";
37525
+ }
37526
+ function runtimeAuthorization(relayUrl) {
37527
+ const credential = runtimeCredential(relayUrl);
37528
+ return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
37529
+ }
37530
+ function relayHttpEndpoint(relayUrl) {
37531
+ const endpoint = new URL(relayUrl);
37532
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
37533
+ endpoint.search = "";
37534
+ return endpoint;
37535
+ }
37536
+
37537
+ // src/agent-catalog/publish-agent-catalog.ts
37538
+ var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
37539
+ var AgentCatalogPublishError = class extends Error {
37540
+ code = "agent_catalog_update_failed";
37541
+ diagnosticDetails;
37542
+ constructor(message, options = {}, diagnosticDetails = {}) {
37543
+ super(message, options);
37544
+ this.diagnosticDetails = diagnosticDetails;
37545
+ this.name = "AgentCatalogPublishError";
37546
+ }
37547
+ };
37548
+ function isRecord9(value) {
37549
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37550
+ }
37551
+ function isSafeRelayErrorMessage(value) {
37552
+ return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
37553
+ }
37554
+ async function rejectedCatalogError(response) {
37555
+ let value;
37556
+ try {
37557
+ value = await response.json();
37558
+ } catch {
37559
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37560
+ }
37561
+ if (!isRecord9(value) || !isRecord9(value["error"])) {
37562
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37563
+ }
37564
+ const code = value["error"]["code"];
37565
+ const message = value["error"]["message"];
37566
+ if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
37567
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37568
+ }
37569
+ return new AgentCatalogPublishError(
37570
+ `The Relay rejected the Agent catalog update (${code}): ${message}`,
37571
+ {},
37572
+ {
37573
+ relayErrorCode: code
37574
+ }
37575
+ );
37576
+ }
37577
+ function catalogEndpoint(config2) {
37578
+ const endpoint = relayHttpEndpoint(config2.relayUrl);
37579
+ if (endpoint.pathname.endsWith("/daemon")) {
37580
+ endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
37581
+ return endpoint;
37582
+ }
37583
+ const runtimePath = "/v1/runtimes/connect";
37584
+ if (endpoint.pathname.endsWith(runtimePath)) {
37585
+ endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
37586
+ return endpoint;
37587
+ }
37588
+ throw new AgentCatalogPublishError("The Relay URL is invalid");
37589
+ }
37590
+ async function publishAgentCatalog(config2, signal) {
37591
+ signal.throwIfAborted();
37592
+ const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
37593
+ const requestSignal = AbortSignal.any([signal, timeoutSignal]);
37594
+ let response;
37595
+ const catalog = config2.catalog.read();
37596
+ try {
37597
+ response = await fetch2(catalogEndpoint(config2), {
37598
+ body: JSON.stringify({
37599
+ agents: catalog.agents.map((agent) => ({
37600
+ agentPath: agent.agentIdentity.requestedPath,
37601
+ agentVersion: agent.agentVersion,
37602
+ agentSettingsDiscovery: true,
37603
+ capabilities: agent.capabilities,
37604
+ id: agent.id,
37605
+ label: agent.label,
37606
+ sessionTurnConfiguration: true
37607
+ })),
37608
+ installableAgents: catalog.installableAgents
37609
+ }),
37610
+ dispatcher: environmentProxyDispatcher,
37611
+ headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
37612
+ method: "PUT",
37613
+ signal: requestSignal
37614
+ });
37615
+ } catch (error62) {
37616
+ if (signal.aborted) {
37617
+ signal.throwIfAborted();
37618
+ }
37619
+ throw new AgentCatalogPublishError(
37620
+ timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
37621
+ { cause: error62 }
37622
+ );
37623
+ }
37624
+ if (!response.ok) {
37625
+ throw await rejectedCatalogError(response);
37626
+ }
37627
+ await response.body?.cancel();
37628
+ }
37629
+
37630
+ // src/agent-catalog/resolve-catalog-agent.ts
37631
+ function createCatalogAgentResolver(discover, readConfig, publish) {
37632
+ const swaps = /* @__PURE__ */ new Map();
37633
+ return async (agent, signal) => {
37634
+ const config2 = readConfig();
37635
+ const pending = swaps.get(agent.id);
37636
+ if (pending !== void 0) {
37637
+ await pending;
37638
+ return config2.catalog.find(agent.id);
37639
+ }
37640
+ let release = () => void 0;
37641
+ const gate = new Promise((resolveGate) => {
37642
+ release = resolveGate;
37643
+ });
37644
+ swaps.set(agent.id, gate);
37645
+ try {
37646
+ if (await unchangedIdentity(agent, signal)) {
37647
+ return agent;
37648
+ }
37649
+ signal.throwIfAborted();
37650
+ const inventory = await discover(signal);
37651
+ signal.throwIfAborted();
37652
+ const previous = config2.catalog.read();
37653
+ const previousAgent = previous.agents.find((entry) => entry.id === agent.id);
37654
+ if (previousAgent === void 0) {
37655
+ throw new Error(`The local Agent ${agent.id} left the catalog before its refresh completed`);
37656
+ }
37657
+ config2.catalog.transition(
37658
+ [
37659
+ ...previous.agents.filter((entry) => entry.id !== agent.id),
37660
+ ...inventory.readyAgents().map((ready) => withDaemonEnvironment(ready, config2.localContext.environment))
37661
+ ],
37662
+ [...previous.installableAgents.filter((entry) => entry.id !== agent.id), ...inventory.installable]
37663
+ );
37664
+ try {
37665
+ await publish(config2, signal);
37666
+ } catch (error62) {
37667
+ config2.catalog.transition(previous.agents, previous.installableAgents);
37668
+ throw error62;
37669
+ }
37670
+ return config2.catalog.find(agent.id);
37671
+ } finally {
37672
+ swaps.delete(agent.id);
37673
+ release();
37674
+ }
37675
+ };
37676
+ }
37677
+ async function unchangedIdentity(agent, signal) {
37678
+ if (!await revalidateExecutable(agent.agentIdentity)) {
37679
+ return false;
37680
+ }
37681
+ signal.throwIfAborted();
37682
+ return agent.kind !== "acp-adapter-process" || await revalidateExecutable(agent.adapterIdentity);
37683
+ }
37684
+
37476
37685
  // src/storage/runtime-installation-store.ts
37477
37686
  import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
37478
37687
  import { mkdir as mkdir5, open as open5, readdir as readdir3, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
37479
- import { dirname as dirname4, join as join16, resolve as resolve4 } from "node:path";
37688
+ import { dirname as dirname4, join as join18, resolve as resolve4 } from "node:path";
37480
37689
  var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
37481
37690
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
37482
37691
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
@@ -37540,7 +37749,7 @@ var VerifiedRuntimeConnection = class {
37540
37749
  this.runtimeId = runtimeId;
37541
37750
  }
37542
37751
  };
37543
- function isRecord9(value) {
37752
+ function isRecord10(value) {
37544
37753
  return typeof value === "object" && value !== null && !Array.isArray(value);
37545
37754
  }
37546
37755
  function hasExactKeys(value, expectedKeys) {
@@ -37613,7 +37822,7 @@ function channelIndexFileName(channelId) {
37613
37822
  return `mci_${createHash4("sha256").update(channelId).digest("hex")}.json`;
37614
37823
  }
37615
37824
  function decodeInstallationPointer(value) {
37616
- if (!isRecord9(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
37825
+ if (!isRecord10(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
37617
37826
  throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
37618
37827
  }
37619
37828
  const storedInstallationId = value["installationId"];
@@ -37623,7 +37832,7 @@ function decodeInstallationPointer(value) {
37623
37832
  return { installationId: validateInstallationId(storedInstallationId) };
37624
37833
  }
37625
37834
  function decodeChannelIndex(value) {
37626
- if (!isRecord9(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
37835
+ if (!isRecord10(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
37627
37836
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
37628
37837
  }
37629
37838
  const applicationId = value["applicationId"];
@@ -37673,7 +37882,7 @@ function decodeVerifiedConnection(value) {
37673
37882
  );
37674
37883
  }
37675
37884
  function decodeConnection(value) {
37676
- if (!isRecord9(value)) {
37885
+ if (!isRecord10(value)) {
37677
37886
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
37678
37887
  }
37679
37888
  return decodeVerifiedConnection(value);
@@ -37719,7 +37928,7 @@ async function readJsonFile(path2, signal, missingCode) {
37719
37928
  async function writeJsonAtomically(path2, value, signal) {
37720
37929
  signal.throwIfAborted();
37721
37930
  const directory = dirname4(path2);
37722
- const temporaryPath = join16(directory, `.${randomUUID3()}.tmp`);
37931
+ const temporaryPath = join18(directory, `.${randomUUID3()}.tmp`);
37723
37932
  try {
37724
37933
  await mkdir5(directory, { mode: 448, recursive: true });
37725
37934
  signal.throwIfAborted();
@@ -37745,14 +37954,14 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37745
37954
  this.applicationId = applicationId;
37746
37955
  this.installationId = installationId2;
37747
37956
  this.stateDirectory = stateDirectory;
37748
- this.#channelDirectory = join16(stateDirectory, "channels");
37749
- this.#connectionDirectory = join16(stateDirectory, "connections");
37957
+ this.#channelDirectory = join18(stateDirectory, "channels");
37958
+ this.#connectionDirectory = join18(stateDirectory, "connections");
37750
37959
  }
37751
37960
  static open = async (options, signal) => {
37752
37961
  signal.throwIfAborted();
37753
37962
  const applicationId = validateApplicationId(options.applicationId);
37754
37963
  const rootDirectory = resolve4(options.stateDirectory);
37755
- const applicationDirectory = join16(rootDirectory, "installations", applicationId);
37964
+ const applicationDirectory = join18(rootDirectory, "installations", applicationId);
37756
37965
  try {
37757
37966
  await mkdir5(applicationDirectory, { mode: 448, recursive: true });
37758
37967
  } catch (cause) {
@@ -37765,7 +37974,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37765
37974
  );
37766
37975
  }
37767
37976
  const storedInstallationId = await readOrCreateInstallationId(applicationDirectory, signal);
37768
- const stateDirectory = join16(applicationDirectory, storedInstallationId);
37977
+ const stateDirectory = join18(applicationDirectory, storedInstallationId);
37769
37978
  try {
37770
37979
  await mkdir5(stateDirectory, { mode: 448, recursive: true });
37771
37980
  } catch (cause) {
@@ -37780,8 +37989,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37780
37989
  signal.throwIfAborted();
37781
37990
  return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
37782
37991
  };
37783
- connectionPath = (connectionId2) => join16(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
37784
- channelIndexPath = (channelId) => join16(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
37992
+ connectionPath = (connectionId2) => join18(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
37993
+ channelIndexPath = (channelId) => join18(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
37785
37994
  readConnection = async (connectionId2, signal) => {
37786
37995
  const stored = decodeConnection(
37787
37996
  await readJsonFile(this.connectionPath(connectionId2), signal, "connection_not_found")
@@ -37943,7 +38152,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37943
38152
  };
37944
38153
  };
37945
38154
  async function readOrCreateInstallationId(applicationDirectory, signal) {
37946
- const pointerPath = join16(applicationDirectory, "current.json");
38155
+ const pointerPath = join18(applicationDirectory, "current.json");
37947
38156
  try {
37948
38157
  return decodeInstallationPointer(await readJsonFile(pointerPath, signal, "installation_not_found")).installationId;
37949
38158
  } catch (cause) {
@@ -37991,7 +38200,7 @@ var PairingClientError = class extends Error {
37991
38200
  this.name = "PairingClientError";
37992
38201
  }
37993
38202
  };
37994
- function isRecord10(value) {
38203
+ function isRecord11(value) {
37995
38204
  return typeof value === "object" && value !== null && !Array.isArray(value);
37996
38205
  }
37997
38206
  function hasExactKeys2(value, expectedKeys) {
@@ -38084,8 +38293,8 @@ async function resolveDefaultWorkspace(path2) {
38084
38293
  const requestedWorkspace = resolve5(path2);
38085
38294
  try {
38086
38295
  await mkdir6(requestedWorkspace, { recursive: true, mode: 448 });
38087
- const defaultWorkspace = await realpath8(requestedWorkspace);
38088
- const metadata = await stat7(defaultWorkspace);
38296
+ const defaultWorkspace = await realpath9(requestedWorkspace);
38297
+ const metadata = await stat8(defaultWorkspace);
38089
38298
  if (!metadata.isDirectory()) {
38090
38299
  throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
38091
38300
  }
@@ -38114,9 +38323,9 @@ async function readJsonResponse(response) {
38114
38323
  }
38115
38324
  }
38116
38325
  function readRelayError(value) {
38117
- if (isRecord10(value)) {
38326
+ if (isRecord11(value)) {
38118
38327
  const error62 = value["error"];
38119
- if (isRecord10(error62)) {
38328
+ if (isRecord11(error62)) {
38120
38329
  const code = error62["code"];
38121
38330
  const message = error62["message"];
38122
38331
  if (typeof code === "string" && typeof message === "string") {
@@ -38127,7 +38336,7 @@ function readRelayError(value) {
38127
38336
  return new PairingClientError("pairing_failed", "The relay could not pair this machine");
38128
38337
  }
38129
38338
  function decodePairingResponse(value, credentialField, expectedKeys) {
38130
- if (!isRecord10(value) || !hasExactKeys2(value, expectedKeys)) {
38339
+ if (!isRecord11(value) || !hasExactKeys2(value, expectedKeys)) {
38131
38340
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
38132
38341
  }
38133
38342
  const appId = value["appId"];
@@ -38152,7 +38361,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
38152
38361
  const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
38153
38362
  let response;
38154
38363
  try {
38155
- response = await fetch2(endpoint, {
38364
+ response = await fetch3(endpoint, {
38156
38365
  body: JSON.stringify({
38157
38366
  agents,
38158
38367
  installableAgents,
@@ -38184,20 +38393,30 @@ function buildPairedDaemon(installation, connection, defaultWorkspace, inventory
38184
38393
  const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
38185
38394
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
38186
38395
  relayUrl.searchParams.set("token", connection.runtimeCredential);
38396
+ const config2 = createDaemonConfig(
38397
+ {
38398
+ defaultWorkspace,
38399
+ channelId: connection.channelId,
38400
+ relayUrl
38401
+ },
38402
+ inventory.readyAgents(),
38403
+ inventory.installable,
38404
+ localContext,
38405
+ new OpaqueDaemonReconnectTarget(connection.connectionId),
38406
+ createCatalogAgentResolver(
38407
+ (refreshSignal) => discoverLocalAgentInventory({
38408
+ defaultWorkspace,
38409
+ environment: localContext.environment,
38410
+ signal: refreshSignal
38411
+ }),
38412
+ () => config2,
38413
+ publishAgentCatalog
38414
+ )
38415
+ );
38187
38416
  return {
38188
38417
  channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
38189
38418
  connectionId: connection.connectionId,
38190
- config: createDaemonConfig(
38191
- {
38192
- defaultWorkspace,
38193
- channelId: connection.channelId,
38194
- relayUrl
38195
- },
38196
- inventory.readyAgents(),
38197
- inventory.installable,
38198
- localContext,
38199
- new OpaqueDaemonReconnectTarget(connection.connectionId)
38200
- ),
38419
+ config: config2,
38201
38420
  connectionPath: installation.connectionPath(connection.connectionId)
38202
38421
  };
38203
38422
  }
@@ -38310,120 +38529,9 @@ function isRuntimeRelayRevocation(closeCode, closeReason) {
38310
38529
 
38311
38530
  // src/run-daemon.ts
38312
38531
  import { createHash as createHash8, randomUUID as randomUUID9 } from "node:crypto";
38313
- import { join as join19 } from "node:path";
38532
+ import { join as join21 } from "node:path";
38314
38533
  import { styleText } from "node:util";
38315
38534
 
38316
- // src/agent-catalog/publish-agent-catalog.ts
38317
- import { fetch as fetch3 } from "undici";
38318
-
38319
- // src/relay-connection/runtime-authentication.ts
38320
- function runtimeCredential(relayUrl) {
38321
- return relayUrl.searchParams.get("token") ?? "";
38322
- }
38323
- function runtimeAuthorization(relayUrl) {
38324
- const credential = runtimeCredential(relayUrl);
38325
- return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
38326
- }
38327
- function relayHttpEndpoint(relayUrl) {
38328
- const endpoint = new URL(relayUrl);
38329
- endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
38330
- endpoint.search = "";
38331
- return endpoint;
38332
- }
38333
-
38334
- // src/agent-catalog/publish-agent-catalog.ts
38335
- var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
38336
- var AgentCatalogPublishError = class extends Error {
38337
- code = "agent_catalog_update_failed";
38338
- diagnosticDetails;
38339
- constructor(message, options = {}, diagnosticDetails = {}) {
38340
- super(message, options);
38341
- this.diagnosticDetails = diagnosticDetails;
38342
- this.name = "AgentCatalogPublishError";
38343
- }
38344
- };
38345
- function isRecord11(value) {
38346
- return typeof value === "object" && value !== null && !Array.isArray(value);
38347
- }
38348
- function isSafeRelayErrorMessage(value) {
38349
- return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
38350
- }
38351
- async function rejectedCatalogError(response) {
38352
- let value;
38353
- try {
38354
- value = await response.json();
38355
- } catch {
38356
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38357
- }
38358
- if (!isRecord11(value) || !isRecord11(value["error"])) {
38359
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38360
- }
38361
- const code = value["error"]["code"];
38362
- const message = value["error"]["message"];
38363
- if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
38364
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38365
- }
38366
- return new AgentCatalogPublishError(
38367
- `The Relay rejected the Agent catalog update (${code}): ${message}`,
38368
- {},
38369
- {
38370
- relayErrorCode: code
38371
- }
38372
- );
38373
- }
38374
- function catalogEndpoint(config2) {
38375
- const endpoint = relayHttpEndpoint(config2.relayUrl);
38376
- if (endpoint.pathname.endsWith("/daemon")) {
38377
- endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
38378
- return endpoint;
38379
- }
38380
- const runtimePath = "/v1/runtimes/connect";
38381
- if (endpoint.pathname.endsWith(runtimePath)) {
38382
- endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
38383
- return endpoint;
38384
- }
38385
- throw new AgentCatalogPublishError("The Relay URL is invalid");
38386
- }
38387
- async function publishAgentCatalog(config2, signal) {
38388
- signal.throwIfAborted();
38389
- const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
38390
- const requestSignal = AbortSignal.any([signal, timeoutSignal]);
38391
- let response;
38392
- const catalog = config2.catalog.read();
38393
- try {
38394
- response = await fetch3(catalogEndpoint(config2), {
38395
- body: JSON.stringify({
38396
- agents: catalog.agents.map((agent) => ({
38397
- agentPath: agent.agentIdentity.requestedPath,
38398
- agentVersion: agent.agentVersion,
38399
- agentSettingsDiscovery: true,
38400
- capabilities: agent.capabilities,
38401
- id: agent.id,
38402
- label: agent.label,
38403
- sessionTurnConfiguration: true
38404
- })),
38405
- installableAgents: catalog.installableAgents
38406
- }),
38407
- dispatcher: environmentProxyDispatcher,
38408
- headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
38409
- method: "PUT",
38410
- signal: requestSignal
38411
- });
38412
- } catch (error62) {
38413
- if (signal.aborted) {
38414
- signal.throwIfAborted();
38415
- }
38416
- throw new AgentCatalogPublishError(
38417
- timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
38418
- { cause: error62 }
38419
- );
38420
- }
38421
- if (!response.ok) {
38422
- throw await rejectedCatalogError(response);
38423
- }
38424
- await response.body?.cancel();
38425
- }
38426
-
38427
38535
  // src/agent-installation/agent-installation-manager.ts
38428
38536
  var INSTALLATION_DEADLINE_MILLISECONDS = 10 * 60 * 1e3;
38429
38537
  var AgentInstallation = class {
@@ -38886,9 +38994,9 @@ var FixedInstallationExecutor = class {
38886
38994
  };
38887
38995
 
38888
38996
  // src/authorization/workspace-directory.ts
38889
- import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
38997
+ import { readdir as readdir4, realpath as realpath10, stat as stat9 } from "node:fs/promises";
38890
38998
  import { homedir as homedir2 } from "node:os";
38891
- import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute10, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
38999
+ import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute10, join as join19, normalize as normalize3, relative as relative4 } from "node:path";
38892
39000
  var WorkspaceDirectoryListing = class {
38893
39001
  directoryId;
38894
39002
  directoryLabel;
@@ -38956,9 +39064,9 @@ var WorkspaceDirectoryService = class {
38956
39064
  throw new LocalAuthorizationError("The local directory path is invalid");
38957
39065
  }
38958
39066
  try {
38959
- const target = await realpath9(requested);
39067
+ const target = await realpath10(requested);
38960
39068
  signal.throwIfAborted();
38961
- const metadata = await stat8(target);
39069
+ const metadata = await stat9(target);
38962
39070
  signal.throwIfAborted();
38963
39071
  if (!isAbsolute10(target) || normalize3(target) !== target || !metadata.isDirectory()) {
38964
39072
  throw new LocalAuthorizationError("The selected location is not a directory");
@@ -39006,7 +39114,7 @@ var WorkspaceDirectoryService = class {
39006
39114
  continue;
39007
39115
  }
39008
39116
  try {
39009
- const path2 = await this.resolvePath(join17(target, child2.name), signal);
39117
+ const path2 = await this.resolvePath(join19(target, child2.name), signal);
39010
39118
  entries.push({ directoryId: encodePath(path2), name: child2.name });
39011
39119
  } catch (cause) {
39012
39120
  signal.throwIfAborted();
@@ -39042,15 +39150,15 @@ var WorkspaceDirectoryService = class {
39042
39150
 
39043
39151
  // src/daemon-diagnostic-log.ts
39044
39152
  import { appendFileSync, mkdirSync, readFileSync as readFileSync2, renameSync, statSync as statSync3, writeFileSync } from "node:fs";
39045
- import { join as join18 } from "node:path";
39153
+ import { join as join20 } from "node:path";
39046
39154
  var MAXIMUM_DAEMON_LOG_BYTES = 1 * 1024 * 1024;
39047
39155
  var DaemonDiagnosticLog = class {
39048
39156
  #directory;
39049
39157
  #path;
39050
39158
  #maximumBytes;
39051
39159
  constructor(stateDirectory, maximumBytes = MAXIMUM_DAEMON_LOG_BYTES) {
39052
- this.#directory = join18(stateDirectory, "logs");
39053
- this.#path = join18(this.#directory, "daemon.log");
39160
+ this.#directory = join20(stateDirectory, "logs");
39161
+ this.#path = join20(this.#directory, "daemon.log");
39054
39162
  this.#maximumBytes = maximumBytes;
39055
39163
  }
39056
39164
  // Export only correlation and failure metadata. Local messages and paths stay local.
@@ -40995,9 +41103,10 @@ var NativeSessionService = class {
40995
41103
  signal
40996
41104
  );
40997
41105
  signal.throwIfAborted();
41106
+ const cataloged = this.#config.catalog.find(command.agentId);
40998
41107
  const options = {
40999
41108
  additionalDirectories,
41000
- agent: this.#config.catalog.find(command.agentId),
41109
+ agent: this.#config.resolveAgent === void 0 ? cataloged : await this.#config.resolveAgent(cataloged, signal),
41001
41110
  cwd,
41002
41111
  sessionId: command.sessionId,
41003
41112
  signal
@@ -41175,7 +41284,7 @@ var NativeSessionService = class {
41175
41284
  sessionId: command.targetSessionId,
41176
41285
  additionalDirectories: target.additionalDirectories
41177
41286
  },
41178
- action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId }
41287
+ action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId, title: title2 }
41179
41288
  );
41180
41289
  signal.throwIfAborted();
41181
41290
  const ready = {
@@ -41549,7 +41658,7 @@ import { WebSocket as WebSocket5 } from "undici";
41549
41658
  // package.json
41550
41659
  var package_default = {
41551
41660
  name: "@moxt-ai/mobius",
41552
- version: "0.0.193",
41661
+ version: "0.0.194",
41553
41662
  description: "Mobius CLI for pairing and running local AI agent services.",
41554
41663
  type: "module",
41555
41664
  bin: {
@@ -41852,7 +41961,8 @@ function unsupportedModelIds(unsupportedModels) {
41852
41961
  return [...new Set(unsupportedModels.map((item) => item.requestedValue))];
41853
41962
  }
41854
41963
  async function discoverAgentSettings(command, config2, directories, sessions, signal) {
41855
- const agent = config2.catalog.find(command.agentId);
41964
+ const cataloged = config2.catalog.find(command.agentId);
41965
+ const agent = config2.resolveAgent === void 0 ? cataloged : await config2.resolveAgent(cataloged, signal);
41856
41966
  const cwd = await directories.resolve(config2.bindingId, "default", signal);
41857
41967
  const inspectedBaseSnapshot = await sessions.inspectAgentSettings({
41858
41968
  additionalDirectories: [],
@@ -42246,7 +42356,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
42246
42356
 
42247
42357
  // src/artifacts/local-file-streamer.ts
42248
42358
  import { createReadStream as createReadStream2 } from "node:fs";
42249
- import { realpath as realpath10, stat as stat9 } from "node:fs/promises";
42359
+ import { realpath as realpath11, stat as stat10 } from "node:fs/promises";
42250
42360
  import { basename as basename5, extname, isAbsolute as isAbsolute11, normalize as normalize4, resolve as resolve7 } from "node:path";
42251
42361
  import { fileURLToPath as fileURLToPath2 } from "node:url";
42252
42362
  var CHUNK_BYTES = 192 * 1024;
@@ -42274,7 +42384,7 @@ async function resolveFile(value, workingDirectory, signal) {
42274
42384
  return null;
42275
42385
  }
42276
42386
  try {
42277
- const target = await realpath10(requested);
42387
+ const target = await realpath11(requested);
42278
42388
  signal.throwIfAborted();
42279
42389
  return isAbsolute11(target) && normalize4(target) === target ? target : null;
42280
42390
  } catch {
@@ -42288,7 +42398,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
42288
42398
  if (target === null) {
42289
42399
  throw new Error("The local file is unavailable");
42290
42400
  }
42291
- const before = await stat9(target);
42401
+ const before = await stat10(target);
42292
42402
  signal.throwIfAborted();
42293
42403
  if (!before.isFile() || before.size < 1 || before.size > command.maxBytes) {
42294
42404
  throw new Error("The local file is too large to read");
@@ -42316,7 +42426,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
42316
42426
  });
42317
42427
  sequence += 1;
42318
42428
  }
42319
- const after = await stat9(target);
42429
+ const after = await stat10(target);
42320
42430
  signal.throwIfAborted();
42321
42431
  if (after.size !== before.size || after.mtimeMs !== before.mtimeMs) {
42322
42432
  throw new Error("The local file changed during transfer");
@@ -42360,6 +42470,232 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
42360
42470
  return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
42361
42471
  }
42362
42472
 
42473
+ // src/daemon-session-commands.ts
42474
+ async function resolveCatalogAgent(config2, agentId, signal) {
42475
+ const agent = config2.catalog.find(agentId);
42476
+ return config2.resolveAgent === void 0 ? agent : await config2.resolveAgent(agent, signal);
42477
+ }
42478
+ async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
42479
+ return await metrics.measure("prepare-total", async () => {
42480
+ const resolved = await metrics.measure(
42481
+ "workspace-resolve",
42482
+ async () => await resolveSessionDirectories(
42483
+ directories,
42484
+ config2.bindingId,
42485
+ command.directoryId,
42486
+ command.additionalDirectoryIds,
42487
+ signal
42488
+ )
42489
+ );
42490
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
42491
+ const preparation = {
42492
+ additionalDirectories: resolved.additionalDirectories,
42493
+ agent,
42494
+ cwd: resolved.cwd,
42495
+ sessionId: command.sessionId,
42496
+ signal
42497
+ };
42498
+ const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
42499
+ const configuration = command.configuration;
42500
+ const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
42501
+ "configuration",
42502
+ async () => await sessions.configureSession({
42503
+ ...preparation,
42504
+ booleanValue: configuration.booleanValue,
42505
+ configId: configuration.configId,
42506
+ requestId: command.requestId,
42507
+ value: configuration.value,
42508
+ valueType: configuration.valueType
42509
+ })
42510
+ );
42511
+ const listing = await metrics.measure(
42512
+ "workspace-list",
42513
+ async () => await directories.list(config2.bindingId, command.directoryId, signal)
42514
+ );
42515
+ audit.record({
42516
+ commandId: command.requestId,
42517
+ event: "session_prepared",
42518
+ sessionId: command.sessionId
42519
+ });
42520
+ if (command.configuration !== void 0) {
42521
+ audit.record({
42522
+ commandId: command.requestId,
42523
+ event: "session_configured",
42524
+ sessionId: command.sessionId
42525
+ });
42526
+ }
42527
+ return {
42528
+ additionalDirectories: resolved.additionalDirectoryEntries,
42529
+ agentId: command.agentId,
42530
+ agentName: prepared.agentName,
42531
+ agentVersion: prepared.agentVersion,
42532
+ capabilities: prepared.capabilities,
42533
+ commands: prepared.commands,
42534
+ configOptions,
42535
+ directoryId: command.directoryId,
42536
+ directoryLabel: listing.directoryLabel,
42537
+ kind: "session.ready",
42538
+ requestId: command.requestId,
42539
+ restored: prepared.restored,
42540
+ sessionId: command.sessionId
42541
+ };
42542
+ });
42543
+ }
42544
+ async function executeWorkspaceList(socket, command, directories, audit, signal) {
42545
+ try {
42546
+ const listing = await directories.list(command.bindingId, command.directoryId, signal);
42547
+ audit.record({
42548
+ commandId: command.requestId,
42549
+ event: "workspace_list_authorized",
42550
+ sessionId: "workspace-browser"
42551
+ });
42552
+ send(socket, {
42553
+ bindingId: command.bindingId,
42554
+ directoryId: listing.directoryId,
42555
+ directoryLabel: listing.directoryLabel,
42556
+ entries: listing.entries,
42557
+ kind: "workspace.entries",
42558
+ parentDirectoryId: listing.parentDirectoryId,
42559
+ requestId: command.requestId
42560
+ });
42561
+ } catch (error62) {
42562
+ reportOperationFailure(socket, command.requestId, "", error62);
42563
+ }
42564
+ }
42565
+ async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
42566
+ const metrics = new AccumulatingOperationMetrics();
42567
+ try {
42568
+ const readyEvent = await prepareSession(
42569
+ command,
42570
+ { kind: "interactive-only" },
42571
+ config2,
42572
+ directories,
42573
+ audit,
42574
+ sessions,
42575
+ metrics,
42576
+ signal
42577
+ );
42578
+ send(socket, {
42579
+ ...readyEvent,
42580
+ runtimeTimings: metrics.snapshot()
42581
+ });
42582
+ } catch (error62) {
42583
+ diagnostics.daemonDiagnostic(
42584
+ "session_prepare_failed",
42585
+ command.requestId,
42586
+ {
42587
+ agentId: command.agentId,
42588
+ code: operationErrorCode(error62),
42589
+ sessionId: command.sessionId
42590
+ },
42591
+ error62
42592
+ );
42593
+ audit.record({
42594
+ commandId: command.requestId,
42595
+ details: {
42596
+ agentId: command.agentId,
42597
+ code: operationErrorCode(error62)
42598
+ },
42599
+ event: "session_prepare_failed",
42600
+ sessionId: command.sessionId
42601
+ });
42602
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42603
+ }
42604
+ }
42605
+ async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
42606
+ const metrics = new AccumulatingOperationMetrics();
42607
+ try {
42608
+ const entry = await metrics.measure("session-lookup", async () => {
42609
+ const [found] = await nativeSessions.querySessions([command.sessionId], signal);
42610
+ if (found === void 0) {
42611
+ throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
42612
+ }
42613
+ return found;
42614
+ });
42615
+ const ready = await prepareSession(
42616
+ {
42617
+ additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
42618
+ agentId: entry.agentId,
42619
+ bindingId: config2.bindingId,
42620
+ directoryId: entry.directoryId,
42621
+ kind: "session.prepare",
42622
+ requestId: command.requestId,
42623
+ sessionId: command.sessionId,
42624
+ sessionState: "provisioned"
42625
+ },
42626
+ { kind: "history-required" },
42627
+ config2,
42628
+ directories,
42629
+ audit,
42630
+ sessions,
42631
+ metrics,
42632
+ signal
42633
+ );
42634
+ send(socket, {
42635
+ entry,
42636
+ kind: "session.restored",
42637
+ ready: { ...ready, runtimeTimings: metrics.snapshot() },
42638
+ requestId: command.requestId
42639
+ });
42640
+ } catch (error62) {
42641
+ diagnostics.daemonDiagnostic(
42642
+ "session_restore_failed",
42643
+ command.requestId,
42644
+ {
42645
+ code: operationErrorCode(error62),
42646
+ sessionId: command.sessionId
42647
+ },
42648
+ error62
42649
+ );
42650
+ audit.record({
42651
+ commandId: command.requestId,
42652
+ details: { code: operationErrorCode(error62) },
42653
+ event: "session_restore_failed",
42654
+ sessionId: command.sessionId
42655
+ });
42656
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42657
+ }
42658
+ }
42659
+ async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
42660
+ try {
42661
+ const resolved = await resolveSessionDirectories(
42662
+ directories,
42663
+ config2.bindingId,
42664
+ command.directoryId,
42665
+ command.additionalDirectoryIds,
42666
+ signal
42667
+ );
42668
+ const configOptions = await sessions.configureSession({
42669
+ additionalDirectories: resolved.additionalDirectories,
42670
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
42671
+ booleanValue: command.booleanValue,
42672
+ configId: command.configId,
42673
+ cwd: resolved.cwd,
42674
+ requestId: command.requestId,
42675
+ sessionId: command.sessionId,
42676
+ signal,
42677
+ value: command.value,
42678
+ valueType: command.valueType
42679
+ });
42680
+ audit.record({
42681
+ commandId: command.requestId,
42682
+ event: "session_configured",
42683
+ sessionId: command.sessionId
42684
+ });
42685
+ send(socket, {
42686
+ configOptions,
42687
+ kind: "session.config.updated",
42688
+ requestId: command.requestId,
42689
+ sessionId: command.sessionId
42690
+ });
42691
+ } catch (error62) {
42692
+ if (signal.aborted) {
42693
+ signal.throwIfAborted();
42694
+ }
42695
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62);
42696
+ }
42697
+ }
42698
+
42363
42699
  // src/daemon-history-commands.ts
42364
42700
  async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, directories, audit, diagnostics, sessions, nativeSessions, eventLogV2, signal) {
42365
42701
  let agentId;
@@ -42378,7 +42714,7 @@ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, dir
42378
42714
  );
42379
42715
  const loadOptions = {
42380
42716
  additionalDirectories: resolved.additionalDirectories,
42381
- agent: config2.catalog.find(entry.agentId),
42717
+ agent: await resolveCatalogAgent(config2, entry.agentId, signal),
42382
42718
  cwd: resolved.cwd,
42383
42719
  sessionId: command.sessionId,
42384
42720
  signal
@@ -42454,7 +42790,7 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, di
42454
42790
  const replay = await sessions.previewNativeSessionEventsV2(
42455
42791
  {
42456
42792
  additionalDirectories: resolved.additionalDirectories,
42457
- agent: config2.catalog.find(command.agentId),
42793
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
42458
42794
  cwd: resolved.cwd,
42459
42795
  sessionId: command.sessionId,
42460
42796
  signal
@@ -42746,7 +43082,7 @@ async function executePrompt({
42746
43082
  command.additionalDirectoryIds,
42747
43083
  signal
42748
43084
  );
42749
- const agent = config2.catalog.find(command.agentId);
43085
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
42750
43086
  const availability = await waitForSessionAvailability(signal);
42751
43087
  if (availability.kind === "busy") {
42752
43088
  throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
@@ -42891,228 +43227,6 @@ async function executePrompt({
42891
43227
  }
42892
43228
  }
42893
43229
 
42894
- // src/daemon-session-commands.ts
42895
- async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
42896
- return await metrics.measure("prepare-total", async () => {
42897
- const resolved = await metrics.measure(
42898
- "workspace-resolve",
42899
- async () => await resolveSessionDirectories(
42900
- directories,
42901
- config2.bindingId,
42902
- command.directoryId,
42903
- command.additionalDirectoryIds,
42904
- signal
42905
- )
42906
- );
42907
- const agent = config2.catalog.find(command.agentId);
42908
- const preparation = {
42909
- additionalDirectories: resolved.additionalDirectories,
42910
- agent,
42911
- cwd: resolved.cwd,
42912
- sessionId: command.sessionId,
42913
- signal
42914
- };
42915
- const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
42916
- const configuration = command.configuration;
42917
- const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
42918
- "configuration",
42919
- async () => await sessions.configureSession({
42920
- ...preparation,
42921
- booleanValue: configuration.booleanValue,
42922
- configId: configuration.configId,
42923
- requestId: command.requestId,
42924
- value: configuration.value,
42925
- valueType: configuration.valueType
42926
- })
42927
- );
42928
- const listing = await metrics.measure(
42929
- "workspace-list",
42930
- async () => await directories.list(config2.bindingId, command.directoryId, signal)
42931
- );
42932
- audit.record({
42933
- commandId: command.requestId,
42934
- event: "session_prepared",
42935
- sessionId: command.sessionId
42936
- });
42937
- if (command.configuration !== void 0) {
42938
- audit.record({
42939
- commandId: command.requestId,
42940
- event: "session_configured",
42941
- sessionId: command.sessionId
42942
- });
42943
- }
42944
- return {
42945
- additionalDirectories: resolved.additionalDirectoryEntries,
42946
- agentId: command.agentId,
42947
- agentName: prepared.agentName,
42948
- agentVersion: prepared.agentVersion,
42949
- capabilities: prepared.capabilities,
42950
- commands: prepared.commands,
42951
- configOptions,
42952
- directoryId: command.directoryId,
42953
- directoryLabel: listing.directoryLabel,
42954
- kind: "session.ready",
42955
- requestId: command.requestId,
42956
- restored: prepared.restored,
42957
- sessionId: command.sessionId
42958
- };
42959
- });
42960
- }
42961
- async function executeWorkspaceList(socket, command, directories, audit, signal) {
42962
- try {
42963
- const listing = await directories.list(command.bindingId, command.directoryId, signal);
42964
- audit.record({
42965
- commandId: command.requestId,
42966
- event: "workspace_list_authorized",
42967
- sessionId: "workspace-browser"
42968
- });
42969
- send(socket, {
42970
- bindingId: command.bindingId,
42971
- directoryId: listing.directoryId,
42972
- directoryLabel: listing.directoryLabel,
42973
- entries: listing.entries,
42974
- kind: "workspace.entries",
42975
- parentDirectoryId: listing.parentDirectoryId,
42976
- requestId: command.requestId
42977
- });
42978
- } catch (error62) {
42979
- reportOperationFailure(socket, command.requestId, "", error62);
42980
- }
42981
- }
42982
- async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
42983
- const metrics = new AccumulatingOperationMetrics();
42984
- try {
42985
- const readyEvent = await prepareSession(
42986
- command,
42987
- { kind: "interactive-only" },
42988
- config2,
42989
- directories,
42990
- audit,
42991
- sessions,
42992
- metrics,
42993
- signal
42994
- );
42995
- send(socket, {
42996
- ...readyEvent,
42997
- runtimeTimings: metrics.snapshot()
42998
- });
42999
- } catch (error62) {
43000
- diagnostics.daemonDiagnostic(
43001
- "session_prepare_failed",
43002
- command.requestId,
43003
- {
43004
- agentId: command.agentId,
43005
- code: operationErrorCode(error62),
43006
- sessionId: command.sessionId
43007
- },
43008
- error62
43009
- );
43010
- audit.record({
43011
- commandId: command.requestId,
43012
- details: {
43013
- agentId: command.agentId,
43014
- code: operationErrorCode(error62)
43015
- },
43016
- event: "session_prepare_failed",
43017
- sessionId: command.sessionId
43018
- });
43019
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
43020
- }
43021
- }
43022
- async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
43023
- const metrics = new AccumulatingOperationMetrics();
43024
- try {
43025
- const entry = await metrics.measure("session-lookup", async () => {
43026
- const [found] = await nativeSessions.querySessions([command.sessionId], signal);
43027
- if (found === void 0) {
43028
- throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
43029
- }
43030
- return found;
43031
- });
43032
- const ready = await prepareSession(
43033
- {
43034
- additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
43035
- agentId: entry.agentId,
43036
- bindingId: config2.bindingId,
43037
- directoryId: entry.directoryId,
43038
- kind: "session.prepare",
43039
- requestId: command.requestId,
43040
- sessionId: command.sessionId,
43041
- sessionState: "provisioned"
43042
- },
43043
- { kind: "history-required" },
43044
- config2,
43045
- directories,
43046
- audit,
43047
- sessions,
43048
- metrics,
43049
- signal
43050
- );
43051
- send(socket, {
43052
- entry,
43053
- kind: "session.restored",
43054
- ready: { ...ready, runtimeTimings: metrics.snapshot() },
43055
- requestId: command.requestId
43056
- });
43057
- } catch (error62) {
43058
- diagnostics.daemonDiagnostic(
43059
- "session_restore_failed",
43060
- command.requestId,
43061
- {
43062
- code: operationErrorCode(error62),
43063
- sessionId: command.sessionId
43064
- },
43065
- error62
43066
- );
43067
- audit.record({
43068
- commandId: command.requestId,
43069
- details: { code: operationErrorCode(error62) },
43070
- event: "session_restore_failed",
43071
- sessionId: command.sessionId
43072
- });
43073
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
43074
- }
43075
- }
43076
- async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
43077
- try {
43078
- const resolved = await resolveSessionDirectories(
43079
- directories,
43080
- config2.bindingId,
43081
- command.directoryId,
43082
- command.additionalDirectoryIds,
43083
- signal
43084
- );
43085
- const configOptions = await sessions.configureSession({
43086
- additionalDirectories: resolved.additionalDirectories,
43087
- agent: config2.catalog.find(command.agentId),
43088
- booleanValue: command.booleanValue,
43089
- configId: command.configId,
43090
- cwd: resolved.cwd,
43091
- requestId: command.requestId,
43092
- sessionId: command.sessionId,
43093
- signal,
43094
- value: command.value,
43095
- valueType: command.valueType
43096
- });
43097
- audit.record({
43098
- commandId: command.requestId,
43099
- event: "session_configured",
43100
- sessionId: command.sessionId
43101
- });
43102
- send(socket, {
43103
- configOptions,
43104
- kind: "session.config.updated",
43105
- requestId: command.requestId,
43106
- sessionId: command.sessionId
43107
- });
43108
- } catch (error62) {
43109
- if (signal.aborted) {
43110
- signal.throwIfAborted();
43111
- }
43112
- reportOperationFailure(socket, command.requestId, command.sessionId, error62);
43113
- }
43114
- }
43115
-
43116
43230
  // src/native-sessions/handle-native-requests.ts
43117
43231
  import { WebSocket as WebSocket4 } from "undici";
43118
43232
  function createNativeSessionRequestHandler(dependencies) {
@@ -44285,11 +44399,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
44285
44399
  stateDirectory
44286
44400
  });
44287
44401
  const channelHash = createHash8("sha256").update(config2.channelId).digest("hex");
44288
- const sessionDatabase = openAcpSessionDatabase(join19(stateDirectory, "sessions", `${channelHash}.sqlite`));
44402
+ const sessionDatabase = openAcpSessionDatabase(join21(stateDirectory, "sessions", `${channelHash}.sqlite`));
44289
44403
  let eventsV2;
44290
44404
  try {
44291
44405
  eventsV2 = new CachedAcpSessionEventStoreV2(
44292
- openSessionEventCacheV2Database(join19(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
44406
+ openSessionEventCacheV2Database(join21(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
44293
44407
  );
44294
44408
  } catch (error62) {
44295
44409
  sessionDatabase.close();
@@ -44492,7 +44606,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
44492
44606
  }
44493
44607
 
44494
44608
  // src/runtime.ts
44495
- import { mkdir as mkdir7, realpath as realpath11, stat as stat10 } from "node:fs/promises";
44609
+ import { mkdir as mkdir7, realpath as realpath12, stat as stat11 } from "node:fs/promises";
44496
44610
  import { resolve as resolve8 } from "node:path";
44497
44611
  var RUNTIME_CREDENTIAL_PATTERN2 = /^[a-zA-Z0-9_-]{32,256}$/;
44498
44612
  var MobiusRuntimeConfigurationError = class extends Error {
@@ -44559,8 +44673,8 @@ async function resolveWorkspace(path2) {
44559
44673
  const requested = resolve8(path2);
44560
44674
  try {
44561
44675
  await mkdir7(requested, { recursive: true, mode: 448 });
44562
- const resolved = await realpath11(requested);
44563
- const metadata = await stat10(resolved);
44676
+ const resolved = await realpath12(requested);
44677
+ const metadata = await stat11(resolved);
44564
44678
  if (!metadata.isDirectory()) {
44565
44679
  throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
44566
44680
  }
@@ -44577,26 +44691,35 @@ async function createMobiusRuntimeEngine(connection, signal, environment = proce
44577
44691
  const localContext = new DaemonLocalContext(readStateDirectory(environment), environment);
44578
44692
  const relayUrl = relayUrlFromConnection(connection);
44579
44693
  const defaultWorkspace = await resolveWorkspace(connection.defaultWorkspace);
44580
- const inventory = await discoverLocalAgentInventory({
44694
+ const specifications = supportedLocalAgentSpecifications();
44695
+ const discoveryEnvironment = localContext.environment;
44696
+ const discover = async (refreshSignal) => await discoverLocalAgentInventory({
44581
44697
  defaultWorkspace,
44582
- environment: localContext.environment,
44583
- signal
44698
+ environment: discoveryEnvironment,
44699
+ signal: refreshSignal,
44700
+ specifications
44584
44701
  });
44702
+ const inventory = await discover(signal);
44585
44703
  if (inventory.available.length + inventory.installable.length === 0) {
44586
44704
  throw new MobiusRuntimeConfigurationError("No supported Agent is available for the local Runtime");
44587
44705
  }
44588
- return new MobiusRuntimeEngine(
44589
- createDaemonConfig(
44590
- {
44591
- channelId: connection.channelId,
44592
- defaultWorkspace,
44593
- relayUrl
44594
- },
44595
- inventory.readyAgents(),
44596
- inventory.installable,
44597
- localContext
44706
+ const config2 = createDaemonConfig(
44707
+ {
44708
+ channelId: connection.channelId,
44709
+ defaultWorkspace,
44710
+ relayUrl
44711
+ },
44712
+ inventory.readyAgents(),
44713
+ inventory.installable,
44714
+ localContext,
44715
+ null,
44716
+ createCatalogAgentResolver(
44717
+ (refreshSignal) => discover(refreshSignal),
44718
+ () => config2,
44719
+ publishAgentCatalog
44598
44720
  )
44599
44721
  );
44722
+ return new MobiusRuntimeEngine(config2);
44600
44723
  }
44601
44724
  var MobiusRuntimeEngine = class {
44602
44725
  #config;