@moxt-ai/mobius 0.0.14 → 0.0.16

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 (95) hide show
  1. package/dist/acp/create-client.d.ts.map +1 -1
  2. package/dist/acp/create-client.js +16 -1
  3. package/dist/acp/create-client.js.map +1 -1
  4. package/dist/agent-catalog/agent-discovery.d.ts +1 -1
  5. package/dist/agent-catalog/agent-discovery.d.ts.map +1 -1
  6. package/dist/agent-catalog/agent-discovery.js +2 -2
  7. package/dist/agent-catalog/agent-discovery.js.map +1 -1
  8. package/dist/agent-catalog/agent-specification.d.ts +1 -0
  9. package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
  10. package/dist/agent-catalog/agent-specification.js +1 -0
  11. package/dist/agent-catalog/agent-specification.js.map +1 -1
  12. package/dist/agent-catalog/agents/cursor-cli-agent.d.ts +13 -0
  13. package/dist/agent-catalog/agents/cursor-cli-agent.d.ts.map +1 -0
  14. package/dist/agent-catalog/agents/cursor-cli-agent.js +25 -0
  15. package/dist/agent-catalog/agents/cursor-cli-agent.js.map +1 -0
  16. package/dist/agent-catalog/agents/grok-build-agent.d.ts +18 -0
  17. package/dist/agent-catalog/agents/grok-build-agent.d.ts.map +1 -0
  18. package/dist/agent-catalog/agents/grok-build-agent.js +75 -0
  19. package/dist/agent-catalog/agents/grok-build-agent.js.map +1 -0
  20. package/dist/agent-catalog/agents/supported-agent-specifications.d.ts.map +1 -1
  21. package/dist/agent-catalog/agents/supported-agent-specifications.js +6 -0
  22. package/dist/agent-catalog/agents/supported-agent-specifications.js.map +1 -1
  23. package/dist/agent-catalog/agents/verify-session-creation.d.ts +3 -0
  24. package/dist/agent-catalog/agents/verify-session-creation.d.ts.map +1 -0
  25. package/dist/agent-catalog/agents/verify-session-creation.js +16 -0
  26. package/dist/agent-catalog/agents/verify-session-creation.js.map +1 -0
  27. package/dist/agent-catalog/agents/workbuddy-agent.d.ts +17 -0
  28. package/dist/agent-catalog/agents/workbuddy-agent.d.ts.map +1 -0
  29. package/dist/agent-catalog/agents/workbuddy-agent.js +73 -0
  30. package/dist/agent-catalog/agents/workbuddy-agent.js.map +1 -0
  31. package/dist/agent-catalog/discover-local-agents.d.ts +3 -0
  32. package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
  33. package/dist/agent-catalog/discover-local-agents.js +4 -10
  34. package/dist/agent-catalog/discover-local-agents.js.map +1 -1
  35. package/dist/agent-catalog/executable-discovery.d.ts.map +1 -1
  36. package/dist/agent-catalog/executable-discovery.js +18 -8
  37. package/dist/agent-catalog/executable-discovery.js.map +1 -1
  38. package/dist/agent-catalog/local-agent.d.ts +1 -2
  39. package/dist/agent-catalog/local-agent.d.ts.map +1 -1
  40. package/dist/agent-catalog/local-agent.js +1 -3
  41. package/dist/agent-catalog/local-agent.js.map +1 -1
  42. package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
  43. package/dist/agent-catalog/publish-agent-catalog.js +0 -1
  44. package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
  45. package/dist/agent-installation/agent-installation-manager.d.ts +1 -8
  46. package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -1
  47. package/dist/agent-installation/agent-installation-manager.js +7 -24
  48. package/dist/agent-installation/agent-installation-manager.js.map +1 -1
  49. package/dist/agent-installation/fixed-agent-install-recipe.d.ts +20 -0
  50. package/dist/agent-installation/fixed-agent-install-recipe.d.ts.map +1 -0
  51. package/dist/agent-installation/fixed-agent-install-recipe.js +18 -0
  52. package/dist/agent-installation/fixed-agent-install-recipe.js.map +1 -0
  53. package/dist/agent-installation/fixed-agent-install-recipes.d.ts +5 -18
  54. package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +1 -1
  55. package/dist/agent-installation/fixed-agent-install-recipes.js +9 -16
  56. package/dist/agent-installation/fixed-agent-install-recipes.js.map +1 -1
  57. package/dist/agent-installation/grok-build-install-recipe.d.ts +12 -0
  58. package/dist/agent-installation/grok-build-install-recipe.d.ts.map +1 -0
  59. package/dist/agent-installation/grok-build-install-recipe.js +102 -0
  60. package/dist/agent-installation/grok-build-install-recipe.js.map +1 -0
  61. package/dist/agent-installation/grok-managed-package.d.ts +4 -0
  62. package/dist/agent-installation/grok-managed-package.d.ts.map +1 -0
  63. package/dist/agent-installation/grok-managed-package.js +34 -0
  64. package/dist/agent-installation/grok-managed-package.js.map +1 -0
  65. package/dist/agent-installation/managed-npm-package.d.ts +8 -0
  66. package/dist/agent-installation/managed-npm-package.d.ts.map +1 -1
  67. package/dist/agent-installation/managed-npm-package.js +32 -3
  68. package/dist/agent-installation/managed-npm-package.js.map +1 -1
  69. package/dist/agent-installation/workbuddy-install-recipe.d.ts +12 -0
  70. package/dist/agent-installation/workbuddy-install-recipe.d.ts.map +1 -0
  71. package/dist/agent-installation/workbuddy-install-recipe.js +51 -0
  72. package/dist/agent-installation/workbuddy-install-recipe.js.map +1 -0
  73. package/dist/agent-installation/workbuddy-managed-package.d.ts +10 -0
  74. package/dist/agent-installation/workbuddy-managed-package.d.ts.map +1 -0
  75. package/dist/agent-installation/workbuddy-managed-package.js +11 -0
  76. package/dist/agent-installation/workbuddy-managed-package.js.map +1 -0
  77. package/dist/cli.js +836 -361
  78. package/dist/cli.js.map +4 -4
  79. package/dist/index.js +781 -306
  80. package/dist/index.js.map +4 -4
  81. package/dist/pairing/pair-local-machine.d.ts.map +1 -1
  82. package/dist/pairing/pair-local-machine.js +0 -1
  83. package/dist/pairing/pair-local-machine.js.map +1 -1
  84. package/dist/run-daemon.d.ts.map +1 -1
  85. package/dist/run-daemon.js +3 -12
  86. package/dist/run-daemon.js.map +1 -1
  87. package/package.json +2 -2
  88. package/dist/agent-installation/installation-grants.d.ts +0 -2
  89. package/dist/agent-installation/installation-grants.d.ts.map +0 -1
  90. package/dist/agent-installation/installation-grants.js +0 -51
  91. package/dist/agent-installation/installation-grants.js.map +0 -1
  92. package/dist/agent-installation/local-installation-authorizer.d.ts +0 -7
  93. package/dist/agent-installation/local-installation-authorizer.d.ts.map +0 -1
  94. package/dist/agent-installation/local-installation-authorizer.js +0 -32
  95. package/dist/agent-installation/local-installation-authorizer.js.map +0 -1
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/cli.ts
9
- import { mkdir as mkdir5 } from "node:fs/promises";
9
+ import { mkdir as mkdir6 } from "node:fs/promises";
10
10
 
11
11
  // src/agent-catalog/local-agent.ts
12
12
  import { realpathSync, statSync } from "node:fs";
@@ -521,11 +521,9 @@ var LocalAgentDefinition = class {
521
521
  var InstallableAgentDefinition = class {
522
522
  id;
523
523
  label;
524
- requiresLocalApproval;
525
- constructor(id, label, requiresLocalApproval = true) {
524
+ constructor(id, label) {
526
525
  this.id = id;
527
526
  this.label = label;
528
- this.requiresLocalApproval = requiresLocalApproval;
529
527
  }
530
528
  };
531
529
  var LocalAgentCatalogSnapshot = class {
@@ -644,7 +642,7 @@ var LocalAgentInventory = class {
644
642
  discoveries;
645
643
  installable;
646
644
  unavailable;
647
- constructor(discoveries, grantedAgents = /* @__PURE__ */ new Set(), platform = process.platform, architecture = process.arch) {
645
+ constructor(discoveries, platform = process.platform, architecture = process.arch) {
648
646
  const available = [];
649
647
  const unavailable = [];
650
648
  for (const discovery of discoveries) {
@@ -667,8 +665,7 @@ var LocalAgentInventory = class {
667
665
  ).map(
668
666
  (discovery) => new InstallableAgentDefinition(
669
667
  discovery.specification.id,
670
- discovery.specification.label,
671
- !grantedAgents.has(discovery.specification.id)
668
+ discovery.specification.label
672
669
  )
673
670
  )
674
671
  );
@@ -752,70 +749,17 @@ function formatAgentDiagnostics(inventory, json2) {
752
749
  `;
753
750
  }
754
751
 
755
- // src/agent-installation/installation-grants.ts
756
- import { open } from "node:fs/promises";
757
- import { join as join2 } from "node:path";
758
- var MAX_GRANT_FILE_LENGTH = 16 * 1024;
759
- var AGENT_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
760
- function isRecord(value) {
761
- return typeof value === "object" && value !== null && !Array.isArray(value);
762
- }
763
- async function readGrantedAgents(stateDirectory) {
764
- const path2 = join2(stateDirectory, "installation-grants.json");
765
- let handle;
766
- try {
767
- handle = await open(path2, "r");
768
- } catch (error61) {
769
- if (error61 instanceof Error && "code" in error61 && error61.code === "ENOENT") {
770
- return /* @__PURE__ */ new Set();
771
- }
772
- throw error61;
773
- }
774
- try {
775
- const metadata = await handle.stat();
776
- if (!metadata.isFile() || metadata.size > MAX_GRANT_FILE_LENGTH || typeof process.getuid === "function" && metadata.uid !== process.getuid() || process.platform !== "win32" && (metadata.mode & 63) !== 0) {
777
- throw new Error("The local installation grant file is not private");
778
- }
779
- const encoded = await handle.readFile({ encoding: "utf8" });
780
- const value = JSON.parse(encoded);
781
- if (!isRecord(value) || Object.keys(value).length !== 1 || !Array.isArray(value["agents"])) {
782
- throw new Error("The local installation grant file is invalid");
783
- }
784
- const agents = /* @__PURE__ */ new Set();
785
- for (const candidate of value["agents"]) {
786
- if (typeof candidate !== "string" || !AGENT_ID_PATTERN.test(candidate) || agents.has(candidate)) {
787
- throw new Error("The local installation grant file is invalid");
788
- }
789
- agents.add(candidate);
790
- }
791
- return agents;
792
- } finally {
793
- await handle.close();
794
- }
795
- }
796
-
797
- // src/storage/state-directory.ts
798
- import { homedir } from "node:os";
799
- import { join as join3, resolve as resolve2 } from "node:path";
800
- function readStateDirectory(environment = process.env) {
801
- const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
802
- if (configured !== void 0 && configured.length > 0) {
803
- return resolve2(configured);
804
- }
805
- return join3(homedir(), ".mobius");
806
- }
807
-
808
752
  // src/agent-installation/managed-npm-package.ts
809
753
  import {
810
754
  mkdir,
811
755
  mkdtemp,
812
- open as open2,
756
+ open,
813
757
  realpath as realpath2,
814
758
  rename,
815
759
  rm,
816
760
  stat as stat2
817
761
  } from "node:fs/promises";
818
- import { delimiter, dirname, isAbsolute, join as join4, relative, sep } from "node:path";
762
+ import { delimiter, dirname, isAbsolute, join as join2, relative, sep } from "node:path";
819
763
  var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
820
764
  var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
821
765
  var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
@@ -834,6 +778,7 @@ var ManagedNpmPackageDefinition = class {
834
778
  };
835
779
  var SriManagedNpmPackageDefinition = class extends ManagedNpmPackageDefinition {
836
780
  integrity;
781
+ requiredDependencies = Object.freeze([]);
837
782
  tarballUrl;
838
783
  constructor(packageName, version2, executableName, integrity, tarballUrl) {
839
784
  super(packageName, version2, executableName);
@@ -841,6 +786,18 @@ var SriManagedNpmPackageDefinition = class extends ManagedNpmPackageDefinition {
841
786
  this.tarballUrl = tarballUrl;
842
787
  }
843
788
  };
789
+ var SriManagedNpmDependencyDefinition = class {
790
+ integrity;
791
+ packageName;
792
+ tarballUrl;
793
+ version;
794
+ constructor(packageName, version2, integrity, tarballUrl) {
795
+ this.integrity = integrity;
796
+ this.packageName = packageName;
797
+ this.tarballUrl = tarballUrl;
798
+ this.version = version2;
799
+ }
800
+ };
844
801
  var ManagedNpmPackageError = class extends Error {
845
802
  code;
846
803
  constructor(code, message, options = {}) {
@@ -849,11 +806,11 @@ var ManagedNpmPackageError = class extends Error {
849
806
  this.name = "ManagedNpmPackageError";
850
807
  }
851
808
  };
852
- function isRecord2(value) {
809
+ function isRecord(value) {
853
810
  return typeof value === "object" && value !== null && !Array.isArray(value);
854
811
  }
855
812
  function packagePath(root, packageName) {
856
- return join4(root, "node_modules", ...packageName.split("/"));
813
+ return join2(root, "node_modules", ...packageName.split("/"));
857
814
  }
858
815
  function isContainedPath(root, candidate) {
859
816
  const difference = relative(root, candidate);
@@ -861,7 +818,7 @@ function isContainedPath(root, candidate) {
861
818
  }
862
819
  async function readJsonRecord(path2, maximumBytes) {
863
820
  try {
864
- const handle = await open2(path2, "r");
821
+ const handle = await open(path2, "r");
865
822
  try {
866
823
  const metadata = await handle.stat();
867
824
  if (!metadata.isFile() || metadata.size > maximumBytes) {
@@ -873,7 +830,7 @@ async function readJsonRecord(path2, maximumBytes) {
873
830
  const value = JSON.parse(
874
831
  await handle.readFile({ encoding: "utf8" })
875
832
  );
876
- if (!isRecord2(value)) {
833
+ if (!isRecord(value)) {
877
834
  throw new ManagedNpmPackageError(
878
835
  "managed_package_verification_failed",
879
836
  "The managed npm package metadata is invalid"
@@ -899,7 +856,7 @@ function readBinPath(packageMetadata, executableName) {
899
856
  if (typeof bin === "string") {
900
857
  return bin;
901
858
  }
902
- if (isRecord2(bin) && typeof bin[executableName] === "string") {
859
+ if (isRecord(bin) && typeof bin[executableName] === "string") {
903
860
  return bin[executableName];
904
861
  }
905
862
  throw new ManagedNpmPackageError(
@@ -907,7 +864,7 @@ function readBinPath(packageMetadata, executableName) {
907
864
  "The managed npm package executable declaration is invalid"
908
865
  );
909
866
  }
910
- function verifyPackageLock(lock, definition) {
867
+ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
911
868
  if (lock["lockfileVersion"] !== 3) {
912
869
  throw new ManagedNpmPackageError(
913
870
  "managed_package_verification_failed",
@@ -915,7 +872,7 @@ function verifyPackageLock(lock, definition) {
915
872
  );
916
873
  }
917
874
  const packages = lock["packages"];
918
- if (!isRecord2(packages)) {
875
+ if (!isRecord(packages)) {
919
876
  throw new ManagedNpmPackageError(
920
877
  "managed_package_verification_failed",
921
878
  "The managed npm package lockfile is invalid"
@@ -926,10 +883,10 @@ function verifyPackageLock(lock, definition) {
926
883
  let matches = 0;
927
884
  for (const [key, candidate] of Object.entries(packages)) {
928
885
  const normalizedKey = key.replaceAll("\\", "/");
929
- if (definition.verifyDependencyClosure && normalizedKey.length > 0) {
886
+ if (verifyDependencyClosure && normalizedKey.length > 0) {
930
887
  let resolved;
931
888
  try {
932
- if (!normalizedKey.split("/").includes("node_modules") || !isRecord2(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
889
+ if (!normalizedKey.split("/").includes("node_modules") || !isRecord(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
933
890
  throw new Error("Invalid locked dependency");
934
891
  }
935
892
  resolved = new URL(candidate["resolved"]);
@@ -952,13 +909,35 @@ function verifyPackageLock(lock, definition) {
952
909
  matches += 1;
953
910
  }
954
911
  }
955
- if (matches !== 1 || !isRecord2(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
912
+ if (matches !== 1 || !isRecord(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
956
913
  throw new ManagedNpmPackageError(
957
914
  "managed_package_verification_failed",
958
915
  "The managed npm package lockfile does not match the pinned artifact"
959
916
  );
960
917
  }
961
918
  }
919
+ async function verifyRequiredDependency(rootPath, lock, definition) {
920
+ const dependencyRoot = await realpath2(
921
+ packagePath(rootPath, definition.packageName)
922
+ );
923
+ if (!isContainedPath(rootPath, dependencyRoot)) {
924
+ throw new ManagedNpmPackageError(
925
+ "managed_package_verification_failed",
926
+ "The required managed npm dependency escaped its private cache"
927
+ );
928
+ }
929
+ const metadata = await readJsonRecord(
930
+ join2(dependencyRoot, "package.json"),
931
+ PACKAGE_METADATA_LIMIT_BYTES
932
+ );
933
+ if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
934
+ throw new ManagedNpmPackageError(
935
+ "managed_package_verification_failed",
936
+ "The required managed npm dependency identity is invalid"
937
+ );
938
+ }
939
+ verifyPackageLockEntry(lock, definition, false);
940
+ }
962
941
  async function validateManagedNpmPackage(root, definition) {
963
942
  try {
964
943
  return await validateManagedNpmPackageContents(root, definition);
@@ -985,7 +964,7 @@ async function validateManagedNpmPackageContents(root, definition) {
985
964
  );
986
965
  }
987
966
  const metadata = await readJsonRecord(
988
- join4(packageRoot, "package.json"),
967
+ join2(packageRoot, "package.json"),
989
968
  PACKAGE_METADATA_LIMIT_BYTES
990
969
  );
991
970
  if (metadata["name"] !== definition.packageName || metadata["version"] !== definition.version) {
@@ -995,17 +974,22 @@ async function validateManagedNpmPackageContents(root, definition) {
995
974
  );
996
975
  }
997
976
  if (definition instanceof SriManagedNpmPackageDefinition) {
998
- verifyPackageLock(
999
- await readJsonRecord(
1000
- join4(rootPath, "package-lock.json"),
1001
- PACKAGE_LOCK_LIMIT_BYTES
1002
- ),
1003
- definition
977
+ const lock = await readJsonRecord(
978
+ join2(rootPath, "package-lock.json"),
979
+ PACKAGE_LOCK_LIMIT_BYTES
980
+ );
981
+ verifyPackageLockEntry(
982
+ lock,
983
+ definition,
984
+ definition.verifyDependencyClosure
1004
985
  );
986
+ for (const dependency of definition.requiredDependencies) {
987
+ await verifyRequiredDependency(rootPath, lock, dependency);
988
+ }
1005
989
  }
1006
990
  const declaredBin = readBinPath(metadata, definition.executableName);
1007
991
  const executable = await resolveExecutablePath(
1008
- join4(packageRoot, declaredBin)
992
+ join2(packageRoot, declaredBin)
1009
993
  );
1010
994
  if (executable === null || !isContainedPath(rootPath, executable.path)) {
1011
995
  throw new ManagedNpmPackageError(
@@ -1031,7 +1015,7 @@ var ManagedNpmPackageInstaller = class {
1031
1015
  const parent = dirname(root);
1032
1016
  await mkdir(parent, { mode: 448, recursive: true });
1033
1017
  const staging = await mkdtemp(
1034
- join4(parent, `.${definition.version}.staging-`)
1018
+ join2(parent, `.${definition.version}.staging-`)
1035
1019
  );
1036
1020
  try {
1037
1021
  const npm = await findExecutableOnPath(
@@ -1061,9 +1045,9 @@ var ManagedNpmPackageInstaller = class {
1061
1045
  `${definition.packageName}@${definition.version}`
1062
1046
  );
1063
1047
  const installEnvironment = {
1064
- HOME: join4(staging, "home"),
1048
+ HOME: join2(staging, "home"),
1065
1049
  NPM_CONFIG_AUDIT: "false",
1066
- NPM_CONFIG_CACHE: join4(staging, ".npm-cache"),
1050
+ NPM_CONFIG_CACHE: join2(staging, ".npm-cache"),
1067
1051
  NPM_CONFIG_FUND: "false",
1068
1052
  NPM_CONFIG_IGNORE_SCRIPTS: "true",
1069
1053
  NPM_CONFIG_PACKAGE_LOCK: "true",
@@ -1085,8 +1069,8 @@ var ManagedNpmPackageInstaller = class {
1085
1069
  timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS
1086
1070
  });
1087
1071
  await Promise.all([
1088
- rm(join4(staging, ".npm-cache"), { force: true, recursive: true }),
1089
- rm(join4(staging, "home"), { force: true, recursive: true })
1072
+ rm(join2(staging, ".npm-cache"), { force: true, recursive: true }),
1073
+ rm(join2(staging, "home"), { force: true, recursive: true })
1090
1074
  ]);
1091
1075
  await validateManagedNpmPackage(staging, definition);
1092
1076
  try {
@@ -1122,7 +1106,7 @@ var ManagedNpmPackageInstaller = class {
1122
1106
  };
1123
1107
 
1124
1108
  // src/agent-catalog/agent-specification.ts
1125
- import { join as join5 } from "node:path";
1109
+ import { join as join3 } from "node:path";
1126
1110
  var VERSION_PROBE_TIMEOUT_MILLISECONDS = 3e3;
1127
1111
  var ACP_PROBE_TIMEOUT_MILLISECONDS = 5e3;
1128
1112
  var DEFAULT_PROMPT_TIMEOUT_MILLISECONDS = 30 * 60 * 1e3;
@@ -1136,7 +1120,7 @@ var LocalAgentSpecification = class {
1136
1120
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
1137
1121
  signal.throwIfAborted();
1138
1122
  const executable = await resolveExecutablePath(
1139
- join5(stateDirectory, ...this.managedAgentExecutablePath),
1123
+ join3(stateDirectory, ...this.managedAgentExecutablePath),
1140
1124
  platform
1141
1125
  );
1142
1126
  signal.throwIfAborted();
@@ -1147,6 +1131,7 @@ var LocalAgentSpecification = class {
1147
1131
  };
1148
1132
  createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
1149
1133
  recoveryCommand = () => "";
1134
+ resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
1150
1135
  supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
1151
1136
  verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
1152
1137
  };
@@ -1241,9 +1226,84 @@ var CodexAgentSpecification = class extends BridgedAcpAgentDefinition {
1241
1226
  managedAgentExecutablePath = ["agents", "codex", "bin", "codex"];
1242
1227
  };
1243
1228
 
1229
+ // src/agent-catalog/agent-probe-error.ts
1230
+ var AgentProbeError = class extends Error {
1231
+ code;
1232
+ constructor(code, message, options = {}) {
1233
+ super(message, options);
1234
+ this.code = code;
1235
+ this.name = "AgentProbeError";
1236
+ }
1237
+ };
1238
+
1239
+ // src/agent-catalog/agents/verify-session-creation.ts
1240
+ import {
1241
+ methods
1242
+ } from "@agentclientprotocol/sdk";
1243
+ async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
1244
+ const session = await connection.agent.request(
1245
+ methods.agent.session.new,
1246
+ {
1247
+ additionalDirectories: [],
1248
+ cwd: defaultWorkspace,
1249
+ mcpServers: []
1250
+ },
1251
+ { cancellationSignal: signal }
1252
+ );
1253
+ if (session.sessionId.length === 0) {
1254
+ throw new AgentProbeError(
1255
+ "acp_incompatible",
1256
+ `${label} returned an invalid ACP session`
1257
+ );
1258
+ }
1259
+ if (capabilities.sessionCapabilities?.close != null) {
1260
+ await connection.agent.request(
1261
+ methods.agent.session.close,
1262
+ { sessionId: session.sessionId },
1263
+ { cancellationSignal: signal }
1264
+ );
1265
+ }
1266
+ }
1267
+
1268
+ // src/agent-catalog/agents/cursor-cli-agent.ts
1269
+ var CURSOR_CLI_TESTED_VERSION = "2026.09.02-c22c1a3";
1270
+ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
1271
+ adapterVersion = CURSOR_CLI_TESTED_VERSION;
1272
+ authenticationCommand = () => "cursor-agent login";
1273
+ agentExecutable = "cursor-agent";
1274
+ id = "cursor";
1275
+ label = "Cursor CLI";
1276
+ constructor() {
1277
+ super(
1278
+ "MOBIUS_CURSOR_PATH",
1279
+ ["--disable-auto-update", "acp"],
1280
+ ["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
1281
+ );
1282
+ }
1283
+ supportsInstallation = (_platform, _architecture) => false;
1284
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1285
+ const capabilities = initialized.agentCapabilities ?? {};
1286
+ if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
1287
+ (method) => method.id === "cursor_login"
1288
+ )) {
1289
+ throw new AgentProbeError(
1290
+ "acp_incompatible",
1291
+ "Cursor CLI reported an unsupported ACP capability set"
1292
+ );
1293
+ }
1294
+ await verifySessionCreation(
1295
+ connection,
1296
+ capabilities,
1297
+ defaultWorkspace,
1298
+ signal,
1299
+ this.label
1300
+ );
1301
+ };
1302
+ };
1303
+
1244
1304
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1245
1305
  import { realpath as realpath3, stat as stat3 } from "node:fs/promises";
1246
- import { isAbsolute as isAbsolute2, join as join6, normalize } from "node:path";
1306
+ import { isAbsolute as isAbsolute2, join as join5, normalize } from "node:path";
1247
1307
 
1248
1308
  // src/agent-installation/deepseek-managed-package.ts
1249
1309
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -1261,15 +1321,16 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
1261
1321
  "https://registry.npmjs.org/@deepseek-ai/dsh/-/dsh-0.1.2-rc.1.tgz"
1262
1322
  );
1263
1323
 
1264
- // src/agent-catalog/agent-probe-error.ts
1265
- var AgentProbeError = class extends Error {
1266
- code;
1267
- constructor(code, message, options = {}) {
1268
- super(message, options);
1269
- this.code = code;
1270
- this.name = "AgentProbeError";
1324
+ // src/storage/state-directory.ts
1325
+ import { homedir } from "node:os";
1326
+ import { join as join4, resolve as resolve2 } from "node:path";
1327
+ function readStateDirectory(environment = process.env) {
1328
+ const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
1329
+ if (configured !== void 0 && configured.length > 0) {
1330
+ return resolve2(configured);
1271
1331
  }
1272
- };
1332
+ return join4(homedir(), ".mobius");
1333
+ }
1273
1334
 
1274
1335
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1275
1336
  async function validateAgentHome(path2) {
@@ -1328,7 +1389,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1328
1389
  context.signal
1329
1390
  );
1330
1391
  if (managed.path === agent.path) {
1331
- selectedHome = join6(
1392
+ selectedHome = join5(
1332
1393
  readStateDirectory(context.environment),
1333
1394
  "agents",
1334
1395
  this.id,
@@ -1349,7 +1410,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1349
1410
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
1350
1411
  signal.throwIfAborted();
1351
1412
  const executable = await validateManagedNpmPackage(
1352
- join6(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1413
+ join5(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1353
1414
  DEEPSEEK_HARNESS_PACKAGE
1354
1415
  );
1355
1416
  signal.throwIfAborted();
@@ -1369,6 +1430,166 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1369
1430
  };
1370
1431
  };
1371
1432
 
1433
+ // src/agent-catalog/agents/grok-build-agent.ts
1434
+ import { realpath as realpath4 } from "node:fs/promises";
1435
+ import { isAbsolute as isAbsolute3, join as join6, relative as relative2, sep as sep2 } from "node:path";
1436
+
1437
+ // src/agent-installation/grok-managed-package.ts
1438
+ var GROK_BUILD_MANAGED_VERSION = "1.0.21";
1439
+ var GrokBuildManagedPackage = class extends SriManagedNpmPackageDefinition {
1440
+ dependencyResolutionArguments = Object.freeze([
1441
+ "--before=2026-09-04T19:51:47.325Z"
1442
+ ]);
1443
+ includeOptionalDependencies = true;
1444
+ requiredDependencies;
1445
+ verifyDependencyClosure = true;
1446
+ constructor(requiredDependency) {
1447
+ super(
1448
+ "@xai-official/grok",
1449
+ GROK_BUILD_MANAGED_VERSION,
1450
+ "grok",
1451
+ "sha512-6yQqC+h1o+ObaqCxImK23dhkrOX1DEBMOKaH6fCK+B4gX0/8XIKZp0n7iKyBdK8KZa5vhMn7pS45kjX49Tps5g==",
1452
+ "https://registry.npmjs.org/@xai-official/grok/-/grok-1.0.21.tgz"
1453
+ );
1454
+ this.requiredDependencies = Object.freeze([requiredDependency]);
1455
+ }
1456
+ };
1457
+ var GROK_DARWIN_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
1458
+ "@xai-official/grok-darwin-arm64",
1459
+ GROK_BUILD_MANAGED_VERSION,
1460
+ "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
1461
+ "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
1462
+ );
1463
+ var GROK_DARWIN_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
1464
+ "@xai-official/grok-darwin-x64",
1465
+ GROK_BUILD_MANAGED_VERSION,
1466
+ "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
1467
+ "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
1468
+ );
1469
+ var GROK_LINUX_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
1470
+ "@xai-official/grok-linux-arm64",
1471
+ GROK_BUILD_MANAGED_VERSION,
1472
+ "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
1473
+ "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
1474
+ );
1475
+ var GROK_LINUX_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
1476
+ "@xai-official/grok-linux-x64",
1477
+ GROK_BUILD_MANAGED_VERSION,
1478
+ "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
1479
+ "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
1480
+ );
1481
+ function grokBuildManagedPackage(platform, architecture) {
1482
+ if (platform === "darwin" && architecture === "arm64") {
1483
+ return new GrokBuildManagedPackage(GROK_DARWIN_ARM64_PACKAGE);
1484
+ }
1485
+ if (platform === "darwin" && architecture === "x64") {
1486
+ return new GrokBuildManagedPackage(GROK_DARWIN_X64_PACKAGE);
1487
+ }
1488
+ if (platform === "linux" && architecture === "arm64") {
1489
+ return new GrokBuildManagedPackage(GROK_LINUX_ARM64_PACKAGE);
1490
+ }
1491
+ if (platform === "linux" && architecture === "x64") {
1492
+ return new GrokBuildManagedPackage(GROK_LINUX_X64_PACKAGE);
1493
+ }
1494
+ throw new Error("Grok Build does not publish a package for this platform");
1495
+ }
1496
+
1497
+ // src/agent-catalog/agents/grok-build-agent.ts
1498
+ function isContainedPath2(root, candidate) {
1499
+ const difference = relative2(root, candidate);
1500
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
1501
+ }
1502
+ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1503
+ adapterVersion = GROK_BUILD_MANAGED_VERSION;
1504
+ authenticationCommand = () => "grok login";
1505
+ agentExecutable = "grok";
1506
+ agentVersionArguments = ["version"];
1507
+ adapterVersionArguments = ["version"];
1508
+ id = "grok-build";
1509
+ label = "Grok Build";
1510
+ constructor() {
1511
+ super(
1512
+ "MOBIUS_GROK_BUILD_PATH",
1513
+ ["--no-auto-update", "agent", "stdio"],
1514
+ [
1515
+ "agents",
1516
+ "grok-build",
1517
+ GROK_BUILD_MANAGED_VERSION,
1518
+ "home",
1519
+ "bin",
1520
+ "grok"
1521
+ ]
1522
+ );
1523
+ }
1524
+ createLaunchEnvironment = async (agent, context) => {
1525
+ const stateDirectory = readStateDirectory(context.environment);
1526
+ try {
1527
+ const managed = await this.resolveManagedAgent(
1528
+ stateDirectory,
1529
+ context.platform ?? process.platform,
1530
+ context.signal
1531
+ );
1532
+ if (managed.path === agent.path) {
1533
+ return Object.freeze({
1534
+ GROK_HOME: await realpath4(
1535
+ join6(
1536
+ stateDirectory,
1537
+ "agents",
1538
+ this.id,
1539
+ GROK_BUILD_MANAGED_VERSION,
1540
+ "home"
1541
+ )
1542
+ )
1543
+ });
1544
+ }
1545
+ } catch {
1546
+ context.signal.throwIfAborted();
1547
+ }
1548
+ return Object.freeze({});
1549
+ };
1550
+ resolveManagedAgent = async (stateDirectory, platform, signal) => {
1551
+ signal.throwIfAborted();
1552
+ const versionRoot = await realpath4(
1553
+ join6(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION)
1554
+ );
1555
+ await validateManagedNpmPackage(
1556
+ join6(versionRoot, "package"),
1557
+ grokBuildManagedPackage(platform, process.arch)
1558
+ );
1559
+ const executable = await resolveExecutablePath(
1560
+ join6(versionRoot, "home", "bin", "grok"),
1561
+ platform
1562
+ );
1563
+ signal.throwIfAborted();
1564
+ if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
1565
+ throw new AgentProbeError(
1566
+ "managed_agent_invalid",
1567
+ "The managed Grok Build executable is invalid"
1568
+ );
1569
+ }
1570
+ return executable;
1571
+ };
1572
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1573
+ const capabilities = initialized.agentCapabilities ?? {};
1574
+ const session = capabilities.sessionCapabilities;
1575
+ if (capabilities.loadSession !== true || session?.close == null || session.list == null || session.resume == null || !(initialized.authMethods ?? []).some(
1576
+ (method) => method.id === "xai.api_key" || method.id === "grok.com"
1577
+ )) {
1578
+ throw new AgentProbeError(
1579
+ "acp_incompatible",
1580
+ "Grok Build reported an unsupported ACP capability set"
1581
+ );
1582
+ }
1583
+ await verifySessionCreation(
1584
+ connection,
1585
+ capabilities,
1586
+ defaultWorkspace,
1587
+ signal,
1588
+ this.label
1589
+ );
1590
+ };
1591
+ };
1592
+
1372
1593
  // src/agent-catalog/agents/opencode-agent.ts
1373
1594
  import { join as join8 } from "node:path";
1374
1595
 
@@ -1380,18 +1601,18 @@ import {
1380
1601
  copyFile,
1381
1602
  mkdir as mkdir2,
1382
1603
  mkdtemp as mkdtemp2,
1383
- open as open4,
1384
- realpath as realpath4,
1604
+ open as open3,
1605
+ realpath as realpath5,
1385
1606
  rename as rename2,
1386
1607
  rm as rm2,
1387
1608
  stat as stat4,
1388
1609
  writeFile
1389
1610
  } from "node:fs/promises";
1390
- import { dirname as dirname2, isAbsolute as isAbsolute3, join as join7, relative as relative2, sep as sep2 } from "node:path";
1611
+ import { dirname as dirname2, isAbsolute as isAbsolute4, join as join7, relative as relative3, sep as sep3 } from "node:path";
1391
1612
 
1392
1613
  // src/agent-installation/verified-download.ts
1393
1614
  import { createHash } from "node:crypto";
1394
- import { open as open3, unlink } from "node:fs/promises";
1615
+ import { open as open2, unlink } from "node:fs/promises";
1395
1616
  import { fetch } from "undici";
1396
1617
 
1397
1618
  // src/network/environment-proxy.ts
@@ -1523,7 +1744,7 @@ async function downloadVerifiedFile(options, transport = new UndiciInstallerDown
1523
1744
  );
1524
1745
  }
1525
1746
  }
1526
- handle = await open3(options.destination, "wx", 384);
1747
+ handle = await open2(options.destination, "wx", 384);
1527
1748
  const digest = createHash("sha256");
1528
1749
  const reader = fetched.response.body.getReader();
1529
1750
  let bytes = 0;
@@ -1633,12 +1854,12 @@ var ManagedAgentArchiveError = class extends Error {
1633
1854
  var ManagedAgentArchiveDownloader = class {
1634
1855
  download = async (options) => await downloadVerifiedFile(options);
1635
1856
  };
1636
- function isRecord3(value) {
1857
+ function isRecord2(value) {
1637
1858
  return typeof value === "object" && value !== null && !Array.isArray(value);
1638
1859
  }
1639
- function isContainedPath2(root, candidate) {
1640
- const difference = relative2(root, candidate);
1641
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
1860
+ function isContainedPath3(root, candidate) {
1861
+ const difference = relative3(root, candidate);
1862
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute4(difference);
1642
1863
  }
1643
1864
  async function hashFile(path2, signal) {
1644
1865
  signal.throwIfAborted();
@@ -1673,7 +1894,7 @@ async function hashFile(path2, signal) {
1673
1894
  async function readManifest(path2) {
1674
1895
  let handle;
1675
1896
  try {
1676
- handle = await open4(path2, "r");
1897
+ handle = await open3(path2, "r");
1677
1898
  } catch (error61) {
1678
1899
  throw new ManagedAgentArchiveError(
1679
1900
  "managed_archive_verification_failed",
@@ -1692,7 +1913,7 @@ async function readManifest(path2) {
1692
1913
  const parsed = JSON.parse(
1693
1914
  await handle.readFile({ encoding: "utf8" })
1694
1915
  );
1695
- if (!isRecord3(parsed)) {
1916
+ if (!isRecord2(parsed)) {
1696
1917
  throw new ManagedAgentArchiveError(
1697
1918
  "managed_archive_verification_failed",
1698
1919
  "The managed Agent archive manifest is invalid"
@@ -1714,7 +1935,7 @@ async function readManifest(path2) {
1714
1935
  }
1715
1936
  async function validateManagedAgentArchive(root, definition, signal) {
1716
1937
  try {
1717
- const rootPath = await realpath4(root);
1938
+ const rootPath = await realpath5(root);
1718
1939
  const rootMetadata = await stat4(rootPath);
1719
1940
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
1720
1941
  throw new Error("Managed Agent root is not user-owned");
@@ -1726,7 +1947,7 @@ async function validateManagedAgentArchive(root, definition, signal) {
1726
1947
  const executable = await resolveExecutablePath(
1727
1948
  join7(rootPath, "bin", definition.executableName)
1728
1949
  );
1729
- if (executable === null || !isContainedPath2(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
1950
+ if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
1730
1951
  throw new Error("Managed Agent executable is invalid");
1731
1952
  }
1732
1953
  return executable;
@@ -1782,7 +2003,7 @@ var ManagedAgentArchiveInstaller = class {
1782
2003
  const archivePath = join7(working, definition.archiveName);
1783
2004
  const extractionRoot = join7(working, "extracted");
1784
2005
  await mkdir2(extractionRoot, { mode: 448 });
1785
- const canonicalExtractionRoot = await realpath4(extractionRoot);
2006
+ const canonicalExtractionRoot = await realpath5(extractionRoot);
1786
2007
  const download = await this.#downloader.download({
1787
2008
  allowedHosts: /* @__PURE__ */ new Set([
1788
2009
  "github.com",
@@ -1820,11 +2041,11 @@ var ManagedAgentArchiveInstaller = class {
1820
2041
  signal,
1821
2042
  timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
1822
2043
  });
1823
- const extracted = await realpath4(
2044
+ const extracted = await realpath5(
1824
2045
  join7(canonicalExtractionRoot, definition.executableName)
1825
2046
  );
1826
2047
  const extractedMetadata = await stat4(extracted);
1827
- if (!isContainedPath2(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
2048
+ if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
1828
2049
  throw new ManagedAgentArchiveError(
1829
2050
  "managed_archive_verification_failed",
1830
2051
  "The managed Agent archive executable is invalid"
@@ -1979,7 +2200,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
1979
2200
  // src/agent-catalog/agents/pi-agent.ts
1980
2201
  import { join as join9 } from "node:path";
1981
2202
  import {
1982
- methods
2203
+ methods as methods2
1983
2204
  } from "@agentclientprotocol/sdk";
1984
2205
 
1985
2206
  // src/agent-installation/pi-managed-packages.ts
@@ -2051,7 +2272,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2051
2272
  );
2052
2273
  }
2053
2274
  const session = await connection.agent.request(
2054
- methods.agent.session.new,
2275
+ methods2.agent.session.new,
2055
2276
  {
2056
2277
  additionalDirectories: [],
2057
2278
  cwd: defaultWorkspace,
@@ -2066,7 +2287,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2066
2287
  );
2067
2288
  }
2068
2289
  const prompt = await connection.agent.request(
2069
- methods.agent.session.prompt,
2290
+ methods2.agent.session.prompt,
2070
2291
  {
2071
2292
  prompt: [{ text: "/session", type: "text" }],
2072
2293
  sessionId: session.sessionId
@@ -2082,6 +2303,110 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2082
2303
  };
2083
2304
  };
2084
2305
 
2306
+ // src/agent-catalog/agents/workbuddy-agent.ts
2307
+ import { isAbsolute as isAbsolute5, join as join10 } from "node:path";
2308
+
2309
+ // src/agent-installation/workbuddy-managed-package.ts
2310
+ var WORKBUDDY_MANAGED_VERSION = "2.146.0";
2311
+ var WorkBuddyManagedPackage = class extends SriManagedNpmPackageDefinition {
2312
+ dependencyResolutionArguments = Object.freeze([
2313
+ "--before=2026-09-05T12:39:25.295Z"
2314
+ ]);
2315
+ includeOptionalDependencies = true;
2316
+ verifyDependencyClosure = true;
2317
+ };
2318
+ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
2319
+ "@tencent-ai/codebuddy-code",
2320
+ WORKBUDDY_MANAGED_VERSION,
2321
+ "codebuddy",
2322
+ "sha512-81V+8rzYJY8PezHZMs4VZN2nvoijrsRWIuCERTr6hELotcxaZaAcqbQQSbHJcN8eTlFE5TRPlzMI4oEkLCat4A==",
2323
+ "https://registry.npmjs.org/@tencent-ai/codebuddy-code/-/codebuddy-code-2.146.0.tgz"
2324
+ );
2325
+
2326
+ // src/agent-catalog/agents/workbuddy-agent.ts
2327
+ var WORKBUDDY_MACOS_EXECUTABLE_PATH = Object.freeze([
2328
+ "WorkBuddy.app",
2329
+ "Contents",
2330
+ "Resources",
2331
+ "app.asar.unpacked",
2332
+ "cli",
2333
+ "bin",
2334
+ "codebuddy"
2335
+ ]);
2336
+ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
2337
+ adapterVersion = WORKBUDDY_MANAGED_VERSION;
2338
+ authenticationCommand = () => "codebuddy";
2339
+ agentExecutable = "codebuddy";
2340
+ id = "workbuddy";
2341
+ label = "WorkBuddy";
2342
+ constructor() {
2343
+ super(
2344
+ "MOBIUS_WORKBUDDY_PATH",
2345
+ ["--acp"],
2346
+ [
2347
+ "agents",
2348
+ "workbuddy",
2349
+ WORKBUDDY_MANAGED_VERSION,
2350
+ "node_modules",
2351
+ "@tencent-ai",
2352
+ "codebuddy-code",
2353
+ "bin",
2354
+ "codebuddy"
2355
+ ]
2356
+ );
2357
+ }
2358
+ createLaunchEnvironment = () => Promise.resolve(Object.freeze({ DISABLE_AUTOUPDATER: "1" }));
2359
+ resolveManagedAgent = async (stateDirectory, _platform, signal) => {
2360
+ signal.throwIfAborted();
2361
+ const executable = await validateManagedNpmPackage(
2362
+ join10(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
2363
+ WORKBUDDY_MANAGED_PACKAGE
2364
+ );
2365
+ signal.throwIfAborted();
2366
+ return executable;
2367
+ };
2368
+ resolveInstalledAgentExecutables = async (context) => {
2369
+ context.signal.throwIfAborted();
2370
+ if ((context.platform ?? process.platform) !== "darwin") {
2371
+ return [];
2372
+ }
2373
+ const requestedPaths = [
2374
+ join10("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)
2375
+ ];
2376
+ const homeDirectory = context.environment["HOME"];
2377
+ if (homeDirectory !== void 0 && isAbsolute5(homeDirectory)) {
2378
+ requestedPaths.unshift(
2379
+ join10(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)
2380
+ );
2381
+ }
2382
+ const executables = [];
2383
+ for (const requestedPath of requestedPaths) {
2384
+ const executable = await resolveExecutablePath(requestedPath, "darwin");
2385
+ context.signal.throwIfAborted();
2386
+ if (executable !== null) {
2387
+ executables.push(executable);
2388
+ }
2389
+ }
2390
+ return executables;
2391
+ };
2392
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
2393
+ const capabilities = initialized.agentCapabilities ?? {};
2394
+ if (capabilities.loadSession !== true || (initialized.authMethods ?? []).length === 0) {
2395
+ throw new AgentProbeError(
2396
+ "acp_incompatible",
2397
+ "WorkBuddy reported an unsupported ACP capability set"
2398
+ );
2399
+ }
2400
+ await verifySessionCreation(
2401
+ connection,
2402
+ capabilities,
2403
+ defaultWorkspace,
2404
+ signal,
2405
+ this.label
2406
+ );
2407
+ };
2408
+ };
2409
+
2085
2410
  // src/agent-catalog/agents/supported-agent-specifications.ts
2086
2411
  function supportedLocalAgentSpecifications() {
2087
2412
  return Object.freeze([
@@ -2089,14 +2414,17 @@ function supportedLocalAgentSpecifications() {
2089
2414
  new ClaudeCodeAgentSpecification(),
2090
2415
  new PiAgentSpecification(),
2091
2416
  new DeepSeekHarnessAgentSpecification(),
2092
- new OpenCodeAgentSpecification()
2417
+ new OpenCodeAgentSpecification(),
2418
+ new CursorCliAgentSpecification(),
2419
+ new GrokBuildAgentSpecification(),
2420
+ new WorkBuddyAgentSpecification()
2093
2421
  ]);
2094
2422
  }
2095
2423
 
2096
2424
  // src/agent-catalog/acp-readiness-probe.ts
2097
2425
  import { spawn as spawn2 } from "node:child_process";
2098
2426
  import {
2099
- methods as methods3,
2427
+ methods as methods4,
2100
2428
  ndJsonStream,
2101
2429
  PROTOCOL_VERSION,
2102
2430
  RequestError
@@ -2105,25 +2433,47 @@ import {
2105
2433
  // src/acp/create-client.ts
2106
2434
  import {
2107
2435
  client,
2108
- methods as methods2
2436
+ methods as methods3
2109
2437
  } from "@agentclientprotocol/sdk";
2438
+ function discardExtensionParams(_params) {
2439
+ return Object.freeze({});
2440
+ }
2110
2441
  var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
2111
- methods2.client.session.requestPermission,
2442
+ methods3.client.session.requestPermission,
2112
2443
  async (context) => await handler.onPermission(context.params, context.signal)
2113
2444
  ).onRequest(
2114
- methods2.client.elicitation.create,
2445
+ methods3.client.elicitation.create,
2115
2446
  async (context) => await handler.onElicitation(context.params, context.signal)
2116
- ).onNotification(methods2.client.session.update, async (context) => {
2447
+ ).onNotification(methods3.client.session.update, async (context) => {
2117
2448
  await handler.onUpdate(context.params);
2118
- }).onNotification(methods2.client.elicitation.complete, async (context) => {
2449
+ }).onNotification(methods3.client.elicitation.complete, async (context) => {
2119
2450
  await handler.onElicitationComplete(context.params);
2120
- });
2451
+ }).onRequest("cursor/ask_question", discardExtensionParams, async () => ({
2452
+ outcome: {
2453
+ outcome: "skipped",
2454
+ reason: "Mobius does not expose Cursor question extensions"
2455
+ }
2456
+ })).onRequest("cursor/create_plan", discardExtensionParams, async () => ({
2457
+ outcome: { outcome: "cancelled" }
2458
+ })).onNotification(
2459
+ "cursor/update_todos",
2460
+ discardExtensionParams,
2461
+ async () => Promise.resolve()
2462
+ ).onNotification(
2463
+ "cursor/task",
2464
+ discardExtensionParams,
2465
+ async () => Promise.resolve()
2466
+ ).onNotification(
2467
+ "cursor/generate_image",
2468
+ discardExtensionParams,
2469
+ async () => Promise.resolve()
2470
+ );
2121
2471
 
2122
2472
  // src/agent-catalog/executable-discovery.ts
2123
- import { isAbsolute as isAbsolute4, join as join11 } from "node:path";
2473
+ import { isAbsolute as isAbsolute6, join as join12 } from "node:path";
2124
2474
 
2125
2475
  // src/agent-installation/managed-adapter-installer.ts
2126
- import { join as join10 } from "node:path";
2476
+ import { join as join11 } from "node:path";
2127
2477
  var ManagedAdapterInstallError = class extends Error {
2128
2478
  code;
2129
2479
  constructor(code, message, options = {}) {
@@ -2185,7 +2535,7 @@ var ManagedAdapterInstaller = class {
2185
2535
  this.#stateDirectory = options.stateDirectory;
2186
2536
  }
2187
2537
  install = async (specification, signal) => {
2188
- const root = join10(
2538
+ const root = join11(
2189
2539
  this.#stateDirectory,
2190
2540
  "adapters",
2191
2541
  specification.id,
@@ -2224,7 +2574,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
2224
2574
  let managed;
2225
2575
  try {
2226
2576
  managed = await validateManagedAdapter(
2227
- join11(
2577
+ join12(
2228
2578
  readStateDirectory(context.environment),
2229
2579
  "adapters",
2230
2580
  specification.id,
@@ -2237,10 +2587,10 @@ async function resolveManagedAdapterExecutable(specification, context) {
2237
2587
  }
2238
2588
  return managed;
2239
2589
  }
2240
- async function resolveSpecificationExecutables(executableName, overrideVariable, resolveManaged, context) {
2590
+ async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
2241
2591
  const override = context.environment[overrideVariable];
2242
2592
  if (override !== void 0) {
2243
- if (override.length === 0 || !isAbsolute4(override)) {
2593
+ if (override.length === 0 || !isAbsolute6(override)) {
2244
2594
  return [];
2245
2595
  }
2246
2596
  const executable = await resolveExecutablePath(override, context.platform);
@@ -2251,19 +2601,30 @@ async function resolveSpecificationExecutables(executableName, overrideVariable,
2251
2601
  context.environment,
2252
2602
  context.platform
2253
2603
  );
2604
+ const installed = await resolveInstalled();
2254
2605
  const managed = await resolveManaged();
2255
- if (external === null) {
2256
- return managed === null ? [] : [managed];
2606
+ const executables = [];
2607
+ const paths = /* @__PURE__ */ new Set();
2608
+ if (external !== null) {
2609
+ executables.push(external);
2610
+ paths.add(external.path);
2257
2611
  }
2258
- if (managed === null || managed.path === external.path) {
2259
- return [external];
2612
+ for (const executable of installed) {
2613
+ if (!paths.has(executable.path)) {
2614
+ executables.push(executable);
2615
+ paths.add(executable.path);
2616
+ }
2260
2617
  }
2261
- return [external, managed];
2618
+ if (managed !== null && !paths.has(managed.path)) {
2619
+ executables.push(managed);
2620
+ }
2621
+ return executables;
2262
2622
  }
2263
2623
  async function resolveAgentExecutables(specification, context) {
2264
2624
  return await resolveSpecificationExecutables(
2265
2625
  specification.agentExecutable,
2266
2626
  specification.agentOverrideVariable,
2627
+ async () => await specification.resolveInstalledAgentExecutables(context),
2267
2628
  async () => await resolveManagedExecutable(specification, context),
2268
2629
  context
2269
2630
  );
@@ -2278,6 +2639,7 @@ async function resolveAdapterExecutables(specification, context) {
2278
2639
  return await resolveSpecificationExecutables(
2279
2640
  specification.adapterExecutable,
2280
2641
  specification.adapterOverrideVariable,
2642
+ () => Promise.resolve([]),
2281
2643
  async () => await resolveManagedAdapterExecutable(specification, context),
2282
2644
  context
2283
2645
  );
@@ -2351,41 +2713,41 @@ var DiscoveryAcpHandler = class {
2351
2713
  };
2352
2714
  function readableAcpStream(input2) {
2353
2715
  let byteLength = 0;
2354
- let open7 = true;
2716
+ let open6 = true;
2355
2717
  return new ReadableStream({
2356
2718
  start(controller) {
2357
2719
  input2.on("data", (chunk) => {
2358
- if (!open7) {
2720
+ if (!open6) {
2359
2721
  return;
2360
2722
  }
2361
2723
  if (!(chunk instanceof Uint8Array)) {
2362
- open7 = false;
2724
+ open6 = false;
2363
2725
  controller.error(new Error("ACP adapter produced invalid output"));
2364
2726
  return;
2365
2727
  }
2366
2728
  byteLength += chunk.byteLength;
2367
2729
  if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
2368
- open7 = false;
2730
+ open6 = false;
2369
2731
  controller.error(new Error("ACP adapter output limit exceeded"));
2370
2732
  return;
2371
2733
  }
2372
2734
  controller.enqueue(new Uint8Array(chunk));
2373
2735
  });
2374
2736
  input2.once("end", () => {
2375
- if (open7) {
2376
- open7 = false;
2737
+ if (open6) {
2738
+ open6 = false;
2377
2739
  controller.close();
2378
2740
  }
2379
2741
  });
2380
2742
  input2.once("error", (error61) => {
2381
- if (open7) {
2382
- open7 = false;
2743
+ if (open6) {
2744
+ open6 = false;
2383
2745
  controller.error(error61);
2384
2746
  }
2385
2747
  });
2386
2748
  },
2387
2749
  cancel() {
2388
- open7 = false;
2750
+ open6 = false;
2389
2751
  }
2390
2752
  });
2391
2753
  }
@@ -2454,7 +2816,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
2454
2816
  try {
2455
2817
  const initialized = await Promise.race([
2456
2818
  connection.agent.request(
2457
- methods3.agent.initialize,
2819
+ methods4.agent.initialize,
2458
2820
  {
2459
2821
  clientCapabilities: {},
2460
2822
  clientInfo: { name: "mobius", version: "0.0.3" },
@@ -2665,16 +3027,8 @@ async function discoverLocalAgentInventory(options) {
2665
3027
  async (specification) => await discoverAgent(specification, options)
2666
3028
  )
2667
3029
  );
2668
- let grantedAgents = /* @__PURE__ */ new Set();
2669
- try {
2670
- grantedAgents = await readGrantedAgents(
2671
- readStateDirectory(options.environment)
2672
- );
2673
- } catch {
2674
- }
2675
3030
  return new LocalAgentInventory(
2676
3031
  discoveries,
2677
- grantedAgents,
2678
3032
  options.platform,
2679
3033
  options.architecture
2680
3034
  );
@@ -2731,7 +3085,7 @@ var AuditStore = class {
2731
3085
  };
2732
3086
 
2733
3087
  // src/config.ts
2734
- import { join as join12 } from "node:path";
3088
+ import { join as join13 } from "node:path";
2735
3089
 
2736
3090
  // ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
2737
3091
  var external_exports = {};
@@ -4693,8 +5047,8 @@ function emoji() {
4693
5047
  }
4694
5048
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
4695
5049
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
4696
- var mac = (delimiter2) => {
4697
- const escapedDelim = escapeRegex(delimiter2 ?? ":");
5050
+ var mac = (delimiter3) => {
5051
+ const escapedDelim = escapeRegex(delimiter3 ?? ":");
4698
5052
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
4699
5053
  };
4700
5054
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -7751,7 +8105,7 @@ function bucketFor(state, inst) {
7751
8105
  return bucket;
7752
8106
  }
7753
8107
  var handoff;
7754
- var open5 = [];
8108
+ var open4 = [];
7755
8109
  var memo = {
7756
8110
  alloc(_inst, payload, empty) {
7757
8111
  const bucket = handoff;
@@ -7760,7 +8114,7 @@ var memo = {
7760
8114
  handoff = void 0;
7761
8115
  const entry = { value: empty, issues: null };
7762
8116
  bucket.set(payload.value, entry);
7763
- open5.push(entry);
8117
+ open4.push(entry);
7764
8118
  return empty;
7765
8119
  },
7766
8120
  guard(inst) {
@@ -7826,10 +8180,10 @@ var memo = {
7826
8180
  return payload;
7827
8181
  }
7828
8182
  handoff = bucket;
7829
- const depth = open5.length;
8183
+ const depth = open4.length;
7830
8184
  const result = base(payload, ctx);
7831
8185
  handoff = void 0;
7832
- const entry = open5.length > depth ? open5.pop() : void 0;
8186
+ const entry = open4.length > depth ? open4.pop() : void 0;
7833
8187
  if (result instanceof Promise) {
7834
8188
  return result.then((r) => {
7835
8189
  if (entry)
@@ -21669,7 +22023,6 @@ var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
21669
22023
  var AGENT_CONTENT_KIND = "agent.content";
21670
22024
  var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
21671
22025
  var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
21672
- var AGENT_INSTALL_AWAITING_APPROVAL_KIND = "agent.install.awaiting_approval";
21673
22026
  var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
21674
22027
  var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
21675
22028
  var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
@@ -21975,10 +22328,6 @@ var agentInstallCancelCommandSchema = external_exports.strictObject({
21975
22328
  kind: external_exports.literal(AGENT_INSTALL_CANCEL_KIND),
21976
22329
  requestId: IDENTIFIER
21977
22330
  }).readonly();
21978
- var agentInstallAwaitingApprovalEventSchema = external_exports.strictObject({
21979
- ...agentInstallIdentityFields,
21980
- kind: external_exports.literal(AGENT_INSTALL_AWAITING_APPROVAL_KIND)
21981
- }).readonly();
21982
22331
  var agentInstallStartedEventSchema = external_exports.strictObject({
21983
22332
  ...agentInstallIdentityFields,
21984
22333
  kind: external_exports.literal(AGENT_INSTALL_STARTED_KIND)
@@ -22061,7 +22410,6 @@ var encodeSessionOperationFailedEvent = (message) => encode3(message, sessionOpe
22061
22410
  var encodeAgentContentEvent = (message) => encode3(message, agentContentEventSchema);
22062
22411
  var decodeAgentInstallRequestCommand = (encoded) => decode3(encoded, agentInstallRequestCommandSchema);
22063
22412
  var decodeAgentInstallCancelCommand = (encoded) => decode3(encoded, agentInstallCancelCommandSchema);
22064
- var encodeAgentInstallAwaitingApprovalEvent = (message) => encode3(message, agentInstallAwaitingApprovalEventSchema);
22065
22413
  var encodeAgentInstallStartedEvent = (message) => encode3(message, agentInstallStartedEventSchema);
22066
22414
  var encodeAgentInstallProgressEvent = (message) => encode3(message, agentInstallProgressEventSchema);
22067
22415
  var encodeAgentInstallCompletedEvent = (message) => encode3(message, agentInstallCompletedEventSchema);
@@ -22118,7 +22466,7 @@ var ProtocolMessageError = class extends Error {
22118
22466
  this.name = "ProtocolMessageError";
22119
22467
  }
22120
22468
  };
22121
- function isRecord4(value) {
22469
+ function isRecord3(value) {
22122
22470
  return typeof value === "object" && value !== null && !Array.isArray(value);
22123
22471
  }
22124
22472
  function parseJson2(encoded) {
@@ -22130,7 +22478,7 @@ function parseJson2(encoded) {
22130
22478
  cause: error61
22131
22479
  });
22132
22480
  }
22133
- if (!isRecord4(value)) {
22481
+ if (!isRecord3(value)) {
22134
22482
  throw new ProtocolMessageError("Message must be a JSON object");
22135
22483
  }
22136
22484
  return value;
@@ -22214,7 +22562,7 @@ function readActivityContent(value) {
22214
22562
  }
22215
22563
  function readActivityDetail(value) {
22216
22564
  const field = value["detail"];
22217
- if (!isRecord4(field)) {
22565
+ if (!isRecord3(field)) {
22218
22566
  throw new ProtocolMessageError("Invalid activity detail field");
22219
22567
  }
22220
22568
  const kind = readString(field, "kind", 32);
@@ -23202,7 +23550,7 @@ var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAckno
23202
23550
  // src/config.ts
23203
23551
  function loadDefaultWorkspace() {
23204
23552
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = process.env;
23205
- return configuredWorkspace ?? join12(readStateDirectory(), "workspace");
23553
+ return configuredWorkspace ?? join13(readStateDirectory(), "workspace");
23206
23554
  }
23207
23555
  function createDaemonConfig(connection, agents = [], installableAgents = []) {
23208
23556
  return {
@@ -23221,14 +23569,14 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
23221
23569
  import { randomUUID } from "node:crypto";
23222
23570
  import {
23223
23571
  mkdir as mkdir3,
23224
- open as open6,
23225
- realpath as realpath5,
23572
+ open as open5,
23573
+ realpath as realpath6,
23226
23574
  rename as rename3,
23227
23575
  stat as stat5,
23228
23576
  writeFile as writeFile2
23229
23577
  } from "node:fs/promises";
23230
23578
  import { hostname as hostname3 } from "node:os";
23231
- import { basename, join as join13, resolve as resolve3 } from "node:path";
23579
+ import { basename, join as join14, resolve as resolve3 } from "node:path";
23232
23580
  import { fetch as fetch2 } from "undici";
23233
23581
  var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
23234
23582
  var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
@@ -23254,7 +23602,7 @@ var PairingClientError = class extends Error {
23254
23602
  this.name = "PairingClientError";
23255
23603
  }
23256
23604
  };
23257
- function isRecord5(value) {
23605
+ function isRecord4(value) {
23258
23606
  return typeof value === "object" && value !== null && !Array.isArray(value);
23259
23607
  }
23260
23608
  function hasExactKeys(value, expectedKeys) {
@@ -23368,7 +23716,7 @@ async function resolveDefaultWorkspace(path2) {
23368
23716
  const requestedWorkspace = resolve3(path2);
23369
23717
  try {
23370
23718
  await mkdir3(requestedWorkspace, { recursive: true, mode: 448 });
23371
- const defaultWorkspace = await realpath5(requestedWorkspace);
23719
+ const defaultWorkspace = await realpath6(requestedWorkspace);
23372
23720
  const metadata = await stat5(defaultWorkspace);
23373
23721
  if (!metadata.isDirectory()) {
23374
23722
  throw new PairingClientError(
@@ -23407,9 +23755,9 @@ async function readJsonResponse(response) {
23407
23755
  }
23408
23756
  }
23409
23757
  function readRelayError(value) {
23410
- if (isRecord5(value)) {
23758
+ if (isRecord4(value)) {
23411
23759
  const error61 = value["error"];
23412
- if (isRecord5(error61)) {
23760
+ if (isRecord4(error61)) {
23413
23761
  const code = error61["code"];
23414
23762
  const message = error61["message"];
23415
23763
  if (typeof code === "string" && typeof message === "string") {
@@ -23423,7 +23771,7 @@ function readRelayError(value) {
23423
23771
  );
23424
23772
  }
23425
23773
  function decodeClaimResponse(value) {
23426
- if (!isRecord5(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
23774
+ if (!isRecord4(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
23427
23775
  throw new PairingClientError(
23428
23776
  "invalid_relay_response",
23429
23777
  "The relay returned an invalid pairing response"
@@ -23453,8 +23801,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
23453
23801
  agents,
23454
23802
  installableAgents: installableAgents.map((agent) => ({
23455
23803
  id: agent.id,
23456
- label: agent.label,
23457
- requiresLocalApproval: agent.requiresLocalApproval
23804
+ label: agent.label
23458
23805
  })),
23459
23806
  machineName: hostname3(),
23460
23807
  pairingCode: options.code,
@@ -23482,10 +23829,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
23482
23829
  return decodeClaimResponse(value);
23483
23830
  }
23484
23831
  async function persistConnection(channelId, relayOrigin, daemonToken, defaultWorkspace) {
23485
- const connectionsDirectory = join13(readStateDirectory(), "connections");
23832
+ const connectionsDirectory = join14(readStateDirectory(), "connections");
23486
23833
  await mkdir3(connectionsDirectory, { mode: 448, recursive: true });
23487
- const connectionPath = join13(connectionsDirectory, `${channelId}.json`);
23488
- const temporaryPath = join13(
23834
+ const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
23835
+ const temporaryPath = join14(
23489
23836
  connectionsDirectory,
23490
23837
  `.${channelId}.${randomUUID()}.tmp`
23491
23838
  );
@@ -23508,7 +23855,7 @@ async function persistConnection(channelId, relayOrigin, daemonToken, defaultWor
23508
23855
  return connectionPath;
23509
23856
  }
23510
23857
  function decodeSavedConnection(value, expectedChannelId) {
23511
- if (!isRecord5(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
23858
+ if (!isRecord4(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
23512
23859
  throw new PairingClientError(
23513
23860
  "invalid_connection",
23514
23861
  "The saved connection is invalid"
@@ -23532,13 +23879,13 @@ function decodeSavedConnection(value, expectedChannelId) {
23532
23879
  };
23533
23880
  }
23534
23881
  async function readSavedConnection(channelId) {
23535
- const connectionPath = join13(
23882
+ const connectionPath = join14(
23536
23883
  readStateDirectory(),
23537
23884
  "connections",
23538
23885
  `${channelId}.json`
23539
23886
  );
23540
23887
  let encoded = "";
23541
- const handle = await open6(connectionPath, "r");
23888
+ const handle = await open5(connectionPath, "r");
23542
23889
  try {
23543
23890
  const metadata = await handle.stat();
23544
23891
  if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
@@ -23587,7 +23934,7 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
23587
23934
  );
23588
23935
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
23589
23936
  relayUrl.searchParams.set("token", connection.daemonToken);
23590
- const auditDatabasePath = join13(
23937
+ const auditDatabasePath = join14(
23591
23938
  readStateDirectory(),
23592
23939
  "audit",
23593
23940
  `${connection.channelId}.sqlite`
@@ -23646,7 +23993,7 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
23646
23993
  }
23647
23994
  async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
23648
23995
  const channelId = parseChannelArgument(arguments_);
23649
- const connectionPath = join13(
23996
+ const connectionPath = join14(
23650
23997
  readStateDirectory(),
23651
23998
  "connections",
23652
23999
  `${channelId}.json`
@@ -23668,7 +24015,7 @@ import { WebSocket as WebSocket2 } from "undici";
23668
24015
  // src/acp/session-manager.ts
23669
24016
  import { spawn as spawn3 } from "node:child_process";
23670
24017
  import {
23671
- methods as methods4,
24018
+ methods as methods5,
23672
24019
  ndJsonStream as ndJsonStream2,
23673
24020
  PROTOCOL_VERSION as PROTOCOL_VERSION2,
23674
24021
  RequestError as RequestError2
@@ -23676,7 +24023,7 @@ import {
23676
24023
 
23677
24024
  // src/acp/activity.ts
23678
24025
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
23679
- function isRecord6(value) {
24026
+ function isRecord5(value) {
23680
24027
  return typeof value === "object" && value !== null && !Array.isArray(value);
23681
24028
  }
23682
24029
  var AcpActivity = class _AcpActivity {
@@ -23950,7 +24297,7 @@ function contentPhase(content) {
23950
24297
  return "";
23951
24298
  }
23952
24299
  const codex = metadata["codex"];
23953
- if (!isRecord6(codex)) {
24300
+ if (!isRecord5(codex)) {
23954
24301
  return "";
23955
24302
  }
23956
24303
  const phase = codex["phase"];
@@ -24584,7 +24931,7 @@ function createWritableAcpStream(output2) {
24584
24931
  function truncate2(value, maximumLength) {
24585
24932
  return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
24586
24933
  }
24587
- function isRecord7(value) {
24934
+ function isRecord6(value) {
24588
24935
  return typeof value === "object" && value !== null && !Array.isArray(value);
24589
24936
  }
24590
24937
  function readString3(value, fallback = "") {
@@ -24614,7 +24961,7 @@ function normalizeConfigValues(value) {
24614
24961
  }
24615
24962
  const normalized = [];
24616
24963
  for (const entry of value) {
24617
- if (!isRecord7(entry)) {
24964
+ if (!isRecord6(entry)) {
24618
24965
  continue;
24619
24966
  }
24620
24967
  const groupedOptions = entry["options"];
@@ -24622,7 +24969,7 @@ function normalizeConfigValues(value) {
24622
24969
  const groupId = readString3(entry["group"]);
24623
24970
  const groupName = readString3(entry["name"]);
24624
24971
  for (const groupedOption of groupedOptions) {
24625
- if (isRecord7(groupedOption)) {
24972
+ if (isRecord6(groupedOption)) {
24626
24973
  normalized.push(
24627
24974
  normalizeConfigValue(groupedOption, groupId, groupName)
24628
24975
  );
@@ -24638,7 +24985,7 @@ function normalizeConfigOptions(value, modes) {
24638
24985
  const normalized = [];
24639
24986
  if (Array.isArray(value)) {
24640
24987
  for (const option of value) {
24641
- if (!isRecord7(option)) {
24988
+ if (!isRecord6(option)) {
24642
24989
  continue;
24643
24990
  }
24644
24991
  const id = truncate2(readString3(option["id"]), 128);
@@ -24677,12 +25024,12 @@ function normalizeConfigOptions(value, modes) {
24677
25024
  }
24678
25025
  }
24679
25026
  }
24680
- if (isRecord7(modes)) {
25027
+ if (isRecord6(modes)) {
24681
25028
  const values = [];
24682
25029
  const availableModes = modes["availableModes"];
24683
25030
  if (Array.isArray(availableModes)) {
24684
25031
  for (const mode of availableModes) {
24685
- if (!isRecord7(mode)) {
25032
+ if (!isRecord6(mode)) {
24686
25033
  continue;
24687
25034
  }
24688
25035
  const id = truncate2(readString3(mode["id"]), 500);
@@ -24760,7 +25107,7 @@ function normalizeElicitationOptions(schema) {
24760
25107
  const oneOf = schema["oneOf"];
24761
25108
  if (Array.isArray(oneOf)) {
24762
25109
  for (const option of oneOf) {
24763
- if (isRecord7(option) && typeof option["const"] === "string") {
25110
+ if (isRecord6(option) && typeof option["const"] === "string") {
24764
25111
  normalized.push({
24765
25112
  description: truncate2(readString3(option["description"]), 500),
24766
25113
  label: truncate2(readString3(option["title"], option["const"]), 255),
@@ -24780,7 +25127,7 @@ function normalizeElicitationOptions(schema) {
24780
25127
  return normalized.slice(0, 200);
24781
25128
  }
24782
25129
  const items = schema["items"];
24783
- if (!isRecord7(items)) {
25130
+ if (!isRecord6(items)) {
24784
25131
  return normalized;
24785
25132
  }
24786
25133
  const anyOf = items["anyOf"];
@@ -24793,7 +25140,7 @@ function numericString(value) {
24793
25140
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
24794
25141
  }
24795
25142
  function normalizeElicitationFields(requestedSchema) {
24796
- if (!isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
25143
+ if (!isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
24797
25144
  return [];
24798
25145
  }
24799
25146
  const properties = requestedSchema["properties"];
@@ -24803,7 +25150,7 @@ function normalizeElicitationFields(requestedSchema) {
24803
25150
  );
24804
25151
  const normalized = [];
24805
25152
  for (const [name, property] of Object.entries(properties)) {
24806
- if (!isRecord7(property)) {
25153
+ if (!isRecord6(property)) {
24807
25154
  continue;
24808
25155
  }
24809
25156
  const type = elicitationFieldType(property["type"]);
@@ -24898,7 +25245,7 @@ function validateElicitationContent(encoded, requestedSchema) {
24898
25245
  "invalid_elicitation_response"
24899
25246
  );
24900
25247
  }
24901
- if (!isRecord7(decoded) || !isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
25248
+ if (!isRecord6(decoded) || !isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
24902
25249
  throw new AcpExecutionError(
24903
25250
  "Elicitation response does not match the requested form",
24904
25251
  {},
@@ -24922,7 +25269,7 @@ function validateElicitationContent(encoded, requestedSchema) {
24922
25269
  const validated = {};
24923
25270
  for (const [name, value] of Object.entries(decoded)) {
24924
25271
  const property = properties[name];
24925
- if (!isRecord7(property)) {
25272
+ if (!isRecord6(property)) {
24926
25273
  throw new AcpExecutionError(
24927
25274
  `Elicitation field ${name} was not requested`,
24928
25275
  {},
@@ -25213,7 +25560,7 @@ var AcpProcessSession = class _AcpProcessSession {
25213
25560
  try {
25214
25561
  await this.race(
25215
25562
  this.#connection.agent.request(
25216
- methods4.agent.session.load,
25563
+ methods5.agent.session.load,
25217
25564
  {
25218
25565
  additionalDirectories: [...this.#additionalDirectories],
25219
25566
  cwd: this.#cwd,
@@ -25235,7 +25582,7 @@ var AcpProcessSession = class _AcpProcessSession {
25235
25582
  async #initializeAgent(signal) {
25236
25583
  const initialized = await this.race(
25237
25584
  this.#connection.agent.request(
25238
- methods4.agent.initialize,
25585
+ methods5.agent.initialize,
25239
25586
  {
25240
25587
  clientCapabilities: {
25241
25588
  elicitation: { form: {}, url: {} },
@@ -25303,7 +25650,7 @@ var AcpProcessSession = class _AcpProcessSession {
25303
25650
  );
25304
25651
  const forked = await this.race(
25305
25652
  this.#connection.agent.request(
25306
- methods4.agent.session.fork,
25653
+ methods5.agent.session.fork,
25307
25654
  {
25308
25655
  sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
25309
25656
  cwd: this.#cwd,
@@ -25336,7 +25683,7 @@ var AcpProcessSession = class _AcpProcessSession {
25336
25683
  if (this.#capabilities.resumeSession) {
25337
25684
  lifecycleResponse = await this.race(
25338
25685
  this.#connection.agent.request(
25339
- methods4.agent.session.resume,
25686
+ methods5.agent.session.resume,
25340
25687
  {
25341
25688
  additionalDirectories: [...this.#additionalDirectories],
25342
25689
  cwd: this.#cwd,
@@ -25353,7 +25700,7 @@ var AcpProcessSession = class _AcpProcessSession {
25353
25700
  try {
25354
25701
  lifecycleResponse = await this.race(
25355
25702
  this.#connection.agent.request(
25356
- methods4.agent.session.load,
25703
+ methods5.agent.session.load,
25357
25704
  {
25358
25705
  additionalDirectories: [...this.#additionalDirectories],
25359
25706
  cwd: this.#cwd,
@@ -25389,7 +25736,7 @@ var AcpProcessSession = class _AcpProcessSession {
25389
25736
  }
25390
25737
  const created = await this.race(
25391
25738
  this.#connection.agent.request(
25392
- methods4.agent.session.new,
25739
+ methods5.agent.session.new,
25393
25740
  {
25394
25741
  additionalDirectories: [...this.#additionalDirectories],
25395
25742
  cwd: this.#cwd,
@@ -25403,7 +25750,7 @@ var AcpProcessSession = class _AcpProcessSession {
25403
25750
  this.selectNativeSession(created.sessionId);
25404
25751
  lifecycleResponse = created;
25405
25752
  }
25406
- const lifecycleRecord = isRecord7(lifecycleResponse) ? lifecycleResponse : {};
25753
+ const lifecycleRecord = isRecord6(lifecycleResponse) ? lifecycleResponse : {};
25407
25754
  this.#configOptions = normalizeConfigOptions(
25408
25755
  lifecycleRecord["configOptions"],
25409
25756
  lifecycleRecord["modes"]
@@ -25432,7 +25779,7 @@ var AcpProcessSession = class _AcpProcessSession {
25432
25779
  );
25433
25780
  const response = await this.race(
25434
25781
  this.#connection.agent.request(
25435
- methods4.agent.session.list,
25782
+ methods5.agent.session.list,
25436
25783
  cursor === null ? {} : { cursor },
25437
25784
  { cancellationSignal: signal }
25438
25785
  ),
@@ -25457,7 +25804,7 @@ var AcpProcessSession = class _AcpProcessSession {
25457
25804
  );
25458
25805
  await this.race(
25459
25806
  this.#connection.agent.request(
25460
- methods4.agent.session.delete,
25807
+ methods5.agent.session.delete,
25461
25808
  { sessionId: nativeSessionIdSchema.parse(nativeSessionId) },
25462
25809
  { cancellationSignal: signal }
25463
25810
  ),
@@ -25488,7 +25835,7 @@ var AcpProcessSession = class _AcpProcessSession {
25488
25835
  if (existing.category === "mode") {
25489
25836
  await this.race(
25490
25837
  this.#connection.agent.request(
25491
- methods4.agent.session.setMode,
25838
+ methods5.agent.session.setMode,
25492
25839
  { modeId: options.value, sessionId: this.#nativeSessionId },
25493
25840
  { cancellationSignal: options.signal }
25494
25841
  ),
@@ -25501,7 +25848,7 @@ var AcpProcessSession = class _AcpProcessSession {
25501
25848
  } else {
25502
25849
  const response = await this.race(
25503
25850
  this.#connection.agent.request(
25504
- methods4.agent.session.setConfigOption,
25851
+ methods5.agent.session.setConfigOption,
25505
25852
  {
25506
25853
  configId: existing.id,
25507
25854
  sessionId: this.#nativeSessionId,
@@ -25520,7 +25867,7 @@ var AcpProcessSession = class _AcpProcessSession {
25520
25867
  } else {
25521
25868
  const response = await this.race(
25522
25869
  this.#connection.agent.request(
25523
- methods4.agent.session.setConfigOption,
25870
+ methods5.agent.session.setConfigOption,
25524
25871
  {
25525
25872
  configId: existing.id,
25526
25873
  sessionId: this.#nativeSessionId,
@@ -25619,7 +25966,7 @@ var AcpProcessSession = class _AcpProcessSession {
25619
25966
  try {
25620
25967
  const response = await this.race(
25621
25968
  this.#connection.agent.request(
25622
- methods4.agent.session.prompt,
25969
+ methods5.agent.session.prompt,
25623
25970
  { prompt, sessionId: this.#nativeSessionId },
25624
25971
  { cancellationSignal: options.signal }
25625
25972
  ),
@@ -25666,7 +26013,7 @@ var AcpProcessSession = class _AcpProcessSession {
25666
26013
  try {
25667
26014
  await this.cancelPendingInteractions();
25668
26015
  if (this.#turn.running) {
25669
- await this.#connection.agent.notify(methods4.agent.session.cancel, {
26016
+ await this.#connection.agent.notify(methods5.agent.session.cancel, {
25670
26017
  sessionId: this.#nativeSessionId
25671
26018
  });
25672
26019
  }
@@ -26022,7 +26369,7 @@ var AcpProcessSession = class _AcpProcessSession {
26022
26369
  if (this.#capabilities.closeSession && this.#nativeSessionId.length > 0) {
26023
26370
  try {
26024
26371
  await this.#connection.agent.request(
26025
- methods4.agent.session.close,
26372
+ methods5.agent.session.close,
26026
26373
  { sessionId: this.#nativeSessionId },
26027
26374
  {
26028
26375
  cancellationSignal: AbortSignal.timeout(
@@ -26659,8 +27006,7 @@ async function publishAgentCatalog(config2, signal) {
26659
27006
  })),
26660
27007
  installableAgents: catalog.installableAgents.map((agent) => ({
26661
27008
  id: agent.id,
26662
- label: agent.label,
26663
- requiresLocalApproval: agent.requiresLocalApproval
27009
+ label: agent.label
26664
27010
  }))
26665
27011
  }),
26666
27012
  dispatcher: environmentProxyDispatcher,
@@ -26701,12 +27047,6 @@ var RequestedInstallation = class extends AgentInstallation {
26701
27047
  super(requestId, agentId);
26702
27048
  }
26703
27049
  };
26704
- var AwaitingLocalApproval = class extends AgentInstallation {
26705
- status = "awaiting_local_approval";
26706
- constructor(requestId, agentId) {
26707
- super(requestId, agentId);
26708
- }
26709
- };
26710
27050
  var RunningInstallation = class extends AgentInstallation {
26711
27051
  stage;
26712
27052
  status = "running";
@@ -26761,9 +27101,9 @@ var InstallationJob = class {
26761
27101
  this.state = new RequestedInstallation(requestId, agentId);
26762
27102
  }
26763
27103
  };
26764
- function specificationFor(specifications, agentId) {
27104
+ function authorizedSpecificationFor(specifications, agentId) {
26765
27105
  for (const specification of specifications) {
26766
- if (specification.id === agentId) {
27106
+ if (specification.id === agentId && specification.supportsInstallation(process.platform, process.arch)) {
26767
27107
  return specification;
26768
27108
  }
26769
27109
  }
@@ -26782,14 +27122,12 @@ function executionFailure(error61) {
26782
27122
  var AgentInstallationManager = class {
26783
27123
  #activeAgents = /* @__PURE__ */ new Map();
26784
27124
  #audit;
26785
- #authorizer;
26786
27125
  #executor;
26787
27126
  #jobs = /* @__PURE__ */ new Map();
26788
27127
  #observer;
26789
27128
  #specifications;
26790
- constructor(specifications, authorizer, executor, observer, audit = new NullInstallationAudit()) {
27129
+ constructor(specifications, executor, observer, audit = new NullInstallationAudit()) {
26791
27130
  this.#audit = audit;
26792
- this.#authorizer = authorizer;
26793
27131
  this.#executor = executor;
26794
27132
  this.#observer = observer;
26795
27133
  this.#specifications = Object.freeze([...specifications]);
@@ -26820,7 +27158,7 @@ var AgentInstallationManager = class {
26820
27158
  command.requestId,
26821
27159
  command.agentId
26822
27160
  );
26823
- const specification = specificationFor(
27161
+ const specification = authorizedSpecificationFor(
26824
27162
  this.#specifications,
26825
27163
  command.agentId
26826
27164
  );
@@ -26923,45 +27261,14 @@ var AgentInstallationManager = class {
26923
27261
  }, INSTALLATION_DEADLINE_MILLISECONDS);
26924
27262
  const signal = job.controller.signal;
26925
27263
  try {
26926
- await this.#transition(
26927
- job,
26928
- new AwaitingLocalApproval(job.requestId, job.agentId)
26929
- );
26930
- this.#audit.record(
26931
- "agent_installation_awaiting_approval",
26932
- job.requestId,
26933
- job.agentId
26934
- );
26935
- const approved = await this.#authorizer.authorize(
26936
- specification.id,
26937
- specification.label,
26938
- job.requestId,
26939
- signal
26940
- );
26941
27264
  signal.throwIfAborted();
26942
- if (!approved) {
26943
- const denied = new FailedInstallation(
26944
- job.requestId,
26945
- job.agentId,
26946
- "installation_not_authorized",
26947
- "Installation was not approved on the local machine"
26948
- );
26949
- await this.#transition(job, denied);
26950
- this.#audit.record(
26951
- "agent_installation_denied",
26952
- job.requestId,
26953
- job.agentId
26954
- );
26955
- job.completion.resolve(denied);
26956
- return;
26957
- }
26958
27265
  this.#audit.record(
26959
27266
  "agent_installation_authorized",
26960
27267
  job.requestId,
26961
- job.agentId
27268
+ specification.id
26962
27269
  );
26963
27270
  await this.#executor.execute(
26964
- job.agentId,
27271
+ specification.id,
26965
27272
  job.requestId,
26966
27273
  async (stage) => {
26967
27274
  signal.throwIfAborted();
@@ -27231,12 +27538,10 @@ import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27231
27538
  import { resolve as resolve4 } from "node:path";
27232
27539
 
27233
27540
  // src/agent-installation/fixed-agent-install-recipes.ts
27234
- import { mkdir as mkdir4, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
27235
- import { join as join14 } from "node:path";
27236
- var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
27237
- var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
27238
- var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
27239
- var MINIMAL_PATH2 = "/usr/bin:/bin";
27541
+ import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
27542
+ import { join as join17 } from "node:path";
27543
+
27544
+ // src/agent-installation/fixed-agent-install-recipe.ts
27240
27545
  var FixedAgentInstallRecipe = class {
27241
27546
  assertSupportedPlatform = () => {
27242
27547
  if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
@@ -27257,28 +27562,243 @@ var FixedAgentInstallRecipe = class {
27257
27562
  return executable;
27258
27563
  };
27259
27564
  };
27565
+
27566
+ // src/agent-installation/grok-build-install-recipe.ts
27567
+ import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27568
+ import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
27569
+ var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
27570
+ function isContainedPath4(root, candidate) {
27571
+ const difference = relative4(root, candidate);
27572
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
27573
+ }
27574
+ async function resolveLifecycleScript(packageRoot) {
27575
+ try {
27576
+ const canonicalPackageRoot = await realpath7(packageRoot);
27577
+ const script = await realpath7(
27578
+ join15(canonicalPackageRoot, "bin", "postinstall.js")
27579
+ );
27580
+ const metadata = await stat6(script);
27581
+ if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
27582
+ throw new Error("Invalid Grok Build lifecycle script");
27583
+ }
27584
+ return script;
27585
+ } catch (error61) {
27586
+ throw new InstallationManagerError(
27587
+ "agent_verification_failed",
27588
+ "The managed Grok Build lifecycle script is invalid",
27589
+ { cause: error61 }
27590
+ );
27591
+ }
27592
+ }
27593
+ var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
27594
+ #npmInstaller;
27595
+ id = "grok-build";
27596
+ label = "Grok Build";
27597
+ releaseChannel = GROK_BUILD_MANAGED_VERSION;
27598
+ constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27599
+ super();
27600
+ this.#npmInstaller = npmInstaller;
27601
+ }
27602
+ install = async (options) => {
27603
+ this.assertSupportedPlatform();
27604
+ const definition = grokBuildManagedPackage(process.platform, process.arch);
27605
+ const versionRoot = join15(
27606
+ options.stateDirectory,
27607
+ "agents",
27608
+ this.id,
27609
+ GROK_BUILD_MANAGED_VERSION
27610
+ );
27611
+ const packageRoot = join15(versionRoot, "package");
27612
+ const managedHome = join15(versionRoot, "home");
27613
+ try {
27614
+ await mkdir4(managedHome, { mode: 448, recursive: true });
27615
+ const canonicalHome = await realpath7(managedHome);
27616
+ await options.report("downloading");
27617
+ await options.report("verifying");
27618
+ await options.report("installing_agent");
27619
+ await this.#npmInstaller.install(
27620
+ packageRoot,
27621
+ definition,
27622
+ options.environment,
27623
+ options.signal
27624
+ );
27625
+ options.audit.record(
27626
+ "agent_npm_package_verified",
27627
+ options.requestId,
27628
+ this.id,
27629
+ {
27630
+ integrity: definition.integrity,
27631
+ package: definition.packageName,
27632
+ version: definition.version
27633
+ }
27634
+ );
27635
+ const script = await resolveLifecycleScript(
27636
+ join15(packageRoot, "node_modules", "@xai-official", "grok")
27637
+ );
27638
+ await runBoundedProcess({
27639
+ arguments: [script],
27640
+ command: process.execPath,
27641
+ cwd: dirname5(script),
27642
+ environment: {
27643
+ GROK_HOME: canonicalHome,
27644
+ GROK_INSTALL_COMPLETIONS: "0",
27645
+ GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
27646
+ HOME: canonicalHome,
27647
+ PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
27648
+ },
27649
+ outputLimitBytes: 64 * 1024,
27650
+ signal: options.signal,
27651
+ timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
27652
+ });
27653
+ options.audit.record(
27654
+ "agent_lifecycle_step_completed",
27655
+ options.requestId,
27656
+ this.id,
27657
+ {
27658
+ lifecycle: "postinstall",
27659
+ package: definition.packageName,
27660
+ version: definition.version
27661
+ }
27662
+ );
27663
+ return await this.requireInstalledExecutable(
27664
+ join15(canonicalHome, "bin", "grok")
27665
+ );
27666
+ } catch (error61) {
27667
+ if (options.signal.aborted) {
27668
+ options.signal.throwIfAborted();
27669
+ }
27670
+ if (error61 instanceof ManagedNpmPackageError) {
27671
+ if (error61.code === "managed_package_verification_failed") {
27672
+ throw new InstallationManagerError(
27673
+ "agent_verification_failed",
27674
+ "The managed Grok Build packages did not match their pinned artifacts",
27675
+ { cause: error61 }
27676
+ );
27677
+ }
27678
+ if (error61.code === "managed_package_publish_failed") {
27679
+ throw new InstallationManagerError(
27680
+ "agent_publish_failed",
27681
+ "The managed Grok Build package could not be published",
27682
+ { cause: error61 }
27683
+ );
27684
+ }
27685
+ throw new InstallationManagerError(error61.code, error61.message, {
27686
+ cause: error61
27687
+ });
27688
+ }
27689
+ if (error61 instanceof InstallationManagerError) {
27690
+ throw error61;
27691
+ }
27692
+ throw new InstallationManagerError(
27693
+ "agent_install_failed",
27694
+ "The fixed Grok Build installation recipe failed",
27695
+ { cause: error61 }
27696
+ );
27697
+ }
27698
+ };
27699
+ };
27700
+
27701
+ // src/agent-installation/workbuddy-install-recipe.ts
27702
+ import { join as join16 } from "node:path";
27703
+ var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
27704
+ #npmInstaller;
27705
+ id = "workbuddy";
27706
+ label = "WorkBuddy";
27707
+ releaseChannel = WORKBUDDY_MANAGED_VERSION;
27708
+ constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27709
+ super();
27710
+ this.#npmInstaller = npmInstaller;
27711
+ }
27712
+ install = async (options) => {
27713
+ this.assertSupportedPlatform();
27714
+ try {
27715
+ await options.report("downloading");
27716
+ await options.report("verifying");
27717
+ await options.report("installing_agent");
27718
+ const executable = await this.#npmInstaller.install(
27719
+ join16(
27720
+ options.stateDirectory,
27721
+ "agents",
27722
+ this.id,
27723
+ WORKBUDDY_MANAGED_VERSION
27724
+ ),
27725
+ WORKBUDDY_MANAGED_PACKAGE,
27726
+ options.environment,
27727
+ options.signal
27728
+ );
27729
+ options.audit.record(
27730
+ "agent_npm_package_verified",
27731
+ options.requestId,
27732
+ this.id,
27733
+ {
27734
+ integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
27735
+ package: WORKBUDDY_MANAGED_PACKAGE.packageName,
27736
+ version: WORKBUDDY_MANAGED_PACKAGE.version
27737
+ }
27738
+ );
27739
+ return executable;
27740
+ } catch (error61) {
27741
+ if (options.signal.aborted) {
27742
+ options.signal.throwIfAborted();
27743
+ }
27744
+ if (error61 instanceof ManagedNpmPackageError) {
27745
+ if (error61.code === "managed_package_verification_failed") {
27746
+ throw new InstallationManagerError(
27747
+ "agent_verification_failed",
27748
+ "The managed WorkBuddy package did not match its pinned artifact",
27749
+ { cause: error61 }
27750
+ );
27751
+ }
27752
+ if (error61.code === "managed_package_publish_failed") {
27753
+ throw new InstallationManagerError(
27754
+ "agent_publish_failed",
27755
+ "The managed WorkBuddy package could not be published",
27756
+ { cause: error61 }
27757
+ );
27758
+ }
27759
+ throw new InstallationManagerError(error61.code, error61.message, {
27760
+ cause: error61
27761
+ });
27762
+ }
27763
+ if (error61 instanceof InstallationManagerError) {
27764
+ throw error61;
27765
+ }
27766
+ throw new InstallationManagerError(
27767
+ "agent_install_failed",
27768
+ "The fixed WorkBuddy installation recipe failed",
27769
+ { cause: error61 }
27770
+ );
27771
+ }
27772
+ };
27773
+ };
27774
+
27775
+ // src/agent-installation/fixed-agent-install-recipes.ts
27776
+ var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
27777
+ var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
27778
+ var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
27779
+ var MINIMAL_PATH2 = "/usr/bin:/bin";
27260
27780
  var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
27261
27781
  id = "codex";
27262
27782
  label = "Codex";
27263
27783
  releaseChannel = "latest";
27264
27784
  install = async (options) => {
27265
27785
  this.assertSupportedPlatform();
27266
- const root = join14(options.stateDirectory, "agents", this.id);
27267
- const temporaryRoot = join14(options.stateDirectory, "temporary");
27786
+ const root = join17(options.stateDirectory, "agents", this.id);
27787
+ const temporaryRoot = join17(options.stateDirectory, "temporary");
27268
27788
  await Promise.all([
27269
- mkdir4(root, { mode: 448, recursive: true }),
27270
- mkdir4(temporaryRoot, { mode: 448, recursive: true })
27789
+ mkdir5(root, { mode: 448, recursive: true }),
27790
+ mkdir5(temporaryRoot, { mode: 448, recursive: true })
27271
27791
  ]);
27272
27792
  const temporaryDirectory = await mkdtemp3(
27273
- join14(temporaryRoot, ".codex-install-")
27793
+ join17(temporaryRoot, ".codex-install-")
27274
27794
  );
27275
- const installerPath = join14(temporaryDirectory, "install.sh");
27276
- const installDirectory = join14(root, "bin");
27277
- const codexHome = join14(root, "home");
27795
+ const installerPath = join17(temporaryDirectory, "install.sh");
27796
+ const installDirectory = join17(root, "bin");
27797
+ const codexHome = join17(root, "home");
27278
27798
  try {
27279
27799
  await Promise.all([
27280
- mkdir4(installDirectory, { mode: 448, recursive: true }),
27281
- mkdir4(codexHome, { mode: 448, recursive: true })
27800
+ mkdir5(installDirectory, { mode: 448, recursive: true }),
27801
+ mkdir5(codexHome, { mode: 448, recursive: true })
27282
27802
  ]);
27283
27803
  await options.report("downloading");
27284
27804
  const download = await downloadVerifiedFile({
@@ -27318,7 +27838,7 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
27318
27838
  timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
27319
27839
  });
27320
27840
  return await this.requireInstalledExecutable(
27321
- join14(installDirectory, "codex")
27841
+ join17(installDirectory, "codex")
27322
27842
  );
27323
27843
  } catch (error61) {
27324
27844
  if (options.signal.aborted) {
@@ -27342,17 +27862,17 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27342
27862
  releaseChannel = "stable";
27343
27863
  install = async (options) => {
27344
27864
  this.assertSupportedPlatform();
27345
- const root = join14(options.stateDirectory, "agents", this.id);
27346
- const managedHome = join14(root, "home");
27347
- const temporaryRoot = join14(options.stateDirectory, "temporary");
27865
+ const root = join17(options.stateDirectory, "agents", this.id);
27866
+ const managedHome = join17(root, "home");
27867
+ const temporaryRoot = join17(options.stateDirectory, "temporary");
27348
27868
  await Promise.all([
27349
- mkdir4(managedHome, { mode: 448, recursive: true }),
27350
- mkdir4(temporaryRoot, { mode: 448, recursive: true })
27869
+ mkdir5(managedHome, { mode: 448, recursive: true }),
27870
+ mkdir5(temporaryRoot, { mode: 448, recursive: true })
27351
27871
  ]);
27352
27872
  const temporaryDirectory = await mkdtemp3(
27353
- join14(temporaryRoot, ".claude-install-")
27873
+ join17(temporaryRoot, ".claude-install-")
27354
27874
  );
27355
- const installerPath = join14(temporaryDirectory, "install.sh");
27875
+ const installerPath = join17(temporaryDirectory, "install.sh");
27356
27876
  try {
27357
27877
  await options.report("downloading");
27358
27878
  const download = await downloadVerifiedFile({
@@ -27389,7 +27909,7 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27389
27909
  timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
27390
27910
  });
27391
27911
  return await this.requireInstalledExecutable(
27392
- join14(managedHome, ".local", "bin", "claude")
27912
+ join17(managedHome, ".local", "bin", "claude")
27393
27913
  );
27394
27914
  } catch (error61) {
27395
27915
  if (options.signal.aborted) {
@@ -27423,7 +27943,7 @@ var PiInstallRecipe = class extends FixedAgentInstallRecipe {
27423
27943
  await options.report("verifying");
27424
27944
  await options.report("installing_agent");
27425
27945
  const executable = await this.#npmInstaller.install(
27426
- join14(
27946
+ join17(
27427
27947
  options.stateDirectory,
27428
27948
  "agents",
27429
27949
  this.id,
@@ -27490,18 +28010,18 @@ var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
27490
28010
  install = async (options) => {
27491
28011
  this.assertSupportedPlatform();
27492
28012
  try {
27493
- const managedHome = join14(
28013
+ const managedHome = join17(
27494
28014
  options.stateDirectory,
27495
28015
  "agents",
27496
28016
  this.id,
27497
28017
  "home"
27498
28018
  );
27499
- await mkdir4(managedHome, { mode: 448, recursive: true });
28019
+ await mkdir5(managedHome, { mode: 448, recursive: true });
27500
28020
  await options.report("downloading");
27501
28021
  await options.report("verifying");
27502
28022
  await options.report("installing_agent");
27503
28023
  const executable = await this.#npmInstaller.install(
27504
- join14(
28024
+ join17(
27505
28025
  options.stateDirectory,
27506
28026
  "agents",
27507
28027
  this.id,
@@ -27573,7 +28093,7 @@ var OpenCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27573
28093
  await options.report("verifying");
27574
28094
  await options.report("installing_agent");
27575
28095
  const executable = await this.#archiveInstaller.install(
27576
- join14(
28096
+ join17(
27577
28097
  options.stateDirectory,
27578
28098
  "agents",
27579
28099
  this.id,
@@ -27632,7 +28152,9 @@ function fixedAgentInstallRecipes() {
27632
28152
  new ClaudeCodeInstallRecipe(),
27633
28153
  new PiInstallRecipe(),
27634
28154
  new DeepSeekHarnessInstallRecipe(),
27635
- new OpenCodeInstallRecipe()
28155
+ new OpenCodeInstallRecipe(),
28156
+ new GrokBuildInstallRecipe(),
28157
+ new WorkBuddyInstallRecipe()
27636
28158
  ]);
27637
28159
  }
27638
28160
 
@@ -27873,41 +28395,6 @@ var FixedInstallationExecutor = class {
27873
28395
  };
27874
28396
  };
27875
28397
 
27876
- // src/agent-installation/local-installation-authorizer.ts
27877
- import { createInterface } from "node:readline/promises";
27878
- var ConsoleInstallationAuthorizer = class {
27879
- #stateDirectory;
27880
- constructor(stateDirectory) {
27881
- this.#stateDirectory = stateDirectory;
27882
- }
27883
- authorize = async (agentId, label, requestId, signal) => {
27884
- signal.throwIfAborted();
27885
- const grants = await readGrantedAgents(this.#stateDirectory);
27886
- signal.throwIfAborted();
27887
- if (grants.has(agentId)) {
27888
- return true;
27889
- }
27890
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
27891
- return false;
27892
- }
27893
- const prompt = createInterface({
27894
- input: process.stdin,
27895
- output: process.stdout
27896
- });
27897
- try {
27898
- const answer = await prompt.question(
27899
- `
27900
- Mobius Web requested installation of ${label} (${requestId}). Allow this fixed user-level recipe? [y/N] `,
27901
- { signal }
27902
- );
27903
- const normalized = answer.trim().toLowerCase();
27904
- return normalized === "y" || normalized === "yes";
27905
- } finally {
27906
- prompt.close();
27907
- }
27908
- };
27909
- };
27910
-
27911
28398
  // src/authorization/local-authorization-error.ts
27912
28399
  var LocalAuthorizationError = class extends Error {
27913
28400
  code = "local_authorization_failed";
@@ -27918,15 +28405,15 @@ var LocalAuthorizationError = class extends Error {
27918
28405
  };
27919
28406
 
27920
28407
  // src/authorization/workspace-directory.ts
27921
- import { readdir, realpath as realpath6, stat as stat6 } from "node:fs/promises";
28408
+ import { readdir, realpath as realpath8, stat as stat7 } from "node:fs/promises";
27922
28409
  import { homedir as homedir2 } from "node:os";
27923
28410
  import {
27924
28411
  basename as basename2,
27925
- dirname as dirname5,
27926
- isAbsolute as isAbsolute5,
27927
- join as join15,
28412
+ dirname as dirname6,
28413
+ isAbsolute as isAbsolute8,
28414
+ join as join18,
27928
28415
  normalize as normalize2,
27929
- relative as relative3
28416
+ relative as relative5
27930
28417
  } from "node:path";
27931
28418
  var WorkspaceDirectoryListing = class {
27932
28419
  directoryId;
@@ -27976,20 +28463,20 @@ var WorkspaceDirectoryService = class {
27976
28463
  if (id === "home") return homedir2();
27977
28464
  if (id.startsWith("path-")) {
27978
28465
  const path2 = decodePath(id, "path-");
27979
- if (isAbsolute5(path2)) return path2;
28466
+ if (isAbsolute8(path2)) return path2;
27980
28467
  }
27981
28468
  throw new LocalAuthorizationError("The directory identifier is invalid");
27982
28469
  };
27983
28470
  resolvePath = async (requested, signal) => {
27984
28471
  signal.throwIfAborted();
27985
- if (!isAbsolute5(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28472
+ if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested)
27986
28473
  throw new LocalAuthorizationError("The local directory path is invalid");
27987
28474
  try {
27988
- const target = await realpath6(requested);
28475
+ const target = await realpath8(requested);
27989
28476
  signal.throwIfAborted();
27990
- const metadata = await stat6(target);
28477
+ const metadata = await stat7(target);
27991
28478
  signal.throwIfAborted();
27992
- if (!isAbsolute5(target) || normalize2(target) !== target || !metadata.isDirectory())
28479
+ if (!isAbsolute8(target) || normalize2(target) !== target || !metadata.isDirectory())
27993
28480
  throw new LocalAuthorizationError(
27994
28481
  "The selected location is not a directory"
27995
28482
  );
@@ -28004,8 +28491,8 @@ var WorkspaceDirectoryService = class {
28004
28491
  }
28005
28492
  };
28006
28493
  label = (path2) => {
28007
- const suffix = relative3(homedir2(), path2);
28008
- return suffix === "" ? "~" : !isAbsolute5(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28494
+ const suffix = relative5(homedir2(), path2);
28495
+ return suffix === "" ? "~" : !isAbsolute8(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28009
28496
  };
28010
28497
  identify = async (bindingId, requestedPath, signal) => {
28011
28498
  this.authorizeMachine(bindingId);
@@ -28033,7 +28520,7 @@ var WorkspaceDirectoryService = class {
28033
28520
  continue;
28034
28521
  }
28035
28522
  try {
28036
- const path2 = await this.resolvePath(join15(target, child.name), signal);
28523
+ const path2 = await this.resolvePath(join18(target, child.name), signal);
28037
28524
  entries.push({ directoryId: encodePath(path2), name: child.name });
28038
28525
  } catch (cause) {
28039
28526
  signal.throwIfAborted();
@@ -28041,7 +28528,7 @@ var WorkspaceDirectoryService = class {
28041
28528
  }
28042
28529
  }
28043
28530
  entries.sort((a, b) => a.name.localeCompare(b.name));
28044
- const parent = dirname5(target);
28531
+ const parent = dirname6(target);
28045
28532
  return new WorkspaceDirectoryListing(
28046
28533
  id,
28047
28534
  this.label(target),
@@ -28834,7 +29321,7 @@ var RelayConnectionLiveness = class {
28834
29321
 
28835
29322
  // src/relay-connection/session-event-outbox.ts
28836
29323
  import { mkdirSync as mkdirSync3 } from "node:fs";
28837
- import { dirname as dirname6 } from "node:path";
29324
+ import { dirname as dirname7 } from "node:path";
28838
29325
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
28839
29326
  function readPendingEnvelope(row) {
28840
29327
  if (typeof row !== "object" || row === null || Array.isArray(row)) {
@@ -28849,7 +29336,7 @@ function readPendingEnvelope(row) {
28849
29336
  var SessionEventOutbox = class {
28850
29337
  #database;
28851
29338
  constructor(path2) {
28852
- mkdirSync3(dirname6(path2), { recursive: true });
29339
+ mkdirSync3(dirname7(path2), { recursive: true });
28853
29340
  this.#database = new DatabaseSync3(path2);
28854
29341
  this.#database.exec(`
28855
29342
  CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
@@ -29141,17 +29628,6 @@ var DaemonInstallationObserver = class {
29141
29628
  if (state instanceof RequestedInstallation) {
29142
29629
  return Promise.resolve();
29143
29630
  }
29144
- if (state instanceof AwaitingLocalApproval) {
29145
- this.#send(
29146
- socket,
29147
- encodeAgentInstallAwaitingApprovalEvent({
29148
- agentId: state.agentId,
29149
- kind: AGENT_INSTALL_AWAITING_APPROVAL_KIND,
29150
- requestId: state.requestId
29151
- })
29152
- );
29153
- return Promise.resolve();
29154
- }
29155
29631
  if (state instanceof RunningInstallation) {
29156
29632
  if (!this.#started.has(state.requestId)) {
29157
29633
  this.#started.add(state.requestId);
@@ -30048,7 +30524,6 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30048
30524
  );
30049
30525
  const installations = new AgentInstallationManager(
30050
30526
  specifications,
30051
- new ConsoleInstallationAuthorizer(stateDirectory),
30052
30527
  installationExecutor,
30053
30528
  installationObserver,
30054
30529
  installationAudit
@@ -30156,7 +30631,7 @@ async function main() {
30156
30631
  if (arguments_.length > 1 || arguments_.length === 1 && arguments_[0] !== "--json") {
30157
30632
  throw new Error("Usage: mobius agents [--json]");
30158
30633
  }
30159
- await mkdir5(loadDefaultWorkspace(), { recursive: true, mode: 448 });
30634
+ await mkdir6(loadDefaultWorkspace(), { recursive: true, mode: 448 });
30160
30635
  const inventory = await discoverLocalAgentInventory({
30161
30636
  defaultWorkspace: loadDefaultWorkspace(),
30162
30637
  environment: process.env,