@moxt-ai/mobius 0.0.193 → 0.0.195

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 +965 -800
  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 +73 -31
  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 +970 -796
  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 +988 -814
  73. package/dist/runtime.js.map +4 -4
  74. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
32
32
  })).onNotification("cursor/update_todos", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/task", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/generate_image", discardExtensionParams, async () => Promise.resolve());
33
33
 
34
34
  // src/config.ts
35
- import { join as join3, resolve as resolve3 } from "node:path";
35
+ import { join as join5, resolve as resolve3 } from "node:path";
36
36
 
37
37
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
38
38
  var external_exports = {};
@@ -21353,6 +21353,7 @@ var provenanceSchema = external_exports.discriminatedUnion("kind", [
21353
21353
  ]);
21354
21354
  var sessionEventFieldsV2 = {
21355
21355
  eventId: identifierStringSchema,
21356
+ mobiusMetadata: external_exports.object({ omitted: external_exports.literal(true).optional() }).readonly().optional(),
21356
21357
  position: positionSchema,
21357
21358
  provenance: provenanceSchema,
21358
21359
  recordedAt: external_exports.iso.datetime({ offset: true }),
@@ -21419,7 +21420,12 @@ var sessionEventLogPageV2Schema = external_exports.object({
21419
21420
  truncated: external_exports.boolean(),
21420
21421
  version: external_exports.literal(2)
21421
21422
  }).readonly();
21422
- var nativeEventPageRequestV2Schema = external_exports.object({ cursor: external_exports.string().min(1).max(512).nullable(), eventLimit: external_exports.number().int().min(1).max(1e4) }).readonly();
21423
+ var sessionEventOmissionV2Schema = external_exports.literal("agent-reasoning");
21424
+ var nativeEventPageRequestV2Schema = external_exports.object({
21425
+ cursor: external_exports.string().min(1).max(512).nullable(),
21426
+ eventLimit: external_exports.number().int().min(1).max(1e4),
21427
+ omit: external_exports.array(sessionEventOmissionV2Schema).max(1).readonly().optional()
21428
+ }).readonly();
21423
21429
  var queuedPromptRequestEventLogV2Schema = external_exports.object({
21424
21430
  commandId: identifierStringSchema,
21425
21431
  content: external_exports.array(contentBlockV2Schema).min(1).max(100).readonly(),
@@ -21466,6 +21472,7 @@ var directoryIdentifier = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-
21466
21472
  var pageRequestFields = {
21467
21473
  cursor: external_exports.string().min(1).max(512).nullable(),
21468
21474
  eventLimit: external_exports.number().int().min(1).max(1e4),
21475
+ omit: external_exports.array(sessionEventOmissionV2Schema).max(1).readonly().optional(),
21469
21476
  requestId: identifierStringSchema,
21470
21477
  sessionId: identifierStringSchema
21471
21478
  };
@@ -21822,15 +21829,266 @@ function normalizeAcpCapabilities(initialized) {
21822
21829
  }
21823
21830
 
21824
21831
  // src/process/executable.ts
21825
- import { execFile, spawn } from "node:child_process";
21832
+ import { spawn } from "node:child_process";
21833
+ import { constants as constants2 } from "node:fs";
21834
+ import { access as access2, realpath as realpath2, stat as stat2 } from "node:fs/promises";
21835
+ import { join as join3, resolve } from "node:path";
21836
+
21837
+ // src/platform/linux.ts
21826
21838
  import { constants, readdirSync, readFileSync } from "node:fs";
21827
21839
  import { access, readdir, readFile, realpath, stat } from "node:fs/promises";
21828
- import { join, resolve } from "node:path";
21840
+ import { join } from "node:path";
21841
+
21842
+ // src/platform/posix.ts
21843
+ import { execFile } from "node:child_process";
21844
+ var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21845
+ var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21846
+ function parseProcessTable(output2) {
21847
+ const entries = [];
21848
+ for (const line of output2.split("\n")) {
21849
+ const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21850
+ if (groups === void 0) {
21851
+ continue;
21852
+ }
21853
+ const processId = Number(groups["pid"]);
21854
+ const parentProcessId = Number(groups["ppid"]);
21855
+ const processGroupId = Number(groups["pgid"]);
21856
+ if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21857
+ continue;
21858
+ }
21859
+ entries.push({ parentProcessId, processGroupId, processId });
21860
+ }
21861
+ return entries;
21862
+ }
21863
+ function readProcessTableWithPs(executable) {
21864
+ return new Promise((resolveTable) => {
21865
+ execFile(
21866
+ executable,
21867
+ ["-axo", "pid=,ppid=,pgid="],
21868
+ {
21869
+ encoding: "utf8",
21870
+ maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
21871
+ signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
21872
+ timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
21873
+ },
21874
+ (error62, stdout) => {
21875
+ resolveTable(error62 === null ? parseProcessTable(stdout) : []);
21876
+ }
21877
+ );
21878
+ });
21879
+ }
21880
+ function processExists(processId) {
21881
+ try {
21882
+ process.kill(processId, 0);
21883
+ return true;
21884
+ } catch {
21885
+ return false;
21886
+ }
21887
+ }
21888
+
21889
+ // src/platform/linux.ts
21890
+ function appendLinuxProcessTableEntry(entries, processId, encoded) {
21891
+ const closingParenthesis = encoded.lastIndexOf(")");
21892
+ if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21893
+ return;
21894
+ }
21895
+ const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21896
+ const parentProcessId = Number(fields[1]);
21897
+ const processGroupId = Number(fields[2]);
21898
+ if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21899
+ return;
21900
+ }
21901
+ entries.push({ parentProcessId, processGroupId, processId });
21902
+ }
21903
+ async function readLinuxProcessTable() {
21904
+ const entries = [];
21905
+ try {
21906
+ const directories = await readdir("/proc", { withFileTypes: true });
21907
+ for (const directory of directories) {
21908
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21909
+ continue;
21910
+ }
21911
+ const processId = Number(directory.name);
21912
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21913
+ continue;
21914
+ }
21915
+ try {
21916
+ appendLinuxProcessTableEntry(
21917
+ entries,
21918
+ processId,
21919
+ await readFile(join("/proc", directory.name, "stat"), "utf8")
21920
+ );
21921
+ } catch {
21922
+ }
21923
+ }
21924
+ } catch {
21925
+ }
21926
+ return entries;
21927
+ }
21928
+ function readLinuxProcessTableSynchronously() {
21929
+ const entries = [];
21930
+ try {
21931
+ const directories = readdirSync("/proc", { withFileTypes: true });
21932
+ for (const directory of directories) {
21933
+ if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21934
+ continue;
21935
+ }
21936
+ const processId = Number(directory.name);
21937
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
21938
+ continue;
21939
+ }
21940
+ try {
21941
+ appendLinuxProcessTableEntry(
21942
+ entries,
21943
+ processId,
21944
+ readFileSync(join("/proc", directory.name, "stat"), "utf8")
21945
+ );
21946
+ } catch {
21947
+ }
21948
+ }
21949
+ } catch {
21950
+ }
21951
+ return entries;
21952
+ }
21953
+ async function readLinuxProcessTableWithFallback() {
21954
+ const procfsEntries = await readLinuxProcessTable();
21955
+ if (procfsEntries.length > 0) {
21956
+ return procfsEntries;
21957
+ }
21958
+ for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
21959
+ try {
21960
+ const resolvedPath = await realpath(candidate);
21961
+ if (!(await stat(resolvedPath)).isFile()) {
21962
+ continue;
21963
+ }
21964
+ await access(resolvedPath, constants.X_OK);
21965
+ } catch {
21966
+ continue;
21967
+ }
21968
+ const entries = await readProcessTableWithPs(candidate);
21969
+ if (entries.length > 0) {
21970
+ return entries;
21971
+ }
21972
+ }
21973
+ return [];
21974
+ }
21975
+ function processExists2(processId) {
21976
+ try {
21977
+ const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
21978
+ const closingParenthesis = encoded.lastIndexOf(")");
21979
+ if (closingParenthesis >= 0) {
21980
+ const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
21981
+ if (processState === "Z" || processState === "X") {
21982
+ return false;
21983
+ }
21984
+ }
21985
+ } catch {
21986
+ }
21987
+ return processExists(processId);
21988
+ }
21989
+ var linuxPlatform = {
21990
+ readProcessTable: readLinuxProcessTableWithFallback,
21991
+ readProcessTableSynchronously: readLinuxProcessTableSynchronously,
21992
+ processExists: processExists2,
21993
+ workBuddyExecutablePaths: () => [],
21994
+ openCodeArchives: {
21995
+ arm64: {
21996
+ asset: "opencode-linux-arm64.tar.gz",
21997
+ sha256: "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
21998
+ format: "tar.gz"
21999
+ },
22000
+ x64: {
22001
+ asset: "opencode-linux-x64.tar.gz",
22002
+ sha256: "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
22003
+ format: "tar.gz"
22004
+ }
22005
+ },
22006
+ grokDependencies: {
22007
+ arm64: {
22008
+ name: "@xai-official/grok-linux-arm64",
22009
+ integrity: "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
22010
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
22011
+ },
22012
+ x64: {
22013
+ name: "@xai-official/grok-linux-x64",
22014
+ integrity: "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
22015
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
22016
+ }
22017
+ }
22018
+ };
22019
+
22020
+ // src/platform/macos.ts
22021
+ import { isAbsolute, join as join2 } from "node:path";
22022
+ var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
22023
+ "WorkBuddy.app",
22024
+ "Contents",
22025
+ "Resources",
22026
+ "app.asar.unpacked",
22027
+ "cli",
22028
+ "bin",
22029
+ "codebuddy"
22030
+ ]);
22031
+ var macosPlatform = {
22032
+ readProcessTable: () => readProcessTableWithPs("/bin/ps"),
22033
+ readProcessTableSynchronously: () => [],
22034
+ processExists,
22035
+ workBuddyExecutablePaths: (environment) => {
22036
+ const paths = [join2("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
22037
+ const homeDirectory = environment["HOME"];
22038
+ if (homeDirectory !== void 0 && isAbsolute(homeDirectory)) {
22039
+ paths.unshift(join2(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
22040
+ }
22041
+ return paths;
22042
+ },
22043
+ openCodeArchives: {
22044
+ arm64: {
22045
+ asset: "opencode-darwin-arm64.zip",
22046
+ sha256: "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
22047
+ format: "zip"
22048
+ },
22049
+ x64: {
22050
+ asset: "opencode-darwin-x64.zip",
22051
+ sha256: "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
22052
+ format: "zip"
22053
+ }
22054
+ },
22055
+ grokDependencies: {
22056
+ arm64: {
22057
+ name: "@xai-official/grok-darwin-arm64",
22058
+ integrity: "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
22059
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
22060
+ },
22061
+ x64: {
22062
+ name: "@xai-official/grok-darwin-x64",
22063
+ integrity: "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
22064
+ tarballUrl: "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
22065
+ }
22066
+ }
22067
+ };
22068
+
22069
+ // src/platform/index.ts
22070
+ var fallbackPlatform = {
22071
+ readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
22072
+ readProcessTableSynchronously: () => [],
22073
+ processExists,
22074
+ workBuddyExecutablePaths: () => [],
22075
+ openCodeArchives: {},
22076
+ grokDependencies: {}
22077
+ };
22078
+ var platforms = /* @__PURE__ */ new Map([
22079
+ ["linux", linuxPlatform],
22080
+ ["darwin", macosPlatform],
22081
+ ["win32", { ...fallbackPlatform, readProcessTable: () => Promise.resolve([]) }]
22082
+ ]);
22083
+ function platformSupportFor(platform) {
22084
+ return platforms.get(platform) ?? fallbackPlatform;
22085
+ }
22086
+
22087
+ // src/process/executable.ts
22088
+ var hostPlatform = platformSupportFor(process.platform);
21829
22089
  var DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024;
21830
22090
  var PROCESS_GRACEFUL_STOP_TIMEOUT_MILLISECONDS = 1e3;
21831
22091
  var PROCESS_FORCED_STOP_TIMEOUT_MILLISECONDS = 5e3;
21832
- var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
21833
- var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
21834
22092
  var PROCESS_EXIT_CHECK_ATTEMPTS = 16;
21835
22093
  var GRACEFUL_STOP_SIGNAL = 15;
21836
22094
  var FORCED_STOP_SIGNAL = 9;
@@ -21889,13 +22147,13 @@ function executableExtensions(executableName, environment, platform) {
21889
22147
  async function resolveExecutablePath(requestedPath2, platform = process.platform) {
21890
22148
  const absoluteRequestedPath = resolve(requestedPath2);
21891
22149
  try {
21892
- const resolvedPath = await realpath(absoluteRequestedPath);
21893
- const metadata = await stat(resolvedPath);
22150
+ const resolvedPath = await realpath2(absoluteRequestedPath);
22151
+ const metadata = await stat2(resolvedPath);
21894
22152
  if (!metadata.isFile()) {
21895
22153
  return null;
21896
22154
  }
21897
22155
  if (platform !== "win32") {
21898
- await access(resolvedPath, constants.X_OK);
22156
+ await access2(resolvedPath, constants2.X_OK);
21899
22157
  }
21900
22158
  return new ResolvedExecutable(
21901
22159
  new ExecutableIdentity(
@@ -21920,7 +22178,7 @@ async function findExecutableOnPath(executableName, environment, platform = proc
21920
22178
  continue;
21921
22179
  }
21922
22180
  for (const extension of extensions) {
21923
- const requestedPath2 = resolve(join(entry, `${executableName}${extension}`));
22181
+ const requestedPath2 = resolve(join3(entry, `${executableName}${extension}`));
21924
22182
  const executable = await resolveExecutablePath(requestedPath2, platform);
21925
22183
  if (executable !== null) {
21926
22184
  return executable;
@@ -21941,128 +22199,8 @@ function appendBounded(chunks, chunk, currentBytes, limitBytes) {
21941
22199
  chunks.push(chunk);
21942
22200
  return nextBytes;
21943
22201
  }
21944
- function parseProcessTable(output2) {
21945
- const entries = [];
21946
- for (const line of output2.split("\n")) {
21947
- const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
21948
- if (groups === void 0) {
21949
- continue;
21950
- }
21951
- const processId = Number(groups["pid"]);
21952
- const parentProcessId = Number(groups["ppid"]);
21953
- const processGroupId = Number(groups["pgid"]);
21954
- if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21955
- continue;
21956
- }
21957
- entries.push({ parentProcessId, processGroupId, processId });
21958
- }
21959
- return entries;
21960
- }
21961
- function appendLinuxProcessTableEntry(entries, processId, encoded) {
21962
- const closingParenthesis = encoded.lastIndexOf(")");
21963
- if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
21964
- return;
21965
- }
21966
- const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
21967
- const parentProcessId = Number(fields[1]);
21968
- const processGroupId = Number(fields[2]);
21969
- if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
21970
- return;
21971
- }
21972
- entries.push({ parentProcessId, processGroupId, processId });
21973
- }
21974
- async function readLinuxProcessTable() {
21975
- const entries = [];
21976
- try {
21977
- const directories = await readdir("/proc", { withFileTypes: true });
21978
- for (const directory of directories) {
21979
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
21980
- continue;
21981
- }
21982
- const processId = Number(directory.name);
21983
- if (!Number.isSafeInteger(processId) || processId <= 0) {
21984
- continue;
21985
- }
21986
- try {
21987
- appendLinuxProcessTableEntry(
21988
- entries,
21989
- processId,
21990
- await readFile(join("/proc", directory.name, "stat"), "utf8")
21991
- );
21992
- } catch {
21993
- }
21994
- }
21995
- } catch {
21996
- }
21997
- return entries;
21998
- }
21999
- function readLinuxProcessTableSynchronously() {
22000
- const entries = [];
22001
- try {
22002
- const directories = readdirSync("/proc", { withFileTypes: true });
22003
- for (const directory of directories) {
22004
- if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
22005
- continue;
22006
- }
22007
- const processId = Number(directory.name);
22008
- if (!Number.isSafeInteger(processId) || processId <= 0) {
22009
- continue;
22010
- }
22011
- try {
22012
- appendLinuxProcessTableEntry(
22013
- entries,
22014
- processId,
22015
- readFileSync(join("/proc", directory.name, "stat"), "utf8")
22016
- );
22017
- } catch {
22018
- }
22019
- }
22020
- } catch {
22021
- }
22022
- return entries;
22023
- }
22024
- function readProcessTableWithPs(executable) {
22025
- return new Promise((resolveTable) => {
22026
- execFile(
22027
- executable,
22028
- ["-axo", "pid=,ppid=,pgid="],
22029
- {
22030
- encoding: "utf8",
22031
- maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
22032
- signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
22033
- timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
22034
- },
22035
- (error62, stdout) => {
22036
- resolveTable(error62 === null ? parseProcessTable(stdout) : []);
22037
- }
22038
- );
22039
- });
22040
- }
22041
- async function readLinuxProcessTableWithFallback() {
22042
- const procfsEntries = await readLinuxProcessTable();
22043
- if (procfsEntries.length > 0) {
22044
- return procfsEntries;
22045
- }
22046
- for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
22047
- const executable = await resolveExecutablePath(candidate);
22048
- if (executable === null) {
22049
- continue;
22050
- }
22051
- const entries = await readProcessTableWithPs(executable.identity.requestedPath);
22052
- if (entries.length > 0) {
22053
- return entries;
22054
- }
22055
- }
22056
- return [];
22057
- }
22058
22202
  function readProcessTable() {
22059
- if (process.platform === "win32") {
22060
- return Promise.resolve([]);
22061
- }
22062
- if (process.platform === "linux") {
22063
- return readLinuxProcessTableWithFallback();
22064
- }
22065
- return readProcessTableWithPs(process.platform === "darwin" ? "/bin/ps" : "/usr/bin/ps");
22203
+ return hostPlatform.readProcessTable();
22066
22204
  }
22067
22205
  function selectProcessTree(entries, rootProcessId) {
22068
22206
  const processIds = /* @__PURE__ */ new Set([rootProcessId]);
@@ -22099,11 +22237,9 @@ async function captureProcessTree(child2) {
22099
22237
  if (process.platform === "win32" || child2.pid === void 0) {
22100
22238
  return [];
22101
22239
  }
22102
- if (process.platform === "linux") {
22103
- const procfsEntries = readLinuxProcessTableSynchronously();
22104
- if (procfsEntries.length > 0) {
22105
- return selectProcessTree(procfsEntries, child2.pid);
22106
- }
22240
+ const entries = hostPlatform.readProcessTableSynchronously();
22241
+ if (entries.length > 0) {
22242
+ return selectProcessTree(entries, child2.pid);
22107
22243
  }
22108
22244
  return selectProcessTree(await readProcessTable(), child2.pid);
22109
22245
  }
@@ -22131,36 +22267,15 @@ function signalCapturedProcessGroups(processes, rootProcessId, signal) {
22131
22267
  }
22132
22268
  }
22133
22269
  }
22134
- function processExists(processId) {
22135
- if (process.platform === "linux") {
22136
- try {
22137
- const encoded = readFileSync(join("/proc", processId.toString(), "stat"), "utf8");
22138
- const closingParenthesis = encoded.lastIndexOf(")");
22139
- if (closingParenthesis >= 0) {
22140
- const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
22141
- if (processState === "Z" || processState === "X") {
22142
- return false;
22143
- }
22144
- }
22145
- } catch {
22146
- }
22147
- }
22148
- try {
22149
- process.kill(processId, 0);
22150
- return true;
22151
- } catch {
22152
- return false;
22153
- }
22154
- }
22155
22270
  async function waitForCapturedProcessesExit(processes, rootProcessId) {
22156
22271
  const processIds = processes.map((identity2) => identity2.processId).filter((processId) => processId !== rootProcessId);
22157
22272
  for (let attempt = 0; attempt < PROCESS_EXIT_CHECK_ATTEMPTS; attempt += 1) {
22158
- if (processIds.every((processId) => !processExists(processId))) {
22273
+ if (processIds.every((processId) => !hostPlatform.processExists(processId))) {
22159
22274
  return true;
22160
22275
  }
22161
22276
  await readProcessTable();
22162
22277
  }
22163
- return processIds.every((processId) => !processExists(processId));
22278
+ return processIds.every((processId) => !hostPlatform.processExists(processId));
22164
22279
  }
22165
22280
  function terminateProcess(child2) {
22166
22281
  if (child2.exitCode !== null || child2.signalCode !== null || child2.pid === void 0) {
@@ -22508,19 +22623,19 @@ var LocalAgentCatalog = class {
22508
22623
 
22509
22624
  // src/storage/state-directory.ts
22510
22625
  import { homedir } from "node:os";
22511
- import { join as join2, resolve as resolve2 } from "node:path";
22626
+ import { join as join4, resolve as resolve2 } from "node:path";
22512
22627
  function readStateDirectory(environment = process.env) {
22513
22628
  const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
22514
22629
  if (configured !== void 0 && configured.length > 0) {
22515
22630
  return resolve2(configured);
22516
22631
  }
22517
- return join2(homedir(), ".mobius");
22632
+ return join4(homedir(), ".mobius");
22518
22633
  }
22519
22634
 
22520
22635
  // src/config.ts
22521
22636
  function loadDefaultWorkspace(environment = process.env) {
22522
22637
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
22523
- return configuredWorkspace ?? join3(readStateDirectory(environment), "workspace");
22638
+ return configuredWorkspace ?? join5(readStateDirectory(environment), "workspace");
22524
22639
  }
22525
22640
  var DaemonLocalContext = class {
22526
22641
  environment;
@@ -22550,7 +22665,7 @@ var OpaqueDaemonReconnectTarget = class extends DaemonReconnectTarget {
22550
22665
  this.commandArgument = `--connection ${connectionId2}`;
22551
22666
  }
22552
22667
  };
22553
- function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null) {
22668
+ function createDaemonConfig(connection, agents = [], installableAgents = [], localContext = new DaemonLocalContext(readStateDirectory(), process.env), reconnectTarget = null, resolveAgent) {
22554
22669
  const daemonAgents = agents.map((agent) => withDaemonEnvironment(agent, localContext.environment));
22555
22670
  return {
22556
22671
  agents: daemonAgents,
@@ -22561,7 +22676,8 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
22561
22676
  installableAgents,
22562
22677
  localContext,
22563
22678
  reconnectTarget,
22564
- relayUrl: connection.relayUrl
22679
+ relayUrl: connection.relayUrl,
22680
+ ...resolveAgent === void 0 ? {} : { resolveAgent }
22565
22681
  };
22566
22682
  }
22567
22683
  function loadDaemonConfig() {
@@ -22695,8 +22811,8 @@ import {
22695
22811
  } from "@agentclientprotocol/sdk";
22696
22812
 
22697
22813
  // src/authorization/local-raster.ts
22698
- import { open as open2, readFile as readFile2, realpath as realpath2, stat as stat2 } from "node:fs/promises";
22699
- import { basename, isAbsolute, normalize } from "node:path";
22814
+ import { open as open2, readFile as readFile2, realpath as realpath3, stat as stat3 } from "node:fs/promises";
22815
+ import { basename, isAbsolute as isAbsolute2, normalize } from "node:path";
22700
22816
  import { fileURLToPath } from "node:url";
22701
22817
  var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
22702
22818
  var MAX_INLINE_RASTER_BYTES = 3e6;
@@ -22762,13 +22878,13 @@ function readInlineRaster(data, name2 = "Image") {
22762
22878
  }
22763
22879
  async function resolveCanonicalPath(requested, signal) {
22764
22880
  signal.throwIfAborted();
22765
- if (!isAbsolute(requested) || requested.includes("\0") || normalize(requested) !== requested) {
22881
+ if (!isAbsolute2(requested) || requested.includes("\0") || normalize(requested) !== requested) {
22766
22882
  return null;
22767
22883
  }
22768
22884
  try {
22769
- const target = await realpath2(requested);
22885
+ const target = await realpath3(requested);
22770
22886
  signal.throwIfAborted();
22771
- if (!isAbsolute(target) || normalize(target) !== target) {
22887
+ if (!isAbsolute2(target) || normalize(target) !== target) {
22772
22888
  return null;
22773
22889
  }
22774
22890
  return target;
@@ -22814,7 +22930,7 @@ async function readLocalRaster(uri, signal) {
22814
22930
  if (target === null) {
22815
22931
  return null;
22816
22932
  }
22817
- const targetMetadata = await stat2(target);
22933
+ const targetMetadata = await stat3(target);
22818
22934
  signal.throwIfAborted();
22819
22935
  if (!targetMetadata.isFile() || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
22820
22936
  return null;
@@ -25646,7 +25762,7 @@ function sql(strings, ...params) {
25646
25762
  return new SQL([new StringChunk(str)]);
25647
25763
  }
25648
25764
  _sql.raw = raw;
25649
- function join20(chunks, separator) {
25765
+ function join22(chunks, separator) {
25650
25766
  const result = [];
25651
25767
  for (const [i, chunk] of chunks.entries()) {
25652
25768
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -25654,7 +25770,7 @@ function sql(strings, ...params) {
25654
25770
  }
25655
25771
  return new SQL(result);
25656
25772
  }
25657
- _sql.join = join20;
25773
+ _sql.join = join22;
25658
25774
  function identifier2(value) {
25659
25775
  return new Name(value);
25660
25776
  }
@@ -27799,7 +27915,7 @@ var SQLiteSelectBase = class extends TypedQueryBuilder {
27799
27915
  const baseTableName = this.tableName;
27800
27916
  const tableName = getTableLikeName(table);
27801
27917
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
27802
- if (typeof tableName === "string" && this.config.joins?.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
27918
+ if (typeof tableName === "string" && this.config.joins?.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
27803
27919
  if (!this.isPartialSelect) {
27804
27920
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
27805
27921
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -28638,7 +28754,7 @@ var SQLiteDialect = class {
28638
28754
  if (!joins2) return;
28639
28755
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
28640
28756
  if (!withEntries.length) return;
28641
- return sql.join(withEntries.map(([k, join20]) => {
28757
+ return sql.join(withEntries.map(([k, join22]) => {
28642
28758
  const relation = tableConfig.relations[k];
28643
28759
  const isSingle2 = is(relation, One);
28644
28760
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -28649,7 +28765,7 @@ var SQLiteDialect = class {
28649
28765
  table: targetTable,
28650
28766
  mode: isSingle2 ? "first" : "many",
28651
28767
  schema,
28652
- queryConfig: join20,
28768
+ queryConfig: join22,
28653
28769
  tableConfig: schema[relation.targetTableName],
28654
28770
  relationWhere: filter,
28655
28771
  isNested: true,
@@ -28663,7 +28779,7 @@ var SQLiteDialect = class {
28663
28779
  key: k,
28664
28780
  selection: innerQuery.selection,
28665
28781
  isArray: !isSingle2,
28666
- isOptional: (relation.optional ?? false) || join20 !== true && !!join20.where
28782
+ isOptional: (relation.optional ?? false) || join22 !== true && !!join22.where
28667
28783
  });
28668
28784
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
28669
28785
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -29279,7 +29395,7 @@ var SQLiteUpdateBase = class {
29279
29395
  createJoin(joinType) {
29280
29396
  return ((table, on) => {
29281
29397
  const tableName = getTableLikeName(table);
29282
- if (typeof tableName === "string" && this.config.joins.some((join20) => join20.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29398
+ if (typeof tableName === "string" && this.config.joins.some((join22) => join22.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
29283
29399
  if (typeof on === "function") {
29284
29400
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
29285
29401
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -30685,7 +30801,7 @@ var AgentSession = class _AgentSession {
30685
30801
  );
30686
30802
  }
30687
30803
  initialize = async (signal, recovery, origin) => {
30688
- if (origin?.kind === "fork") {
30804
+ if (origin !== void 0) {
30689
30805
  this.#sessionTitle = origin.title;
30690
30806
  }
30691
30807
  await this.#initializeAgent(signal);
@@ -30699,7 +30815,7 @@ var AgentSession = class _AgentSession {
30699
30815
  this.#cwd,
30700
30816
  this.#additionalDirectories,
30701
30817
  true,
30702
- ""
30818
+ origin.title
30703
30819
  )
30704
30820
  ) : this.#store.read(this.#mobiusSessionId)
30705
30821
  );
@@ -31938,8 +32054,8 @@ var AcpContentExternalizer = class {
31938
32054
 
31939
32055
  // src/external-content/local-external-content-store.ts
31940
32056
  import { createHash, randomUUID as randomUUID2 } from "node:crypto";
31941
- import { lstat, mkdir, readdir as readdir2, realpath as realpath3, rename, rm, stat as stat3, utimes, writeFile } from "node:fs/promises";
31942
- import { dirname, join as join4 } from "node:path";
32057
+ import { lstat, mkdir, readdir as readdir2, realpath as realpath4, rename, rm, stat as stat4, utimes, writeFile } from "node:fs/promises";
32058
+ import { dirname, join as join6 } from "node:path";
31943
32059
  var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
31944
32060
  var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
31945
32061
  var metadataSchema2 = external_exports.strictObject({
@@ -31975,7 +32091,7 @@ var LocalExternalContentStore = class {
31975
32091
  #expirationTimer;
31976
32092
  #cleanup = Promise.resolve();
31977
32093
  constructor(stateDirectory) {
31978
- this.#root = join4(stateDirectory, "tmp", "session-content", randomUUID2());
32094
+ this.#root = join6(stateDirectory, "tmp", "session-content", randomUUID2());
31979
32095
  this.#expirationTimer = setInterval(() => {
31980
32096
  void this.#expire().catch(() => void 0);
31981
32097
  }, 6e4);
@@ -31990,11 +32106,11 @@ var LocalExternalContentStore = class {
31990
32106
  if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
31991
32107
  continue;
31992
32108
  }
31993
- const path2 = join4(dirname(this.#root), directory.name);
32109
+ const path2 = join6(dirname(this.#root), directory.name);
31994
32110
  if (path2 === this.#root) {
31995
32111
  continue;
31996
32112
  }
31997
- const modified = await stat3(path2).then(
32113
+ const modified = await stat4(path2).then(
31998
32114
  (entry) => entry.mtimeMs,
31999
32115
  () => Date.now()
32000
32116
  );
@@ -32040,10 +32156,10 @@ var LocalExternalContentStore = class {
32040
32156
  }
32041
32157
  await this.#expire();
32042
32158
  active.throwIfAborted();
32043
- const directory = join4(this.#root, kind);
32159
+ const directory = join6(this.#root, kind);
32044
32160
  await mkdir(directory, { mode: 448, recursive: true });
32045
32161
  active.throwIfAborted();
32046
- const path2 = join4(directory, key);
32162
+ const path2 = join6(directory, key);
32047
32163
  const write = atomicWrite(path2, bytes, active);
32048
32164
  await write;
32049
32165
  active.throwIfAborted();
@@ -32076,8 +32192,8 @@ var LocalExternalContentStore = class {
32076
32192
  }
32077
32193
  try {
32078
32194
  const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
32079
- realpath3(dirname(entry.path)),
32080
- realpath3(entry.path),
32195
+ realpath4(dirname(entry.path)),
32196
+ realpath4(entry.path),
32081
32197
  lstat(entry.path)
32082
32198
  ]);
32083
32199
  signal.throwIfAborted();
@@ -32515,7 +32631,7 @@ var AgentRuntimeManager = class {
32515
32631
  return await this.#startRetainedSessionProcess(
32516
32632
  options,
32517
32633
  async () => await AgentSession.start(
32518
- options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId } } : options,
32634
+ options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId, title: "" } } : options,
32519
32635
  recovery,
32520
32636
  () => this.#observer,
32521
32637
  this.#store,
@@ -33174,10 +33290,10 @@ var LocalAuthorizationError = class extends Error {
33174
33290
  };
33175
33291
 
33176
33292
  // src/pairing/pair-local-machine.ts
33177
- import { mkdir as mkdir6, realpath as realpath8, stat as stat7 } from "node:fs/promises";
33293
+ import { mkdir as mkdir6, realpath as realpath9, stat as stat8 } from "node:fs/promises";
33178
33294
  import { hostname as hostname3 } from "node:os";
33179
33295
  import { basename as basename3, resolve as resolve5 } from "node:path";
33180
- import { fetch as fetch2 } from "undici";
33296
+ import { fetch as fetch3 } from "undici";
33181
33297
 
33182
33298
  // src/agent-catalog/agent-discovery.ts
33183
33299
  var AgentDiscovery = class {
@@ -33319,8 +33435,8 @@ var LocalAgentInventory = class {
33319
33435
  };
33320
33436
 
33321
33437
  // src/agent-installation/managed-npm-package.ts
33322
- import { mkdir as mkdir2, mkdtemp, open as open3, realpath as realpath4, rename as rename2, rm as rm2, stat as stat4 } from "node:fs/promises";
33323
- import { delimiter, dirname as dirname2, isAbsolute as isAbsolute2, join as join5, relative, sep } from "node:path";
33438
+ import { mkdir as mkdir2, mkdtemp, open as open3, realpath as realpath5, rename as rename2, rm as rm2, stat as stat5 } from "node:fs/promises";
33439
+ import { delimiter, dirname as dirname2, isAbsolute as isAbsolute3, join as join7, relative, sep } from "node:path";
33324
33440
  var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
33325
33441
  var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
33326
33442
  var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
@@ -33371,11 +33487,11 @@ function isRecord7(value) {
33371
33487
  return typeof value === "object" && value !== null && !Array.isArray(value);
33372
33488
  }
33373
33489
  function packagePath(root, packageName) {
33374
- return join5(root, "node_modules", ...packageName.split("/"));
33490
+ return join7(root, "node_modules", ...packageName.split("/"));
33375
33491
  }
33376
33492
  function isContainedPath(root, candidate) {
33377
33493
  const difference = relative(root, candidate);
33378
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute2(difference);
33494
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep}`) && !isAbsolute3(difference);
33379
33495
  }
33380
33496
  async function readJsonRecord(path2, maximumBytes) {
33381
33497
  try {
@@ -33476,14 +33592,14 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
33476
33592
  }
33477
33593
  }
33478
33594
  async function verifyRequiredDependency(rootPath, lock, definition) {
33479
- const dependencyRoot = await realpath4(packagePath(rootPath, definition.packageName));
33595
+ const dependencyRoot = await realpath5(packagePath(rootPath, definition.packageName));
33480
33596
  if (!isContainedPath(rootPath, dependencyRoot)) {
33481
33597
  throw new ManagedNpmPackageError(
33482
33598
  "managed_package_verification_failed",
33483
33599
  "The required managed npm dependency escaped its private cache"
33484
33600
  );
33485
33601
  }
33486
- const metadata = await readJsonRecord(join5(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33602
+ const metadata = await readJsonRecord(join7(dependencyRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33487
33603
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
33488
33604
  throw new ManagedNpmPackageError(
33489
33605
  "managed_package_verification_failed",
@@ -33505,15 +33621,15 @@ async function validateManagedNpmPackage(root, definition) {
33505
33621
  }
33506
33622
  }
33507
33623
  async function validateManagedNpmPackageContents(root, definition) {
33508
- const rootPath = await realpath4(root);
33509
- const packageRoot = await realpath4(packagePath(rootPath, definition.packageName));
33624
+ const rootPath = await realpath5(root);
33625
+ const packageRoot = await realpath5(packagePath(rootPath, definition.packageName));
33510
33626
  if (!isContainedPath(rootPath, packageRoot)) {
33511
33627
  throw new ManagedNpmPackageError(
33512
33628
  "managed_package_verification_failed",
33513
33629
  "The managed npm package escaped its private cache"
33514
33630
  );
33515
33631
  }
33516
- const metadata = await readJsonRecord(join5(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33632
+ const metadata = await readJsonRecord(join7(packageRoot, "package.json"), PACKAGE_METADATA_LIMIT_BYTES);
33517
33633
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
33518
33634
  throw new ManagedNpmPackageError(
33519
33635
  "managed_package_verification_failed",
@@ -33521,14 +33637,14 @@ async function validateManagedNpmPackageContents(root, definition) {
33521
33637
  );
33522
33638
  }
33523
33639
  if (definition instanceof SriManagedNpmPackageDefinition) {
33524
- const lock = await readJsonRecord(join5(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
33640
+ const lock = await readJsonRecord(join7(rootPath, "package-lock.json"), PACKAGE_LOCK_LIMIT_BYTES);
33525
33641
  verifyPackageLockEntry(lock, definition, definition.verifyDependencyClosure);
33526
33642
  for (const dependency of definition.requiredDependencies) {
33527
33643
  await verifyRequiredDependency(rootPath, lock, dependency);
33528
33644
  }
33529
33645
  }
33530
33646
  const declaredBin = readBinPath(metadata, definition.executableName);
33531
- const executable = await resolveExecutablePath(join5(packageRoot, declaredBin));
33647
+ const executable = await resolveExecutablePath(join7(packageRoot, declaredBin));
33532
33648
  if (executable === null || !isContainedPath(rootPath, executable.path)) {
33533
33649
  throw new ManagedNpmPackageError(
33534
33650
  "managed_package_verification_failed",
@@ -33541,7 +33657,7 @@ var ManagedNpmPackageInstaller = class {
33541
33657
  install = async (root, definition, environment, signal) => {
33542
33658
  signal.throwIfAborted();
33543
33659
  try {
33544
- const metadata = await stat4(root);
33660
+ const metadata = await stat5(root);
33545
33661
  if (metadata.isDirectory()) {
33546
33662
  return await validateManagedNpmPackage(root, definition);
33547
33663
  }
@@ -33552,7 +33668,7 @@ var ManagedNpmPackageInstaller = class {
33552
33668
  }
33553
33669
  const parent = dirname2(root);
33554
33670
  await mkdir2(parent, { mode: 448, recursive: true });
33555
- const staging = await mkdtemp(join5(parent, `.${definition.version}.staging-`));
33671
+ const staging = await mkdtemp(join7(parent, `.${definition.version}.staging-`));
33556
33672
  try {
33557
33673
  const npm = await findExecutableOnPath(process.platform === "win32" ? "npm.cmd" : "npm", environment);
33558
33674
  if (npm === null) {
@@ -33578,9 +33694,9 @@ var ManagedNpmPackageInstaller = class {
33578
33694
  `${definition.packageName}@${definition.version}`
33579
33695
  );
33580
33696
  const installEnvironment = {
33581
- HOME: join5(staging, "home"),
33697
+ HOME: join7(staging, "home"),
33582
33698
  NPM_CONFIG_AUDIT: "false",
33583
- NPM_CONFIG_CACHE: join5(staging, ".npm-cache"),
33699
+ NPM_CONFIG_CACHE: join7(staging, ".npm-cache"),
33584
33700
  NPM_CONFIG_FUND: "false",
33585
33701
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
33586
33702
  NPM_CONFIG_PACKAGE_LOCK: "true",
@@ -33602,8 +33718,8 @@ var ManagedNpmPackageInstaller = class {
33602
33718
  timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
33603
33719
  });
33604
33720
  await Promise.all([
33605
- rm2(join5(staging, ".npm-cache"), { force: true, recursive: true }),
33606
- rm2(join5(staging, "home"), { force: true, recursive: true })
33721
+ rm2(join7(staging, ".npm-cache"), { force: true, recursive: true }),
33722
+ rm2(join7(staging, "home"), { force: true, recursive: true })
33607
33723
  ]);
33608
33724
  await validateManagedNpmPackage(staging, definition);
33609
33725
  try {
@@ -33639,7 +33755,7 @@ var ManagedNpmPackageInstaller = class {
33639
33755
  };
33640
33756
 
33641
33757
  // src/agent-catalog/agent-specification.ts
33642
- import { join as join6 } from "node:path";
33758
+ import { join as join8 } from "node:path";
33643
33759
 
33644
33760
  // src/agent-catalog/version-output.ts
33645
33761
  function normalizeVersionOutput(output2) {
@@ -33662,7 +33778,7 @@ var LocalAgentSpecification = class {
33662
33778
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
33663
33779
  signal.throwIfAborted();
33664
33780
  const executable = await resolveExecutablePath(
33665
- join6(stateDirectory, ...this.managedAgentExecutablePath),
33781
+ join8(stateDirectory, ...this.managedAgentExecutablePath),
33666
33782
  platform
33667
33783
  );
33668
33784
  signal.throwIfAborted();
@@ -33760,7 +33876,7 @@ import {
33760
33876
  import { spawn as spawn3 } from "node:child_process";
33761
33877
 
33762
33878
  // src/acp/codex/app-server-protocol.ts
33763
- import { isAbsolute as isAbsolute3 } from "node:path";
33879
+ import { isAbsolute as isAbsolute4 } from "node:path";
33764
33880
  var boundedText = (maximum) => external_exports.string().max(maximum);
33765
33881
  var jsonValue = external_exports.lazy(() => external_exports.unknown());
33766
33882
  var requestIdSchema = external_exports.union([external_exports.number(), external_exports.string()]).refine((value) => typeof value === "number" || value.length <= 256);
@@ -33831,7 +33947,7 @@ var imageGenerationItemSchema = external_exports.object({
33831
33947
  });
33832
33948
  var threadItemSchema = external_exports.discriminatedUnion("type", [
33833
33949
  imageGenerationItemSchema,
33834
- external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute3) }),
33950
+ external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute4) }),
33835
33951
  external_exports.object({
33836
33952
  id: boundedText(256),
33837
33953
  text: boundedText(1e6),
@@ -35697,15 +35813,15 @@ var AgentProbeError = class extends Error {
35697
35813
  };
35698
35814
 
35699
35815
  // src/agent-catalog/agents/resolve-user-local-executable.ts
35700
- import { isAbsolute as isAbsolute4, join as join7 } from "node:path";
35816
+ import { isAbsolute as isAbsolute5, join as join9 } from "node:path";
35701
35817
  async function resolveUserLocalExecutable(executableName, context) {
35702
35818
  context.signal.throwIfAborted();
35703
35819
  const platform = context.platform ?? process.platform;
35704
35820
  const homeDirectory = context.environment["HOME"];
35705
- if (platform === "win32" || homeDirectory === void 0 || !isAbsolute4(homeDirectory)) {
35821
+ if (platform === "win32" || homeDirectory === void 0 || !isAbsolute5(homeDirectory)) {
35706
35822
  return [];
35707
35823
  }
35708
- const executable = await resolveExecutablePath(join7(homeDirectory, ".local", "bin", executableName), platform);
35824
+ const executable = await resolveExecutablePath(join9(homeDirectory, ".local", "bin", executableName), platform);
35709
35825
  context.signal.throwIfAborted();
35710
35826
  return executable === null ? [] : [executable];
35711
35827
  }
@@ -35794,8 +35910,8 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
35794
35910
  };
35795
35911
 
35796
35912
  // src/agent-catalog/agents/deepseek-harness-agent.ts
35797
- import { mkdir as mkdir3, realpath as realpath5, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
35798
- import { isAbsolute as isAbsolute5, join as join8, normalize as normalize2 } from "node:path";
35913
+ import { mkdir as mkdir3, realpath as realpath6, stat as stat6, writeFile as writeFile2 } from "node:fs/promises";
35914
+ import { isAbsolute as isAbsolute6, join as join10, normalize as normalize2 } from "node:path";
35799
35915
 
35800
35916
  // src/agent-installation/deepseek-managed-package.ts
35801
35917
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -35819,20 +35935,20 @@ var DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH = `# Managed by Mobius: pin the ACP brid
35819
35935
  model: deepseek-v4-flash-vision-exp
35820
35936
  `;
35821
35937
  async function prepareAgentHome(path2, imagePrompts) {
35822
- if (!isAbsolute5(path2) || normalize2(path2) !== path2) {
35938
+ if (!isAbsolute6(path2) || normalize2(path2) !== path2) {
35823
35939
  throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
35824
35940
  }
35825
35941
  try {
35826
35942
  if (imagePrompts) {
35827
35943
  await mkdir3(path2, { mode: 448, recursive: true });
35828
35944
  }
35829
- const resolved = await realpath5(path2);
35830
- const metadata = await stat5(resolved);
35945
+ const resolved = await realpath6(path2);
35946
+ const metadata = await stat6(resolved);
35831
35947
  if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
35832
35948
  throw new Error("Agent home is not a user-owned directory");
35833
35949
  }
35834
35950
  if (imagePrompts) {
35835
- await writeFile2(join8(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
35951
+ await writeFile2(join10(resolved, "cordis.patch.yml"), DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH, {
35836
35952
  mode: 384
35837
35953
  });
35838
35954
  }
@@ -35880,7 +35996,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
35880
35996
  context.signal
35881
35997
  );
35882
35998
  if (managed.path === agent.path) {
35883
- selectedHome = join8(readStateDirectory(context.environment), "agents", this.id, "home");
35999
+ selectedHome = join10(readStateDirectory(context.environment), "agents", this.id, "home");
35884
36000
  managedHome = true;
35885
36001
  }
35886
36002
  } catch {
@@ -35896,7 +36012,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
35896
36012
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
35897
36013
  signal.throwIfAborted();
35898
36014
  const executable = await validateManagedNpmPackage(
35899
- join8(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
36015
+ join10(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
35900
36016
  DEEPSEEK_HARNESS_PACKAGE
35901
36017
  );
35902
36018
  signal.throwIfAborted();
@@ -35950,8 +36066,8 @@ var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
35950
36066
  };
35951
36067
 
35952
36068
  // src/agent-catalog/agents/grok-build-agent.ts
35953
- import { realpath as realpath6 } from "node:fs/promises";
35954
- import { isAbsolute as isAbsolute6, join as join9, relative as relative2, sep as sep2 } from "node:path";
36069
+ import { realpath as realpath7 } from "node:fs/promises";
36070
+ import { isAbsolute as isAbsolute7, join as join11, relative as relative2, sep as sep2 } from "node:path";
35955
36071
  import {
35956
36072
  RequestError as RequestError2
35957
36073
  } from "@agentclientprotocol/sdk";
@@ -35974,50 +36090,25 @@ var GrokBuildManagedPackage = class extends SriManagedNpmPackageDefinition {
35974
36090
  this.requiredDependencies = Object.freeze([requiredDependency]);
35975
36091
  }
35976
36092
  };
35977
- var GROK_DARWIN_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
35978
- "@xai-official/grok-darwin-arm64",
35979
- GROK_BUILD_MANAGED_VERSION,
35980
- "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
35981
- "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
35982
- );
35983
- var GROK_DARWIN_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
35984
- "@xai-official/grok-darwin-x64",
35985
- GROK_BUILD_MANAGED_VERSION,
35986
- "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
35987
- "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
35988
- );
35989
- var GROK_LINUX_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
35990
- "@xai-official/grok-linux-arm64",
35991
- GROK_BUILD_MANAGED_VERSION,
35992
- "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
35993
- "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
35994
- );
35995
- var GROK_LINUX_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
35996
- "@xai-official/grok-linux-x64",
35997
- GROK_BUILD_MANAGED_VERSION,
35998
- "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
35999
- "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
36000
- );
36001
36093
  function grokBuildManagedPackage(platform, architecture) {
36002
- if (platform === "darwin" && architecture === "arm64") {
36003
- return new GrokBuildManagedPackage(GROK_DARWIN_ARM64_PACKAGE);
36094
+ const release = platformSupportFor(platform).grokDependencies[architecture];
36095
+ if (release === void 0) {
36096
+ throw new Error("Grok Build does not publish a package for this platform");
36004
36097
  }
36005
- if (platform === "darwin" && architecture === "x64") {
36006
- return new GrokBuildManagedPackage(GROK_DARWIN_X64_PACKAGE);
36007
- }
36008
- if (platform === "linux" && architecture === "arm64") {
36009
- return new GrokBuildManagedPackage(GROK_LINUX_ARM64_PACKAGE);
36010
- }
36011
- if (platform === "linux" && architecture === "x64") {
36012
- return new GrokBuildManagedPackage(GROK_LINUX_X64_PACKAGE);
36013
- }
36014
- throw new Error("Grok Build does not publish a package for this platform");
36098
+ return new GrokBuildManagedPackage(
36099
+ new SriManagedNpmDependencyDefinition(
36100
+ release.name,
36101
+ GROK_BUILD_MANAGED_VERSION,
36102
+ release.integrity,
36103
+ release.tarballUrl
36104
+ )
36105
+ );
36015
36106
  }
36016
36107
 
36017
36108
  // src/agent-catalog/agents/grok-build-agent.ts
36018
36109
  function isContainedPath2(root, candidate) {
36019
36110
  const difference = relative2(root, candidate);
36020
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute6(difference);
36111
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute7(difference);
36021
36112
  }
36022
36113
  var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36023
36114
  adapterVersion = GROK_BUILD_MANAGED_VERSION;
@@ -36046,8 +36137,8 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36046
36137
  );
36047
36138
  if (managed.path === agent.path) {
36048
36139
  return Object.freeze({
36049
- GROK_HOME: await realpath6(
36050
- join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
36140
+ GROK_HOME: await realpath7(
36141
+ join11(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
36051
36142
  )
36052
36143
  });
36053
36144
  }
@@ -36058,9 +36149,9 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
36058
36149
  };
36059
36150
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
36060
36151
  signal.throwIfAborted();
36061
- const versionRoot = await realpath6(join9(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
36062
- await validateManagedNpmPackage(join9(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
36063
- const executable = await resolveExecutablePath(join9(versionRoot, "home", "bin", "grok"), platform);
36152
+ const versionRoot = await realpath7(join11(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
36153
+ await validateManagedNpmPackage(join11(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
36154
+ const executable = await resolveExecutablePath(join11(versionRoot, "home", "bin", "grok"), platform);
36064
36155
  signal.throwIfAborted();
36065
36156
  if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
36066
36157
  throw new AgentProbeError("managed_agent_invalid", "The managed Grok Build executable is invalid");
@@ -36160,13 +36251,13 @@ var OhMyPiAgentSpecification = class extends DirectAcpAgentDefinition {
36160
36251
  };
36161
36252
 
36162
36253
  // src/agent-catalog/agents/opencode-agent.ts
36163
- import { join as join11 } from "node:path";
36254
+ import { join as join13 } from "node:path";
36164
36255
 
36165
36256
  // src/agent-installation/managed-agent-archive.ts
36166
36257
  import { createHash as createHash3 } from "node:crypto";
36167
36258
  import { createReadStream } from "node:fs";
36168
- import { chmod, copyFile, mkdir as mkdir4, mkdtemp as mkdtemp2, open as open4, realpath as realpath7, rename as rename3, rm as rm3, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
36169
- import { delimiter as delimiter2, dirname as dirname3, isAbsolute as isAbsolute7, join as join10, relative as relative3, sep as sep3 } from "node:path";
36259
+ import { chmod, copyFile, mkdir as mkdir4, mkdtemp as mkdtemp2, open as open4, realpath as realpath8, rename as rename3, rm as rm3, stat as stat7, writeFile as writeFile3 } from "node:fs/promises";
36260
+ import { delimiter as delimiter2, dirname as dirname3, isAbsolute as isAbsolute8, join as join12, relative as relative3, sep as sep3 } from "node:path";
36170
36261
 
36171
36262
  // src/agent-installation/verified-download.ts
36172
36263
  import { fetch } from "undici";
@@ -36272,7 +36363,7 @@ function isRecord8(value) {
36272
36363
  }
36273
36364
  function isContainedPath3(root, candidate) {
36274
36365
  const difference = relative3(root, candidate);
36275
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute7(difference);
36366
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute8(difference);
36276
36367
  }
36277
36368
  async function hashFile(path2, signal) {
36278
36369
  signal.throwIfAborted();
@@ -36346,16 +36437,16 @@ async function readManifest(path2) {
36346
36437
  }
36347
36438
  async function validateManagedAgentArchive(root, definition, signal) {
36348
36439
  try {
36349
- const rootPath = await realpath7(root);
36350
- const rootMetadata = await stat6(rootPath);
36440
+ const rootPath = await realpath8(root);
36441
+ const rootMetadata = await stat7(rootPath);
36351
36442
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
36352
36443
  throw new Error("Managed Agent root is not user-owned");
36353
36444
  }
36354
- const manifest = await readManifest(join10(rootPath, "archive.json"));
36445
+ const manifest = await readManifest(join12(rootPath, "archive.json"));
36355
36446
  if (manifest["archiveSha256"] !== definition.archiveSha256 || manifest["archiveUrl"] !== definition.archiveUrl.toString() || manifest["version"] !== definition.version || typeof manifest["executableSha256"] !== "string") {
36356
36447
  throw new Error("Managed Agent archive identity is invalid");
36357
36448
  }
36358
- const executable = await resolveExecutablePath(join10(rootPath, "bin", definition.executableName));
36449
+ const executable = await resolveExecutablePath(join12(rootPath, "bin", definition.executableName));
36359
36450
  if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
36360
36451
  throw new Error("Managed Agent executable is invalid");
36361
36452
  }
@@ -36381,47 +36472,21 @@ function releaseUrl(asset) {
36381
36472
  return new URL(`https://github.com/anomalyco/opencode/releases/download/v${OPENCODE_MANAGED_VERSION}/${asset}`);
36382
36473
  }
36383
36474
  function openCodeManagedArchive(platform, architecture) {
36384
- if (platform === "darwin" && architecture === "arm64") {
36385
- const asset = "opencode-darwin-arm64.zip";
36386
- return new ZipManagedAgentArchiveDefinition(
36387
- OPENCODE_MANAGED_VERSION,
36388
- asset,
36389
- releaseUrl(asset),
36390
- "fe764f7f360c584a83e18dd5f23fb1a6b2725f5ee8854b0252fe558f7798e946",
36391
- "opencode"
36392
- );
36393
- }
36394
- if (platform === "darwin" && architecture === "x64") {
36395
- const asset = "opencode-darwin-x64.zip";
36396
- return new ZipManagedAgentArchiveDefinition(
36397
- OPENCODE_MANAGED_VERSION,
36398
- asset,
36399
- releaseUrl(asset),
36400
- "9858853e7bacdbbd22c2d70c377e009dc4b354dd04f5588705411e7afb89fd2d",
36401
- "opencode"
36402
- );
36403
- }
36404
- if (platform === "linux" && architecture === "arm64") {
36405
- const asset = "opencode-linux-arm64.tar.gz";
36406
- return new TarGzipManagedAgentArchiveDefinition(
36407
- OPENCODE_MANAGED_VERSION,
36408
- asset,
36409
- releaseUrl(asset),
36410
- "70baf769395ca4e7a68924026530c390eace194f3b7e4919d4efcb2aa2eed3c0",
36411
- "opencode"
36412
- );
36413
- }
36414
- if (platform === "linux" && architecture === "x64") {
36415
- const asset = "opencode-linux-x64.tar.gz";
36416
- return new TarGzipManagedAgentArchiveDefinition(
36417
- OPENCODE_MANAGED_VERSION,
36418
- asset,
36419
- releaseUrl(asset),
36420
- "ea800b7ff56226b70952126c9fc1e2517ca4c4b5682fd9d3f9e87449697a1194",
36421
- "opencode"
36422
- );
36423
- }
36424
- throw new Error("OpenCode does not publish an approved archive for this platform");
36475
+ const release = platformSupportFor(platform).openCodeArchives[architecture];
36476
+ if (release === void 0) {
36477
+ throw new Error("OpenCode does not publish an approved archive for this platform");
36478
+ }
36479
+ const Definition = {
36480
+ zip: ZipManagedAgentArchiveDefinition,
36481
+ "tar.gz": TarGzipManagedAgentArchiveDefinition
36482
+ }[release.format];
36483
+ return new Definition(
36484
+ OPENCODE_MANAGED_VERSION,
36485
+ release.asset,
36486
+ releaseUrl(release.asset),
36487
+ release.sha256,
36488
+ "opencode"
36489
+ );
36425
36490
  }
36426
36491
 
36427
36492
  // src/agent-catalog/agents/opencode-agent.ts
@@ -36547,7 +36612,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
36547
36612
  return Object.freeze(environment);
36548
36613
  };
36549
36614
  resolveManagedAgent = async (stateDirectory, platform, signal) => await validateManagedAgentArchive(
36550
- join11(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
36615
+ join13(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
36551
36616
  openCodeManagedArchive(platform, process.arch),
36552
36617
  signal
36553
36618
  );
@@ -36565,7 +36630,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
36565
36630
  };
36566
36631
 
36567
36632
  // src/agent-catalog/agents/pi-agent.ts
36568
- import { join as join12 } from "node:path";
36633
+ import { join as join14 } from "node:path";
36569
36634
  import {
36570
36635
  methods as methods7
36571
36636
  } from "@agentclientprotocol/sdk";
@@ -36624,7 +36689,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
36624
36689
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
36625
36690
  signal.throwIfAborted();
36626
36691
  const executable = await validateManagedNpmPackage(
36627
- join12(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
36692
+ join14(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
36628
36693
  PI_AGENT_PACKAGE
36629
36694
  );
36630
36695
  signal.throwIfAborted();
@@ -36662,7 +36727,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
36662
36727
  };
36663
36728
 
36664
36729
  // src/agent-catalog/agents/workbuddy-agent.ts
36665
- import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
36730
+ import { join as join15 } from "node:path";
36666
36731
 
36667
36732
  // src/agent-installation/workbuddy-managed-package.ts
36668
36733
  var WORKBUDDY_MANAGED_VERSION = "2.146.0";
@@ -36680,15 +36745,6 @@ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
36680
36745
  );
36681
36746
 
36682
36747
  // src/agent-catalog/agents/workbuddy-agent.ts
36683
- var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
36684
- "WorkBuddy.app",
36685
- "Contents",
36686
- "Resources",
36687
- "app.asar.unpacked",
36688
- "cli",
36689
- "bin",
36690
- "codebuddy"
36691
- ]);
36692
36748
  var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36693
36749
  adapterVersion = WORKBUDDY_MANAGED_VERSION;
36694
36750
  authenticationCommand = () => "codebuddy";
@@ -36717,7 +36773,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36717
36773
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
36718
36774
  signal.throwIfAborted();
36719
36775
  const executable = await validateManagedNpmPackage(
36720
- join13(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
36776
+ join15(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
36721
36777
  WORKBUDDY_MANAGED_PACKAGE
36722
36778
  );
36723
36779
  signal.throwIfAborted();
@@ -36725,17 +36781,11 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
36725
36781
  };
36726
36782
  resolveInstalledAgentExecutables = async (context) => {
36727
36783
  context.signal.throwIfAborted();
36728
- if ((context.platform ?? process.platform) !== "darwin") {
36729
- return [];
36730
- }
36731
- const requestedPaths = [join13("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
36732
- const homeDirectory = context.environment["HOME"];
36733
- if (homeDirectory !== void 0 && isAbsolute8(homeDirectory)) {
36734
- requestedPaths.unshift(join13(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
36735
- }
36784
+ const platform = context.platform ?? process.platform;
36785
+ const requestedPaths = platformSupportFor(platform).workBuddyExecutablePaths(context.environment);
36736
36786
  const executables = [];
36737
36787
  for (const requestedPath2 of requestedPaths) {
36738
- const executable = await resolveExecutablePath(requestedPath2, "darwin");
36788
+ const executable = await resolveExecutablePath(requestedPath2, platform);
36739
36789
  context.signal.throwIfAborted();
36740
36790
  if (executable !== null) {
36741
36791
  executables.push(executable);
@@ -37066,10 +37116,10 @@ function isAgentVersionSupported(reportedVersion, minimumSupportedVersion) {
37066
37116
  }
37067
37117
 
37068
37118
  // src/agent-catalog/executable-discovery.ts
37069
- import { isAbsolute as isAbsolute9, join as join15 } from "node:path";
37119
+ import { isAbsolute as isAbsolute9, join as join17 } from "node:path";
37070
37120
 
37071
37121
  // src/agent-installation/managed-adapter-installer.ts
37072
- import { join as join14 } from "node:path";
37122
+ import { join as join16 } from "node:path";
37073
37123
  var ManagedAdapterInstallError = class extends Error {
37074
37124
  code;
37075
37125
  constructor(code, message, options = {}) {
@@ -37126,7 +37176,7 @@ var ManagedAdapterInstaller = class {
37126
37176
  this.#stateDirectory = options.stateDirectory;
37127
37177
  }
37128
37178
  install = async (specification, signal) => {
37129
- const root = join14(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
37179
+ const root = join16(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
37130
37180
  try {
37131
37181
  return await this.#npmInstaller.install(
37132
37182
  root,
@@ -37160,7 +37210,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
37160
37210
  let managed;
37161
37211
  try {
37162
37212
  managed = await validateManagedAdapter(
37163
- join15(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
37213
+ join17(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
37164
37214
  specification
37165
37215
  );
37166
37216
  } catch {
@@ -37473,10 +37523,176 @@ async function discoverLocalAgentInventory(options) {
37473
37523
  return new LocalAgentInventory(results);
37474
37524
  }
37475
37525
 
37526
+ // src/agent-catalog/publish-agent-catalog.ts
37527
+ import { fetch as fetch2 } from "undici";
37528
+
37529
+ // src/relay-connection/runtime-authentication.ts
37530
+ function runtimeCredential(relayUrl) {
37531
+ return relayUrl.searchParams.get("token") ?? "";
37532
+ }
37533
+ function runtimeAuthorization(relayUrl) {
37534
+ const credential = runtimeCredential(relayUrl);
37535
+ return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
37536
+ }
37537
+ function relayHttpEndpoint(relayUrl) {
37538
+ const endpoint = new URL(relayUrl);
37539
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
37540
+ endpoint.search = "";
37541
+ return endpoint;
37542
+ }
37543
+
37544
+ // src/agent-catalog/publish-agent-catalog.ts
37545
+ var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
37546
+ var AgentCatalogPublishError = class extends Error {
37547
+ code = "agent_catalog_update_failed";
37548
+ diagnosticDetails;
37549
+ constructor(message, options = {}, diagnosticDetails = {}) {
37550
+ super(message, options);
37551
+ this.diagnosticDetails = diagnosticDetails;
37552
+ this.name = "AgentCatalogPublishError";
37553
+ }
37554
+ };
37555
+ function isRecord9(value) {
37556
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37557
+ }
37558
+ function isSafeRelayErrorMessage(value) {
37559
+ return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
37560
+ }
37561
+ async function rejectedCatalogError(response) {
37562
+ let value;
37563
+ try {
37564
+ value = await response.json();
37565
+ } catch {
37566
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37567
+ }
37568
+ if (!isRecord9(value) || !isRecord9(value["error"])) {
37569
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37570
+ }
37571
+ const code = value["error"]["code"];
37572
+ const message = value["error"]["message"];
37573
+ if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
37574
+ return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
37575
+ }
37576
+ return new AgentCatalogPublishError(
37577
+ `The Relay rejected the Agent catalog update (${code}): ${message}`,
37578
+ {},
37579
+ {
37580
+ relayErrorCode: code
37581
+ }
37582
+ );
37583
+ }
37584
+ function catalogEndpoint(config2) {
37585
+ const endpoint = relayHttpEndpoint(config2.relayUrl);
37586
+ if (endpoint.pathname.endsWith("/daemon")) {
37587
+ endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
37588
+ return endpoint;
37589
+ }
37590
+ const runtimePath = "/v1/runtimes/connect";
37591
+ if (endpoint.pathname.endsWith(runtimePath)) {
37592
+ endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
37593
+ return endpoint;
37594
+ }
37595
+ throw new AgentCatalogPublishError("The Relay URL is invalid");
37596
+ }
37597
+ async function publishAgentCatalog(config2, signal) {
37598
+ signal.throwIfAborted();
37599
+ const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
37600
+ const requestSignal = AbortSignal.any([signal, timeoutSignal]);
37601
+ let response;
37602
+ const catalog = config2.catalog.read();
37603
+ try {
37604
+ response = await fetch2(catalogEndpoint(config2), {
37605
+ body: JSON.stringify({
37606
+ agents: catalog.agents.map((agent) => ({
37607
+ agentPath: agent.agentIdentity.requestedPath,
37608
+ agentVersion: agent.agentVersion,
37609
+ agentSettingsDiscovery: true,
37610
+ capabilities: agent.capabilities,
37611
+ id: agent.id,
37612
+ label: agent.label,
37613
+ sessionTurnConfiguration: true
37614
+ })),
37615
+ installableAgents: catalog.installableAgents
37616
+ }),
37617
+ dispatcher: environmentProxyDispatcher,
37618
+ headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
37619
+ method: "PUT",
37620
+ signal: requestSignal
37621
+ });
37622
+ } catch (error62) {
37623
+ if (signal.aborted) {
37624
+ signal.throwIfAborted();
37625
+ }
37626
+ throw new AgentCatalogPublishError(
37627
+ timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
37628
+ { cause: error62 }
37629
+ );
37630
+ }
37631
+ if (!response.ok) {
37632
+ throw await rejectedCatalogError(response);
37633
+ }
37634
+ await response.body?.cancel();
37635
+ }
37636
+
37637
+ // src/agent-catalog/resolve-catalog-agent.ts
37638
+ function createCatalogAgentResolver(discover, readConfig, publish) {
37639
+ const swaps = /* @__PURE__ */ new Map();
37640
+ return async (agent, signal) => {
37641
+ const config2 = readConfig();
37642
+ const pending = swaps.get(agent.id);
37643
+ if (pending !== void 0) {
37644
+ await pending;
37645
+ return config2.catalog.find(agent.id);
37646
+ }
37647
+ let release = () => void 0;
37648
+ const gate = new Promise((resolveGate) => {
37649
+ release = resolveGate;
37650
+ });
37651
+ swaps.set(agent.id, gate);
37652
+ try {
37653
+ if (await unchangedIdentity(agent, signal)) {
37654
+ return agent;
37655
+ }
37656
+ signal.throwIfAborted();
37657
+ const inventory = await discover(signal);
37658
+ signal.throwIfAborted();
37659
+ const previous = config2.catalog.read();
37660
+ const previousAgent = previous.agents.find((entry) => entry.id === agent.id);
37661
+ if (previousAgent === void 0) {
37662
+ throw new Error(`The local Agent ${agent.id} left the catalog before its refresh completed`);
37663
+ }
37664
+ config2.catalog.transition(
37665
+ [
37666
+ ...previous.agents.filter((entry) => entry.id !== agent.id),
37667
+ ...inventory.readyAgents().map((ready) => withDaemonEnvironment(ready, config2.localContext.environment))
37668
+ ],
37669
+ [...previous.installableAgents.filter((entry) => entry.id !== agent.id), ...inventory.installable]
37670
+ );
37671
+ try {
37672
+ await publish(config2, signal);
37673
+ } catch (error62) {
37674
+ config2.catalog.transition(previous.agents, previous.installableAgents);
37675
+ throw error62;
37676
+ }
37677
+ return config2.catalog.find(agent.id);
37678
+ } finally {
37679
+ swaps.delete(agent.id);
37680
+ release();
37681
+ }
37682
+ };
37683
+ }
37684
+ async function unchangedIdentity(agent, signal) {
37685
+ if (!await revalidateExecutable(agent.agentIdentity)) {
37686
+ return false;
37687
+ }
37688
+ signal.throwIfAborted();
37689
+ return agent.kind !== "acp-adapter-process" || await revalidateExecutable(agent.adapterIdentity);
37690
+ }
37691
+
37476
37692
  // src/storage/runtime-installation-store.ts
37477
37693
  import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
37478
37694
  import { mkdir as mkdir5, open as open5, readdir as readdir3, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
37479
- import { dirname as dirname4, join as join16, resolve as resolve4 } from "node:path";
37695
+ import { dirname as dirname4, join as join18, resolve as resolve4 } from "node:path";
37480
37696
  var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
37481
37697
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
37482
37698
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
@@ -37540,7 +37756,7 @@ var VerifiedRuntimeConnection = class {
37540
37756
  this.runtimeId = runtimeId;
37541
37757
  }
37542
37758
  };
37543
- function isRecord9(value) {
37759
+ function isRecord10(value) {
37544
37760
  return typeof value === "object" && value !== null && !Array.isArray(value);
37545
37761
  }
37546
37762
  function hasExactKeys(value, expectedKeys) {
@@ -37613,7 +37829,7 @@ function channelIndexFileName(channelId) {
37613
37829
  return `mci_${createHash4("sha256").update(channelId).digest("hex")}.json`;
37614
37830
  }
37615
37831
  function decodeInstallationPointer(value) {
37616
- if (!isRecord9(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
37832
+ if (!isRecord10(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
37617
37833
  throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
37618
37834
  }
37619
37835
  const storedInstallationId = value["installationId"];
@@ -37623,7 +37839,7 @@ function decodeInstallationPointer(value) {
37623
37839
  return { installationId: validateInstallationId(storedInstallationId) };
37624
37840
  }
37625
37841
  function decodeChannelIndex(value) {
37626
- if (!isRecord9(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
37842
+ if (!isRecord10(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
37627
37843
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
37628
37844
  }
37629
37845
  const applicationId = value["applicationId"];
@@ -37673,7 +37889,7 @@ function decodeVerifiedConnection(value) {
37673
37889
  );
37674
37890
  }
37675
37891
  function decodeConnection(value) {
37676
- if (!isRecord9(value)) {
37892
+ if (!isRecord10(value)) {
37677
37893
  throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
37678
37894
  }
37679
37895
  return decodeVerifiedConnection(value);
@@ -37719,7 +37935,7 @@ async function readJsonFile(path2, signal, missingCode) {
37719
37935
  async function writeJsonAtomically(path2, value, signal) {
37720
37936
  signal.throwIfAborted();
37721
37937
  const directory = dirname4(path2);
37722
- const temporaryPath = join16(directory, `.${randomUUID3()}.tmp`);
37938
+ const temporaryPath = join18(directory, `.${randomUUID3()}.tmp`);
37723
37939
  try {
37724
37940
  await mkdir5(directory, { mode: 448, recursive: true });
37725
37941
  signal.throwIfAborted();
@@ -37745,14 +37961,14 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37745
37961
  this.applicationId = applicationId;
37746
37962
  this.installationId = installationId2;
37747
37963
  this.stateDirectory = stateDirectory;
37748
- this.#channelDirectory = join16(stateDirectory, "channels");
37749
- this.#connectionDirectory = join16(stateDirectory, "connections");
37964
+ this.#channelDirectory = join18(stateDirectory, "channels");
37965
+ this.#connectionDirectory = join18(stateDirectory, "connections");
37750
37966
  }
37751
37967
  static open = async (options, signal) => {
37752
37968
  signal.throwIfAborted();
37753
37969
  const applicationId = validateApplicationId(options.applicationId);
37754
37970
  const rootDirectory = resolve4(options.stateDirectory);
37755
- const applicationDirectory = join16(rootDirectory, "installations", applicationId);
37971
+ const applicationDirectory = join18(rootDirectory, "installations", applicationId);
37756
37972
  try {
37757
37973
  await mkdir5(applicationDirectory, { mode: 448, recursive: true });
37758
37974
  } catch (cause) {
@@ -37765,7 +37981,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37765
37981
  );
37766
37982
  }
37767
37983
  const storedInstallationId = await readOrCreateInstallationId(applicationDirectory, signal);
37768
- const stateDirectory = join16(applicationDirectory, storedInstallationId);
37984
+ const stateDirectory = join18(applicationDirectory, storedInstallationId);
37769
37985
  try {
37770
37986
  await mkdir5(stateDirectory, { mode: 448, recursive: true });
37771
37987
  } catch (cause) {
@@ -37780,8 +37996,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37780
37996
  signal.throwIfAborted();
37781
37997
  return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
37782
37998
  };
37783
- connectionPath = (connectionId2) => join16(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
37784
- channelIndexPath = (channelId) => join16(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
37999
+ connectionPath = (connectionId2) => join18(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
38000
+ channelIndexPath = (channelId) => join18(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
37785
38001
  readConnection = async (connectionId2, signal) => {
37786
38002
  const stored = decodeConnection(
37787
38003
  await readJsonFile(this.connectionPath(connectionId2), signal, "connection_not_found")
@@ -37943,7 +38159,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
37943
38159
  };
37944
38160
  };
37945
38161
  async function readOrCreateInstallationId(applicationDirectory, signal) {
37946
- const pointerPath = join16(applicationDirectory, "current.json");
38162
+ const pointerPath = join18(applicationDirectory, "current.json");
37947
38163
  try {
37948
38164
  return decodeInstallationPointer(await readJsonFile(pointerPath, signal, "installation_not_found")).installationId;
37949
38165
  } catch (cause) {
@@ -37991,7 +38207,7 @@ var PairingClientError = class extends Error {
37991
38207
  this.name = "PairingClientError";
37992
38208
  }
37993
38209
  };
37994
- function isRecord10(value) {
38210
+ function isRecord11(value) {
37995
38211
  return typeof value === "object" && value !== null && !Array.isArray(value);
37996
38212
  }
37997
38213
  function hasExactKeys2(value, expectedKeys) {
@@ -38084,8 +38300,8 @@ async function resolveDefaultWorkspace(path2) {
38084
38300
  const requestedWorkspace = resolve5(path2);
38085
38301
  try {
38086
38302
  await mkdir6(requestedWorkspace, { recursive: true, mode: 448 });
38087
- const defaultWorkspace = await realpath8(requestedWorkspace);
38088
- const metadata = await stat7(defaultWorkspace);
38303
+ const defaultWorkspace = await realpath9(requestedWorkspace);
38304
+ const metadata = await stat8(defaultWorkspace);
38089
38305
  if (!metadata.isDirectory()) {
38090
38306
  throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
38091
38307
  }
@@ -38114,9 +38330,9 @@ async function readJsonResponse(response) {
38114
38330
  }
38115
38331
  }
38116
38332
  function readRelayError(value) {
38117
- if (isRecord10(value)) {
38333
+ if (isRecord11(value)) {
38118
38334
  const error62 = value["error"];
38119
- if (isRecord10(error62)) {
38335
+ if (isRecord11(error62)) {
38120
38336
  const code = error62["code"];
38121
38337
  const message = error62["message"];
38122
38338
  if (typeof code === "string" && typeof message === "string") {
@@ -38127,7 +38343,7 @@ function readRelayError(value) {
38127
38343
  return new PairingClientError("pairing_failed", "The relay could not pair this machine");
38128
38344
  }
38129
38345
  function decodePairingResponse(value, credentialField, expectedKeys) {
38130
- if (!isRecord10(value) || !hasExactKeys2(value, expectedKeys)) {
38346
+ if (!isRecord11(value) || !hasExactKeys2(value, expectedKeys)) {
38131
38347
  throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
38132
38348
  }
38133
38349
  const appId = value["appId"];
@@ -38152,7 +38368,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
38152
38368
  const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
38153
38369
  let response;
38154
38370
  try {
38155
- response = await fetch2(endpoint, {
38371
+ response = await fetch3(endpoint, {
38156
38372
  body: JSON.stringify({
38157
38373
  agents,
38158
38374
  installableAgents,
@@ -38184,20 +38400,30 @@ function buildPairedDaemon(installation, connection, defaultWorkspace, inventory
38184
38400
  const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
38185
38401
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
38186
38402
  relayUrl.searchParams.set("token", connection.runtimeCredential);
38403
+ const config2 = createDaemonConfig(
38404
+ {
38405
+ defaultWorkspace,
38406
+ channelId: connection.channelId,
38407
+ relayUrl
38408
+ },
38409
+ inventory.readyAgents(),
38410
+ inventory.installable,
38411
+ localContext,
38412
+ new OpaqueDaemonReconnectTarget(connection.connectionId),
38413
+ createCatalogAgentResolver(
38414
+ (refreshSignal) => discoverLocalAgentInventory({
38415
+ defaultWorkspace,
38416
+ environment: localContext.environment,
38417
+ signal: refreshSignal
38418
+ }),
38419
+ () => config2,
38420
+ publishAgentCatalog
38421
+ )
38422
+ );
38187
38423
  return {
38188
38424
  channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
38189
38425
  connectionId: connection.connectionId,
38190
- config: createDaemonConfig(
38191
- {
38192
- defaultWorkspace,
38193
- channelId: connection.channelId,
38194
- relayUrl
38195
- },
38196
- inventory.readyAgents(),
38197
- inventory.installable,
38198
- localContext,
38199
- new OpaqueDaemonReconnectTarget(connection.connectionId)
38200
- ),
38426
+ config: config2,
38201
38427
  connectionPath: installation.connectionPath(connection.connectionId)
38202
38428
  };
38203
38429
  }
@@ -38310,120 +38536,9 @@ function isRuntimeRelayRevocation(closeCode, closeReason) {
38310
38536
 
38311
38537
  // src/run-daemon.ts
38312
38538
  import { createHash as createHash8, randomUUID as randomUUID9 } from "node:crypto";
38313
- import { join as join19 } from "node:path";
38539
+ import { join as join21 } from "node:path";
38314
38540
  import { styleText } from "node:util";
38315
38541
 
38316
- // src/agent-catalog/publish-agent-catalog.ts
38317
- import { fetch as fetch3 } from "undici";
38318
-
38319
- // src/relay-connection/runtime-authentication.ts
38320
- function runtimeCredential(relayUrl) {
38321
- return relayUrl.searchParams.get("token") ?? "";
38322
- }
38323
- function runtimeAuthorization(relayUrl) {
38324
- const credential = runtimeCredential(relayUrl);
38325
- return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
38326
- }
38327
- function relayHttpEndpoint(relayUrl) {
38328
- const endpoint = new URL(relayUrl);
38329
- endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
38330
- endpoint.search = "";
38331
- return endpoint;
38332
- }
38333
-
38334
- // src/agent-catalog/publish-agent-catalog.ts
38335
- var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
38336
- var AgentCatalogPublishError = class extends Error {
38337
- code = "agent_catalog_update_failed";
38338
- diagnosticDetails;
38339
- constructor(message, options = {}, diagnosticDetails = {}) {
38340
- super(message, options);
38341
- this.diagnosticDetails = diagnosticDetails;
38342
- this.name = "AgentCatalogPublishError";
38343
- }
38344
- };
38345
- function isRecord11(value) {
38346
- return typeof value === "object" && value !== null && !Array.isArray(value);
38347
- }
38348
- function isSafeRelayErrorMessage(value) {
38349
- return value.length > 0 && value.length <= 512 && Array.from(value).every((character) => character.charCodeAt(0) >= 32 && character.charCodeAt(0) !== 127);
38350
- }
38351
- async function rejectedCatalogError(response) {
38352
- let value;
38353
- try {
38354
- value = await response.json();
38355
- } catch {
38356
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38357
- }
38358
- if (!isRecord11(value) || !isRecord11(value["error"])) {
38359
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38360
- }
38361
- const code = value["error"]["code"];
38362
- const message = value["error"]["message"];
38363
- if (typeof code !== "string" || !/^[a-z][a-z0-9_]{0,63}$/.test(code) || typeof message !== "string" || !isSafeRelayErrorMessage(message)) {
38364
- return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
38365
- }
38366
- return new AgentCatalogPublishError(
38367
- `The Relay rejected the Agent catalog update (${code}): ${message}`,
38368
- {},
38369
- {
38370
- relayErrorCode: code
38371
- }
38372
- );
38373
- }
38374
- function catalogEndpoint(config2) {
38375
- const endpoint = relayHttpEndpoint(config2.relayUrl);
38376
- if (endpoint.pathname.endsWith("/daemon")) {
38377
- endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
38378
- return endpoint;
38379
- }
38380
- const runtimePath = "/v1/runtimes/connect";
38381
- if (endpoint.pathname.endsWith(runtimePath)) {
38382
- endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
38383
- return endpoint;
38384
- }
38385
- throw new AgentCatalogPublishError("The Relay URL is invalid");
38386
- }
38387
- async function publishAgentCatalog(config2, signal) {
38388
- signal.throwIfAborted();
38389
- const timeoutSignal = AbortSignal.timeout(CATALOG_UPDATE_TIMEOUT_MILLISECONDS);
38390
- const requestSignal = AbortSignal.any([signal, timeoutSignal]);
38391
- let response;
38392
- const catalog = config2.catalog.read();
38393
- try {
38394
- response = await fetch3(catalogEndpoint(config2), {
38395
- body: JSON.stringify({
38396
- agents: catalog.agents.map((agent) => ({
38397
- agentPath: agent.agentIdentity.requestedPath,
38398
- agentVersion: agent.agentVersion,
38399
- agentSettingsDiscovery: true,
38400
- capabilities: agent.capabilities,
38401
- id: agent.id,
38402
- label: agent.label,
38403
- sessionTurnConfiguration: true
38404
- })),
38405
- installableAgents: catalog.installableAgents
38406
- }),
38407
- dispatcher: environmentProxyDispatcher,
38408
- headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
38409
- method: "PUT",
38410
- signal: requestSignal
38411
- });
38412
- } catch (error62) {
38413
- if (signal.aborted) {
38414
- signal.throwIfAborted();
38415
- }
38416
- throw new AgentCatalogPublishError(
38417
- timeoutSignal.aborted ? "The Agent catalog update timed out" : "The Agent catalog could not be updated",
38418
- { cause: error62 }
38419
- );
38420
- }
38421
- if (!response.ok) {
38422
- throw await rejectedCatalogError(response);
38423
- }
38424
- await response.body?.cancel();
38425
- }
38426
-
38427
38542
  // src/agent-installation/agent-installation-manager.ts
38428
38543
  var INSTALLATION_DEADLINE_MILLISECONDS = 10 * 60 * 1e3;
38429
38544
  var AgentInstallation = class {
@@ -38886,9 +39001,9 @@ var FixedInstallationExecutor = class {
38886
39001
  };
38887
39002
 
38888
39003
  // src/authorization/workspace-directory.ts
38889
- import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
39004
+ import { readdir as readdir4, realpath as realpath10, stat as stat9 } from "node:fs/promises";
38890
39005
  import { homedir as homedir2 } from "node:os";
38891
- import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute10, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
39006
+ import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute10, join as join19, normalize as normalize3, relative as relative4 } from "node:path";
38892
39007
  var WorkspaceDirectoryListing = class {
38893
39008
  directoryId;
38894
39009
  directoryLabel;
@@ -38956,9 +39071,9 @@ var WorkspaceDirectoryService = class {
38956
39071
  throw new LocalAuthorizationError("The local directory path is invalid");
38957
39072
  }
38958
39073
  try {
38959
- const target = await realpath9(requested);
39074
+ const target = await realpath10(requested);
38960
39075
  signal.throwIfAborted();
38961
- const metadata = await stat8(target);
39076
+ const metadata = await stat9(target);
38962
39077
  signal.throwIfAborted();
38963
39078
  if (!isAbsolute10(target) || normalize3(target) !== target || !metadata.isDirectory()) {
38964
39079
  throw new LocalAuthorizationError("The selected location is not a directory");
@@ -39006,7 +39121,7 @@ var WorkspaceDirectoryService = class {
39006
39121
  continue;
39007
39122
  }
39008
39123
  try {
39009
- const path2 = await this.resolvePath(join17(target, child2.name), signal);
39124
+ const path2 = await this.resolvePath(join19(target, child2.name), signal);
39010
39125
  entries.push({ directoryId: encodePath(path2), name: child2.name });
39011
39126
  } catch (cause) {
39012
39127
  signal.throwIfAborted();
@@ -39042,15 +39157,15 @@ var WorkspaceDirectoryService = class {
39042
39157
 
39043
39158
  // src/daemon-diagnostic-log.ts
39044
39159
  import { appendFileSync, mkdirSync, readFileSync as readFileSync2, renameSync, statSync as statSync3, writeFileSync } from "node:fs";
39045
- import { join as join18 } from "node:path";
39160
+ import { join as join20 } from "node:path";
39046
39161
  var MAXIMUM_DAEMON_LOG_BYTES = 1 * 1024 * 1024;
39047
39162
  var DaemonDiagnosticLog = class {
39048
39163
  #directory;
39049
39164
  #path;
39050
39165
  #maximumBytes;
39051
39166
  constructor(stateDirectory, maximumBytes = MAXIMUM_DAEMON_LOG_BYTES) {
39052
- this.#directory = join18(stateDirectory, "logs");
39053
- this.#path = join18(this.#directory, "daemon.log");
39167
+ this.#directory = join20(stateDirectory, "logs");
39168
+ this.#path = join20(this.#directory, "daemon.log");
39054
39169
  this.#maximumBytes = maximumBytes;
39055
39170
  }
39056
39171
  // Export only correlation and failure metadata. Local messages and paths stay local.
@@ -40995,9 +41110,10 @@ var NativeSessionService = class {
40995
41110
  signal
40996
41111
  );
40997
41112
  signal.throwIfAborted();
41113
+ const cataloged = this.#config.catalog.find(command.agentId);
40998
41114
  const options = {
40999
41115
  additionalDirectories,
41000
- agent: this.#config.catalog.find(command.agentId),
41116
+ agent: this.#config.resolveAgent === void 0 ? cataloged : await this.#config.resolveAgent(cataloged, signal),
41001
41117
  cwd,
41002
41118
  sessionId: command.sessionId,
41003
41119
  signal
@@ -41175,7 +41291,7 @@ var NativeSessionService = class {
41175
41291
  sessionId: command.targetSessionId,
41176
41292
  additionalDirectories: target.additionalDirectories
41177
41293
  },
41178
- action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId }
41294
+ action === "fork" ? { kind: "fork", nativeSessionId: target.info.sessionId, title: title2 } : { kind: "import", nativeSessionId: target.info.sessionId, title: title2 }
41179
41295
  );
41180
41296
  signal.throwIfAborted();
41181
41297
  const ready = {
@@ -41549,7 +41665,7 @@ import { WebSocket as WebSocket5 } from "undici";
41549
41665
  // package.json
41550
41666
  var package_default = {
41551
41667
  name: "@moxt-ai/mobius",
41552
- version: "0.0.193",
41668
+ version: "0.0.195",
41553
41669
  description: "Mobius CLI for pairing and running local AI agent services.",
41554
41670
  type: "module",
41555
41671
  bin: {
@@ -41852,7 +41968,8 @@ function unsupportedModelIds(unsupportedModels) {
41852
41968
  return [...new Set(unsupportedModels.map((item) => item.requestedValue))];
41853
41969
  }
41854
41970
  async function discoverAgentSettings(command, config2, directories, sessions, signal) {
41855
- const agent = config2.catalog.find(command.agentId);
41971
+ const cataloged = config2.catalog.find(command.agentId);
41972
+ const agent = config2.resolveAgent === void 0 ? cataloged : await config2.resolveAgent(cataloged, signal);
41856
41973
  const cwd = await directories.resolve(config2.bindingId, "default", signal);
41857
41974
  const inspectedBaseSnapshot = await sessions.inspectAgentSettings({
41858
41975
  additionalDirectories: [],
@@ -42246,7 +42363,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
42246
42363
 
42247
42364
  // src/artifacts/local-file-streamer.ts
42248
42365
  import { createReadStream as createReadStream2 } from "node:fs";
42249
- import { realpath as realpath10, stat as stat9 } from "node:fs/promises";
42366
+ import { realpath as realpath11, stat as stat10 } from "node:fs/promises";
42250
42367
  import { basename as basename5, extname, isAbsolute as isAbsolute11, normalize as normalize4, resolve as resolve7 } from "node:path";
42251
42368
  import { fileURLToPath as fileURLToPath2 } from "node:url";
42252
42369
  var CHUNK_BYTES = 192 * 1024;
@@ -42274,7 +42391,7 @@ async function resolveFile(value, workingDirectory, signal) {
42274
42391
  return null;
42275
42392
  }
42276
42393
  try {
42277
- const target = await realpath10(requested);
42394
+ const target = await realpath11(requested);
42278
42395
  signal.throwIfAborted();
42279
42396
  return isAbsolute11(target) && normalize4(target) === target ? target : null;
42280
42397
  } catch {
@@ -42288,7 +42405,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
42288
42405
  if (target === null) {
42289
42406
  throw new Error("The local file is unavailable");
42290
42407
  }
42291
- const before = await stat9(target);
42408
+ const before = await stat10(target);
42292
42409
  signal.throwIfAborted();
42293
42410
  if (!before.isFile() || before.size < 1 || before.size > command.maxBytes) {
42294
42411
  throw new Error("The local file is too large to read");
@@ -42316,7 +42433,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
42316
42433
  });
42317
42434
  sequence += 1;
42318
42435
  }
42319
- const after = await stat9(target);
42436
+ const after = await stat10(target);
42320
42437
  signal.throwIfAborted();
42321
42438
  if (after.size !== before.size || after.mtimeMs !== before.mtimeMs) {
42322
42439
  throw new Error("The local file changed during transfer");
@@ -42360,7 +42477,305 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
42360
42477
  return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
42361
42478
  }
42362
42479
 
42480
+ // src/daemon-session-commands.ts
42481
+ async function resolveCatalogAgent(config2, agentId, signal) {
42482
+ const agent = config2.catalog.find(agentId);
42483
+ return config2.resolveAgent === void 0 ? agent : await config2.resolveAgent(agent, signal);
42484
+ }
42485
+ async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
42486
+ return await metrics.measure("prepare-total", async () => {
42487
+ const resolved = await metrics.measure(
42488
+ "workspace-resolve",
42489
+ async () => await resolveSessionDirectories(
42490
+ directories,
42491
+ config2.bindingId,
42492
+ command.directoryId,
42493
+ command.additionalDirectoryIds,
42494
+ signal
42495
+ )
42496
+ );
42497
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
42498
+ const preparation = {
42499
+ additionalDirectories: resolved.additionalDirectories,
42500
+ agent,
42501
+ cwd: resolved.cwd,
42502
+ sessionId: command.sessionId,
42503
+ signal
42504
+ };
42505
+ const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
42506
+ const configuration = command.configuration;
42507
+ const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
42508
+ "configuration",
42509
+ async () => await sessions.configureSession({
42510
+ ...preparation,
42511
+ booleanValue: configuration.booleanValue,
42512
+ configId: configuration.configId,
42513
+ requestId: command.requestId,
42514
+ value: configuration.value,
42515
+ valueType: configuration.valueType
42516
+ })
42517
+ );
42518
+ const listing = await metrics.measure(
42519
+ "workspace-list",
42520
+ async () => await directories.list(config2.bindingId, command.directoryId, signal)
42521
+ );
42522
+ audit.record({
42523
+ commandId: command.requestId,
42524
+ event: "session_prepared",
42525
+ sessionId: command.sessionId
42526
+ });
42527
+ if (command.configuration !== void 0) {
42528
+ audit.record({
42529
+ commandId: command.requestId,
42530
+ event: "session_configured",
42531
+ sessionId: command.sessionId
42532
+ });
42533
+ }
42534
+ return {
42535
+ additionalDirectories: resolved.additionalDirectoryEntries,
42536
+ agentId: command.agentId,
42537
+ agentName: prepared.agentName,
42538
+ agentVersion: prepared.agentVersion,
42539
+ capabilities: prepared.capabilities,
42540
+ commands: prepared.commands,
42541
+ configOptions,
42542
+ directoryId: command.directoryId,
42543
+ directoryLabel: listing.directoryLabel,
42544
+ kind: "session.ready",
42545
+ requestId: command.requestId,
42546
+ restored: prepared.restored,
42547
+ sessionId: command.sessionId
42548
+ };
42549
+ });
42550
+ }
42551
+ async function executeWorkspaceList(socket, command, directories, audit, signal) {
42552
+ try {
42553
+ const listing = await directories.list(command.bindingId, command.directoryId, signal);
42554
+ audit.record({
42555
+ commandId: command.requestId,
42556
+ event: "workspace_list_authorized",
42557
+ sessionId: "workspace-browser"
42558
+ });
42559
+ send(socket, {
42560
+ bindingId: command.bindingId,
42561
+ directoryId: listing.directoryId,
42562
+ directoryLabel: listing.directoryLabel,
42563
+ entries: listing.entries,
42564
+ kind: "workspace.entries",
42565
+ parentDirectoryId: listing.parentDirectoryId,
42566
+ requestId: command.requestId
42567
+ });
42568
+ } catch (error62) {
42569
+ reportOperationFailure(socket, command.requestId, "", error62);
42570
+ }
42571
+ }
42572
+ async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
42573
+ const metrics = new AccumulatingOperationMetrics();
42574
+ try {
42575
+ const readyEvent = await prepareSession(
42576
+ command,
42577
+ { kind: "interactive-only" },
42578
+ config2,
42579
+ directories,
42580
+ audit,
42581
+ sessions,
42582
+ metrics,
42583
+ signal
42584
+ );
42585
+ send(socket, {
42586
+ ...readyEvent,
42587
+ runtimeTimings: metrics.snapshot()
42588
+ });
42589
+ } catch (error62) {
42590
+ diagnostics.daemonDiagnostic(
42591
+ "session_prepare_failed",
42592
+ command.requestId,
42593
+ {
42594
+ agentId: command.agentId,
42595
+ code: operationErrorCode(error62),
42596
+ sessionId: command.sessionId
42597
+ },
42598
+ error62
42599
+ );
42600
+ audit.record({
42601
+ commandId: command.requestId,
42602
+ details: {
42603
+ agentId: command.agentId,
42604
+ code: operationErrorCode(error62)
42605
+ },
42606
+ event: "session_prepare_failed",
42607
+ sessionId: command.sessionId
42608
+ });
42609
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42610
+ }
42611
+ }
42612
+ async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
42613
+ const metrics = new AccumulatingOperationMetrics();
42614
+ try {
42615
+ const entry = await metrics.measure("session-lookup", async () => {
42616
+ const [found] = await nativeSessions.querySessions([command.sessionId], signal);
42617
+ if (found === void 0) {
42618
+ throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
42619
+ }
42620
+ return found;
42621
+ });
42622
+ const ready = await prepareSession(
42623
+ {
42624
+ additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
42625
+ agentId: entry.agentId,
42626
+ bindingId: config2.bindingId,
42627
+ directoryId: entry.directoryId,
42628
+ kind: "session.prepare",
42629
+ requestId: command.requestId,
42630
+ sessionId: command.sessionId,
42631
+ sessionState: "provisioned"
42632
+ },
42633
+ { kind: "history-required" },
42634
+ config2,
42635
+ directories,
42636
+ audit,
42637
+ sessions,
42638
+ metrics,
42639
+ signal
42640
+ );
42641
+ send(socket, {
42642
+ entry,
42643
+ kind: "session.restored",
42644
+ ready: { ...ready, runtimeTimings: metrics.snapshot() },
42645
+ requestId: command.requestId
42646
+ });
42647
+ } catch (error62) {
42648
+ diagnostics.daemonDiagnostic(
42649
+ "session_restore_failed",
42650
+ command.requestId,
42651
+ {
42652
+ code: operationErrorCode(error62),
42653
+ sessionId: command.sessionId
42654
+ },
42655
+ error62
42656
+ );
42657
+ audit.record({
42658
+ commandId: command.requestId,
42659
+ details: { code: operationErrorCode(error62) },
42660
+ event: "session_restore_failed",
42661
+ sessionId: command.sessionId
42662
+ });
42663
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
42664
+ }
42665
+ }
42666
+ async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
42667
+ try {
42668
+ const resolved = await resolveSessionDirectories(
42669
+ directories,
42670
+ config2.bindingId,
42671
+ command.directoryId,
42672
+ command.additionalDirectoryIds,
42673
+ signal
42674
+ );
42675
+ const configOptions = await sessions.configureSession({
42676
+ additionalDirectories: resolved.additionalDirectories,
42677
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
42678
+ booleanValue: command.booleanValue,
42679
+ configId: command.configId,
42680
+ cwd: resolved.cwd,
42681
+ requestId: command.requestId,
42682
+ sessionId: command.sessionId,
42683
+ signal,
42684
+ value: command.value,
42685
+ valueType: command.valueType
42686
+ });
42687
+ audit.record({
42688
+ commandId: command.requestId,
42689
+ event: "session_configured",
42690
+ sessionId: command.sessionId
42691
+ });
42692
+ send(socket, {
42693
+ configOptions,
42694
+ kind: "session.config.updated",
42695
+ requestId: command.requestId,
42696
+ sessionId: command.sessionId
42697
+ });
42698
+ } catch (error62) {
42699
+ if (signal.aborted) {
42700
+ signal.throwIfAborted();
42701
+ }
42702
+ reportOperationFailure(socket, command.requestId, command.sessionId, error62);
42703
+ }
42704
+ }
42705
+
42363
42706
  // src/daemon-history-commands.ts
42707
+ function isAgentReasoning(event) {
42708
+ return event?.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk";
42709
+ }
42710
+ function omitAgentReasoning(events) {
42711
+ const retained = [];
42712
+ let previousReasoningMessageId;
42713
+ for (const event of events) {
42714
+ if (event.type !== "acp" || event.payload.sessionUpdate !== "agent_thought_chunk") {
42715
+ previousReasoningMessageId = void 0;
42716
+ retained.push(event);
42717
+ continue;
42718
+ }
42719
+ const messageId = event.payload.messageId ?? null;
42720
+ if (previousReasoningMessageId === void 0 || previousReasoningMessageId !== messageId) {
42721
+ retained.push({
42722
+ ...event,
42723
+ mobiusMetadata: { omitted: true },
42724
+ payload: { ...event.payload, content: { text: "", type: "text" } }
42725
+ });
42726
+ }
42727
+ previousReasoningMessageId = messageId;
42728
+ }
42729
+ return retained;
42730
+ }
42731
+ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoning, queuedPromptRequests, load, eventLogV2) {
42732
+ let cursor = initialCursor;
42733
+ let loaded = [];
42734
+ let sessionGenerationId = null;
42735
+ let sourceNextCursor = null;
42736
+ do {
42737
+ const replay = await load(eventLimit, cursor);
42738
+ if (sessionGenerationId !== null && replay.sessionGenerationId !== sessionGenerationId) {
42739
+ throw new AcpExecutionError("The Session reloaded while history was loading", {}, "session_reloaded");
42740
+ }
42741
+ sessionGenerationId = replay.sessionGenerationId;
42742
+ const events2 = replay.events.map(
42743
+ (event, index2) => eventLogV2.event(
42744
+ sessionId,
42745
+ replay.sessionGenerationId,
42746
+ replay.startPosition + index2,
42747
+ event,
42748
+ "1970-01-01T00:00:00.000Z"
42749
+ )
42750
+ );
42751
+ loaded = [...events2, ...loaded];
42752
+ sourceNextCursor = replay.nextCursor;
42753
+ const visible2 = omitReasoning ? omitAgentReasoning(loaded) : loaded;
42754
+ const reasoningContinuesBeforePage = sourceNextCursor !== null && isAgentReasoning(loaded[0]);
42755
+ if (visible2.length >= eventLimit && !reasoningContinuesBeforePage) {
42756
+ break;
42757
+ }
42758
+ cursor = sourceNextCursor;
42759
+ } while (cursor !== null);
42760
+ if (sessionGenerationId === null) {
42761
+ throw new AcpExecutionError("The Session history is unavailable", {}, "session_history_unavailable");
42762
+ }
42763
+ const visible = omitReasoning ? omitAgentReasoning(loaded) : loaded;
42764
+ const events = visible.slice(-eventLimit);
42765
+ const firstPosition = events[0] === void 0 ? 0 : Number(events[0].position);
42766
+ const nextCursor = firstPosition <= 1 ? null : (firstPosition - 1).toString();
42767
+ return {
42768
+ events: {
42769
+ events,
42770
+ nextCursor,
42771
+ sessionGenerationId,
42772
+ tailCursor: events.at(-1)?.eventId ?? "",
42773
+ truncated: nextCursor !== null,
42774
+ version: 2
42775
+ },
42776
+ queuedPromptRequests
42777
+ };
42778
+ }
42364
42779
  async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, directories, audit, diagnostics, sessions, nativeSessions, eventLogV2, signal) {
42365
42780
  let agentId;
42366
42781
  try {
@@ -42378,41 +42793,29 @@ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, dir
42378
42793
  );
42379
42794
  const loadOptions = {
42380
42795
  additionalDirectories: resolved.additionalDirectories,
42381
- agent: config2.catalog.find(entry.agentId),
42796
+ agent: await resolveCatalogAgent(config2, entry.agentId, signal),
42382
42797
  cwd: resolved.cwd,
42383
42798
  sessionId: command.sessionId,
42384
42799
  signal
42385
42800
  };
42386
42801
  const recovery = eventLogV2.promptRequestRecovery(command.sessionId);
42387
- const replay = await sessions.loadSessionEventsV2(loadOptions, command.eventLimit, command.cursor);
42388
- signal.throwIfAborted();
42389
- const events = replay.events.map(
42390
- (event, index2) => eventLogV2.event(
42391
- command.sessionId,
42392
- replay.sessionGenerationId,
42393
- replay.startPosition + index2,
42394
- event,
42395
- "1970-01-01T00:00:00.000Z"
42396
- )
42802
+ const events = await loadHistoryPage(
42803
+ command.sessionId,
42804
+ command.eventLimit,
42805
+ command.cursor,
42806
+ command.omit?.includes("agent-reasoning") === true,
42807
+ recovery.queuedPromptRequests,
42808
+ async (eventLimit, cursor) => await sessions.loadSessionEventsV2(loadOptions, eventLimit, cursor),
42809
+ eventLogV2
42397
42810
  );
42398
- const tailCursor = events.at(-1)?.eventId ?? "";
42811
+ signal.throwIfAborted();
42399
42812
  audit.record({
42400
42813
  commandId: command.requestId,
42401
42814
  event: "session_event_log_v2_loaded",
42402
42815
  sessionId: command.sessionId
42403
42816
  });
42404
42817
  send(socket, {
42405
- events: {
42406
- events: {
42407
- events,
42408
- nextCursor: replay.nextCursor,
42409
- sessionGenerationId: replay.sessionGenerationId,
42410
- tailCursor,
42411
- truncated: replay.truncated,
42412
- version: 2
42413
- },
42414
- queuedPromptRequests: recovery.queuedPromptRequests
42415
- },
42818
+ events,
42416
42819
  kind: SESSION_LIVE_HISTORY_V2_PAGE_LOADED_KIND,
42417
42820
  requestId: command.requestId,
42418
42821
  sessionId: command.sessionId
@@ -42451,46 +42854,30 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, di
42451
42854
  command.additionalDirectoryIds,
42452
42855
  signal
42453
42856
  );
42454
- const replay = await sessions.previewNativeSessionEventsV2(
42455
- {
42456
- additionalDirectories: resolved.additionalDirectories,
42457
- agent: config2.catalog.find(command.agentId),
42458
- cwd: resolved.cwd,
42459
- sessionId: command.sessionId,
42460
- signal
42461
- },
42857
+ const loadOptions = {
42858
+ additionalDirectories: resolved.additionalDirectories,
42859
+ agent: await resolveCatalogAgent(config2, command.agentId, signal),
42860
+ cwd: resolved.cwd,
42861
+ sessionId: command.sessionId,
42862
+ signal
42863
+ };
42864
+ const events = await loadHistoryPage(
42462
42865
  command.sessionId,
42463
42866
  command.eventLimit,
42464
- command.cursor
42867
+ command.cursor,
42868
+ command.omit?.includes("agent-reasoning") === true,
42869
+ [],
42870
+ async (eventLimit, cursor) => await sessions.previewNativeSessionEventsV2(loadOptions, command.sessionId, eventLimit, cursor),
42871
+ eventLogV2
42465
42872
  );
42466
42873
  signal.throwIfAborted();
42467
- const events = replay.events.map(
42468
- (event, index2) => eventLogV2.event(
42469
- command.sessionId,
42470
- replay.sessionGenerationId,
42471
- replay.startPosition + index2,
42472
- event,
42473
- "1970-01-01T00:00:00.000Z"
42474
- )
42475
- );
42476
- const tailCursor = events.at(-1)?.eventId ?? "";
42477
42874
  audit.record({
42478
42875
  commandId: command.requestId,
42479
42876
  event: "session_event_log_v2_loaded",
42480
42877
  sessionId: command.sessionId
42481
42878
  });
42482
42879
  send(socket, {
42483
- events: {
42484
- events: {
42485
- events,
42486
- nextCursor: replay.nextCursor,
42487
- sessionGenerationId: replay.sessionGenerationId,
42488
- tailCursor,
42489
- truncated: replay.truncated,
42490
- version: 2
42491
- },
42492
- queuedPromptRequests: []
42493
- },
42880
+ events,
42494
42881
  kind: SESSION_PREVIEW_HISTORY_PAGE_LOADED_KIND,
42495
42882
  requestId: command.requestId,
42496
42883
  sessionId: command.sessionId
@@ -42746,7 +43133,7 @@ async function executePrompt({
42746
43133
  command.additionalDirectoryIds,
42747
43134
  signal
42748
43135
  );
42749
- const agent = config2.catalog.find(command.agentId);
43136
+ const agent = await resolveCatalogAgent(config2, command.agentId, signal);
42750
43137
  const availability = await waitForSessionAvailability(signal);
42751
43138
  if (availability.kind === "busy") {
42752
43139
  throw new AcpExecutionError("Another prompt is already running in this conversation", {}, "session_busy");
@@ -42891,228 +43278,6 @@ async function executePrompt({
42891
43278
  }
42892
43279
  }
42893
43280
 
42894
- // src/daemon-session-commands.ts
42895
- async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
42896
- return await metrics.measure("prepare-total", async () => {
42897
- const resolved = await metrics.measure(
42898
- "workspace-resolve",
42899
- async () => await resolveSessionDirectories(
42900
- directories,
42901
- config2.bindingId,
42902
- command.directoryId,
42903
- command.additionalDirectoryIds,
42904
- signal
42905
- )
42906
- );
42907
- const agent = config2.catalog.find(command.agentId);
42908
- const preparation = {
42909
- additionalDirectories: resolved.additionalDirectories,
42910
- agent,
42911
- cwd: resolved.cwd,
42912
- sessionId: command.sessionId,
42913
- signal
42914
- };
42915
- const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
42916
- const configuration = command.configuration;
42917
- const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
42918
- "configuration",
42919
- async () => await sessions.configureSession({
42920
- ...preparation,
42921
- booleanValue: configuration.booleanValue,
42922
- configId: configuration.configId,
42923
- requestId: command.requestId,
42924
- value: configuration.value,
42925
- valueType: configuration.valueType
42926
- })
42927
- );
42928
- const listing = await metrics.measure(
42929
- "workspace-list",
42930
- async () => await directories.list(config2.bindingId, command.directoryId, signal)
42931
- );
42932
- audit.record({
42933
- commandId: command.requestId,
42934
- event: "session_prepared",
42935
- sessionId: command.sessionId
42936
- });
42937
- if (command.configuration !== void 0) {
42938
- audit.record({
42939
- commandId: command.requestId,
42940
- event: "session_configured",
42941
- sessionId: command.sessionId
42942
- });
42943
- }
42944
- return {
42945
- additionalDirectories: resolved.additionalDirectoryEntries,
42946
- agentId: command.agentId,
42947
- agentName: prepared.agentName,
42948
- agentVersion: prepared.agentVersion,
42949
- capabilities: prepared.capabilities,
42950
- commands: prepared.commands,
42951
- configOptions,
42952
- directoryId: command.directoryId,
42953
- directoryLabel: listing.directoryLabel,
42954
- kind: "session.ready",
42955
- requestId: command.requestId,
42956
- restored: prepared.restored,
42957
- sessionId: command.sessionId
42958
- };
42959
- });
42960
- }
42961
- async function executeWorkspaceList(socket, command, directories, audit, signal) {
42962
- try {
42963
- const listing = await directories.list(command.bindingId, command.directoryId, signal);
42964
- audit.record({
42965
- commandId: command.requestId,
42966
- event: "workspace_list_authorized",
42967
- sessionId: "workspace-browser"
42968
- });
42969
- send(socket, {
42970
- bindingId: command.bindingId,
42971
- directoryId: listing.directoryId,
42972
- directoryLabel: listing.directoryLabel,
42973
- entries: listing.entries,
42974
- kind: "workspace.entries",
42975
- parentDirectoryId: listing.parentDirectoryId,
42976
- requestId: command.requestId
42977
- });
42978
- } catch (error62) {
42979
- reportOperationFailure(socket, command.requestId, "", error62);
42980
- }
42981
- }
42982
- async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
42983
- const metrics = new AccumulatingOperationMetrics();
42984
- try {
42985
- const readyEvent = await prepareSession(
42986
- command,
42987
- { kind: "interactive-only" },
42988
- config2,
42989
- directories,
42990
- audit,
42991
- sessions,
42992
- metrics,
42993
- signal
42994
- );
42995
- send(socket, {
42996
- ...readyEvent,
42997
- runtimeTimings: metrics.snapshot()
42998
- });
42999
- } catch (error62) {
43000
- diagnostics.daemonDiagnostic(
43001
- "session_prepare_failed",
43002
- command.requestId,
43003
- {
43004
- agentId: command.agentId,
43005
- code: operationErrorCode(error62),
43006
- sessionId: command.sessionId
43007
- },
43008
- error62
43009
- );
43010
- audit.record({
43011
- commandId: command.requestId,
43012
- details: {
43013
- agentId: command.agentId,
43014
- code: operationErrorCode(error62)
43015
- },
43016
- event: "session_prepare_failed",
43017
- sessionId: command.sessionId
43018
- });
43019
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
43020
- }
43021
- }
43022
- async function executeSessionRestore(socket, command, config2, directories, audit, sessions, nativeSessions, diagnostics, signal) {
43023
- const metrics = new AccumulatingOperationMetrics();
43024
- try {
43025
- const entry = await metrics.measure("session-lookup", async () => {
43026
- const [found] = await nativeSessions.querySessions([command.sessionId], signal);
43027
- if (found === void 0) {
43028
- throw new AcpExecutionError("The Session was not found", {}, "session_not_found");
43029
- }
43030
- return found;
43031
- });
43032
- const ready = await prepareSession(
43033
- {
43034
- additionalDirectoryIds: entry.additionalDirectories.map((directory) => directory.directoryId),
43035
- agentId: entry.agentId,
43036
- bindingId: config2.bindingId,
43037
- directoryId: entry.directoryId,
43038
- kind: "session.prepare",
43039
- requestId: command.requestId,
43040
- sessionId: command.sessionId,
43041
- sessionState: "provisioned"
43042
- },
43043
- { kind: "history-required" },
43044
- config2,
43045
- directories,
43046
- audit,
43047
- sessions,
43048
- metrics,
43049
- signal
43050
- );
43051
- send(socket, {
43052
- entry,
43053
- kind: "session.restored",
43054
- ready: { ...ready, runtimeTimings: metrics.snapshot() },
43055
- requestId: command.requestId
43056
- });
43057
- } catch (error62) {
43058
- diagnostics.daemonDiagnostic(
43059
- "session_restore_failed",
43060
- command.requestId,
43061
- {
43062
- code: operationErrorCode(error62),
43063
- sessionId: command.sessionId
43064
- },
43065
- error62
43066
- );
43067
- audit.record({
43068
- commandId: command.requestId,
43069
- details: { code: operationErrorCode(error62) },
43070
- event: "session_restore_failed",
43071
- sessionId: command.sessionId
43072
- });
43073
- reportOperationFailure(socket, command.requestId, command.sessionId, error62, metrics.snapshot());
43074
- }
43075
- }
43076
- async function executeSessionConfigure(socket, command, config2, directories, audit, sessions, signal) {
43077
- try {
43078
- const resolved = await resolveSessionDirectories(
43079
- directories,
43080
- config2.bindingId,
43081
- command.directoryId,
43082
- command.additionalDirectoryIds,
43083
- signal
43084
- );
43085
- const configOptions = await sessions.configureSession({
43086
- additionalDirectories: resolved.additionalDirectories,
43087
- agent: config2.catalog.find(command.agentId),
43088
- booleanValue: command.booleanValue,
43089
- configId: command.configId,
43090
- cwd: resolved.cwd,
43091
- requestId: command.requestId,
43092
- sessionId: command.sessionId,
43093
- signal,
43094
- value: command.value,
43095
- valueType: command.valueType
43096
- });
43097
- audit.record({
43098
- commandId: command.requestId,
43099
- event: "session_configured",
43100
- sessionId: command.sessionId
43101
- });
43102
- send(socket, {
43103
- configOptions,
43104
- kind: "session.config.updated",
43105
- requestId: command.requestId,
43106
- sessionId: command.sessionId
43107
- });
43108
- } catch (error62) {
43109
- if (signal.aborted) {
43110
- signal.throwIfAborted();
43111
- }
43112
- reportOperationFailure(socket, command.requestId, command.sessionId, error62);
43113
- }
43114
- }
43115
-
43116
43281
  // src/native-sessions/handle-native-requests.ts
43117
43282
  import { WebSocket as WebSocket4 } from "undici";
43118
43283
  function createNativeSessionRequestHandler(dependencies) {
@@ -44285,11 +44450,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
44285
44450
  stateDirectory
44286
44451
  });
44287
44452
  const channelHash = createHash8("sha256").update(config2.channelId).digest("hex");
44288
- const sessionDatabase = openAcpSessionDatabase(join19(stateDirectory, "sessions", `${channelHash}.sqlite`));
44453
+ const sessionDatabase = openAcpSessionDatabase(join21(stateDirectory, "sessions", `${channelHash}.sqlite`));
44289
44454
  let eventsV2;
44290
44455
  try {
44291
44456
  eventsV2 = new CachedAcpSessionEventStoreV2(
44292
- openSessionEventCacheV2Database(join19(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
44457
+ openSessionEventCacheV2Database(join21(stateDirectory, "sessions", `${channelHash}.events.sqlite`))
44293
44458
  );
44294
44459
  } catch (error62) {
44295
44460
  sessionDatabase.close();
@@ -44492,7 +44657,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
44492
44657
  }
44493
44658
 
44494
44659
  // src/runtime.ts
44495
- import { mkdir as mkdir7, realpath as realpath11, stat as stat10 } from "node:fs/promises";
44660
+ import { mkdir as mkdir7, realpath as realpath12, stat as stat11 } from "node:fs/promises";
44496
44661
  import { resolve as resolve8 } from "node:path";
44497
44662
  var RUNTIME_CREDENTIAL_PATTERN2 = /^[a-zA-Z0-9_-]{32,256}$/;
44498
44663
  var MobiusRuntimeConfigurationError = class extends Error {
@@ -44559,8 +44724,8 @@ async function resolveWorkspace(path2) {
44559
44724
  const requested = resolve8(path2);
44560
44725
  try {
44561
44726
  await mkdir7(requested, { recursive: true, mode: 448 });
44562
- const resolved = await realpath11(requested);
44563
- const metadata = await stat10(resolved);
44727
+ const resolved = await realpath12(requested);
44728
+ const metadata = await stat11(resolved);
44564
44729
  if (!metadata.isDirectory()) {
44565
44730
  throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
44566
44731
  }
@@ -44577,26 +44742,35 @@ async function createMobiusRuntimeEngine(connection, signal, environment = proce
44577
44742
  const localContext = new DaemonLocalContext(readStateDirectory(environment), environment);
44578
44743
  const relayUrl = relayUrlFromConnection(connection);
44579
44744
  const defaultWorkspace = await resolveWorkspace(connection.defaultWorkspace);
44580
- const inventory = await discoverLocalAgentInventory({
44745
+ const specifications = supportedLocalAgentSpecifications();
44746
+ const discoveryEnvironment = localContext.environment;
44747
+ const discover = async (refreshSignal) => await discoverLocalAgentInventory({
44581
44748
  defaultWorkspace,
44582
- environment: localContext.environment,
44583
- signal
44749
+ environment: discoveryEnvironment,
44750
+ signal: refreshSignal,
44751
+ specifications
44584
44752
  });
44753
+ const inventory = await discover(signal);
44585
44754
  if (inventory.available.length + inventory.installable.length === 0) {
44586
44755
  throw new MobiusRuntimeConfigurationError("No supported Agent is available for the local Runtime");
44587
44756
  }
44588
- return new MobiusRuntimeEngine(
44589
- createDaemonConfig(
44590
- {
44591
- channelId: connection.channelId,
44592
- defaultWorkspace,
44593
- relayUrl
44594
- },
44595
- inventory.readyAgents(),
44596
- inventory.installable,
44597
- localContext
44757
+ const config2 = createDaemonConfig(
44758
+ {
44759
+ channelId: connection.channelId,
44760
+ defaultWorkspace,
44761
+ relayUrl
44762
+ },
44763
+ inventory.readyAgents(),
44764
+ inventory.installable,
44765
+ localContext,
44766
+ null,
44767
+ createCatalogAgentResolver(
44768
+ (refreshSignal) => discover(refreshSignal),
44769
+ () => config2,
44770
+ publishAgentCatalog
44598
44771
  )
44599
44772
  );
44773
+ return new MobiusRuntimeEngine(config2);
44600
44774
  }
44601
44775
  var MobiusRuntimeEngine = class {
44602
44776
  #config;