@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/runtime.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/runtime.ts
8
- import { mkdir as mkdir7, realpath as realpath11, stat as stat10 } from "node:fs/promises";
8
+ import { mkdir as mkdir7, realpath as realpath12, stat as stat11 } from "node:fs/promises";
9
9
  import { resolve as resolve8 } from "node:path";
10
10
 
11
11
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
@@ -21796,15 +21796,266 @@ function normalizeAcpCapabilities(initialized) {
21796
21796
  }
21797
21797
 
21798
21798
  // src/process/executable.ts
21799
- import { execFile, spawn } from "node:child_process";
21799
+ import { spawn } from "node:child_process";
21800
+ import { constants as constants2 } from "node:fs";
21801
+ import { access as access2, realpath as realpath2, stat as stat2 } from "node:fs/promises";
21802
+ import { join as join3, resolve } from "node:path";
21803
+
21804
+ // src/platform/linux.ts
21800
21805
  import { constants, readdirSync, readFileSync } from "node:fs";
21801
21806
  import { access, readdir, readFile, realpath, stat } from "node:fs/promises";
21802
- import { join, resolve } from "node:path";
21807
+ import { join } from "node:path";
21808
+
21809
+ // src/platform/posix.ts
21810
+ import { execFile } from "node:child_process";
21811
+ var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21812
+ var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21813
+ function parseProcessTable(output2) {
21814
+ const entries = [];
21815
+ for (const line of output2.split("\n")) {
21816
+ const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21817
+ if (groups === void 0) {
21818
+ continue;
21819
+ }
21820
+ const processId = Number(groups["pid"]);
21821
+ const parentProcessId = Number(groups["ppid"]);
21822
+ const processGroupId = Number(groups["pgid"]);
21823
+ if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21824
+ continue;
21825
+ }
21826
+ entries.push({ parentProcessId, processGroupId, processId });
21827
+ }
21828
+ return entries;
21829
+ }
21830
+ function readProcessTableWithPs(executable) {
21831
+ return new Promise((resolveTable) => {
21832
+ execFile(
21833
+ executable,
21834
+ ["-axo", "pid=,ppid=,pgid="],
21835
+ {
21836
+ encoding: "utf8",
21837
+ maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
21838
+ signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
21839
+ timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
21840
+ },
21841
+ (error62, stdout) => {
21842
+ resolveTable(error62 === null ? parseProcessTable(stdout) : []);
21843
+ }
21844
+ );
21845
+ });
21846
+ }
21847
+ function processExists(processId) {
21848
+ try {
21849
+ process.kill(processId, 0);
21850
+ return true;
21851
+ } catch {
21852
+ return false;
21853
+ }
21854
+ }
21855
+
21856
+ // src/platform/linux.ts
21857
+ function appendLinuxProcessTableEntry(entries, processId, encoded) {
21858
+ const closingParenthesis = encoded.lastIndexOf(")");
21859
+ if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21860
+ return;
21861
+ }
21862
+ const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21863
+ const parentProcessId = Number(fields[1]);
21864
+ const processGroupId = Number(fields[2]);
21865
+ if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21866
+ return;
21867
+ }
21868
+ entries.push({ parentProcessId, processGroupId, processId });
21869
+ }
21870
+ async function readLinuxProcessTable() {
21871
+ const entries = [];
21872
+ try {
21873
+ const directories = await readdir("/proc", { withFileTypes: true });
21874
+ for (const directory of directories) {
21875
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21876
+ continue;
21877
+ }
21878
+ const processId = Number(directory.name);
21879
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21880
+ continue;
21881
+ }
21882
+ try {
21883
+ appendLinuxProcessTableEntry(
21884
+ entries,
21885
+ processId,
21886
+ await readFile(join("/proc", directory.name, "stat"), "utf8")
21887
+ );
21888
+ } catch {
21889
+ }
21890
+ }
21891
+ } catch {
21892
+ }
21893
+ return entries;
21894
+ }
21895
+ function readLinuxProcessTableSynchronously() {
21896
+ const entries = [];
21897
+ try {
21898
+ const directories = readdirSync("/proc", { withFileTypes: true });
21899
+ for (const directory of directories) {
21900
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21901
+ continue;
21902
+ }
21903
+ const processId = Number(directory.name);
21904
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21905
+ continue;
21906
+ }
21907
+ try {
21908
+ appendLinuxProcessTableEntry(
21909
+ entries,
21910
+ processId,
21911
+ readFileSync(join("/proc", directory.name, "stat"), "utf8")
21912
+ );
21913
+ } catch {
21914
+ }
21915
+ }
21916
+ } catch {
21917
+ }
21918
+ return entries;
21919
+ }
21920
+ async function readLinuxProcessTableWithFallback() {
21921
+ const procfsEntries = await readLinuxProcessTable();
21922
+ if (procfsEntries.length > 0) {
21923
+ return procfsEntries;
21924
+ }
21925
+ for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
21926
+ try {
21927
+ const resolvedPath = await realpath(candidate);
21928
+ if (!(await stat(resolvedPath)).isFile()) {
21929
+ continue;
21930
+ }
21931
+ await access(resolvedPath, constants.X_OK);
21932
+ } catch {
21933
+ continue;
21934
+ }
21935
+ const entries = await readProcessTableWithPs(candidate);
21936
+ if (entries.length > 0) {
21937
+ return entries;
21938
+ }
21939
+ }
21940
+ return [];
21941
+ }
21942
+ function processExists2(processId) {
21943
+ try {
21944
+ const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
21945
+ const closingParenthesis = encoded.lastIndexOf(")");
21946
+ if (closingParenthesis >= 0) {
21947
+ const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
21948
+ if (processState === "Z" || processState === "X") {
21949
+ return false;
21950
+ }
21951
+ }
21952
+ } catch {
21953
+ }
21954
+ return processExists(processId);
21955
+ }
21956
+ var linuxPlatform = {
21957
+ readProcessTable: readLinuxProcessTableWithFallback,
21958
+ readProcessTableSynchronously: readLinuxProcessTableSynchronously,
21959
+ processExists: processExists2,
21960
+ workBuddyExecutablePaths: () => [],
21961
+ openCodeArchives: {
21962
+ arm64: {
21963
+ asset: "opencode-linux-arm64.tar.gz",
21964
+ sha256: "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
21965
+ format: "tar.gz"
21966
+ },
21967
+ x64: {
21968
+ asset: "opencode-linux-x64.tar.gz",
21969
+ sha256: "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
21970
+ format: "tar.gz"
21971
+ }
21972
+ },
21973
+ grokDependencies: {
21974
+ arm64: {
21975
+ name: "@xai-official/grok-linux-arm64",
21976
+ integrity: "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
21977
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
21978
+ },
21979
+ x64: {
21980
+ name: "@xai-official/grok-linux-x64",
21981
+ integrity: "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
21982
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
21983
+ }
21984
+ }
21985
+ };
21986
+
21987
+ // src/platform/macos.ts
21988
+ import { isAbsolute, join as join2 } from "node:path";
21989
+ var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
21990
+ "WorkBuddy.app",
21991
+ "Contents",
21992
+ "Resources",
21993
+ "app.asar.unpacked",
21994
+ "cli",
21995
+ "bin",
21996
+ "codebuddy"
21997
+ ]);
21998
+ var macosPlatform = {
21999
+ readProcessTable: () => readProcessTableWithPs("/bin/ps"),
22000
+ readProcessTableSynchronously: () => [],
22001
+ processExists,
22002
+ workBuddyExecutablePaths: (environment) => {
22003
+ const paths = [join2("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
22004
+ const homeDirectory = environment["HOME"];
22005
+ if (homeDirectory !== void 0 && isAbsolute(homeDirectory)) {
22006
+ paths.unshift(join2(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
22007
+ }
22008
+ return paths;
22009
+ },
22010
+ openCodeArchives: {
22011
+ arm64: {
22012
+ asset: "opencode-darwin-arm64.zip",
22013
+ sha256: "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
22014
+ format: "zip"
22015
+ },
22016
+ x64: {
22017
+ asset: "opencode-darwin-x64.zip",
22018
+ sha256: "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
22019
+ format: "zip"
22020
+ }
22021
+ },
22022
+ grokDependencies: {
22023
+ arm64: {
22024
+ name: "@xai-official/grok-darwin-arm64",
22025
+ integrity: "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
22026
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
22027
+ },
22028
+ x64: {
22029
+ name: "@xai-official/grok-darwin-x64",
22030
+ integrity: "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
22031
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
22032
+ }
22033
+ }
22034
+ };
22035
+
22036
+ // src/platform/index.ts
22037
+ var fallbackPlatform = {
22038
+ readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
22039
+ readProcessTableSynchronously: () => [],
22040
+ processExists,
22041
+ workBuddyExecutablePaths: () => [],
22042
+ openCodeArchives: {},
22043
+ grokDependencies: {}
22044
+ };
22045
+ var platforms = /* @__PURE__ */ new Map([
22046
+ ["linux", linuxPlatform],
22047
+ ["darwin", macosPlatform],
22048
+ ["win32", { ...fallbackPlatform, readProcessTable: () => Promise.resolve([]) }]
22049
+ ]);
22050
+ function platformSupportFor(platform) {
22051
+ return platforms.get(platform) ?? fallbackPlatform;
22052
+ }
22053
+
22054
+ // src/process/executable.ts
22055
+ var hostPlatform = platformSupportFor(process.platform);
21803
22056
  var DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024;
21804
22057
  var PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS = 1e3;
21805
22058
  var PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS = 5e3;
21806
- var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21807
- var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21808
22059
  var PROCESS_EXIT_CHECK_ATTEMPTS = 16;
21809
22060
  var GRACEFUL_STOP_SIGNAL = 15;
21810
22061
  var FORCED_STOP_SIGNAL = 9;
@@ -21863,13 +22114,13 @@ function executableExtensions(executableName, environment, platform) {
21863
22114
  async function resolveExecutablePath(requestedPath2, platform = process.platform) {
21864
22115
  const absoluteRequestedPath = resolve(requestedPath2);
21865
22116
  try {
21866
- const resolvedPath = await realpath(absoluteRequestedPath);
21867
- const metadata = await stat(resolvedPath);
22117
+ const resolvedPath = await realpath2(absoluteRequestedPath);
22118
+ const metadata = await stat2(resolvedPath);
21868
22119
  if (!metadata.isFile()) {
21869
22120
  return null;
21870
22121
  }
21871
22122
  if (platform !== "win32") {
21872
- await access(resolvedPath, constants.X_OK);
22123
+ await access2(resolvedPath, constants2.X_OK);
21873
22124
  }
21874
22125
  return new ResolvedExecutable(
21875
22126
  new ExecutableIdentity(
@@ -21894,7 +22145,7 @@ async function findExecutableOnPath(executableName, environment, platform = proc
21894
22145
  continue;
21895
22146
  }
21896
22147
  for (const extension of extensions) {
21897
- const requestedPath2 = resolve(join(entry, `${executableName}${extension}`));
22148
+ const requestedPath2 = resolve(join3(entry, `${executableName}${extension}`));
21898
22149
  const executable = await resolveExecutablePath(requestedPath2, platform);
21899
22150
  if (executable !== null) {
21900
22151
  return executable;
@@ -21915,128 +22166,8 @@ function appendBounded(chunks, chunk, currentBytes, limitBytes) {
21915
22166
  chunks.push(chunk);
21916
22167
  return nextBytes;
21917
22168
  }
21918
- function parseProcessTable(output2) {
21919
- const entries = [];
21920
- for (const line of output2.split("\n")) {
21921
- const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21922
- if (groups === void 0) {
21923
- continue;
21924
- }
21925
- const processId = Number(groups["pid"]);
21926
- const parentProcessId = Number(groups["ppid"]);
21927
- const processGroupId = Number(groups["pgid"]);
21928
- if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21929
- continue;
21930
- }
21931
- entries.push({ parentProcessId, processGroupId, processId });
21932
- }
21933
- return entries;
21934
- }
21935
- function appendLinuxProcessTableEntry(entries, processId, encoded) {
21936
- const closingParenthesis = encoded.lastIndexOf(")");
21937
- if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21938
- return;
21939
- }
21940
- const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21941
- const parentProcessId = Number(fields[1]);
21942
- const processGroupId = Number(fields[2]);
21943
- if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21944
- return;
21945
- }
21946
- entries.push({ parentProcessId, processGroupId, processId });
21947
- }
21948
- async function readLinuxProcessTable() {
21949
- const entries = [];
21950
- try {
21951
- const directories = await readdir("/proc", { withFileTypes: true });
21952
- for (const directory of directories) {
21953
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21954
- continue;
21955
- }
21956
- const processId = Number(directory.name);
21957
- if (!Number.isSafeInteger(processId) || processId <= 0) {
21958
- continue;
21959
- }
21960
- try {
21961
- appendLinuxProcessTableEntry(
21962
- entries,
21963
- processId,
21964
- await readFile(join("/proc", directory.name, "stat"), "utf8")
21965
- );
21966
- } catch {
21967
- }
21968
- }
21969
- } catch {
21970
- }
21971
- return entries;
21972
- }
21973
- function readLinuxProcessTableSynchronously() {
21974
- const entries = [];
21975
- try {
21976
- const directories = readdirSync("/proc", { withFileTypes: true });
21977
- for (const directory of directories) {
21978
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21979
- continue;
21980
- }
21981
- const processId = Number(directory.name);
21982
- if (!Number.isSafeInteger(processId) || processId <= 0) {
21983
- continue;
21984
- }
21985
- try {
21986
- appendLinuxProcessTableEntry(
21987
- entries,
21988
- processId,
21989
- readFileSync(join("/proc", directory.name, "stat"), "utf8")
21990
- );
21991
- } catch {
21992
- }
21993
- }
21994
- } catch {
21995
- }
21996
- return entries;
21997
- }
21998
- function readProcessTableWithPs(executable) {
21999
- return new Promise((resolveTable) => {
22000
- execFile(
22001
- executable,
22002
- ["-axo", "pid=,ppid=,pgid="],
22003
- {
22004
- encoding: "utf8",
22005
- maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
22006
- signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
22007
- timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
22008
- },
22009
- (error62, stdout) => {
22010
- resolveTable(error62 === null ? parseProcessTable(stdout) : []);
22011
- }
22012
- );
22013
- });
22014
- }
22015
- async function readLinuxProcessTableWithFallback() {
22016
- const procfsEntries = await readLinuxProcessTable();
22017
- if (procfsEntries.length > 0) {
22018
- return procfsEntries;
22019
- }
22020
- for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
22021
- const executable = await resolveExecutablePath(candidate);
22022
- if (executable === null) {
22023
- continue;
22024
- }
22025
- const entries = await readProcessTableWithPs(executable.identity.requestedPath);
22026
- if (entries.length > 0) {
22027
- return entries;
22028
- }
22029
- }
22030
- return [];
22031
- }
22032
22169
  function readProcessTable() {
22033
- if (process.platform === "win32") {
22034
- return Promise.resolve([]);
22035
- }
22036
- if (process.platform === "linux") {
22037
- return readLinuxProcessTableWithFallback();
22038
- }
22039
- return readProcessTableWithPs(process.platform === "darwin" ? "/bin/ps" : "/usr/bin/ps");
22170
+ return hostPlatform.readProcessTable();
22040
22171
  }
22041
22172
  function selectProcessTree(entries, rootProcessId) {
22042
22173
  const processIds = /* @__PURE__ */ new Set([rootProcessId]);
@@ -22073,11 +22204,9 @@ async function captureProcessTree(child2) {
22073
22204
  if (process.platform === "win32" || child2.pid === void 0) {
22074
22205
  return [];
22075
22206
  }
22076
- if (process.platform === "linux") {
22077
- const procfsEntries = readLinuxProcessTableSynchronously();
22078
- if (procfsEntries.length > 0) {
22079
- return selectProcessTree(procfsEntries, child2.pid);
22080
- }
22207
+ const entries = hostPlatform.readProcessTableSynchronously();
22208
+ if (entries.length > 0) {
22209
+ return selectProcessTree(entries, child2.pid);
22081
22210
  }
22082
22211
  return selectProcessTree(await readProcessTable(), child2.pid);
22083
22212
  }
@@ -22105,36 +22234,15 @@ function signalCapturedProcessGroups(processes, rootProcessId, signal) {
22105
22234
  }
22106
22235
  }
22107
22236
  }
22108
- function processExists(processId) {
22109
- if (process.platform === "linux") {
22110
- try {
22111
- const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
22112
- const closingParenthesis = encoded.lastIndexOf(")");
22113
- if (closingParenthesis >= 0) {
22114
- const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
22115
- if (processState === "Z" || processState === "X") {
22116
- return false;
22117
- }
22118
- }
22119
- } catch {
22120
- }
22121
- }
22122
- try {
22123
- process.kill(processId, 0);
22124
- return true;
22125
- } catch {
22126
- return false;
22127
- }
22128
- }
22129
22237
  async function waitForCapturedProcessesExit(processes, rootProcessId) {
22130
22238
  const processIds = processes.map((identity2) => identity2.processId).filter((processId) => processId !== rootProcessId);
22131
22239
  for (let attempt = 0; attempt < PROCESS_EXIT_CHECK_ATTEMPTS; attempt += 1) {
22132
- if (processIds.every((processId) => !processExists(processId))) {
22240
+ if (processIds.every((processId) => !hostPlatform.processExists(processId))) {
22133
22241
  return true;
22134
22242
  }
22135
22243
  await readProcessTable();
22136
22244
  }
22137
- return processIds.every((processId) => !processExists(processId));
22245
+ return processIds.every((processId) => !hostPlatform.processExists(processId));
22138
22246
  }
22139
22247
  function terminateProcess(child2) {
22140
22248
  if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
@@ -22620,8 +22728,8 @@ var LocalAgentInventory = class {
22620
22728
  };
22621
22729
 
22622
22730
  // src/agent-installation/managed-npm-package.ts
22623
- import { mkdir, mkdtemp, open as open2, realpath as realpath2, rename, rm, stat as stat2 } from "node:fs/promises";
22624
- import { delimiter, dirname, isAbsolute, join as join2, relative, sep } from "node:path";
22731
+ import { mkdir, mkdtemp, open as open2, realpath as realpath3, rename, rm, stat as stat3 } from "node:fs/promises";
22732
+ import { delimiter, dirname, isAbsolute as isAbsolute2, join as join4, relative, sep } from "node:path";
22625
22733
  var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
22626
22734
  var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
22627
22735
  var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
@@ -22672,11 +22780,11 @@ function isRecord3(value) {
22672
22780
  return typeof value === "object" && value !== null && !Array.isArray(value);
22673
22781
  }
22674
22782
  function packagePath(root, packageName) {
22675
- return join2(root, "node_modules", ...packageName.split("/"));
22783
+ return join4(root, "node_modules", ...packageName.split("/"));
22676
22784
  }
22677
22785
  function isContainedPath(root, candidate) {
22678
22786
  const difference = relative(root, candidate);
22679
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute(difference);
22787
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute2(difference);
22680
22788
  }
22681
22789
  async function readJsonRecord(path2, maximumBytes) {
22682
22790
  try {
@@ -22777,14 +22885,14 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
22777
22885
  }
22778
22886
  }
22779
22887
  async function verifyRequiredDependency(rootPath, lock, definition) {
22780
- const dependencyRoot = await realpath2(packagePath(rootPath, definition.packageName));
22888
+ const dependencyRoot = await realpath3(packagePath(rootPath, definition.packageName));
22781
22889
  if (!isContainedPath(rootPath, dependencyRoot)) {
22782
22890
  throw new ManagedNpmPackageError(
22783
22891
  "managed_package_verification_failed",
22784
22892
  "The required managed npm dependency escaped its private cache"
22785
22893
  );
22786
22894
  }
22787
- const metadata = await readJsonRecord(join2(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
22895
+ const metadata = await readJsonRecord(join4(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
22788
22896
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
22789
22897
  throw new ManagedNpmPackageError(
22790
22898
  "managed_package_verification_failed",
@@ -22806,15 +22914,15 @@ async function validateManagedNpmPackage(root, definition) {
22806
22914
  }
22807
22915
  }
22808
22916
  async function validateManagedNpmPackageContents(root, definition) {
22809
- const rootPath = await realpath2(root);
22810
- const packageRoot = await realpath2(packagePath(rootPath, definition.packageName));
22917
+ const rootPath = await realpath3(root);
22918
+ const packageRoot = await realpath3(packagePath(rootPath, definition.packageName));
22811
22919
  if (!isContainedPath(rootPath, packageRoot)) {
22812
22920
  throw new ManagedNpmPackageError(
22813
22921
  "managed_package_verification_failed",
22814
22922
  "The managed npm package escaped its private cache"
22815
22923
  );
22816
22924
  }
22817
- const metadata = await readJsonRecord(join2(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
22925
+ const metadata = await readJsonRecord(join4(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
22818
22926
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
22819
22927
  throw new ManagedNpmPackageError(
22820
22928
  "managed_package_verification_failed",
@@ -22822,14 +22930,14 @@ async function validateManagedNpmPackageContents(root, definition) {
22822
22930
  );
22823
22931
  }
22824
22932
  if (definition instanceof SriManagedNpmPackageDefinition) {
22825
- const lock = await readJsonRecord(join2(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
22933
+ const lock = await readJsonRecord(join4(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
22826
22934
  verifyPackageLockEntry(lock, definition, definition.verifyDependencyClosure);
22827
22935
  for (const dependency of definition.requiredDependencies) {
22828
22936
  await verifyRequiredDependency(rootPath, lock, dependency);
22829
22937
  }
22830
22938
  }
22831
22939
  const declaredBin = readBinPath(metadata, definition.executableName);
22832
- const executable = await resolveExecutablePath(join2(packageRoot, declaredBin));
22940
+ const executable = await resolveExecutablePath(join4(packageRoot, declaredBin));
22833
22941
  if (executable === null || !isContainedPath(rootPath, executable.path)) {
22834
22942
  throw new ManagedNpmPackageError(
22835
22943
  "managed_package_verification_failed",
@@ -22842,7 +22950,7 @@ var ManagedNpmPackageInstaller = class {
22842
22950
  install = async (root, definition, environment, signal) => {
22843
22951
  signal.throwIfAborted();
22844
22952
  try {
22845
- const metadata = await stat2(root);
22953
+ const metadata = await stat3(root);
22846
22954
  if (metadata.isDirectory()) {
22847
22955
  return await validateManagedNpmPackage(root, definition);
22848
22956
  }
@@ -22853,7 +22961,7 @@ var ManagedNpmPackageInstaller = class {
22853
22961
  }
22854
22962
  const parent = dirname(root);
22855
22963
  await mkdir(parent, { mode: 448, recursive: true });
22856
- const staging = await mkdtemp(join2(parent, `.${definition.version}.staging-`));
22964
+ const staging = await mkdtemp(join4(parent, `.${definition.version}.staging-`));
22857
22965
  try {
22858
22966
  const npm = await findExecutableOnPath(process.platform === "win32" ? "npm.cmd" : "npm", environment);
22859
22967
  if (npm === null) {
@@ -22879,9 +22987,9 @@ var ManagedNpmPackageInstaller = class {
22879
22987
  `${definition.packageName}@${definition.version}`
22880
22988
  );
22881
22989
  const installEnvironment = {
22882
- HOME: join2(staging, "home"),
22990
+ HOME: join4(staging, "home"),
22883
22991
  NPM_CONFIG_AUDIT: "false",
22884
- NPM_CONFIG_CACHE: join2(staging, ".npm-cache"),
22992
+ NPM_CONFIG_CACHE: join4(staging, ".npm-cache"),
22885
22993
  NPM_CONFIG_FUND: "false",
22886
22994
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
22887
22995
  NPM_CONFIG_PACKAGE_LOCK: "true",
@@ -22903,8 +23011,8 @@ var ManagedNpmPackageInstaller = class {
22903
23011
  timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
22904
23012
  });
22905
23013
  await Promise.all([
22906
- rm(join2(staging, ".npm-cache"), { force: true, recursive: true }),
22907
- rm(join2(staging, "home"), { force: true, recursive: true })
23014
+ rm(join4(staging, ".npm-cache"), { force: true, recursive: true }),
23015
+ rm(join4(staging, "home"), { force: true, recursive: true })
22908
23016
  ]);
22909
23017
  await validateManagedNpmPackage(staging, definition);
22910
23018
  try {
@@ -22940,7 +23048,7 @@ var ManagedNpmPackageInstaller = class {
22940
23048
  };
22941
23049
 
22942
23050
  // src/agent-catalog/agent-specification.ts
22943
- import { join as join3 } from "node:path";
23051
+ import { join as join5 } from "node:path";
22944
23052
 
22945
23053
  // src/agent-catalog/version-output.ts
22946
23054
  function normalizeVersionOutput(output2) {
@@ -22963,7 +23071,7 @@ var LocalAgentSpecification = class {
22963
23071
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
22964
23072
  signal.throwIfAborted();
22965
23073
  const executable = await resolveExecutablePath(
22966
- join3(stateDirectory, ...this.managedAgentExecutablePath),
23074
+ join5(stateDirectory, ...this.managedAgentExecutablePath),
22967
23075
  platform
22968
23076
  );
22969
23077
  signal.throwIfAborted();
@@ -23167,7 +23275,7 @@ function sessionFailureMeta(failure2) {
23167
23275
  import { spawn as spawn2 } from "node:child_process";
23168
23276
 
23169
23277
  // src/acp/codex/app-server-protocol.ts
23170
- import { isAbsolute as isAbsolute2 } from "node:path";
23278
+ import { isAbsolute as isAbsolute3 } from "node:path";
23171
23279
  var boundedText = (maximum) => external_exports.string().max(maximum);
23172
23280
  var jsonValue = external_exports.lazy(() => external_exports.unknown());
23173
23281
  var requestIdSchema = external_exports.union([external_exports.number(), external_exports.string()]).refine((value) => typeof value === "number" || value.length <= 256);
@@ -23238,7 +23346,7 @@ var imageGenerationItemSchema = external_exports.object({
23238
23346
  });
23239
23347
  var threadItemSchema = external_exports.discriminatedUnion("type", [
23240
23348
  imageGenerationItemSchema,
23241
- external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute2) }),
23349
+ external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute3) }),
23242
23350
  external_exports.object({
23243
23351
  id: boundedText(256),
23244
23352
  text: boundedText(1e6),
@@ -25104,15 +25212,15 @@ var AgentProbeError = class extends Error {
25104
25212
  };
25105
25213
 
25106
25214
  // src/agent-catalog/agents/resolve-user-local-executable.ts
25107
- import { isAbsolute as isAbsolute3, join as join4 } from "node:path";
25215
+ import { isAbsolute as isAbsolute4, join as join6 } from "node:path";
25108
25216
  async function resolveUserLocalExecutable(executableName, context) {
25109
25217
  context.signal.throwIfAborted();
25110
25218
  const platform = context.platform ?? process.platform;
25111
25219
  const homeDirectory = context.environment["HOME"];
25112
- if (platform === "win32" || homeDirectory === void 0 || !isAbsolute3(homeDirectory)) {
25220
+ if (platform === "win32" || homeDirectory === void 0 || !isAbsolute4(homeDirectory)) {
25113
25221
  return [];
25114
25222
  }
25115
- const executable = await resolveExecutablePath(join4(homeDirectory, ".local", "bin", executableName), platform);
25223
+ const executable = await resolveExecutablePath(join6(homeDirectory, ".local", "bin", executableName), platform);
25116
25224
  context.signal.throwIfAborted();
25117
25225
  return executable === null ? [] : [executable];
25118
25226
  }
@@ -25201,8 +25309,8 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
25201
25309
  };
25202
25310
 
25203
25311
  // src/agent-catalog/agents/deepseek-harness-agent.ts
25204
- import { mkdir as mkdir2, realpath as realpath3, stat as stat3, writeFile } from "node:fs/promises";
25205
- import { isAbsolute as isAbsolute4, join as join6, normalize } from "node:path";
25312
+ import { mkdir as mkdir2, realpath as realpath4, stat as stat4, writeFile } from "node:fs/promises";
25313
+ import { isAbsolute as isAbsolute5, join as join8, normalize } from "node:path";
25206
25314
 
25207
25315
  // src/agent-installation/deepseek-managed-package.ts
25208
25316
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -25220,13 +25328,13 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
25220
25328
 
25221
25329
  // src/storage/state-directory.ts
25222
25330
  import { homedir } from "node:os";
25223
- import { join as join5, resolve as resolve2 } from "node:path";
25331
+ import { join as join7, resolve as resolve2 } from "node:path";
25224
25332
  function readStateDirectory(environment = process.env) {
25225
25333
  const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
25226
25334
  if (configured !== void 0 && configured.length > 0) {
25227
25335
  return resolve2(configured);
25228
25336
  }
25229
- return join5(homedir(), ".mobius");
25337
+ return join7(homedir(), ".mobius");
25230
25338
  }
25231
25339
 
25232
25340
  // src/agent-catalog/agents/deepseek-harness-agent.ts
@@ -25237,20 +25345,20 @@ var DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH = `# Managed by Mobius: pin the ACP brid
25237
25345
  model: deepseek-v4-flash-vision-exp
25238
25346
  `;
25239
25347
  async function prepareAgentHome(path2, imagePrompts) {
25240
- if (!isAbsolute4(path2) || normalize(path2) !== path2) {
25348
+ if (!isAbsolute5(path2) || normalize(path2) !== path2) {
25241
25349
  throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
25242
25350
  }
25243
25351
  try {
25244
25352
  if (imagePrompts) {
25245
25353
  await mkdir2(path2, { mode: 448, recursive: true });
25246
25354
  }
25247
- const resolved = await realpath3(path2);
25248
- const metadata = await stat3(resolved);
25355
+ const resolved = await realpath4(path2);
25356
+ const metadata = await stat4(resolved);
25249
25357
  if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
25250
25358
  throw new Error("Agent home is not a user-owned directory");
25251
25359
  }
25252
25360
  if (imagePrompts) {
25253
- await writeFile(join6(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
25361
+ await writeFile(join8(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
25254
25362
  mode: 384
25255
25363
  });
25256
25364
  }
@@ -25298,7 +25406,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
25298
25406
  context.signal
25299
25407
  );
25300
25408
  if (managed.path === agent.path) {
25301
- selectedHome = join6(readStateDirectory(context.environment), "agents", this.id, "home");
25409
+ selectedHome = join8(readStateDirectory(context.environment), "agents", this.id, "home");
25302
25410
  managedHome = true;
25303
25411
  }
25304
25412
  } catch {
@@ -25314,7 +25422,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
25314
25422
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
25315
25423
  signal.throwIfAborted();
25316
25424
  const executable = await validateManagedNpmPackage(
25317
- join6(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
25425
+ join8(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
25318
25426
  DEEPSEEK_HARNESS_PACKAGE
25319
25427
  );
25320
25428
  signal.throwIfAborted();
@@ -25368,8 +25476,8 @@ var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
25368
25476
  };
25369
25477
 
25370
25478
  // src/agent-catalog/agents/grok-build-agent.ts
25371
- import { realpath as realpath4 } from "node:fs/promises";
25372
- import { isAbsolute as isAbsolute5, join as join7, relative as relative2, sep as sep2 } from "node:path";
25479
+ import { realpath as realpath5 } from "node:fs/promises";
25480
+ import { isAbsolute as isAbsolute6, join as join9, relative as relative2, sep as sep2 } from "node:path";
25373
25481
  import {
25374
25482
  RequestError
25375
25483
  } from "@agentclientprotocol/sdk";
@@ -25392,50 +25500,25 @@ var GrokBuildManagedPackage = class extends SriManagedNpmPackageDefinition {
25392
25500
  this.requiredDependencies = Object.freeze([requiredDependency]);
25393
25501
  }
25394
25502
  };
25395
- var GROK_DARWIN_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
25396
- "@xai-official/grok-darwin-arm64",
25397
- GROK_BUILD_MANAGED_VERSION,
25398
- "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
25399
- "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
25400
- );
25401
- var GROK_DARWIN_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
25402
- "@xai-official/grok-darwin-x64",
25403
- GROK_BUILD_MANAGED_VERSION,
25404
- "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
25405
- "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
25406
- );
25407
- var GROK_LINUX_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
25408
- "@xai-official/grok-linux-arm64",
25409
- GROK_BUILD_MANAGED_VERSION,
25410
- "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
25411
- "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
25412
- );
25413
- var GROK_LINUX_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
25414
- "@xai-official/grok-linux-x64",
25415
- GROK_BUILD_MANAGED_VERSION,
25416
- "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
25417
- "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
25418
- );
25419
25503
  function grokBuildManagedPackage(platform, architecture) {
25420
- if (platform === "darwin" && architecture === "arm64") {
25421
- return new GrokBuildManagedPackage(GROK_DARWIN_ARM64_PACKAGE);
25422
- }
25423
- if (platform === "darwin" && architecture === "x64") {
25424
- return new GrokBuildManagedPackage(GROK_DARWIN_X64_PACKAGE);
25504
+ const release = platformSupportFor(platform).grokDependencies[architecture];
25505
+ if (release === void 0) {
25506
+ throw new Error("Grok Build does not publish a package for this platform");
25425
25507
  }
25426
- if (platform === "linux" && architecture === "arm64") {
25427
- return new GrokBuildManagedPackage(GROK_LINUX_ARM64_PACKAGE);
25428
- }
25429
- if (platform === "linux" && architecture === "x64") {
25430
- return new GrokBuildManagedPackage(GROK_LINUX_X64_PACKAGE);
25431
- }
25432
- throw new Error("Grok Build does not publish a package for this platform");
25508
+ return new GrokBuildManagedPackage(
25509
+ new SriManagedNpmDependencyDefinition(
25510
+ release.name,
25511
+ GROK_BUILD_MANAGED_VERSION,
25512
+ release.integrity,
25513
+ release.tarballUrl
25514
+ )
25515
+ );
25433
25516
  }
25434
25517
 
25435
25518
  // src/agent-catalog/agents/grok-build-agent.ts
25436
25519
  function isContainedPath2(root, candidate) {
25437
25520
  const difference = relative2(root, candidate);
25438
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute5(difference);
25521
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute6(difference);
25439
25522
  }
25440
25523
  var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
25441
25524
  adapterVersion = GROK_BUILD_MANAGED_VERSION;
@@ -25464,8 +25547,8 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
25464
25547
  );
25465
25548
  if (managed.path === agent.path) {
25466
25549
  return Object.freeze({
25467
- GROK_HOME: await realpath4(
25468
- join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
25550
+ GROK_HOME: await realpath5(
25551
+ join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
25469
25552
  )
25470
25553
  });
25471
25554
  }
@@ -25476,9 +25559,9 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
25476
25559
  };
25477
25560
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
25478
25561
  signal.throwIfAborted();
25479
- const versionRoot = await realpath4(join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
25480
- await validateManagedNpmPackage(join7(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
25481
- const executable = await resolveExecutablePath(join7(versionRoot, "home", "bin", "grok"), platform);
25562
+ const versionRoot = await realpath5(join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
25563
+ await validateManagedNpmPackage(join9(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
25564
+ const executable = await resolveExecutablePath(join9(versionRoot, "home", "bin", "grok"), platform);
25482
25565
  signal.throwIfAborted();
25483
25566
  if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
25484
25567
  throw new AgentProbeError("managed_agent_invalid", "The managed Grok Build executable is invalid");
@@ -25578,13 +25661,13 @@ var OhMyPiAgentSpecification = class extends DirectAcpAgentDefinition {
25578
25661
  };
25579
25662
 
25580
25663
  // src/agent-catalog/agents/opencode-agent.ts
25581
- import { join as join9 } from "node:path";
25664
+ import { join as join11 } from "node:path";
25582
25665
 
25583
25666
  // src/agent-installation/managed-agent-archive.ts
25584
25667
  import { createHash } from "node:crypto";
25585
25668
  import { createReadStream } from "node:fs";
25586
- import { chmod, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as realpath5, rename as rename2, rm as rm2, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
25587
- import { delimiter as delimiter2, dirname as dirname2, isAbsolute as isAbsolute6, join as join8, relative as relative3, sep as sep3 } from "node:path";
25669
+ import { chmod, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as realpath6, rename as rename2, rm as rm2, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
25670
+ import { delimiter as delimiter2, dirname as dirname2, isAbsolute as isAbsolute7, join as join10, relative as relative3, sep as sep3 } from "node:path";
25588
25671
 
25589
25672
  // src/agent-installation/verified-download.ts
25590
25673
  import { fetch } from "undici";
@@ -25690,7 +25773,7 @@ function isRecord5(value) {
25690
25773
  }
25691
25774
  function isContainedPath3(root, candidate) {
25692
25775
  const difference = relative3(root, candidate);
25693
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute6(difference);
25776
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute7(difference);
25694
25777
  }
25695
25778
  async function hashFile(path2, signal) {
25696
25779
  signal.throwIfAborted();
@@ -25764,16 +25847,16 @@ async function readManifest(path2) {
25764
25847
  }
25765
25848
  async function validateManagedAgentArchive(root, definition, signal) {
25766
25849
  try {
25767
- const rootPath = await realpath5(root);
25768
- const rootMetadata = await stat4(rootPath);
25850
+ const rootPath = await realpath6(root);
25851
+ const rootMetadata = await stat5(rootPath);
25769
25852
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
25770
25853
  throw new Error("Managed Agent root is not user-owned");
25771
25854
  }
25772
- const manifest = await readManifest(join8(rootPath, "archive.json"));
25855
+ const manifest = await readManifest(join10(rootPath, "archive.json"));
25773
25856
  if (manifest["archiveSha256"] !== definition.archiveSha256 || manifest["archiveUrl"] !== definition.archiveUrl.toString() || manifest["version"] !== definition.version || typeof manifest["executableSha256"] !== "string") {
25774
25857
  throw new Error("Managed Agent archive identity is invalid");
25775
25858
  }
25776
- const executable = await resolveExecutablePath(join8(rootPath, "bin", definition.executableName));
25859
+ const executable = await resolveExecutablePath(join10(rootPath, "bin", definition.executableName));
25777
25860
  if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
25778
25861
  throw new Error("Managed Agent executable is invalid");
25779
25862
  }
@@ -25799,47 +25882,21 @@ function releaseUrl(asset) {
25799
25882
  return new URL(`https://github.com/anomalyco/opencode/releases/download/v${OPENCODE_MANAGED_VERSION}/${asset}`);
25800
25883
  }
25801
25884
  function openCodeManagedArchive(platform, architecture) {
25802
- if (platform === "darwin" && architecture === "arm64") {
25803
- const asset = "opencode-darwin-arm64.zip";
25804
- return new ZipManagedAgentArchiveDefinition(
25805
- OPENCODE_MANAGED_VERSION,
25806
- asset,
25807
- releaseUrl(asset),
25808
- "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
25809
- "opencode"
25810
- );
25811
- }
25812
- if (platform === "darwin" && architecture === "x64") {
25813
- const asset = "opencode-darwin-x64.zip";
25814
- return new ZipManagedAgentArchiveDefinition(
25815
- OPENCODE_MANAGED_VERSION,
25816
- asset,
25817
- releaseUrl(asset),
25818
- "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
25819
- "opencode"
25820
- );
25821
- }
25822
- if (platform === "linux" && architecture === "arm64") {
25823
- const asset = "opencode-linux-arm64.tar.gz";
25824
- return new TarGzipManagedAgentArchiveDefinition(
25825
- OPENCODE_MANAGED_VERSION,
25826
- asset,
25827
- releaseUrl(asset),
25828
- "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
25829
- "opencode"
25830
- );
25831
- }
25832
- if (platform === "linux" && architecture === "x64") {
25833
- const asset = "opencode-linux-x64.tar.gz";
25834
- return new TarGzipManagedAgentArchiveDefinition(
25835
- OPENCODE_MANAGED_VERSION,
25836
- asset,
25837
- releaseUrl(asset),
25838
- "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
25839
- "opencode"
25840
- );
25841
- }
25842
- throw new Error("OpenCode does not publish an approved archive for this platform");
25885
+ const release = platformSupportFor(platform).openCodeArchives[architecture];
25886
+ if (release === void 0) {
25887
+ throw new Error("OpenCode does not publish an approved archive for this platform");
25888
+ }
25889
+ const Definition = {
25890
+ zip: ZipManagedAgentArchiveDefinition,
25891
+ "tar.gz": TarGzipManagedAgentArchiveDefinition
25892
+ }[release.format];
25893
+ return new Definition(
25894
+ OPENCODE_MANAGED_VERSION,
25895
+ release.asset,
25896
+ releaseUrl(release.asset),
25897
+ release.sha256,
25898
+ "opencode"
25899
+ );
25843
25900
  }
25844
25901
 
25845
25902
  // src/agent-catalog/agents/opencode-agent.ts
@@ -25965,7 +26022,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
25965
26022
  return Object.freeze(environment);
25966
26023
  };
25967
26024
  resolveManagedAgent = async (stateDirectory, platform, signal) => await validateManagedAgentArchive(
25968
- join9(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
26025
+ join11(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
25969
26026
  openCodeManagedArchive(platform, process.arch),
25970
26027
  signal
25971
26028
  );
@@ -25983,7 +26040,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
25983
26040
  };
25984
26041
 
25985
26042
  // src/agent-catalog/agents/pi-agent.ts
25986
- import { join as join10 } from "node:path";
26043
+ import { join as join12 } from "node:path";
25987
26044
  import {
25988
26045
  methods as methods4
25989
26046
  } from "@agentclientprotocol/sdk";
@@ -26042,7 +26099,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
26042
26099
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
26043
26100
  signal.throwIfAborted();
26044
26101
  const executable = await validateManagedNpmPackage(
26045
- join10(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
26102
+ join12(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
26046
26103
  PI_AGENT_PACKAGE
26047
26104
  );
26048
26105
  signal.throwIfAborted();
@@ -26080,7 +26137,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
26080
26137
  };
26081
26138
 
26082
26139
  // src/agent-catalog/agents/workbuddy-agent.ts
26083
- import { isAbsolute as isAbsolute7, join as join11 } from "node:path";
26140
+ import { join as join13 } from "node:path";
26084
26141
 
26085
26142
  // src/agent-installation/workbuddy-managed-package.ts
26086
26143
  var WORKBUDDY_MANAGED_VERSION = "2.146.0";
@@ -26098,15 +26155,6 @@ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
26098
26155
  );
26099
26156
 
26100
26157
  // src/agent-catalog/agents/workbuddy-agent.ts
26101
- var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
26102
- "WorkBuddy.app",
26103
- "Contents",
26104
- "Resources",
26105
- "app.asar.unpacked",
26106
- "cli",
26107
- "bin",
26108
- "codebuddy"
26109
- ]);
26110
26158
  var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
26111
26159
  adapterVersion = WORKBUDDY_MANAGED_VERSION;
26112
26160
  authenticationCommand = () => "codebuddy";
@@ -26135,7 +26183,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
26135
26183
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
26136
26184
  signal.throwIfAborted();
26137
26185
  const executable = await validateManagedNpmPackage(
26138
- join11(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
26186
+ join13(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
26139
26187
  WORKBUDDY_MANAGED_PACKAGE
26140
26188
  );
26141
26189
  signal.throwIfAborted();
@@ -26143,17 +26191,11 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
26143
26191
  };
26144
26192
  resolveInstalledAgentExecutables = async (context) => {
26145
26193
  context.signal.throwIfAborted();
26146
- if ((context.platform ?? process.platform) !== "darwin") {
26147
- return [];
26148
- }
26149
- const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
26150
- const homeDirectory = context.environment["HOME"];
26151
- if (homeDirectory !== void 0 && isAbsolute7(homeDirectory)) {
26152
- requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
26153
- }
26194
+ const platform = context.platform ?? process.platform;
26195
+ const requestedPaths = platformSupportFor(platform).workBuddyExecutablePaths(context.environment);
26154
26196
  const executables = [];
26155
26197
  for (const requestedPath2 of requestedPaths) {
26156
- const executable = await resolveExecutablePath(requestedPath2, "darwin");
26198
+ const executable = await resolveExecutablePath(requestedPath2, platform);
26157
26199
  context.signal.throwIfAborted();
26158
26200
  if (executable !== null) {
26159
26201
  executables.push(executable);
@@ -26513,10 +26555,10 @@ function isAgentVersionSupported(reportedVersion, minimumSupportedVersion) {
26513
26555
  }
26514
26556
 
26515
26557
  // src/agent-catalog/executable-discovery.ts
26516
- import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
26558
+ import { isAbsolute as isAbsolute8, join as join15 } from "node:path";
26517
26559
 
26518
26560
  // src/agent-installation/managed-adapter-installer.ts
26519
- import { join as join12 } from "node:path";
26561
+ import { join as join14 } from "node:path";
26520
26562
  var ManagedAdapterInstallError = class extends Error {
26521
26563
  code;
26522
26564
  constructor(code, message, options = {}) {
@@ -26573,7 +26615,7 @@ var ManagedAdapterInstaller = class {
26573
26615
  this.#stateDirectory = options.stateDirectory;
26574
26616
  }
26575
26617
  install = async (specification, signal) => {
26576
- const root = join12(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
26618
+ const root = join14(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
26577
26619
  try {
26578
26620
  return await this.#npmInstaller.install(
26579
26621
  root,
@@ -26607,7 +26649,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
26607
26649
  let managed;
26608
26650
  try {
26609
26651
  managed = await validateManagedAdapter(
26610
- join13(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
26652
+ join15(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
26611
26653
  specification
26612
26654
  );
26613
26655
  } catch {
@@ -26920,28 +26962,122 @@ async function discoverLocalAgentInventory(options) {
26920
26962
  return new LocalAgentInventory(results);
26921
26963
  }
26922
26964
 
26923
- // src/audit/audit-store.ts
26924
- var MAX_AUDIT_RECORDS = 1024;
26925
- var AuditStore = class {
26926
- #records = [];
26927
- record = (record2) => {
26928
- if (this.#records.length === MAX_AUDIT_RECORDS) {
26929
- this.#records.shift();
26965
+ // src/agent-catalog/publish-agent-catalog.ts
26966
+ import { fetch as fetch2 } from "undici";
26967
+
26968
+ // src/relay-connection/runtime-authentication.ts
26969
+ function runtimeCredential(relayUrl) {
26970
+ return relayUrl.searchParams.get("token") ?? "";
26971
+ }
26972
+ function runtimeAuthorization(relayUrl) {
26973
+ const credential = runtimeCredential(relayUrl);
26974
+ return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
26975
+ }
26976
+ function relayHttpEndpoint(relayUrl) {
26977
+ const endpoint = new URL(relayUrl);
26978
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
26979
+ endpoint.search = "";
26980
+ return endpoint;
26981
+ }
26982
+
26983
+ // src/agent-catalog/publish-agent-catalog.ts
26984
+ var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
26985
+ var AgentCatalogPublishError = class extends Error {
26986
+ code = "agent_catalog_update_failed";
26987
+ diagnosticDetails;
26988
+ constructor(message, options = {}, diagnosticDetails = {}) {
26989
+ super(message, options);
26990
+ this.diagnosticDetails = diagnosticDetails;
26991
+ this.name = "AgentCatalogPublishError";
26992
+ }
26993
+ };
26994
+ function isRecord6(value) {
26995
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26996
+ }
26997
+ function isSafeRelayErrorMessage(value) {
26998
+ return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
26999
+ }
27000
+ async function rejectedCatalogError(response) {
27001
+ let value;
27002
+ try {
27003
+ value = await response.json();
27004
+ } catch {
27005
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
27006
+ }
27007
+ if (!isRecord6(value) || !isRecord6(value["error"])) {
27008
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
27009
+ }
27010
+ const code = value["error"]["code"];
27011
+ const message = value["error"]["message"];
27012
+ if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
27013
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
27014
+ }
27015
+ return new AgentCatalogPublishError(
27016
+ `The Relay rejected the Agent catalog update (${code}): ${message}`,
27017
+ {},
27018
+ {
27019
+ relayErrorCode: code
26930
27020
  }
26931
- this.#records.push(
26932
- record2.details === void 0 ? { ...record2 } : { ...record2, details: { ...record2.details } }
27021
+ );
27022
+ }
27023
+ function catalogEndpoint(config2) {
27024
+ const endpoint = relayHttpEndpoint(config2.relayUrl);
27025
+ if (endpoint.pathname.endsWith("/daemon")) {
27026
+ endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
27027
+ return endpoint;
27028
+ }
27029
+ const runtimePath = "/v1/runtimes/connect";
27030
+ if (endpoint.pathname.endsWith(runtimePath)) {
27031
+ endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
27032
+ return endpoint;
27033
+ }
27034
+ throw new AgentCatalogPublishError("The Relay URL is invalid");
27035
+ }
27036
+ async function publishAgentCatalog(config2, signal) {
27037
+ signal.throwIfAborted();
27038
+ const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
27039
+ const requestSignal = AbortSignal.any([signal, timeoutSignal]);
27040
+ let response;
27041
+ const catalog = config2.catalog.read();
27042
+ try {
27043
+ response = await fetch2(catalogEndpoint(config2), {
27044
+ body: JSON.stringify({
27045
+ agents: catalog.agents.map((agent) => ({
27046
+ agentPath: agent.agentIdentity.requestedPath,
27047
+ agentVersion: agent.agentVersion,
27048
+ agentSettingsDiscovery: true,
27049
+ capabilities: agent.capabilities,
27050
+ id: agent.id,
27051
+ label: agent.label,
27052
+ sessionTurnConfiguration: true
27053
+ })),
27054
+ installableAgents: catalog.installableAgents
27055
+ }),
27056
+ dispatcher: environmentProxyDispatcher,
27057
+ headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
27058
+ method: "PUT",
27059
+ signal: requestSignal
27060
+ });
27061
+ } catch (error62) {
27062
+ if (signal.aborted) {
27063
+ signal.throwIfAborted();
27064
+ }
27065
+ throw new AgentCatalogPublishError(
27066
+ timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
27067
+ { cause: error62 }
26933
27068
  );
26934
- };
26935
- close = () => {
26936
- this.#records.length = 0;
26937
- };
26938
- };
27069
+ }
27070
+ if (!response.ok) {
27071
+ throw await rejectedCatalogError(response);
27072
+ }
27073
+ await response.body?.cancel();
27074
+ }
26939
27075
 
26940
27076
  // src/config.ts
26941
- import { join as join14, resolve as resolve3 } from "node:path";
27077
+ import { join as join16, resolve as resolve3 } from "node:path";
26942
27078
  function loadDefaultWorkspace(environment = process.env) {
26943
27079
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
26944
- return configuredWorkspace ?? join14(readStateDirectory(environment), "workspace");
27080
+ return configuredWorkspace ?? join16(readStateDirectory(environment), "workspace");
26945
27081
  }
26946
27082
  var DaemonLocalContext = class {
26947
27083
  environment;
@@ -26971,7 +27107,7 @@ var OpaqueDaemonReconnectTarget = class extends DaemonReconnectTarget {
26971
27107
  this.commandArgument = `--connection ${connectionId2}`;
26972
27108
  }
26973
27109
  };
26974
- function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null) {
27110
+ function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null, resolveAgent) {
26975
27111
  const daemonAgents = agents.map((agent) => withDaemonEnvironment(agent, localContext.environment));
26976
27112
  return {
26977
27113
  agents: daemonAgents,
@@ -26982,13 +27118,86 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
26982
27118
  installableAgents,
26983
27119
  localContext,
26984
27120
  reconnectTarget,
26985
- relayUrl: connection.relayUrl
27121
+ relayUrl: connection.relayUrl,
27122
+ ...resolveAgent === void 0 ? {} : { resolveAgent }
26986
27123
  };
26987
27124
  }
26988
27125
 
27126
+ // src/agent-catalog/resolve-catalog-agent.ts
27127
+ function createCatalogAgentResolver(discover, readConfig, publish) {
27128
+ const swaps = /* @__PURE__ */ new Map();
27129
+ return async (agent, signal) => {
27130
+ const config2 = readConfig();
27131
+ const pending = swaps.get(agent.id);
27132
+ if (pending !== void 0) {
27133
+ await pending;
27134
+ return config2.catalog.find(agent.id);
27135
+ }
27136
+ let release = () => void 0;
27137
+ const gate = new Promise((resolveGate) => {
27138
+ release = resolveGate;
27139
+ });
27140
+ swaps.set(agent.id, gate);
27141
+ try {
27142
+ if (await unchangedIdentity(agent, signal)) {
27143
+ return agent;
27144
+ }
27145
+ signal.throwIfAborted();
27146
+ const inventory = await discover(signal);
27147
+ signal.throwIfAborted();
27148
+ const previous = config2.catalog.read();
27149
+ const previousAgent = previous.agents.find((entry) => entry.id === agent.id);
27150
+ if (previousAgent === void 0) {
27151
+ throw new Error(`The local Agent ${agent.id} left the catalog before its refresh completed`);
27152
+ }
27153
+ config2.catalog.transition(
27154
+ [
27155
+ ...previous.agents.filter((entry) => entry.id !== agent.id),
27156
+ ...inventory.readyAgents().map((ready) => withDaemonEnvironment(ready, config2.localContext.environment))
27157
+ ],
27158
+ [...previous.installableAgents.filter((entry) => entry.id !== agent.id), ...inventory.installable]
27159
+ );
27160
+ try {
27161
+ await publish(config2, signal);
27162
+ } catch (error62) {
27163
+ config2.catalog.transition(previous.agents, previous.installableAgents);
27164
+ throw error62;
27165
+ }
27166
+ return config2.catalog.find(agent.id);
27167
+ } finally {
27168
+ swaps.delete(agent.id);
27169
+ release();
27170
+ }
27171
+ };
27172
+ }
27173
+ async function unchangedIdentity(agent, signal) {
27174
+ if (!await revalidateExecutable(agent.agentIdentity)) {
27175
+ return false;
27176
+ }
27177
+ signal.throwIfAborted();
27178
+ return agent.kind !== "acp-adapter-process" || await revalidateExecutable(agent.adapterIdentity);
27179
+ }
27180
+
27181
+ // src/audit/audit-store.ts
27182
+ var MAX_AUDIT_RECORDS = 1024;
27183
+ var AuditStore = class {
27184
+ #records = [];
27185
+ record = (record2) => {
27186
+ if (this.#records.length === MAX_AUDIT_RECORDS) {
27187
+ this.#records.shift();
27188
+ }
27189
+ this.#records.push(
27190
+ record2.details === void 0 ? { ...record2 } : { ...record2, details: { ...record2.details } }
27191
+ );
27192
+ };
27193
+ close = () => {
27194
+ this.#records.length = 0;
27195
+ };
27196
+ };
27197
+
26989
27198
  // src/run-daemon.ts
26990
27199
  import { createHash as createHash7, randomUUID as randomUUID8 } from "node:crypto";
26991
- import { join as join18 } from "node:path";
27200
+ import { join as join20 } from "node:path";
26992
27201
  import { styleText } from "node:util";
26993
27202
 
26994
27203
  // src/acp/active-executions.ts
@@ -27079,7 +27288,7 @@ import {
27079
27288
  } from "@agentclientprotocol/sdk";
27080
27289
 
27081
27290
  // src/authorization/local-raster.ts
27082
- import { open as open4, readFile as readFile2, realpath as realpath6, stat as stat5 } from "node:fs/promises";
27291
+ import { open as open4, readFile as readFile2, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27083
27292
  import { basename, isAbsolute as isAbsolute9, normalize as normalize2 } from "node:path";
27084
27293
  import { fileURLToPath } from "node:url";
27085
27294
  var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
@@ -27150,7 +27359,7 @@ async function resolveCanonicalPath(requested, signal) {
27150
27359
  return null;
27151
27360
  }
27152
27361
  try {
27153
- const target = await realpath6(requested);
27362
+ const target = await realpath7(requested);
27154
27363
  signal.throwIfAborted();
27155
27364
  if (!isAbsolute9(target) || normalize2(target) !== target) {
27156
27365
  return null;
@@ -27198,7 +27407,7 @@ async function readLocalRaster(uri, signal) {
27198
27407
  if (target === null) {
27199
27408
  return null;
27200
27409
  }
27201
- const targetMetadata = await stat5(target);
27410
+ const targetMetadata = await stat6(target);
27202
27411
  signal.throwIfAborted();
27203
27412
  if (!targetMetadata.isFile() || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
27204
27413
  return null;
@@ -27377,7 +27586,7 @@ async function replaceImageMarkers(text2, replace) {
27377
27586
 
27378
27587
  // src/acp/activity-content.ts
27379
27588
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
27380
- function isRecord6(value) {
27589
+ function isRecord7(value) {
27381
27590
  return typeof value === "object" && value !== null && !Array.isArray(value);
27382
27591
  }
27383
27592
  function truncate3(value, maximumLength) {
@@ -27561,16 +27770,16 @@ async function normalizeToolContent(content, prepareContent) {
27561
27770
  return normalized;
27562
27771
  }
27563
27772
  function rawMcpToolContent(rawOutput) {
27564
- if (!isRecord6(rawOutput)) {
27773
+ if (!isRecord7(rawOutput)) {
27565
27774
  return [];
27566
27775
  }
27567
- const result = isRecord6(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
27776
+ const result = isRecord7(rawOutput["result"]) ? rawOutput["result"] : rawOutput;
27568
27777
  const content = result["content"];
27569
27778
  if (!Array.isArray(content)) {
27570
27779
  return [];
27571
27780
  }
27572
27781
  return content.flatMap((item) => {
27573
- if (!isRecord6(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
27782
+ if (!isRecord7(item) || item["type"] !== "image" || typeof item["data"] !== "string" || typeof item["mimeType"] !== "string") {
27574
27783
  return [];
27575
27784
  }
27576
27785
  const uri = item["uri"];
@@ -27647,7 +27856,7 @@ function contentPhase(content) {
27647
27856
  return "";
27648
27857
  }
27649
27858
  const codex = metadata["codex"];
27650
- if (!isRecord6(codex)) {
27859
+ if (!isRecord7(codex)) {
27651
27860
  return "";
27652
27861
  }
27653
27862
  const phase = codex["phase"];
@@ -28354,7 +28563,7 @@ var SessionConfigProtocolError = class extends Error {
28354
28563
  this.name = "SessionConfigProtocolError";
28355
28564
  }
28356
28565
  };
28357
- function isRecord7(value) {
28566
+ function isRecord8(value) {
28358
28567
  return typeof value === "object" && value !== null && !Array.isArray(value);
28359
28568
  }
28360
28569
  function readString3(value, fallback = "") {
@@ -28385,7 +28594,7 @@ function normalizeConfigValues(value) {
28385
28594
  }
28386
28595
  const normalized = [];
28387
28596
  for (const entry of value) {
28388
- if (!isRecord7(entry)) {
28597
+ if (!isRecord8(entry)) {
28389
28598
  continue;
28390
28599
  }
28391
28600
  const groupedOptions = entry["options"];
@@ -28393,7 +28602,7 @@ function normalizeConfigValues(value) {
28393
28602
  const groupId = readString3(entry["group"]);
28394
28603
  const groupName = readString3(entry["name"]);
28395
28604
  for (const groupedOption of groupedOptions) {
28396
- if (isRecord7(groupedOption)) {
28605
+ if (isRecord8(groupedOption)) {
28397
28606
  const normalizedValue = normalizeConfigValue(groupedOption, groupId, groupName);
28398
28607
  if (normalizedValue !== void 0) {
28399
28608
  normalized.push(normalizedValue);
@@ -28413,7 +28622,7 @@ function normalizeConfigOptions(value, modes) {
28413
28622
  const normalized = [];
28414
28623
  if (Array.isArray(value)) {
28415
28624
  for (const option of value) {
28416
- if (!isRecord7(option)) {
28625
+ if (!isRecord8(option)) {
28417
28626
  continue;
28418
28627
  }
28419
28628
  const id = truncate4(readString3(option["id"]), 128);
@@ -28453,12 +28662,12 @@ function normalizeConfigOptions(value, modes) {
28453
28662
  }
28454
28663
  }
28455
28664
  }
28456
- if (isRecord7(modes)) {
28665
+ if (isRecord8(modes)) {
28457
28666
  const values = [];
28458
28667
  const availableModes = modes["availableModes"];
28459
28668
  if (Array.isArray(availableModes)) {
28460
28669
  for (const mode of availableModes) {
28461
- if (!isRecord7(mode)) {
28670
+ if (!isRecord8(mode)) {
28462
28671
  continue;
28463
28672
  }
28464
28673
  const id = truncate4(readString3(mode["id"]), 500);
@@ -28491,7 +28700,7 @@ function normalizeConfigOptions(value, modes) {
28491
28700
  return normalized.slice(0, MAXIMUM_CONFIG_OPTIONS);
28492
28701
  }
28493
28702
  function normalizeStandardLifecycle(response) {
28494
- const lifecycle = isRecord7(response) ? response : {};
28703
+ const lifecycle = isRecord8(response) ? response : {};
28495
28704
  return normalizeConfigOptions(lifecycle["configOptions"], lifecycle["modes"]);
28496
28705
  }
28497
28706
  function replaceStandardConfigOptions(current, value) {
@@ -28533,7 +28742,7 @@ var StandardSessionConfigProtocol = class {
28533
28742
  "ACP agent exited while changing session configuration",
28534
28743
  change.signal
28535
28744
  );
28536
- if (!isRecord7(response) || !Array.isArray(response["configOptions"])) {
28745
+ if (!isRecord8(response) || !Array.isArray(response["configOptions"])) {
28537
28746
  throw new SessionConfigProtocolError("The Agent returned an invalid session configuration response");
28538
28747
  }
28539
28748
  return replaceStandardConfigOptions(current, response["configOptions"]);
@@ -29946,7 +30155,7 @@ function sql(strings, ...params) {
29946
30155
  return new SQL([new StringChunk(str)]);
29947
30156
  }
29948
30157
  _sql.raw = raw;
29949
- function join20(chunks, separator) {
30158
+ function join22(chunks, separator) {
29950
30159
  const result = [];
29951
30160
  for (const [i, chunk] of chunks.entries()) {
29952
30161
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -29954,7 +30163,7 @@ function sql(strings, ...params) {
29954
30163
  }
29955
30164
  return new SQL(result);
29956
30165
  }
29957
- _sql.join = join20;
30166
+ _sql.join = join22;
29958
30167
  function identifier2(value) {
29959
30168
  return new Name(value);
29960
30169
  }
@@ -32099,7 +32308,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
32099
32308
  const baseTableName = this.tableName;
32100
32309
  const tableName = getTableLikeName(table);
32101
32310
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
32102
- if (typeof tableName === "string" && this.config.joins?.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
32311
+ if (typeof tableName === "string" && this.config.joins?.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
32103
32312
  if (!this.isPartialSelect) {
32104
32313
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
32105
32314
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -32938,7 +33147,7 @@ var SQLiteDialect = class {
32938
33147
  if (!joins2) return;
32939
33148
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
32940
33149
  if (!withEntries.length) return;
32941
- return sql.join(withEntries.map(([k, join20]) => {
33150
+ return sql.join(withEntries.map(([k, join22]) => {
32942
33151
  const relation = tableConfig.relations[k];
32943
33152
  const isSingle2 = is(relation, One);
32944
33153
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -32949,7 +33158,7 @@ var SQLiteDialect = class {
32949
33158
  table: targetTable,
32950
33159
  mode: isSingle2 ? "first" : "many",
32951
33160
  schema,
32952
- queryConfig: join20,
33161
+ queryConfig: join22,
32953
33162
  tableConfig: schema[relation.targetTableName],
32954
33163
  relationWhere: filter,
32955
33164
  isNested: true,
@@ -32963,7 +33172,7 @@ var SQLiteDialect = class {
32963
33172
  key: k,
32964
33173
  selection: innerQuery.selection,
32965
33174
  isArray: !isSingle2,
32966
- isOptional: (relation.optional ?? false) || join20 !== true && !!join20.where
33175
+ isOptional: (relation.optional ?? false) || join22 !== true && !!join22.where
32967
33176
  });
32968
33177
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
32969
33178
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -33579,7 +33788,7 @@ var SQLiteUpdateBase = class {
33579
33788
  createJoin(joinType) {
33580
33789
  return ((table, on) => {
33581
33790
  const tableName = getTableLikeName(table);
33582
- if (typeof tableName === "string" && this.config.joins.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
33791
+ if (typeof tableName === "string" && this.config.joins.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
33583
33792
  if (typeof on === "function") {
33584
33793
  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;
33585
33794
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -34985,7 +35194,7 @@ var AgentSession = class _AgentSession {
34985
35194
  );
34986
35195
  }
34987
35196
  initialize = async (signal, recovery, origin) => {
34988
- if (origin?.kind === "fork") {
35197
+ if (origin !== void 0) {
34989
35198
  this.#sessionTitle = origin.title;
34990
35199
  }
34991
35200
  await this.#initializeAgent(signal);
@@ -34999,7 +35208,7 @@ var AgentSession = class _AgentSession {
34999
35208
  this.#cwd,
35000
35209
  this.#additionalDirectories,
35001
35210
  true,
35002
- ""
35211
+ origin.title
35003
35212
  )
35004
35213
  ) : this.#store.read(this.#mobiusSessionId)
35005
35214
  );
@@ -36027,7 +36236,7 @@ var toolImageSchema = external_exports.union([
36027
36236
  file: external_exports.object({ base64: external_exports.string(), type: external_exports.string() })
36028
36237
  }).transform(({ file: file2 }) => ({ type: "image", data: file2.base64, mimeType: file2.type }))
36029
36238
  ]);
36030
- function isRecord8(value) {
36239
+ function isRecord9(value) {
36031
36240
  return typeof value === "object" && value !== null && !Array.isArray(value);
36032
36241
  }
36033
36242
  var AcpContentExternalizer = class {
@@ -36143,13 +36352,13 @@ var AcpContentExternalizer = class {
36143
36352
  }
36144
36353
  return result2;
36145
36354
  }
36146
- if (!isRecord8(value)) {
36355
+ if (!isRecord9(value)) {
36147
36356
  return value;
36148
36357
  }
36149
36358
  const image = toolImageSchema.safeParse(value);
36150
36359
  if (image.success && image.data.data.length > 0) {
36151
36360
  const prepared = await this.#content(sessionId, image.data, signal);
36152
- if (isRecord8(prepared.event) && typeof prepared.event["imageKey"] === "string") {
36361
+ if (isRecord9(prepared.event) && typeof prepared.event["imageKey"] === "string") {
36153
36362
  images.set(prepared.event["imageKey"], prepared);
36154
36363
  } else {
36155
36364
  images.set(`unavailable:${images.size}`, prepared);
@@ -36180,7 +36389,7 @@ var AcpContentExternalizer = class {
36180
36389
  const prepared = await this.#content(sessionId, content, signal);
36181
36390
  agentContent.push({ ...item, content: prepared.agent });
36182
36391
  eventContent.push({ ...item, content: prepared.event });
36183
- if (isRecord8(prepared.event) && typeof prepared.event["imageKey"] === "string") {
36392
+ if (isRecord9(prepared.event) && typeof prepared.event["imageKey"] === "string") {
36184
36393
  images.delete(prepared.event["imageKey"]);
36185
36394
  }
36186
36395
  }
@@ -36238,8 +36447,8 @@ var AcpContentExternalizer = class {
36238
36447
 
36239
36448
  // src/external-content/local-external-content-store.ts
36240
36449
  import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
36241
- import { lstat, mkdir as mkdir4, readdir as readdir2, realpath as realpath7, rename as rename3, rm as rm3, stat as stat6, utimes, writeFile as writeFile3 } from "node:fs/promises";
36242
- import { dirname as dirname3, join as join15 } from "node:path";
36450
+ import { lstat, mkdir as mkdir4, readdir as readdir2, realpath as realpath8, rename as rename3, rm as rm3, stat as stat7, utimes, writeFile as writeFile3 } from "node:fs/promises";
36451
+ import { dirname as dirname3, join as join17 } from "node:path";
36243
36452
  var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
36244
36453
  var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
36245
36454
  var metadataSchema2 = external_exports.strictObject({
@@ -36275,7 +36484,7 @@ var LocalExternalContentStore = class {
36275
36484
  #expirationTimer;
36276
36485
  #cleanup = Promise.resolve();
36277
36486
  constructor(stateDirectory) {
36278
- this.#root = join15(stateDirectory, "tmp", "session-content", randomUUID2());
36487
+ this.#root = join17(stateDirectory, "tmp", "session-content", randomUUID2());
36279
36488
  this.#expirationTimer = setInterval(() => {
36280
36489
  void this.#expire().catch(() => void 0);
36281
36490
  }, 6e4);
@@ -36290,11 +36499,11 @@ var LocalExternalContentStore = class {
36290
36499
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
36291
36500
  continue;
36292
36501
  }
36293
- const path2 = join15(dirname3(this.#root), directory.name);
36502
+ const path2 = join17(dirname3(this.#root), directory.name);
36294
36503
  if (path2 === this.#root) {
36295
36504
  continue;
36296
36505
  }
36297
- const modified = await stat6(path2).then(
36506
+ const modified = await stat7(path2).then(
36298
36507
  (entry) => entry.mtimeMs,
36299
36508
  () => Date.now()
36300
36509
  );
@@ -36340,10 +36549,10 @@ var LocalExternalContentStore = class {
36340
36549
  }
36341
36550
  await this.#expire();
36342
36551
  active.throwIfAborted();
36343
- const directory = join15(this.#root, kind);
36552
+ const directory = join17(this.#root, kind);
36344
36553
  await mkdir4(directory, { mode: 448, recursive: true });
36345
36554
  active.throwIfAborted();
36346
- const path2 = join15(directory, key);
36555
+ const path2 = join17(directory, key);
36347
36556
  const write = atomicWrite(path2, bytes, active);
36348
36557
  await write;
36349
36558
  active.throwIfAborted();
@@ -36376,8 +36585,8 @@ var LocalExternalContentStore = class {
36376
36585
  }
36377
36586
  try {
36378
36587
  const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
36379
- realpath7(dirname3(entry.path)),
36380
- realpath7(entry.path),
36588
+ realpath8(dirname3(entry.path)),
36589
+ realpath8(entry.path),
36381
36590
  lstat(entry.path)
36382
36591
  ]);
36383
36592
  signal.throwIfAborted();
@@ -36815,7 +37024,7 @@ var AgentRuntimeManager = class {
36815
37024
  return await this.#startRetainedSessionProcess(
36816
37025
  options,
36817
37026
  async () => await AgentSession.start(
36818
- 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,
37027
+ 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,
36819
37028
  recovery,
36820
37029
  () => this.#observer,
36821
37030
  this.#store,
@@ -37418,117 +37627,6 @@ var AgentRuntimeManager = class {
37418
37627
  });
37419
37628
  };
37420
37629
 
37421
- // src/agent-catalog/publish-agent-catalog.ts
37422
- import { fetch as fetch2 } from "undici";
37423
-
37424
- // src/relay-connection/runtime-authentication.ts
37425
- function runtimeCredential(relayUrl) {
37426
- return relayUrl.searchParams.get("token") ?? "";
37427
- }
37428
- function runtimeAuthorization(relayUrl) {
37429
- const credential = runtimeCredential(relayUrl);
37430
- return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
37431
- }
37432
- function relayHttpEndpoint(relayUrl) {
37433
- const endpoint = new URL(relayUrl);
37434
- endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
37435
- endpoint.search = "";
37436
- return endpoint;
37437
- }
37438
-
37439
- // src/agent-catalog/publish-agent-catalog.ts
37440
- var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
37441
- var AgentCatalogPublishError = class extends Error {
37442
- code = "agent_catalog_update_failed";
37443
- diagnosticDetails;
37444
- constructor(message, options = {}, diagnosticDetails = {}) {
37445
- super(message, options);
37446
- this.diagnosticDetails = diagnosticDetails;
37447
- this.name = "AgentCatalogPublishError";
37448
- }
37449
- };
37450
- function isRecord9(value) {
37451
- return typeof value === "object" && value !== null && !Array.isArray(value);
37452
- }
37453
- function isSafeRelayErrorMessage(value) {
37454
- return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
37455
- }
37456
- async function rejectedCatalogError(response) {
37457
- let value;
37458
- try {
37459
- value = await response.json();
37460
- } catch {
37461
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37462
- }
37463
- if (!isRecord9(value) || !isRecord9(value["error"])) {
37464
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37465
- }
37466
- const code = value["error"]["code"];
37467
- const message = value["error"]["message"];
37468
- if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
37469
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37470
- }
37471
- return new AgentCatalogPublishError(
37472
- `The Relay rejected the Agent catalog update (${code}): ${message}`,
37473
- {},
37474
- {
37475
- relayErrorCode: code
37476
- }
37477
- );
37478
- }
37479
- function catalogEndpoint(config2) {
37480
- const endpoint = relayHttpEndpoint(config2.relayUrl);
37481
- if (endpoint.pathname.endsWith("/daemon")) {
37482
- endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
37483
- return endpoint;
37484
- }
37485
- const runtimePath = "/v1/runtimes/connect";
37486
- if (endpoint.pathname.endsWith(runtimePath)) {
37487
- endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
37488
- return endpoint;
37489
- }
37490
- throw new AgentCatalogPublishError("The Relay URL is invalid");
37491
- }
37492
- async function publishAgentCatalog(config2, signal) {
37493
- signal.throwIfAborted();
37494
- const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
37495
- const requestSignal = AbortSignal.any([signal, timeoutSignal]);
37496
- let response;
37497
- const catalog = config2.catalog.read();
37498
- try {
37499
- response = await fetch2(catalogEndpoint(config2), {
37500
- body: JSON.stringify({
37501
- agents: catalog.agents.map((agent) => ({
37502
- agentPath: agent.agentIdentity.requestedPath,
37503
- agentVersion: agent.agentVersion,
37504
- agentSettingsDiscovery: true,
37505
- capabilities: agent.capabilities,
37506
- id: agent.id,
37507
- label: agent.label,
37508
- sessionTurnConfiguration: true
37509
- })),
37510
- installableAgents: catalog.installableAgents
37511
- }),
37512
- dispatcher: environmentProxyDispatcher,
37513
- headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
37514
- method: "PUT",
37515
- signal: requestSignal
37516
- });
37517
- } catch (error62) {
37518
- if (signal.aborted) {
37519
- signal.throwIfAborted();
37520
- }
37521
- throw new AgentCatalogPublishError(
37522
- timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
37523
- { cause: error62 }
37524
- );
37525
- }
37526
- if (!response.ok) {
37527
- throw await rejectedCatalogError(response);
37528
- }
37529
- await response.body?.cancel();
37530
- }
37531
-
37532
37630
  // src/agent-installation/agent-installation-manager.ts
37533
37631
  var INSTALLATION_DEADLINE_MILLISECONDS = 10 * 60 * 1e3;
37534
37632
  var AgentInstallation = class {
@@ -37991,9 +38089,9 @@ var FixedInstallationExecutor = class {
37991
38089
  };
37992
38090
 
37993
38091
  // src/authorization/workspace-directory.ts
37994
- import { readdir as readdir3, realpath as realpath8, stat as stat7 } from "node:fs/promises";
38092
+ import { readdir as readdir3, realpath as realpath9, stat as stat8 } from "node:fs/promises";
37995
38093
  import { homedir as homedir2 } from "node:os";
37996
- import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute10, join as join16, normalize as normalize3, relative as relative4 } from "node:path";
38094
+ import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute10, join as join18, normalize as normalize3, relative as relative4 } from "node:path";
37997
38095
 
37998
38096
  // src/authorization/local-authorization-error.ts
37999
38097
  var LocalAuthorizationError = class extends Error {
@@ -38072,9 +38170,9 @@ var WorkspaceDirectoryService = class {
38072
38170
  throw new LocalAuthorizationError("The local directory path is invalid");
38073
38171
  }
38074
38172
  try {
38075
- const target = await realpath8(requested);
38173
+ const target = await realpath9(requested);
38076
38174
  signal.throwIfAborted();
38077
- const metadata = await stat7(target);
38175
+ const metadata = await stat8(target);
38078
38176
  signal.throwIfAborted();
38079
38177
  if (!isAbsolute10(target) || normalize3(target) !== target || !metadata.isDirectory()) {
38080
38178
  throw new LocalAuthorizationError("The selected location is not a directory");
@@ -38122,7 +38220,7 @@ var WorkspaceDirectoryService = class {
38122
38220
  continue;
38123
38221
  }
38124
38222
  try {
38125
- const path2 = await this.resolvePath(join16(target, child2.name), signal);
38223
+ const path2 = await this.resolvePath(join18(target, child2.name), signal);
38126
38224
  entries.push({ directoryId: encodePath(path2), name: child2.name });
38127
38225
  } catch (cause) {
38128
38226
  signal.throwIfAborted();
@@ -38158,15 +38256,15 @@ var WorkspaceDirectoryService = class {
38158
38256
 
38159
38257
  // src/daemon-diagnostic-log.ts
38160
38258
  import { appendFileSync, mkdirSync, readFileSync as readFileSync2, renameSync, statSync as statSync3, writeFileSync } from "node:fs";
38161
- import { join as join17 } from "node:path";
38259
+ import { join as join19 } from "node:path";
38162
38260
  var MAXIMUM_DAEMON_LOG_BYTES = 1 * 1024 * 1024;
38163
38261
  var DaemonDiagnosticLog = class {
38164
38262
  #directory;
38165
38263
  #path;
38166
38264
  #maximumBytes;
38167
38265
  constructor(stateDirectory, maximumBytes = MAXIMUM_DAEMON_LOG_BYTES) {
38168
- this.#directory = join17(stateDirectory, "logs");
38169
- this.#path = join17(this.#directory, "daemon.log");
38266
+ this.#directory = join19(stateDirectory, "logs");
38267
+ this.#path = join19(this.#directory, "daemon.log");
38170
38268
  this.#maximumBytes = maximumBytes;
38171
38269
  }
38172
38270
  // Export only correlation and failure metadata. Local messages and paths stay local.
@@ -40111,9 +40209,10 @@ var NativeSessionService = class {
40111
40209
  signal
40112
40210
  );
40113
40211
  signal.throwIfAborted();
40212
+ const cataloged = this.#config.catalog.find(command.agentId);
40114
40213
  const options = {
40115
40214
  additionalDirectories,
40116
- agent: this.#config.catalog.find(command.agentId),
40215
+ agent: this.#config.resolveAgent === void 0 ? cataloged : await this.#config.resolveAgent(cataloged, signal),
40117
40216
  cwd,
40118
40217
  sessionId: command.sessionId,
40119
40218
  signal
@@ -40291,7 +40390,7 @@ var NativeSessionService = class {
40291
40390
  sessionId: command.targetSessionId,
40292
40391
  additionalDirectories: target.additionalDirectories
40293
40392
  },
40294
- action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId }
40393
+ action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId, title: title2 }
40295
40394
  );
40296
40395
  signal.throwIfAborted();
40297
40396
  const ready = {
@@ -40665,7 +40764,7 @@ import { WebSocket as WebSocket5 } from "undici";
40665
40764
  // package.json
40666
40765
  var package_default = {
40667
40766
  name: "@moxt-ai/mobius",
40668
- version: "0.0.193",
40767
+ version: "0.0.194",
40669
40768
  description: "Mobius CLI for pairing and running local AI agent services.",
40670
40769
  type: "module",
40671
40770
  bin: {
@@ -40968,7 +41067,8 @@ function unsupportedModelIds(unsupportedModels) {
40968
41067
  return [...new Set(unsupportedModels.map((item) => item.requestedValue))];
40969
41068
  }
40970
41069
  async function discoverAgentSettings(command, config2, directories, sessions, signal) {
40971
- const agent = config2.catalog.find(command.agentId);
41070
+ const cataloged = config2.catalog.find(command.agentId);
41071
+ const agent = config2.resolveAgent === void 0 ? cataloged : await config2.resolveAgent(cataloged, signal);
40972
41072
  const cwd = await directories.resolve(config2.bindingId, "default", signal);
40973
41073
  const inspectedBaseSnapshot = await sessions.inspectAgentSettings({
40974
41074
  additionalDirectories: [],
@@ -41362,7 +41462,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
41362
41462
 
41363
41463
  // src/artifacts/local-file-streamer.ts
41364
41464
  import { createReadStream as createReadStream2 } from "node:fs";
41365
- import { realpath as realpath9, stat as stat8 } from "node:fs/promises";
41465
+ import { realpath as realpath10, stat as stat9 } from "node:fs/promises";
41366
41466
  import { basename as basename4, extname, isAbsolute as isAbsolute11, normalize as normalize4, resolve as resolve5 } from "node:path";
41367
41467
  import { fileURLToPath as fileURLToPath2 } from "node:url";
41368
41468
  var CHUNK_BYTES = 192 * 1024;
@@ -41390,7 +41490,7 @@ async function resolveFile(value, workingDirectory, signal) {
41390
41490
  return null;
41391
41491
  }
41392
41492
  try {
41393
- const target = await realpath9(requested);
41493
+ const target = await realpath10(requested);
41394
41494
  signal.throwIfAborted();
41395
41495
  return isAbsolute11(target) && normalize4(target) === target ? target : null;
41396
41496
  } catch {
@@ -41404,7 +41504,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
41404
41504
  if (target === null) {
41405
41505
  throw new Error("The local file is unavailable");
41406
41506
  }
41407
- const before = await stat8(target);
41507
+ const before = await stat9(target);
41408
41508
  signal.throwIfAborted();
41409
41509
  if (!before.isFile() || before.size < 1 || before.size > command.maxBytes) {
41410
41510
  throw new Error("The local file is too large to read");
@@ -41432,7 +41532,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
41432
41532
  });
41433
41533
  sequence += 1;
41434
41534
  }
41435
- const after = await stat8(target);
41535
+ const after = await stat9(target);
41436
41536
  signal.throwIfAborted();
41437
41537
  if (after.size !== before.size || after.mtimeMs !== before.mtimeMs) {
41438
41538
  throw new Error("The local file changed during transfer");
@@ -41476,6 +41576,232 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
41476
41576
  return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
41477
41577
  }
41478
41578
 
41579
+ // src/daemon-session-commands.ts
41580
+ async function resolveCatalogAgent(config2, agentId, signal) {
41581
+ const agent = config2.catalog.find(agentId);
41582
+ return config2.resolveAgent === void 0 ? agent : await config2.resolveAgent(agent, signal);
41583
+ }
41584
+ async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
41585
+ return await metrics.measure("prepare-total", async () => {
41586
+ const resolved = await metrics.measure(
41587
+ "workspace-resolve",
41588
+ async () => await resolveSessionDirectories(
41589
+ directories,
41590
+ config2.bindingId,
41591
+ command.directoryId,
41592
+ command.additionalDirectoryIds,
41593
+ signal
41594
+ )
41595
+ );
41596
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
41597
+ const preparation = {
41598
+ additionalDirectories: resolved.additionalDirectories,
41599
+ agent,
41600
+ cwd: resolved.cwd,
41601
+ sessionId: command.sessionId,
41602
+ signal
41603
+ };
41604
+ const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
41605
+ const configuration = command.configuration;
41606
+ const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
41607
+ "configuration",
41608
+ async () => await sessions.configureSession({
41609
+ ...preparation,
41610
+ booleanValue: configuration.booleanValue,
41611
+ configId: configuration.configId,
41612
+ requestId: command.requestId,
41613
+ value: configuration.value,
41614
+ valueType: configuration.valueType
41615
+ })
41616
+ );
41617
+ const listing = await metrics.measure(
41618
+ "workspace-list",
41619
+ async () => await directories.list(config2.bindingId, command.directoryId, signal)
41620
+ );
41621
+ audit.record({
41622
+ commandId: command.requestId,
41623
+ event: "session_prepared",
41624
+ sessionId: command.sessionId
41625
+ });
41626
+ if (command.configuration !== void 0) {
41627
+ audit.record({
41628
+ commandId: command.requestId,
41629
+ event: "session_configured",
41630
+ sessionId: command.sessionId
41631
+ });
41632
+ }
41633
+ return {
41634
+ additionalDirectories: resolved.additionalDirectoryEntries,
41635
+ agentId: command.agentId,
41636
+ agentName: prepared.agentName,
41637
+ agentVersion: prepared.agentVersion,
41638
+ capabilities: prepared.capabilities,
41639
+ commands: prepared.commands,
41640
+ configOptions,
41641
+ directoryId: command.directoryId,
41642
+ directoryLabel: listing.directoryLabel,
41643
+ kind: "session.ready",
41644
+ requestId: command.requestId,
41645
+ restored: prepared.restored,
41646
+ sessionId: command.sessionId
41647
+ };
41648
+ });
41649
+ }
41650
+ async function executeWorkspaceList(socket, command, directories, audit, signal) {
41651
+ try {
41652
+ const listing = await directories.list(command.bindingId, command.directoryId, signal);
41653
+ audit.record({
41654
+ commandId: command.requestId,
41655
+ event: "workspace_list_authorized",
41656
+ sessionId: "workspace-browser"
41657
+ });
41658
+ send(socket, {
41659
+ bindingId: command.bindingId,
41660
+ directoryId: listing.directoryId,
41661
+ directoryLabel: listing.directoryLabel,
41662
+ entries: listing.entries,
41663
+ kind: "workspace.entries",
41664
+ parentDirectoryId: listing.parentDirectoryId,
41665
+ requestId: command.requestId
41666
+ });
41667
+ } catch (error62) {
41668
+ reportOperationFailure(socket, command.requestId, "", error62);
41669
+ }
41670
+ }
41671
+ async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
41672
+ const metrics = new AccumulatingOperationMetrics();
41673
+ try {
41674
+ const readyEvent = await prepareSession(
41675
+ command,
41676
+ { kind: "interactive-only" },
41677
+ config2,
41678
+ directories,
41679
+ audit,
41680
+ sessions,
41681
+ metrics,
41682
+ signal
41683
+ );
41684
+ send(socket, {
41685
+ ...readyEvent,
41686
+ runtimeTimings: metrics.snapshot()
41687
+ });
41688
+ } catch (error62) {
41689
+ diagnostics.daemonDiagnostic(
41690
+ "session_prepare_failed",
41691
+ command.requestId,
41692
+ {
41693
+ agentId: command.agentId,
41694
+ code: operationErrorCode(error62),
41695
+ sessionId: command.sessionId
41696
+ },
41697
+ error62
41698
+ );
41699
+ audit.record({
41700
+ commandId: command.requestId,
41701
+ details: {
41702
+ agentId: command.agentId,
41703
+ code: operationErrorCode(error62)
41704
+ },
41705
+ event: "session_prepare_failed",
41706
+ sessionId: command.sessionId
41707
+ });
41708
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
41709
+ }
41710
+ }
41711
+ async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
41712
+ const metrics = new AccumulatingOperationMetrics();
41713
+ try {
41714
+ const entry = await metrics.measure("session-lookup", async () => {
41715
+ const [found] = await nativeSessions.querySessions([command.sessionId], signal);
41716
+ if (found === void 0) {
41717
+ throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
41718
+ }
41719
+ return found;
41720
+ });
41721
+ const ready = await prepareSession(
41722
+ {
41723
+ additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
41724
+ agentId: entry.agentId,
41725
+ bindingId: config2.bindingId,
41726
+ directoryId: entry.directoryId,
41727
+ kind: "session.prepare",
41728
+ requestId: command.requestId,
41729
+ sessionId: command.sessionId,
41730
+ sessionState: "provisioned"
41731
+ },
41732
+ { kind: "history-required" },
41733
+ config2,
41734
+ directories,
41735
+ audit,
41736
+ sessions,
41737
+ metrics,
41738
+ signal
41739
+ );
41740
+ send(socket, {
41741
+ entry,
41742
+ kind: "session.restored",
41743
+ ready: { ...ready, runtimeTimings: metrics.snapshot() },
41744
+ requestId: command.requestId
41745
+ });
41746
+ } catch (error62) {
41747
+ diagnostics.daemonDiagnostic(
41748
+ "session_restore_failed",
41749
+ command.requestId,
41750
+ {
41751
+ code: operationErrorCode(error62),
41752
+ sessionId: command.sessionId
41753
+ },
41754
+ error62
41755
+ );
41756
+ audit.record({
41757
+ commandId: command.requestId,
41758
+ details: { code: operationErrorCode(error62) },
41759
+ event: "session_restore_failed",
41760
+ sessionId: command.sessionId
41761
+ });
41762
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
41763
+ }
41764
+ }
41765
+ async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
41766
+ try {
41767
+ const resolved = await resolveSessionDirectories(
41768
+ directories,
41769
+ config2.bindingId,
41770
+ command.directoryId,
41771
+ command.additionalDirectoryIds,
41772
+ signal
41773
+ );
41774
+ const configOptions = await sessions.configureSession({
41775
+ additionalDirectories: resolved.additionalDirectories,
41776
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
41777
+ booleanValue: command.booleanValue,
41778
+ configId: command.configId,
41779
+ cwd: resolved.cwd,
41780
+ requestId: command.requestId,
41781
+ sessionId: command.sessionId,
41782
+ signal,
41783
+ value: command.value,
41784
+ valueType: command.valueType
41785
+ });
41786
+ audit.record({
41787
+ commandId: command.requestId,
41788
+ event: "session_configured",
41789
+ sessionId: command.sessionId
41790
+ });
41791
+ send(socket, {
41792
+ configOptions,
41793
+ kind: "session.config.updated",
41794
+ requestId: command.requestId,
41795
+ sessionId: command.sessionId
41796
+ });
41797
+ } catch (error62) {
41798
+ if (signal.aborted) {
41799
+ signal.throwIfAborted();
41800
+ }
41801
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62);
41802
+ }
41803
+ }
41804
+
41479
41805
  // src/daemon-history-commands.ts
41480
41806
  async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, directories, audit, diagnostics, sessions, nativeSessions, eventLogV2, signal) {
41481
41807
  let agentId;
@@ -41494,7 +41820,7 @@ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, dir
41494
41820
  );
41495
41821
  const loadOptions = {
41496
41822
  additionalDirectories: resolved.additionalDirectories,
41497
- agent: config2.catalog.find(entry.agentId),
41823
+ agent: await resolveCatalogAgent(config2, entry.agentId, signal),
41498
41824
  cwd: resolved.cwd,
41499
41825
  sessionId: command.sessionId,
41500
41826
  signal
@@ -41570,7 +41896,7 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, di
41570
41896
  const replay = await sessions.previewNativeSessionEventsV2(
41571
41897
  {
41572
41898
  additionalDirectories: resolved.additionalDirectories,
41573
- agent: config2.catalog.find(command.agentId),
41899
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
41574
41900
  cwd: resolved.cwd,
41575
41901
  sessionId: command.sessionId,
41576
41902
  signal
@@ -41862,7 +42188,7 @@ async function executePrompt({
41862
42188
  command.additionalDirectoryIds,
41863
42189
  signal
41864
42190
  );
41865
- const agent = config2.catalog.find(command.agentId);
42191
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
41866
42192
  const availability = await waitForSessionAvailability(signal);
41867
42193
  if (availability.kind === "busy") {
41868
42194
  throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
@@ -42007,228 +42333,6 @@ async function executePrompt({
42007
42333
  }
42008
42334
  }
42009
42335
 
42010
- // src/daemon-session-commands.ts
42011
- async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
42012
- return await metrics.measure("prepare-total", async () => {
42013
- const resolved = await metrics.measure(
42014
- "workspace-resolve",
42015
- async () => await resolveSessionDirectories(
42016
- directories,
42017
- config2.bindingId,
42018
- command.directoryId,
42019
- command.additionalDirectoryIds,
42020
- signal
42021
- )
42022
- );
42023
- const agent = config2.catalog.find(command.agentId);
42024
- const preparation = {
42025
- additionalDirectories: resolved.additionalDirectories,
42026
- agent,
42027
- cwd: resolved.cwd,
42028
- sessionId: command.sessionId,
42029
- signal
42030
- };
42031
- const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
42032
- const configuration = command.configuration;
42033
- const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
42034
- "configuration",
42035
- async () => await sessions.configureSession({
42036
- ...preparation,
42037
- booleanValue: configuration.booleanValue,
42038
- configId: configuration.configId,
42039
- requestId: command.requestId,
42040
- value: configuration.value,
42041
- valueType: configuration.valueType
42042
- })
42043
- );
42044
- const listing = await metrics.measure(
42045
- "workspace-list",
42046
- async () => await directories.list(config2.bindingId, command.directoryId, signal)
42047
- );
42048
- audit.record({
42049
- commandId: command.requestId,
42050
- event: "session_prepared",
42051
- sessionId: command.sessionId
42052
- });
42053
- if (command.configuration !== void 0) {
42054
- audit.record({
42055
- commandId: command.requestId,
42056
- event: "session_configured",
42057
- sessionId: command.sessionId
42058
- });
42059
- }
42060
- return {
42061
- additionalDirectories: resolved.additionalDirectoryEntries,
42062
- agentId: command.agentId,
42063
- agentName: prepared.agentName,
42064
- agentVersion: prepared.agentVersion,
42065
- capabilities: prepared.capabilities,
42066
- commands: prepared.commands,
42067
- configOptions,
42068
- directoryId: command.directoryId,
42069
- directoryLabel: listing.directoryLabel,
42070
- kind: "session.ready",
42071
- requestId: command.requestId,
42072
- restored: prepared.restored,
42073
- sessionId: command.sessionId
42074
- };
42075
- });
42076
- }
42077
- async function executeWorkspaceList(socket, command, directories, audit, signal) {
42078
- try {
42079
- const listing = await directories.list(command.bindingId, command.directoryId, signal);
42080
- audit.record({
42081
- commandId: command.requestId,
42082
- event: "workspace_list_authorized",
42083
- sessionId: "workspace-browser"
42084
- });
42085
- send(socket, {
42086
- bindingId: command.bindingId,
42087
- directoryId: listing.directoryId,
42088
- directoryLabel: listing.directoryLabel,
42089
- entries: listing.entries,
42090
- kind: "workspace.entries",
42091
- parentDirectoryId: listing.parentDirectoryId,
42092
- requestId: command.requestId
42093
- });
42094
- } catch (error62) {
42095
- reportOperationFailure(socket, command.requestId, "", error62);
42096
- }
42097
- }
42098
- async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
42099
- const metrics = new AccumulatingOperationMetrics();
42100
- try {
42101
- const readyEvent = await prepareSession(
42102
- command,
42103
- { kind: "interactive-only" },
42104
- config2,
42105
- directories,
42106
- audit,
42107
- sessions,
42108
- metrics,
42109
- signal
42110
- );
42111
- send(socket, {
42112
- ...readyEvent,
42113
- runtimeTimings: metrics.snapshot()
42114
- });
42115
- } catch (error62) {
42116
- diagnostics.daemonDiagnostic(
42117
- "session_prepare_failed",
42118
- command.requestId,
42119
- {
42120
- agentId: command.agentId,
42121
- code: operationErrorCode(error62),
42122
- sessionId: command.sessionId
42123
- },
42124
- error62
42125
- );
42126
- audit.record({
42127
- commandId: command.requestId,
42128
- details: {
42129
- agentId: command.agentId,
42130
- code: operationErrorCode(error62)
42131
- },
42132
- event: "session_prepare_failed",
42133
- sessionId: command.sessionId
42134
- });
42135
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42136
- }
42137
- }
42138
- async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
42139
- const metrics = new AccumulatingOperationMetrics();
42140
- try {
42141
- const entry = await metrics.measure("session-lookup", async () => {
42142
- const [found] = await nativeSessions.querySessions([command.sessionId], signal);
42143
- if (found === void 0) {
42144
- throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
42145
- }
42146
- return found;
42147
- });
42148
- const ready = await prepareSession(
42149
- {
42150
- additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
42151
- agentId: entry.agentId,
42152
- bindingId: config2.bindingId,
42153
- directoryId: entry.directoryId,
42154
- kind: "session.prepare",
42155
- requestId: command.requestId,
42156
- sessionId: command.sessionId,
42157
- sessionState: "provisioned"
42158
- },
42159
- { kind: "history-required" },
42160
- config2,
42161
- directories,
42162
- audit,
42163
- sessions,
42164
- metrics,
42165
- signal
42166
- );
42167
- send(socket, {
42168
- entry,
42169
- kind: "session.restored",
42170
- ready: { ...ready, runtimeTimings: metrics.snapshot() },
42171
- requestId: command.requestId
42172
- });
42173
- } catch (error62) {
42174
- diagnostics.daemonDiagnostic(
42175
- "session_restore_failed",
42176
- command.requestId,
42177
- {
42178
- code: operationErrorCode(error62),
42179
- sessionId: command.sessionId
42180
- },
42181
- error62
42182
- );
42183
- audit.record({
42184
- commandId: command.requestId,
42185
- details: { code: operationErrorCode(error62) },
42186
- event: "session_restore_failed",
42187
- sessionId: command.sessionId
42188
- });
42189
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42190
- }
42191
- }
42192
- async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
42193
- try {
42194
- const resolved = await resolveSessionDirectories(
42195
- directories,
42196
- config2.bindingId,
42197
- command.directoryId,
42198
- command.additionalDirectoryIds,
42199
- signal
42200
- );
42201
- const configOptions = await sessions.configureSession({
42202
- additionalDirectories: resolved.additionalDirectories,
42203
- agent: config2.catalog.find(command.agentId),
42204
- booleanValue: command.booleanValue,
42205
- configId: command.configId,
42206
- cwd: resolved.cwd,
42207
- requestId: command.requestId,
42208
- sessionId: command.sessionId,
42209
- signal,
42210
- value: command.value,
42211
- valueType: command.valueType
42212
- });
42213
- audit.record({
42214
- commandId: command.requestId,
42215
- event: "session_configured",
42216
- sessionId: command.sessionId
42217
- });
42218
- send(socket, {
42219
- configOptions,
42220
- kind: "session.config.updated",
42221
- requestId: command.requestId,
42222
- sessionId: command.sessionId
42223
- });
42224
- } catch (error62) {
42225
- if (signal.aborted) {
42226
- signal.throwIfAborted();
42227
- }
42228
- reportOperationFailure(socket, command.requestId, command.sessionId, error62);
42229
- }
42230
- }
42231
-
42232
42336
  // src/native-sessions/handle-native-requests.ts
42233
42337
  import { WebSocket as WebSocket4 } from "undici";
42234
42338
  function createNativeSessionRequestHandler(dependencies) {
@@ -43421,11 +43525,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43421
43525
  stateDirectory
43422
43526
  });
43423
43527
  const channelHash = createHash7("sha256").update(config2.channelId).digest("hex");
43424
- const sessionDatabase = openAcpSessionDatabase(join18(stateDirectory, "sessions", `${channelHash}.sqlite`));
43528
+ const sessionDatabase = openAcpSessionDatabase(join20(stateDirectory, "sessions", `${channelHash}.sqlite`));
43425
43529
  let eventsV2;
43426
43530
  try {
43427
43531
  eventsV2 = new CachedAcpSessionEventStoreV2(
43428
- openSessionEventCacheV2Database(join18(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
43532
+ openSessionEventCacheV2Database(join20(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
43429
43533
  );
43430
43534
  } catch (error62) {
43431
43535
  sessionDatabase.close();
@@ -43628,7 +43732,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43628
43732
  }
43629
43733
 
43630
43734
  // src/pairing/pair-local-machine.ts
43631
- import { mkdir as mkdir6, realpath as realpath10, stat as stat9 } from "node:fs/promises";
43735
+ import { mkdir as mkdir6, realpath as realpath11, stat as stat10 } from "node:fs/promises";
43632
43736
  import { hostname as hostname3 } from "node:os";
43633
43737
  import { basename as basename6, resolve as resolve7 } from "node:path";
43634
43738
  import { fetch as fetch4 } from "undici";
@@ -43636,7 +43740,7 @@ import { fetch as fetch4 } from "undici";
43636
43740
  // src/storage/runtime-installation-store.ts
43637
43741
  import { createHash as createHash8, randomUUID as randomUUID9 } from "node:crypto";
43638
43742
  import { mkdir as mkdir5, open as open5, readdir as readdir4, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
43639
- import { dirname as dirname6, join as join19, resolve as resolve6 } from "node:path";
43743
+ import { dirname as dirname6, join as join21, resolve as resolve6 } from "node:path";
43640
43744
  var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
43641
43745
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
43642
43746
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
@@ -43879,7 +43983,7 @@ async function readJsonFile(path2, signal, missingCode) {
43879
43983
  async function writeJsonAtomically(path2, value, signal) {
43880
43984
  signal.throwIfAborted();
43881
43985
  const directory = dirname6(path2);
43882
- const temporaryPath = join19(directory, `.${randomUUID9()}.tmp`);
43986
+ const temporaryPath = join21(directory, `.${randomUUID9()}.tmp`);
43883
43987
  try {
43884
43988
  await mkdir5(directory, { mode: 448, recursive: true });
43885
43989
  signal.throwIfAborted();
@@ -43905,14 +44009,14 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
43905
44009
  this.applicationId = applicationId;
43906
44010
  this.installationId = installationId2;
43907
44011
  this.stateDirectory = stateDirectory;
43908
- this.#channelDirectory = join19(stateDirectory, "channels");
43909
- this.#connectionDirectory = join19(stateDirectory, "connections");
44012
+ this.#channelDirectory = join21(stateDirectory, "channels");
44013
+ this.#connectionDirectory = join21(stateDirectory, "connections");
43910
44014
  }
43911
44015
  static open = async (options, signal) => {
43912
44016
  signal.throwIfAborted();
43913
44017
  const applicationId = validateApplicationId(options.applicationId);
43914
44018
  const rootDirectory = resolve6(options.stateDirectory);
43915
- const applicationDirectory = join19(rootDirectory, "installations", applicationId);
44019
+ const applicationDirectory = join21(rootDirectory, "installations", applicationId);
43916
44020
  try {
43917
44021
  await mkdir5(applicationDirectory, { mode: 448, recursive: true });
43918
44022
  } catch (cause) {
@@ -43925,7 +44029,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
43925
44029
  );
43926
44030
  }
43927
44031
  const storedInstallationId = await readOrCreateInstallationId(applicationDirectory, signal);
43928
- const stateDirectory = join19(applicationDirectory, storedInstallationId);
44032
+ const stateDirectory = join21(applicationDirectory, storedInstallationId);
43929
44033
  try {
43930
44034
  await mkdir5(stateDirectory, { mode: 448, recursive: true });
43931
44035
  } catch (cause) {
@@ -43940,8 +44044,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
43940
44044
  signal.throwIfAborted();
43941
44045
  return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
43942
44046
  };
43943
- connectionPath = (connectionId2) => join19(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
43944
- channelIndexPath = (channelId) => join19(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
44047
+ connectionPath = (connectionId2) => join21(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
44048
+ channelIndexPath = (channelId) => join21(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
43945
44049
  readConnection = async (connectionId2, signal) => {
43946
44050
  const stored = decodeConnection(
43947
44051
  await readJsonFile(this.connectionPath(connectionId2), signal, "connection_not_found")
@@ -44103,7 +44207,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
44103
44207
  };
44104
44208
  };
44105
44209
  async function readOrCreateInstallationId(applicationDirectory, signal) {
44106
- const pointerPath = join19(applicationDirectory, "current.json");
44210
+ const pointerPath = join21(applicationDirectory, "current.json");
44107
44211
  try {
44108
44212
  return decodeInstallationPointer(await readJsonFile(pointerPath, signal, "installation_not_found")).installationId;
44109
44213
  } catch (cause) {
@@ -44198,8 +44302,8 @@ async function resolveDefaultWorkspace2(path2) {
44198
44302
  const requestedWorkspace = resolve7(path2);
44199
44303
  try {
44200
44304
  await mkdir6(requestedWorkspace, { recursive: true, mode: 448 });
44201
- const defaultWorkspace = await realpath10(requestedWorkspace);
44202
- const metadata = await stat9(defaultWorkspace);
44305
+ const defaultWorkspace = await realpath11(requestedWorkspace);
44306
+ const metadata = await stat10(defaultWorkspace);
44203
44307
  if (!metadata.isDirectory()) {
44204
44308
  throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
44205
44309
  }
@@ -44298,20 +44402,30 @@ function buildPairedDaemon(installation, connection, defaultWorkspace, inventory
44298
44402
  const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
44299
44403
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
44300
44404
  relayUrl.searchParams.set("token", connection.runtimeCredential);
44405
+ const config2 = createDaemonConfig(
44406
+ {
44407
+ defaultWorkspace,
44408
+ channelId: connection.channelId,
44409
+ relayUrl
44410
+ },
44411
+ inventory.readyAgents(),
44412
+ inventory.installable,
44413
+ localContext,
44414
+ new OpaqueDaemonReconnectTarget(connection.connectionId),
44415
+ createCatalogAgentResolver(
44416
+ (refreshSignal) => discoverLocalAgentInventory({
44417
+ defaultWorkspace,
44418
+ environment: localContext.environment,
44419
+ signal: refreshSignal
44420
+ }),
44421
+ () => config2,
44422
+ publishAgentCatalog
44423
+ )
44424
+ );
44301
44425
  return {
44302
44426
  channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
44303
44427
  connectionId: connection.connectionId,
44304
- config: createDaemonConfig(
44305
- {
44306
- defaultWorkspace,
44307
- channelId: connection.channelId,
44308
- relayUrl
44309
- },
44310
- inventory.readyAgents(),
44311
- inventory.installable,
44312
- localContext,
44313
- new OpaqueDaemonReconnectTarget(connection.connectionId)
44314
- ),
44428
+ config: config2,
44315
44429
  connectionPath: installation.connectionPath(connection.connectionId)
44316
44430
  };
44317
44431
  }
@@ -44434,8 +44548,8 @@ async function resolveWorkspace(path2) {
44434
44548
  const requested = resolve8(path2);
44435
44549
  try {
44436
44550
  await mkdir7(requested, { recursive: true, mode: 448 });
44437
- const resolved = await realpath11(requested);
44438
- const metadata = await stat10(resolved);
44551
+ const resolved = await realpath12(requested);
44552
+ const metadata = await stat11(resolved);
44439
44553
  if (!metadata.isDirectory()) {
44440
44554
  throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
44441
44555
  }
@@ -44452,26 +44566,35 @@ async function createMobiusRuntimeEngine(connection, signal, environment = proce
44452
44566
  const localContext = new DaemonLocalContext(readStateDirectory(environment), environment);
44453
44567
  const relayUrl = relayUrlFromConnection(connection);
44454
44568
  const defaultWorkspace = await resolveWorkspace(connection.defaultWorkspace);
44455
- const inventory = await discoverLocalAgentInventory({
44569
+ const specifications = supportedLocalAgentSpecifications();
44570
+ const discoveryEnvironment = localContext.environment;
44571
+ const discover = async (refreshSignal) => await discoverLocalAgentInventory({
44456
44572
  defaultWorkspace,
44457
- environment: localContext.environment,
44458
- signal
44573
+ environment: discoveryEnvironment,
44574
+ signal: refreshSignal,
44575
+ specifications
44459
44576
  });
44577
+ const inventory = await discover(signal);
44460
44578
  if (inventory.available.length + inventory.installable.length === 0) {
44461
44579
  throw new MobiusRuntimeConfigurationError("No supported Agent is available for the local Runtime");
44462
44580
  }
44463
- return new MobiusRuntimeEngine(
44464
- createDaemonConfig(
44465
- {
44466
- channelId: connection.channelId,
44467
- defaultWorkspace,
44468
- relayUrl
44469
- },
44470
- inventory.readyAgents(),
44471
- inventory.installable,
44472
- localContext
44581
+ const config2 = createDaemonConfig(
44582
+ {
44583
+ channelId: connection.channelId,
44584
+ defaultWorkspace,
44585
+ relayUrl
44586
+ },
44587
+ inventory.readyAgents(),
44588
+ inventory.installable,
44589
+ localContext,
44590
+ null,
44591
+ createCatalogAgentResolver(
44592
+ (refreshSignal) => discover(refreshSignal),
44593
+ () => config2,
44594
+ publishAgentCatalog
44473
44595
  )
44474
44596
  );
44597
+ return new MobiusRuntimeEngine(config2);
44475
44598
  }
44476
44599
  var MobiusRuntimeEngine = class {
44477
44600
  #config;