@moxt-ai/mobius 0.0.14 → 0.0.15

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 (88) 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/agents/cursor-cli-agent.d.ts +13 -0
  9. package/dist/agent-catalog/agents/cursor-cli-agent.d.ts.map +1 -0
  10. package/dist/agent-catalog/agents/cursor-cli-agent.js +25 -0
  11. package/dist/agent-catalog/agents/cursor-cli-agent.js.map +1 -0
  12. package/dist/agent-catalog/agents/grok-build-agent.d.ts +18 -0
  13. package/dist/agent-catalog/agents/grok-build-agent.d.ts.map +1 -0
  14. package/dist/agent-catalog/agents/grok-build-agent.js +75 -0
  15. package/dist/agent-catalog/agents/grok-build-agent.js.map +1 -0
  16. package/dist/agent-catalog/agents/supported-agent-specifications.d.ts.map +1 -1
  17. package/dist/agent-catalog/agents/supported-agent-specifications.js +6 -0
  18. package/dist/agent-catalog/agents/supported-agent-specifications.js.map +1 -1
  19. package/dist/agent-catalog/agents/verify-session-creation.d.ts +3 -0
  20. package/dist/agent-catalog/agents/verify-session-creation.d.ts.map +1 -0
  21. package/dist/agent-catalog/agents/verify-session-creation.js +16 -0
  22. package/dist/agent-catalog/agents/verify-session-creation.js.map +1 -0
  23. package/dist/agent-catalog/agents/workbuddy-agent.d.ts +15 -0
  24. package/dist/agent-catalog/agents/workbuddy-agent.d.ts.map +1 -0
  25. package/dist/agent-catalog/agents/workbuddy-agent.js +41 -0
  26. package/dist/agent-catalog/agents/workbuddy-agent.js.map +1 -0
  27. package/dist/agent-catalog/discover-local-agents.d.ts +3 -0
  28. package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
  29. package/dist/agent-catalog/discover-local-agents.js +4 -10
  30. package/dist/agent-catalog/discover-local-agents.js.map +1 -1
  31. package/dist/agent-catalog/local-agent.d.ts +1 -2
  32. package/dist/agent-catalog/local-agent.d.ts.map +1 -1
  33. package/dist/agent-catalog/local-agent.js +1 -3
  34. package/dist/agent-catalog/local-agent.js.map +1 -1
  35. package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
  36. package/dist/agent-catalog/publish-agent-catalog.js +0 -1
  37. package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
  38. package/dist/agent-installation/agent-installation-manager.d.ts +1 -8
  39. package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -1
  40. package/dist/agent-installation/agent-installation-manager.js +7 -24
  41. package/dist/agent-installation/agent-installation-manager.js.map +1 -1
  42. package/dist/agent-installation/fixed-agent-install-recipe.d.ts +20 -0
  43. package/dist/agent-installation/fixed-agent-install-recipe.d.ts.map +1 -0
  44. package/dist/agent-installation/fixed-agent-install-recipe.js +18 -0
  45. package/dist/agent-installation/fixed-agent-install-recipe.js.map +1 -0
  46. package/dist/agent-installation/fixed-agent-install-recipes.d.ts +5 -18
  47. package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +1 -1
  48. package/dist/agent-installation/fixed-agent-install-recipes.js +9 -16
  49. package/dist/agent-installation/fixed-agent-install-recipes.js.map +1 -1
  50. package/dist/agent-installation/grok-build-install-recipe.d.ts +12 -0
  51. package/dist/agent-installation/grok-build-install-recipe.d.ts.map +1 -0
  52. package/dist/agent-installation/grok-build-install-recipe.js +102 -0
  53. package/dist/agent-installation/grok-build-install-recipe.js.map +1 -0
  54. package/dist/agent-installation/grok-managed-package.d.ts +4 -0
  55. package/dist/agent-installation/grok-managed-package.d.ts.map +1 -0
  56. package/dist/agent-installation/grok-managed-package.js +34 -0
  57. package/dist/agent-installation/grok-managed-package.js.map +1 -0
  58. package/dist/agent-installation/managed-npm-package.d.ts +8 -0
  59. package/dist/agent-installation/managed-npm-package.d.ts.map +1 -1
  60. package/dist/agent-installation/managed-npm-package.js +32 -3
  61. package/dist/agent-installation/managed-npm-package.js.map +1 -1
  62. package/dist/agent-installation/workbuddy-install-recipe.d.ts +12 -0
  63. package/dist/agent-installation/workbuddy-install-recipe.d.ts.map +1 -0
  64. package/dist/agent-installation/workbuddy-install-recipe.js +51 -0
  65. package/dist/agent-installation/workbuddy-install-recipe.js.map +1 -0
  66. package/dist/agent-installation/workbuddy-managed-package.d.ts +10 -0
  67. package/dist/agent-installation/workbuddy-managed-package.d.ts.map +1 -0
  68. package/dist/agent-installation/workbuddy-managed-package.js +11 -0
  69. package/dist/agent-installation/workbuddy-managed-package.js.map +1 -0
  70. package/dist/cli.js +784 -355
  71. package/dist/cli.js.map +4 -4
  72. package/dist/index.js +729 -300
  73. package/dist/index.js.map +4 -4
  74. package/dist/pairing/pair-local-machine.d.ts.map +1 -1
  75. package/dist/pairing/pair-local-machine.js +0 -1
  76. package/dist/pairing/pair-local-machine.js.map +1 -1
  77. package/dist/run-daemon.d.ts.map +1 -1
  78. package/dist/run-daemon.js +3 -12
  79. package/dist/run-daemon.js.map +1 -1
  80. package/package.json +2 -2
  81. package/dist/agent-installation/installation-grants.d.ts +0 -2
  82. package/dist/agent-installation/installation-grants.d.ts.map +0 -1
  83. package/dist/agent-installation/installation-grants.js +0 -51
  84. package/dist/agent-installation/installation-grants.js.map +0 -1
  85. package/dist/agent-installation/local-installation-authorizer.d.ts +0 -7
  86. package/dist/agent-installation/local-installation-authorizer.d.ts.map +0 -1
  87. package/dist/agent-installation/local-installation-authorizer.js +0 -32
  88. 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();
@@ -1241,9 +1225,84 @@ var CodexAgentSpecification = class extends BridgedAcpAgentDefinition {
1241
1225
  managedAgentExecutablePath = ["agents", "codex", "bin", "codex"];
1242
1226
  };
1243
1227
 
1228
+ // src/agent-catalog/agent-probe-error.ts
1229
+ var AgentProbeError = class extends Error {
1230
+ code;
1231
+ constructor(code, message, options = {}) {
1232
+ super(message, options);
1233
+ this.code = code;
1234
+ this.name = "AgentProbeError";
1235
+ }
1236
+ };
1237
+
1238
+ // src/agent-catalog/agents/verify-session-creation.ts
1239
+ import {
1240
+ methods
1241
+ } from "@agentclientprotocol/sdk";
1242
+ async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
1243
+ const session = await connection.agent.request(
1244
+ methods.agent.session.new,
1245
+ {
1246
+ additionalDirectories: [],
1247
+ cwd: defaultWorkspace,
1248
+ mcpServers: []
1249
+ },
1250
+ { cancellationSignal: signal }
1251
+ );
1252
+ if (session.sessionId.length === 0) {
1253
+ throw new AgentProbeError(
1254
+ "acp_incompatible",
1255
+ `${label} returned an invalid ACP session`
1256
+ );
1257
+ }
1258
+ if (capabilities.sessionCapabilities?.close != null) {
1259
+ await connection.agent.request(
1260
+ methods.agent.session.close,
1261
+ { sessionId: session.sessionId },
1262
+ { cancellationSignal: signal }
1263
+ );
1264
+ }
1265
+ }
1266
+
1267
+ // src/agent-catalog/agents/cursor-cli-agent.ts
1268
+ var CURSOR_CLI_TESTED_VERSION = "2026.09.02-c22c1a3";
1269
+ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
1270
+ adapterVersion = CURSOR_CLI_TESTED_VERSION;
1271
+ authenticationCommand = () => "cursor-agent login";
1272
+ agentExecutable = "cursor-agent";
1273
+ id = "cursor";
1274
+ label = "Cursor CLI";
1275
+ constructor() {
1276
+ super(
1277
+ "MOBIUS_CURSOR_PATH",
1278
+ ["--disable-auto-update", "acp"],
1279
+ ["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
1280
+ );
1281
+ }
1282
+ supportsInstallation = (_platform, _architecture) => false;
1283
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1284
+ const capabilities = initialized.agentCapabilities ?? {};
1285
+ if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
1286
+ (method) => method.id === "cursor_login"
1287
+ )) {
1288
+ throw new AgentProbeError(
1289
+ "acp_incompatible",
1290
+ "Cursor CLI reported an unsupported ACP capability set"
1291
+ );
1292
+ }
1293
+ await verifySessionCreation(
1294
+ connection,
1295
+ capabilities,
1296
+ defaultWorkspace,
1297
+ signal,
1298
+ this.label
1299
+ );
1300
+ };
1301
+ };
1302
+
1244
1303
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1245
1304
  import { realpath as realpath3, stat as stat3 } from "node:fs/promises";
1246
- import { isAbsolute as isAbsolute2, join as join6, normalize } from "node:path";
1305
+ import { isAbsolute as isAbsolute2, join as join5, normalize } from "node:path";
1247
1306
 
1248
1307
  // src/agent-installation/deepseek-managed-package.ts
1249
1308
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -1261,15 +1320,16 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
1261
1320
  "https://registry.npmjs.org/@deepseek-ai/dsh/-/dsh-0.1.2-rc.1.tgz"
1262
1321
  );
1263
1322
 
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";
1323
+ // src/storage/state-directory.ts
1324
+ import { homedir } from "node:os";
1325
+ import { join as join4, resolve as resolve2 } from "node:path";
1326
+ function readStateDirectory(environment = process.env) {
1327
+ const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
1328
+ if (configured !== void 0 && configured.length > 0) {
1329
+ return resolve2(configured);
1271
1330
  }
1272
- };
1331
+ return join4(homedir(), ".mobius");
1332
+ }
1273
1333
 
1274
1334
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1275
1335
  async function validateAgentHome(path2) {
@@ -1328,7 +1388,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1328
1388
  context.signal
1329
1389
  );
1330
1390
  if (managed.path === agent.path) {
1331
- selectedHome = join6(
1391
+ selectedHome = join5(
1332
1392
  readStateDirectory(context.environment),
1333
1393
  "agents",
1334
1394
  this.id,
@@ -1349,7 +1409,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1349
1409
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
1350
1410
  signal.throwIfAborted();
1351
1411
  const executable = await validateManagedNpmPackage(
1352
- join6(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1412
+ join5(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1353
1413
  DEEPSEEK_HARNESS_PACKAGE
1354
1414
  );
1355
1415
  signal.throwIfAborted();
@@ -1369,6 +1429,166 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1369
1429
  };
1370
1430
  };
1371
1431
 
1432
+ // src/agent-catalog/agents/grok-build-agent.ts
1433
+ import { realpath as realpath4 } from "node:fs/promises";
1434
+ import { isAbsolute as isAbsolute3, join as join6, relative as relative2, sep as sep2 } from "node:path";
1435
+
1436
+ // src/agent-installation/grok-managed-package.ts
1437
+ var GROK_BUILD_MANAGED_VERSION = "1.0.21";
1438
+ var GrokBuildManagedPackage = class extends SriManagedNpmPackageDefinition {
1439
+ dependencyResolutionArguments = Object.freeze([
1440
+ "--before=2026-09-04T19:51:47.325Z"
1441
+ ]);
1442
+ includeOptionalDependencies = true;
1443
+ requiredDependencies;
1444
+ verifyDependencyClosure = true;
1445
+ constructor(requiredDependency) {
1446
+ super(
1447
+ "@xai-official/grok",
1448
+ GROK_BUILD_MANAGED_VERSION,
1449
+ "grok",
1450
+ "sha512-6yQqC+h1o+ObaqCxImK23dhkrOX1DEBMOKaH6fCK+B4gX0/8XIKZp0n7iKyBdK8KZa5vhMn7pS45kjX49Tps5g==",
1451
+ "https://registry.npmjs.org/@xai-official/grok/-/grok-1.0.21.tgz"
1452
+ );
1453
+ this.requiredDependencies = Object.freeze([requiredDependency]);
1454
+ }
1455
+ };
1456
+ var GROK_DARWIN_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
1457
+ "@xai-official/grok-darwin-arm64",
1458
+ GROK_BUILD_MANAGED_VERSION,
1459
+ "sha512-I4pKZGnR6Mv4MJOJsB9B/i2o0ODF4eZtp4jHN5feoTqKIeAUVg38OzBtE8aN/wZa7Xg+qhnf6Jd1tcAFvMoFtQ==",
1460
+ "https://registry.npmjs.org/@xai-official/grok-darwin-arm64/-/grok-darwin-arm64-1.0.21.tgz"
1461
+ );
1462
+ var GROK_DARWIN_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
1463
+ "@xai-official/grok-darwin-x64",
1464
+ GROK_BUILD_MANAGED_VERSION,
1465
+ "sha512-h0nFj3NZ9Kz8w6fQ6UDxxeSIhC1WjwwoRE92iNbG//tZy6YGkppR3s7oRVtt4Xl0CJANKUt0EusyIYnnAvKLzw==",
1466
+ "https://registry.npmjs.org/@xai-official/grok-darwin-x64/-/grok-darwin-x64-1.0.21.tgz"
1467
+ );
1468
+ var GROK_LINUX_ARM64_PACKAGE = new SriManagedNpmDependencyDefinition(
1469
+ "@xai-official/grok-linux-arm64",
1470
+ GROK_BUILD_MANAGED_VERSION,
1471
+ "sha512-Jlwz9XtZPNKz/V/ydifC8OVu3hIZz7pmoStt8c4KCqkSWjWiZ/PBIC0iJiq8rvByhx5Z0EdSyq8ZXVwtocceGA==",
1472
+ "https://registry.npmjs.org/@xai-official/grok-linux-arm64/-/grok-linux-arm64-1.0.21.tgz"
1473
+ );
1474
+ var GROK_LINUX_X64_PACKAGE = new SriManagedNpmDependencyDefinition(
1475
+ "@xai-official/grok-linux-x64",
1476
+ GROK_BUILD_MANAGED_VERSION,
1477
+ "sha512-AjDV5ifEz5LFG2Jt5IlhAeEkJati/wOvCchVbR4eIj2ogjvmXoXlzBrYRXuAJpXBy5q0se/Yuez5FxDU9Ju81w==",
1478
+ "https://registry.npmjs.org/@xai-official/grok-linux-x64/-/grok-linux-x64-1.0.21.tgz"
1479
+ );
1480
+ function grokBuildManagedPackage(platform, architecture) {
1481
+ if (platform === "darwin" && architecture === "arm64") {
1482
+ return new GrokBuildManagedPackage(GROK_DARWIN_ARM64_PACKAGE);
1483
+ }
1484
+ if (platform === "darwin" && architecture === "x64") {
1485
+ return new GrokBuildManagedPackage(GROK_DARWIN_X64_PACKAGE);
1486
+ }
1487
+ if (platform === "linux" && architecture === "arm64") {
1488
+ return new GrokBuildManagedPackage(GROK_LINUX_ARM64_PACKAGE);
1489
+ }
1490
+ if (platform === "linux" && architecture === "x64") {
1491
+ return new GrokBuildManagedPackage(GROK_LINUX_X64_PACKAGE);
1492
+ }
1493
+ throw new Error("Grok Build does not publish a package for this platform");
1494
+ }
1495
+
1496
+ // src/agent-catalog/agents/grok-build-agent.ts
1497
+ function isContainedPath2(root, candidate) {
1498
+ const difference = relative2(root, candidate);
1499
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
1500
+ }
1501
+ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1502
+ adapterVersion = GROK_BUILD_MANAGED_VERSION;
1503
+ authenticationCommand = () => "grok login";
1504
+ agentExecutable = "grok";
1505
+ agentVersionArguments = ["version"];
1506
+ adapterVersionArguments = ["version"];
1507
+ id = "grok-build";
1508
+ label = "Grok Build";
1509
+ constructor() {
1510
+ super(
1511
+ "MOBIUS_GROK_BUILD_PATH",
1512
+ ["--no-auto-update", "agent", "stdio"],
1513
+ [
1514
+ "agents",
1515
+ "grok-build",
1516
+ GROK_BUILD_MANAGED_VERSION,
1517
+ "home",
1518
+ "bin",
1519
+ "grok"
1520
+ ]
1521
+ );
1522
+ }
1523
+ createLaunchEnvironment = async (agent, context) => {
1524
+ const stateDirectory = readStateDirectory(context.environment);
1525
+ try {
1526
+ const managed = await this.resolveManagedAgent(
1527
+ stateDirectory,
1528
+ context.platform ?? process.platform,
1529
+ context.signal
1530
+ );
1531
+ if (managed.path === agent.path) {
1532
+ return Object.freeze({
1533
+ GROK_HOME: await realpath4(
1534
+ join6(
1535
+ stateDirectory,
1536
+ "agents",
1537
+ this.id,
1538
+ GROK_BUILD_MANAGED_VERSION,
1539
+ "home"
1540
+ )
1541
+ )
1542
+ });
1543
+ }
1544
+ } catch {
1545
+ context.signal.throwIfAborted();
1546
+ }
1547
+ return Object.freeze({});
1548
+ };
1549
+ resolveManagedAgent = async (stateDirectory, platform, signal) => {
1550
+ signal.throwIfAborted();
1551
+ const versionRoot = await realpath4(
1552
+ join6(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION)
1553
+ );
1554
+ await validateManagedNpmPackage(
1555
+ join6(versionRoot, "package"),
1556
+ grokBuildManagedPackage(platform, process.arch)
1557
+ );
1558
+ const executable = await resolveExecutablePath(
1559
+ join6(versionRoot, "home", "bin", "grok"),
1560
+ platform
1561
+ );
1562
+ signal.throwIfAborted();
1563
+ if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
1564
+ throw new AgentProbeError(
1565
+ "managed_agent_invalid",
1566
+ "The managed Grok Build executable is invalid"
1567
+ );
1568
+ }
1569
+ return executable;
1570
+ };
1571
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1572
+ const capabilities = initialized.agentCapabilities ?? {};
1573
+ const session = capabilities.sessionCapabilities;
1574
+ if (capabilities.loadSession !== true || session?.close == null || session.list == null || session.resume == null || !(initialized.authMethods ?? []).some(
1575
+ (method) => method.id === "xai.api_key" || method.id === "grok.com"
1576
+ )) {
1577
+ throw new AgentProbeError(
1578
+ "acp_incompatible",
1579
+ "Grok Build reported an unsupported ACP capability set"
1580
+ );
1581
+ }
1582
+ await verifySessionCreation(
1583
+ connection,
1584
+ capabilities,
1585
+ defaultWorkspace,
1586
+ signal,
1587
+ this.label
1588
+ );
1589
+ };
1590
+ };
1591
+
1372
1592
  // src/agent-catalog/agents/opencode-agent.ts
1373
1593
  import { join as join8 } from "node:path";
1374
1594
 
@@ -1380,18 +1600,18 @@ import {
1380
1600
  copyFile,
1381
1601
  mkdir as mkdir2,
1382
1602
  mkdtemp as mkdtemp2,
1383
- open as open4,
1384
- realpath as realpath4,
1603
+ open as open3,
1604
+ realpath as realpath5,
1385
1605
  rename as rename2,
1386
1606
  rm as rm2,
1387
1607
  stat as stat4,
1388
1608
  writeFile
1389
1609
  } from "node:fs/promises";
1390
- import { dirname as dirname2, isAbsolute as isAbsolute3, join as join7, relative as relative2, sep as sep2 } from "node:path";
1610
+ import { dirname as dirname2, isAbsolute as isAbsolute4, join as join7, relative as relative3, sep as sep3 } from "node:path";
1391
1611
 
1392
1612
  // src/agent-installation/verified-download.ts
1393
1613
  import { createHash } from "node:crypto";
1394
- import { open as open3, unlink } from "node:fs/promises";
1614
+ import { open as open2, unlink } from "node:fs/promises";
1395
1615
  import { fetch } from "undici";
1396
1616
 
1397
1617
  // src/network/environment-proxy.ts
@@ -1523,7 +1743,7 @@ async function downloadVerifiedFile(options, transport = new UndiciInstallerDown
1523
1743
  );
1524
1744
  }
1525
1745
  }
1526
- handle = await open3(options.destination, "wx", 384);
1746
+ handle = await open2(options.destination, "wx", 384);
1527
1747
  const digest = createHash("sha256");
1528
1748
  const reader = fetched.response.body.getReader();
1529
1749
  let bytes = 0;
@@ -1633,12 +1853,12 @@ var ManagedAgentArchiveError = class extends Error {
1633
1853
  var ManagedAgentArchiveDownloader = class {
1634
1854
  download = async (options) => await downloadVerifiedFile(options);
1635
1855
  };
1636
- function isRecord3(value) {
1856
+ function isRecord2(value) {
1637
1857
  return typeof value === "object" && value !== null && !Array.isArray(value);
1638
1858
  }
1639
- function isContainedPath2(root, candidate) {
1640
- const difference = relative2(root, candidate);
1641
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
1859
+ function isContainedPath3(root, candidate) {
1860
+ const difference = relative3(root, candidate);
1861
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute4(difference);
1642
1862
  }
1643
1863
  async function hashFile(path2, signal) {
1644
1864
  signal.throwIfAborted();
@@ -1673,7 +1893,7 @@ async function hashFile(path2, signal) {
1673
1893
  async function readManifest(path2) {
1674
1894
  let handle;
1675
1895
  try {
1676
- handle = await open4(path2, "r");
1896
+ handle = await open3(path2, "r");
1677
1897
  } catch (error61) {
1678
1898
  throw new ManagedAgentArchiveError(
1679
1899
  "managed_archive_verification_failed",
@@ -1692,7 +1912,7 @@ async function readManifest(path2) {
1692
1912
  const parsed = JSON.parse(
1693
1913
  await handle.readFile({ encoding: "utf8" })
1694
1914
  );
1695
- if (!isRecord3(parsed)) {
1915
+ if (!isRecord2(parsed)) {
1696
1916
  throw new ManagedAgentArchiveError(
1697
1917
  "managed_archive_verification_failed",
1698
1918
  "The managed Agent archive manifest is invalid"
@@ -1714,7 +1934,7 @@ async function readManifest(path2) {
1714
1934
  }
1715
1935
  async function validateManagedAgentArchive(root, definition, signal) {
1716
1936
  try {
1717
- const rootPath = await realpath4(root);
1937
+ const rootPath = await realpath5(root);
1718
1938
  const rootMetadata = await stat4(rootPath);
1719
1939
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
1720
1940
  throw new Error("Managed Agent root is not user-owned");
@@ -1726,7 +1946,7 @@ async function validateManagedAgentArchive(root, definition, signal) {
1726
1946
  const executable = await resolveExecutablePath(
1727
1947
  join7(rootPath, "bin", definition.executableName)
1728
1948
  );
1729
- if (executable === null || !isContainedPath2(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
1949
+ if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
1730
1950
  throw new Error("Managed Agent executable is invalid");
1731
1951
  }
1732
1952
  return executable;
@@ -1782,7 +2002,7 @@ var ManagedAgentArchiveInstaller = class {
1782
2002
  const archivePath = join7(working, definition.archiveName);
1783
2003
  const extractionRoot = join7(working, "extracted");
1784
2004
  await mkdir2(extractionRoot, { mode: 448 });
1785
- const canonicalExtractionRoot = await realpath4(extractionRoot);
2005
+ const canonicalExtractionRoot = await realpath5(extractionRoot);
1786
2006
  const download = await this.#downloader.download({
1787
2007
  allowedHosts: /* @__PURE__ */ new Set([
1788
2008
  "github.com",
@@ -1820,11 +2040,11 @@ var ManagedAgentArchiveInstaller = class {
1820
2040
  signal,
1821
2041
  timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
1822
2042
  });
1823
- const extracted = await realpath4(
2043
+ const extracted = await realpath5(
1824
2044
  join7(canonicalExtractionRoot, definition.executableName)
1825
2045
  );
1826
2046
  const extractedMetadata = await stat4(extracted);
1827
- if (!isContainedPath2(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
2047
+ if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
1828
2048
  throw new ManagedAgentArchiveError(
1829
2049
  "managed_archive_verification_failed",
1830
2050
  "The managed Agent archive executable is invalid"
@@ -1979,7 +2199,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
1979
2199
  // src/agent-catalog/agents/pi-agent.ts
1980
2200
  import { join as join9 } from "node:path";
1981
2201
  import {
1982
- methods
2202
+ methods as methods2
1983
2203
  } from "@agentclientprotocol/sdk";
1984
2204
 
1985
2205
  // src/agent-installation/pi-managed-packages.ts
@@ -2051,7 +2271,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2051
2271
  );
2052
2272
  }
2053
2273
  const session = await connection.agent.request(
2054
- methods.agent.session.new,
2274
+ methods2.agent.session.new,
2055
2275
  {
2056
2276
  additionalDirectories: [],
2057
2277
  cwd: defaultWorkspace,
@@ -2066,7 +2286,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2066
2286
  );
2067
2287
  }
2068
2288
  const prompt = await connection.agent.request(
2069
- methods.agent.session.prompt,
2289
+ methods2.agent.session.prompt,
2070
2290
  {
2071
2291
  prompt: [{ text: "/session", type: "text" }],
2072
2292
  sessionId: session.sessionId
@@ -2082,6 +2302,77 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
2082
2302
  };
2083
2303
  };
2084
2304
 
2305
+ // src/agent-catalog/agents/workbuddy-agent.ts
2306
+ import { join as join10 } from "node:path";
2307
+
2308
+ // src/agent-installation/workbuddy-managed-package.ts
2309
+ var WORKBUDDY_MANAGED_VERSION = "2.146.0";
2310
+ var WorkBuddyManagedPackage = class extends SriManagedNpmPackageDefinition {
2311
+ dependencyResolutionArguments = Object.freeze([
2312
+ "--before=2026-09-05T12:39:25.295Z"
2313
+ ]);
2314
+ includeOptionalDependencies = true;
2315
+ verifyDependencyClosure = true;
2316
+ };
2317
+ var WORKBUDDY_MANAGED_PACKAGE = new WorkBuddyManagedPackage(
2318
+ "@tencent-ai/codebuddy-code",
2319
+ WORKBUDDY_MANAGED_VERSION,
2320
+ "codebuddy",
2321
+ "sha512-81V+8rzYJY8PezHZMs4VZN2nvoijrsRWIuCERTr6hELotcxaZaAcqbQQSbHJcN8eTlFE5TRPlzMI4oEkLCat4A==",
2322
+ "https://registry.npmjs.org/@tencent-ai/codebuddy-code/-/codebuddy-code-2.146.0.tgz"
2323
+ );
2324
+
2325
+ // src/agent-catalog/agents/workbuddy-agent.ts
2326
+ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
2327
+ adapterVersion = WORKBUDDY_MANAGED_VERSION;
2328
+ authenticationCommand = () => "codebuddy";
2329
+ agentExecutable = "codebuddy";
2330
+ id = "workbuddy";
2331
+ label = "WorkBuddy";
2332
+ constructor() {
2333
+ super(
2334
+ "MOBIUS_WORKBUDDY_PATH",
2335
+ ["--acp"],
2336
+ [
2337
+ "agents",
2338
+ "workbuddy",
2339
+ WORKBUDDY_MANAGED_VERSION,
2340
+ "node_modules",
2341
+ "@tencent-ai",
2342
+ "codebuddy-code",
2343
+ "bin",
2344
+ "codebuddy"
2345
+ ]
2346
+ );
2347
+ }
2348
+ createLaunchEnvironment = () => Promise.resolve(Object.freeze({ DISABLE_AUTOUPDATER: "1" }));
2349
+ resolveManagedAgent = async (stateDirectory, _platform, signal) => {
2350
+ signal.throwIfAborted();
2351
+ const executable = await validateManagedNpmPackage(
2352
+ join10(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
2353
+ WORKBUDDY_MANAGED_PACKAGE
2354
+ );
2355
+ signal.throwIfAborted();
2356
+ return executable;
2357
+ };
2358
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
2359
+ const capabilities = initialized.agentCapabilities ?? {};
2360
+ if (capabilities.loadSession !== true || (initialized.authMethods ?? []).length === 0) {
2361
+ throw new AgentProbeError(
2362
+ "acp_incompatible",
2363
+ "WorkBuddy reported an unsupported ACP capability set"
2364
+ );
2365
+ }
2366
+ await verifySessionCreation(
2367
+ connection,
2368
+ capabilities,
2369
+ defaultWorkspace,
2370
+ signal,
2371
+ this.label
2372
+ );
2373
+ };
2374
+ };
2375
+
2085
2376
  // src/agent-catalog/agents/supported-agent-specifications.ts
2086
2377
  function supportedLocalAgentSpecifications() {
2087
2378
  return Object.freeze([
@@ -2089,14 +2380,17 @@ function supportedLocalAgentSpecifications() {
2089
2380
  new ClaudeCodeAgentSpecification(),
2090
2381
  new PiAgentSpecification(),
2091
2382
  new DeepSeekHarnessAgentSpecification(),
2092
- new OpenCodeAgentSpecification()
2383
+ new OpenCodeAgentSpecification(),
2384
+ new CursorCliAgentSpecification(),
2385
+ new GrokBuildAgentSpecification(),
2386
+ new WorkBuddyAgentSpecification()
2093
2387
  ]);
2094
2388
  }
2095
2389
 
2096
2390
  // src/agent-catalog/acp-readiness-probe.ts
2097
2391
  import { spawn as spawn2 } from "node:child_process";
2098
2392
  import {
2099
- methods as methods3,
2393
+ methods as methods4,
2100
2394
  ndJsonStream,
2101
2395
  PROTOCOL_VERSION,
2102
2396
  RequestError
@@ -2105,25 +2399,47 @@ import {
2105
2399
  // src/acp/create-client.ts
2106
2400
  import {
2107
2401
  client,
2108
- methods as methods2
2402
+ methods as methods3
2109
2403
  } from "@agentclientprotocol/sdk";
2404
+ function discardExtensionParams(_params) {
2405
+ return Object.freeze({});
2406
+ }
2110
2407
  var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
2111
- methods2.client.session.requestPermission,
2408
+ methods3.client.session.requestPermission,
2112
2409
  async (context) => await handler.onPermission(context.params, context.signal)
2113
2410
  ).onRequest(
2114
- methods2.client.elicitation.create,
2411
+ methods3.client.elicitation.create,
2115
2412
  async (context) => await handler.onElicitation(context.params, context.signal)
2116
- ).onNotification(methods2.client.session.update, async (context) => {
2413
+ ).onNotification(methods3.client.session.update, async (context) => {
2117
2414
  await handler.onUpdate(context.params);
2118
- }).onNotification(methods2.client.elicitation.complete, async (context) => {
2415
+ }).onNotification(methods3.client.elicitation.complete, async (context) => {
2119
2416
  await handler.onElicitationComplete(context.params);
2120
- });
2417
+ }).onRequest("cursor/ask_question", discardExtensionParams, async () => ({
2418
+ outcome: {
2419
+ outcome: "skipped",
2420
+ reason: "Mobius does not expose Cursor question extensions"
2421
+ }
2422
+ })).onRequest("cursor/create_plan", discardExtensionParams, async () => ({
2423
+ outcome: { outcome: "cancelled" }
2424
+ })).onNotification(
2425
+ "cursor/update_todos",
2426
+ discardExtensionParams,
2427
+ async () => Promise.resolve()
2428
+ ).onNotification(
2429
+ "cursor/task",
2430
+ discardExtensionParams,
2431
+ async () => Promise.resolve()
2432
+ ).onNotification(
2433
+ "cursor/generate_image",
2434
+ discardExtensionParams,
2435
+ async () => Promise.resolve()
2436
+ );
2121
2437
 
2122
2438
  // src/agent-catalog/executable-discovery.ts
2123
- import { isAbsolute as isAbsolute4, join as join11 } from "node:path";
2439
+ import { isAbsolute as isAbsolute5, join as join12 } from "node:path";
2124
2440
 
2125
2441
  // src/agent-installation/managed-adapter-installer.ts
2126
- import { join as join10 } from "node:path";
2442
+ import { join as join11 } from "node:path";
2127
2443
  var ManagedAdapterInstallError = class extends Error {
2128
2444
  code;
2129
2445
  constructor(code, message, options = {}) {
@@ -2185,7 +2501,7 @@ var ManagedAdapterInstaller = class {
2185
2501
  this.#stateDirectory = options.stateDirectory;
2186
2502
  }
2187
2503
  install = async (specification, signal) => {
2188
- const root = join10(
2504
+ const root = join11(
2189
2505
  this.#stateDirectory,
2190
2506
  "adapters",
2191
2507
  specification.id,
@@ -2224,7 +2540,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
2224
2540
  let managed;
2225
2541
  try {
2226
2542
  managed = await validateManagedAdapter(
2227
- join11(
2543
+ join12(
2228
2544
  readStateDirectory(context.environment),
2229
2545
  "adapters",
2230
2546
  specification.id,
@@ -2240,7 +2556,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
2240
2556
  async function resolveSpecificationExecutables(executableName, overrideVariable, resolveManaged, context) {
2241
2557
  const override = context.environment[overrideVariable];
2242
2558
  if (override !== void 0) {
2243
- if (override.length === 0 || !isAbsolute4(override)) {
2559
+ if (override.length === 0 || !isAbsolute5(override)) {
2244
2560
  return [];
2245
2561
  }
2246
2562
  const executable = await resolveExecutablePath(override, context.platform);
@@ -2351,41 +2667,41 @@ var DiscoveryAcpHandler = class {
2351
2667
  };
2352
2668
  function readableAcpStream(input2) {
2353
2669
  let byteLength = 0;
2354
- let open7 = true;
2670
+ let open6 = true;
2355
2671
  return new ReadableStream({
2356
2672
  start(controller) {
2357
2673
  input2.on("data", (chunk) => {
2358
- if (!open7) {
2674
+ if (!open6) {
2359
2675
  return;
2360
2676
  }
2361
2677
  if (!(chunk instanceof Uint8Array)) {
2362
- open7 = false;
2678
+ open6 = false;
2363
2679
  controller.error(new Error("ACP adapter produced invalid output"));
2364
2680
  return;
2365
2681
  }
2366
2682
  byteLength += chunk.byteLength;
2367
2683
  if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
2368
- open7 = false;
2684
+ open6 = false;
2369
2685
  controller.error(new Error("ACP adapter output limit exceeded"));
2370
2686
  return;
2371
2687
  }
2372
2688
  controller.enqueue(new Uint8Array(chunk));
2373
2689
  });
2374
2690
  input2.once("end", () => {
2375
- if (open7) {
2376
- open7 = false;
2691
+ if (open6) {
2692
+ open6 = false;
2377
2693
  controller.close();
2378
2694
  }
2379
2695
  });
2380
2696
  input2.once("error", (error61) => {
2381
- if (open7) {
2382
- open7 = false;
2697
+ if (open6) {
2698
+ open6 = false;
2383
2699
  controller.error(error61);
2384
2700
  }
2385
2701
  });
2386
2702
  },
2387
2703
  cancel() {
2388
- open7 = false;
2704
+ open6 = false;
2389
2705
  }
2390
2706
  });
2391
2707
  }
@@ -2454,7 +2770,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
2454
2770
  try {
2455
2771
  const initialized = await Promise.race([
2456
2772
  connection.agent.request(
2457
- methods3.agent.initialize,
2773
+ methods4.agent.initialize,
2458
2774
  {
2459
2775
  clientCapabilities: {},
2460
2776
  clientInfo: { name: "mobius", version: "0.0.3" },
@@ -2665,16 +2981,8 @@ async function discoverLocalAgentInventory(options) {
2665
2981
  async (specification) => await discoverAgent(specification, options)
2666
2982
  )
2667
2983
  );
2668
- let grantedAgents = /* @__PURE__ */ new Set();
2669
- try {
2670
- grantedAgents = await readGrantedAgents(
2671
- readStateDirectory(options.environment)
2672
- );
2673
- } catch {
2674
- }
2675
2984
  return new LocalAgentInventory(
2676
2985
  discoveries,
2677
- grantedAgents,
2678
2986
  options.platform,
2679
2987
  options.architecture
2680
2988
  );
@@ -2731,7 +3039,7 @@ var AuditStore = class {
2731
3039
  };
2732
3040
 
2733
3041
  // src/config.ts
2734
- import { join as join12 } from "node:path";
3042
+ import { join as join13 } from "node:path";
2735
3043
 
2736
3044
  // ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
2737
3045
  var external_exports = {};
@@ -4693,8 +5001,8 @@ function emoji() {
4693
5001
  }
4694
5002
  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
5003
  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 ?? ":");
5004
+ var mac = (delimiter3) => {
5005
+ const escapedDelim = escapeRegex(delimiter3 ?? ":");
4698
5006
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
4699
5007
  };
4700
5008
  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 +8059,7 @@ function bucketFor(state, inst) {
7751
8059
  return bucket;
7752
8060
  }
7753
8061
  var handoff;
7754
- var open5 = [];
8062
+ var open4 = [];
7755
8063
  var memo = {
7756
8064
  alloc(_inst, payload, empty) {
7757
8065
  const bucket = handoff;
@@ -7760,7 +8068,7 @@ var memo = {
7760
8068
  handoff = void 0;
7761
8069
  const entry = { value: empty, issues: null };
7762
8070
  bucket.set(payload.value, entry);
7763
- open5.push(entry);
8071
+ open4.push(entry);
7764
8072
  return empty;
7765
8073
  },
7766
8074
  guard(inst) {
@@ -7826,10 +8134,10 @@ var memo = {
7826
8134
  return payload;
7827
8135
  }
7828
8136
  handoff = bucket;
7829
- const depth = open5.length;
8137
+ const depth = open4.length;
7830
8138
  const result = base(payload, ctx);
7831
8139
  handoff = void 0;
7832
- const entry = open5.length > depth ? open5.pop() : void 0;
8140
+ const entry = open4.length > depth ? open4.pop() : void 0;
7833
8141
  if (result instanceof Promise) {
7834
8142
  return result.then((r) => {
7835
8143
  if (entry)
@@ -21669,7 +21977,6 @@ var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
21669
21977
  var AGENT_CONTENT_KIND = "agent.content";
21670
21978
  var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
21671
21979
  var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
21672
- var AGENT_INSTALL_AWAITING_APPROVAL_KIND = "agent.install.awaiting_approval";
21673
21980
  var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
21674
21981
  var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
21675
21982
  var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
@@ -21975,10 +22282,6 @@ var agentInstallCancelCommandSchema = external_exports.strictObject({
21975
22282
  kind: external_exports.literal(AGENT_INSTALL_CANCEL_KIND),
21976
22283
  requestId: IDENTIFIER
21977
22284
  }).readonly();
21978
- var agentInstallAwaitingApprovalEventSchema = external_exports.strictObject({
21979
- ...agentInstallIdentityFields,
21980
- kind: external_exports.literal(AGENT_INSTALL_AWAITING_APPROVAL_KIND)
21981
- }).readonly();
21982
22285
  var agentInstallStartedEventSchema = external_exports.strictObject({
21983
22286
  ...agentInstallIdentityFields,
21984
22287
  kind: external_exports.literal(AGENT_INSTALL_STARTED_KIND)
@@ -22061,7 +22364,6 @@ var encodeSessionOperationFailedEvent = (message) => encode3(message, sessionOpe
22061
22364
  var encodeAgentContentEvent = (message) => encode3(message, agentContentEventSchema);
22062
22365
  var decodeAgentInstallRequestCommand = (encoded) => decode3(encoded, agentInstallRequestCommandSchema);
22063
22366
  var decodeAgentInstallCancelCommand = (encoded) => decode3(encoded, agentInstallCancelCommandSchema);
22064
- var encodeAgentInstallAwaitingApprovalEvent = (message) => encode3(message, agentInstallAwaitingApprovalEventSchema);
22065
22367
  var encodeAgentInstallStartedEvent = (message) => encode3(message, agentInstallStartedEventSchema);
22066
22368
  var encodeAgentInstallProgressEvent = (message) => encode3(message, agentInstallProgressEventSchema);
22067
22369
  var encodeAgentInstallCompletedEvent = (message) => encode3(message, agentInstallCompletedEventSchema);
@@ -22118,7 +22420,7 @@ var ProtocolMessageError = class extends Error {
22118
22420
  this.name = "ProtocolMessageError";
22119
22421
  }
22120
22422
  };
22121
- function isRecord4(value) {
22423
+ function isRecord3(value) {
22122
22424
  return typeof value === "object" && value !== null && !Array.isArray(value);
22123
22425
  }
22124
22426
  function parseJson2(encoded) {
@@ -22130,7 +22432,7 @@ function parseJson2(encoded) {
22130
22432
  cause: error61
22131
22433
  });
22132
22434
  }
22133
- if (!isRecord4(value)) {
22435
+ if (!isRecord3(value)) {
22134
22436
  throw new ProtocolMessageError("Message must be a JSON object");
22135
22437
  }
22136
22438
  return value;
@@ -22214,7 +22516,7 @@ function readActivityContent(value) {
22214
22516
  }
22215
22517
  function readActivityDetail(value) {
22216
22518
  const field = value["detail"];
22217
- if (!isRecord4(field)) {
22519
+ if (!isRecord3(field)) {
22218
22520
  throw new ProtocolMessageError("Invalid activity detail field");
22219
22521
  }
22220
22522
  const kind = readString(field, "kind", 32);
@@ -23202,7 +23504,7 @@ var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAckno
23202
23504
  // src/config.ts
23203
23505
  function loadDefaultWorkspace() {
23204
23506
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = process.env;
23205
- return configuredWorkspace ?? join12(readStateDirectory(), "workspace");
23507
+ return configuredWorkspace ?? join13(readStateDirectory(), "workspace");
23206
23508
  }
23207
23509
  function createDaemonConfig(connection, agents = [], installableAgents = []) {
23208
23510
  return {
@@ -23221,14 +23523,14 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
23221
23523
  import { randomUUID } from "node:crypto";
23222
23524
  import {
23223
23525
  mkdir as mkdir3,
23224
- open as open6,
23225
- realpath as realpath5,
23526
+ open as open5,
23527
+ realpath as realpath6,
23226
23528
  rename as rename3,
23227
23529
  stat as stat5,
23228
23530
  writeFile as writeFile2
23229
23531
  } from "node:fs/promises";
23230
23532
  import { hostname as hostname3 } from "node:os";
23231
- import { basename, join as join13, resolve as resolve3 } from "node:path";
23533
+ import { basename, join as join14, resolve as resolve3 } from "node:path";
23232
23534
  import { fetch as fetch2 } from "undici";
23233
23535
  var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
23234
23536
  var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
@@ -23254,7 +23556,7 @@ var PairingClientError = class extends Error {
23254
23556
  this.name = "PairingClientError";
23255
23557
  }
23256
23558
  };
23257
- function isRecord5(value) {
23559
+ function isRecord4(value) {
23258
23560
  return typeof value === "object" && value !== null && !Array.isArray(value);
23259
23561
  }
23260
23562
  function hasExactKeys(value, expectedKeys) {
@@ -23368,7 +23670,7 @@ async function resolveDefaultWorkspace(path2) {
23368
23670
  const requestedWorkspace = resolve3(path2);
23369
23671
  try {
23370
23672
  await mkdir3(requestedWorkspace, { recursive: true, mode: 448 });
23371
- const defaultWorkspace = await realpath5(requestedWorkspace);
23673
+ const defaultWorkspace = await realpath6(requestedWorkspace);
23372
23674
  const metadata = await stat5(defaultWorkspace);
23373
23675
  if (!metadata.isDirectory()) {
23374
23676
  throw new PairingClientError(
@@ -23407,9 +23709,9 @@ async function readJsonResponse(response) {
23407
23709
  }
23408
23710
  }
23409
23711
  function readRelayError(value) {
23410
- if (isRecord5(value)) {
23712
+ if (isRecord4(value)) {
23411
23713
  const error61 = value["error"];
23412
- if (isRecord5(error61)) {
23714
+ if (isRecord4(error61)) {
23413
23715
  const code = error61["code"];
23414
23716
  const message = error61["message"];
23415
23717
  if (typeof code === "string" && typeof message === "string") {
@@ -23423,7 +23725,7 @@ function readRelayError(value) {
23423
23725
  );
23424
23726
  }
23425
23727
  function decodeClaimResponse(value) {
23426
- if (!isRecord5(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
23728
+ if (!isRecord4(value) || !hasExactKeys(value, CLAIM_RESPONSE_KEYS)) {
23427
23729
  throw new PairingClientError(
23428
23730
  "invalid_relay_response",
23429
23731
  "The relay returned an invalid pairing response"
@@ -23453,8 +23755,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
23453
23755
  agents,
23454
23756
  installableAgents: installableAgents.map((agent) => ({
23455
23757
  id: agent.id,
23456
- label: agent.label,
23457
- requiresLocalApproval: agent.requiresLocalApproval
23758
+ label: agent.label
23458
23759
  })),
23459
23760
  machineName: hostname3(),
23460
23761
  pairingCode: options.code,
@@ -23482,10 +23783,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
23482
23783
  return decodeClaimResponse(value);
23483
23784
  }
23484
23785
  async function persistConnection(channelId, relayOrigin, daemonToken, defaultWorkspace) {
23485
- const connectionsDirectory = join13(readStateDirectory(), "connections");
23786
+ const connectionsDirectory = join14(readStateDirectory(), "connections");
23486
23787
  await mkdir3(connectionsDirectory, { mode: 448, recursive: true });
23487
- const connectionPath = join13(connectionsDirectory, `${channelId}.json`);
23488
- const temporaryPath = join13(
23788
+ const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
23789
+ const temporaryPath = join14(
23489
23790
  connectionsDirectory,
23490
23791
  `.${channelId}.${randomUUID()}.tmp`
23491
23792
  );
@@ -23508,7 +23809,7 @@ async function persistConnection(channelId, relayOrigin, daemonToken, defaultWor
23508
23809
  return connectionPath;
23509
23810
  }
23510
23811
  function decodeSavedConnection(value, expectedChannelId) {
23511
- if (!isRecord5(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
23812
+ if (!isRecord4(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
23512
23813
  throw new PairingClientError(
23513
23814
  "invalid_connection",
23514
23815
  "The saved connection is invalid"
@@ -23532,13 +23833,13 @@ function decodeSavedConnection(value, expectedChannelId) {
23532
23833
  };
23533
23834
  }
23534
23835
  async function readSavedConnection(channelId) {
23535
- const connectionPath = join13(
23836
+ const connectionPath = join14(
23536
23837
  readStateDirectory(),
23537
23838
  "connections",
23538
23839
  `${channelId}.json`
23539
23840
  );
23540
23841
  let encoded = "";
23541
- const handle = await open6(connectionPath, "r");
23842
+ const handle = await open5(connectionPath, "r");
23542
23843
  try {
23543
23844
  const metadata = await handle.stat();
23544
23845
  if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
@@ -23587,7 +23888,7 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
23587
23888
  );
23588
23889
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
23589
23890
  relayUrl.searchParams.set("token", connection.daemonToken);
23590
- const auditDatabasePath = join13(
23891
+ const auditDatabasePath = join14(
23591
23892
  readStateDirectory(),
23592
23893
  "audit",
23593
23894
  `${connection.channelId}.sqlite`
@@ -23646,7 +23947,7 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
23646
23947
  }
23647
23948
  async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
23648
23949
  const channelId = parseChannelArgument(arguments_);
23649
- const connectionPath = join13(
23950
+ const connectionPath = join14(
23650
23951
  readStateDirectory(),
23651
23952
  "connections",
23652
23953
  `${channelId}.json`
@@ -23668,7 +23969,7 @@ import { WebSocket as WebSocket2 } from "undici";
23668
23969
  // src/acp/session-manager.ts
23669
23970
  import { spawn as spawn3 } from "node:child_process";
23670
23971
  import {
23671
- methods as methods4,
23972
+ methods as methods5,
23672
23973
  ndJsonStream as ndJsonStream2,
23673
23974
  PROTOCOL_VERSION as PROTOCOL_VERSION2,
23674
23975
  RequestError as RequestError2
@@ -23676,7 +23977,7 @@ import {
23676
23977
 
23677
23978
  // src/acp/activity.ts
23678
23979
  var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
23679
- function isRecord6(value) {
23980
+ function isRecord5(value) {
23680
23981
  return typeof value === "object" && value !== null && !Array.isArray(value);
23681
23982
  }
23682
23983
  var AcpActivity = class _AcpActivity {
@@ -23950,7 +24251,7 @@ function contentPhase(content) {
23950
24251
  return "";
23951
24252
  }
23952
24253
  const codex = metadata["codex"];
23953
- if (!isRecord6(codex)) {
24254
+ if (!isRecord5(codex)) {
23954
24255
  return "";
23955
24256
  }
23956
24257
  const phase = codex["phase"];
@@ -24584,7 +24885,7 @@ function createWritableAcpStream(output2) {
24584
24885
  function truncate2(value, maximumLength) {
24585
24886
  return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
24586
24887
  }
24587
- function isRecord7(value) {
24888
+ function isRecord6(value) {
24588
24889
  return typeof value === "object" && value !== null && !Array.isArray(value);
24589
24890
  }
24590
24891
  function readString3(value, fallback = "") {
@@ -24614,7 +24915,7 @@ function normalizeConfigValues(value) {
24614
24915
  }
24615
24916
  const normalized = [];
24616
24917
  for (const entry of value) {
24617
- if (!isRecord7(entry)) {
24918
+ if (!isRecord6(entry)) {
24618
24919
  continue;
24619
24920
  }
24620
24921
  const groupedOptions = entry["options"];
@@ -24622,7 +24923,7 @@ function normalizeConfigValues(value) {
24622
24923
  const groupId = readString3(entry["group"]);
24623
24924
  const groupName = readString3(entry["name"]);
24624
24925
  for (const groupedOption of groupedOptions) {
24625
- if (isRecord7(groupedOption)) {
24926
+ if (isRecord6(groupedOption)) {
24626
24927
  normalized.push(
24627
24928
  normalizeConfigValue(groupedOption, groupId, groupName)
24628
24929
  );
@@ -24638,7 +24939,7 @@ function normalizeConfigOptions(value, modes) {
24638
24939
  const normalized = [];
24639
24940
  if (Array.isArray(value)) {
24640
24941
  for (const option of value) {
24641
- if (!isRecord7(option)) {
24942
+ if (!isRecord6(option)) {
24642
24943
  continue;
24643
24944
  }
24644
24945
  const id = truncate2(readString3(option["id"]), 128);
@@ -24677,12 +24978,12 @@ function normalizeConfigOptions(value, modes) {
24677
24978
  }
24678
24979
  }
24679
24980
  }
24680
- if (isRecord7(modes)) {
24981
+ if (isRecord6(modes)) {
24681
24982
  const values = [];
24682
24983
  const availableModes = modes["availableModes"];
24683
24984
  if (Array.isArray(availableModes)) {
24684
24985
  for (const mode of availableModes) {
24685
- if (!isRecord7(mode)) {
24986
+ if (!isRecord6(mode)) {
24686
24987
  continue;
24687
24988
  }
24688
24989
  const id = truncate2(readString3(mode["id"]), 500);
@@ -24760,7 +25061,7 @@ function normalizeElicitationOptions(schema) {
24760
25061
  const oneOf = schema["oneOf"];
24761
25062
  if (Array.isArray(oneOf)) {
24762
25063
  for (const option of oneOf) {
24763
- if (isRecord7(option) && typeof option["const"] === "string") {
25064
+ if (isRecord6(option) && typeof option["const"] === "string") {
24764
25065
  normalized.push({
24765
25066
  description: truncate2(readString3(option["description"]), 500),
24766
25067
  label: truncate2(readString3(option["title"], option["const"]), 255),
@@ -24780,7 +25081,7 @@ function normalizeElicitationOptions(schema) {
24780
25081
  return normalized.slice(0, 200);
24781
25082
  }
24782
25083
  const items = schema["items"];
24783
- if (!isRecord7(items)) {
25084
+ if (!isRecord6(items)) {
24784
25085
  return normalized;
24785
25086
  }
24786
25087
  const anyOf = items["anyOf"];
@@ -24793,7 +25094,7 @@ function numericString(value) {
24793
25094
  return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
24794
25095
  }
24795
25096
  function normalizeElicitationFields(requestedSchema) {
24796
- if (!isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
25097
+ if (!isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
24797
25098
  return [];
24798
25099
  }
24799
25100
  const properties = requestedSchema["properties"];
@@ -24803,7 +25104,7 @@ function normalizeElicitationFields(requestedSchema) {
24803
25104
  );
24804
25105
  const normalized = [];
24805
25106
  for (const [name, property] of Object.entries(properties)) {
24806
- if (!isRecord7(property)) {
25107
+ if (!isRecord6(property)) {
24807
25108
  continue;
24808
25109
  }
24809
25110
  const type = elicitationFieldType(property["type"]);
@@ -24898,7 +25199,7 @@ function validateElicitationContent(encoded, requestedSchema) {
24898
25199
  "invalid_elicitation_response"
24899
25200
  );
24900
25201
  }
24901
- if (!isRecord7(decoded) || !isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
25202
+ if (!isRecord6(decoded) || !isRecord6(requestedSchema) || !isRecord6(requestedSchema["properties"])) {
24902
25203
  throw new AcpExecutionError(
24903
25204
  "Elicitation response does not match the requested form",
24904
25205
  {},
@@ -24922,7 +25223,7 @@ function validateElicitationContent(encoded, requestedSchema) {
24922
25223
  const validated = {};
24923
25224
  for (const [name, value] of Object.entries(decoded)) {
24924
25225
  const property = properties[name];
24925
- if (!isRecord7(property)) {
25226
+ if (!isRecord6(property)) {
24926
25227
  throw new AcpExecutionError(
24927
25228
  `Elicitation field ${name} was not requested`,
24928
25229
  {},
@@ -25213,7 +25514,7 @@ var AcpProcessSession = class _AcpProcessSession {
25213
25514
  try {
25214
25515
  await this.race(
25215
25516
  this.#connection.agent.request(
25216
- methods4.agent.session.load,
25517
+ methods5.agent.session.load,
25217
25518
  {
25218
25519
  additionalDirectories: [...this.#additionalDirectories],
25219
25520
  cwd: this.#cwd,
@@ -25235,7 +25536,7 @@ var AcpProcessSession = class _AcpProcessSession {
25235
25536
  async #initializeAgent(signal) {
25236
25537
  const initialized = await this.race(
25237
25538
  this.#connection.agent.request(
25238
- methods4.agent.initialize,
25539
+ methods5.agent.initialize,
25239
25540
  {
25240
25541
  clientCapabilities: {
25241
25542
  elicitation: { form: {}, url: {} },
@@ -25303,7 +25604,7 @@ var AcpProcessSession = class _AcpProcessSession {
25303
25604
  );
25304
25605
  const forked = await this.race(
25305
25606
  this.#connection.agent.request(
25306
- methods4.agent.session.fork,
25607
+ methods5.agent.session.fork,
25307
25608
  {
25308
25609
  sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
25309
25610
  cwd: this.#cwd,
@@ -25336,7 +25637,7 @@ var AcpProcessSession = class _AcpProcessSession {
25336
25637
  if (this.#capabilities.resumeSession) {
25337
25638
  lifecycleResponse = await this.race(
25338
25639
  this.#connection.agent.request(
25339
- methods4.agent.session.resume,
25640
+ methods5.agent.session.resume,
25340
25641
  {
25341
25642
  additionalDirectories: [...this.#additionalDirectories],
25342
25643
  cwd: this.#cwd,
@@ -25353,7 +25654,7 @@ var AcpProcessSession = class _AcpProcessSession {
25353
25654
  try {
25354
25655
  lifecycleResponse = await this.race(
25355
25656
  this.#connection.agent.request(
25356
- methods4.agent.session.load,
25657
+ methods5.agent.session.load,
25357
25658
  {
25358
25659
  additionalDirectories: [...this.#additionalDirectories],
25359
25660
  cwd: this.#cwd,
@@ -25389,7 +25690,7 @@ var AcpProcessSession = class _AcpProcessSession {
25389
25690
  }
25390
25691
  const created = await this.race(
25391
25692
  this.#connection.agent.request(
25392
- methods4.agent.session.new,
25693
+ methods5.agent.session.new,
25393
25694
  {
25394
25695
  additionalDirectories: [...this.#additionalDirectories],
25395
25696
  cwd: this.#cwd,
@@ -25403,7 +25704,7 @@ var AcpProcessSession = class _AcpProcessSession {
25403
25704
  this.selectNativeSession(created.sessionId);
25404
25705
  lifecycleResponse = created;
25405
25706
  }
25406
- const lifecycleRecord = isRecord7(lifecycleResponse) ? lifecycleResponse : {};
25707
+ const lifecycleRecord = isRecord6(lifecycleResponse) ? lifecycleResponse : {};
25407
25708
  this.#configOptions = normalizeConfigOptions(
25408
25709
  lifecycleRecord["configOptions"],
25409
25710
  lifecycleRecord["modes"]
@@ -25432,7 +25733,7 @@ var AcpProcessSession = class _AcpProcessSession {
25432
25733
  );
25433
25734
  const response = await this.race(
25434
25735
  this.#connection.agent.request(
25435
- methods4.agent.session.list,
25736
+ methods5.agent.session.list,
25436
25737
  cursor === null ? {} : { cursor },
25437
25738
  { cancellationSignal: signal }
25438
25739
  ),
@@ -25457,7 +25758,7 @@ var AcpProcessSession = class _AcpProcessSession {
25457
25758
  );
25458
25759
  await this.race(
25459
25760
  this.#connection.agent.request(
25460
- methods4.agent.session.delete,
25761
+ methods5.agent.session.delete,
25461
25762
  { sessionId: nativeSessionIdSchema.parse(nativeSessionId) },
25462
25763
  { cancellationSignal: signal }
25463
25764
  ),
@@ -25488,7 +25789,7 @@ var AcpProcessSession = class _AcpProcessSession {
25488
25789
  if (existing.category === "mode") {
25489
25790
  await this.race(
25490
25791
  this.#connection.agent.request(
25491
- methods4.agent.session.setMode,
25792
+ methods5.agent.session.setMode,
25492
25793
  { modeId: options.value, sessionId: this.#nativeSessionId },
25493
25794
  { cancellationSignal: options.signal }
25494
25795
  ),
@@ -25501,7 +25802,7 @@ var AcpProcessSession = class _AcpProcessSession {
25501
25802
  } else {
25502
25803
  const response = await this.race(
25503
25804
  this.#connection.agent.request(
25504
- methods4.agent.session.setConfigOption,
25805
+ methods5.agent.session.setConfigOption,
25505
25806
  {
25506
25807
  configId: existing.id,
25507
25808
  sessionId: this.#nativeSessionId,
@@ -25520,7 +25821,7 @@ var AcpProcessSession = class _AcpProcessSession {
25520
25821
  } else {
25521
25822
  const response = await this.race(
25522
25823
  this.#connection.agent.request(
25523
- methods4.agent.session.setConfigOption,
25824
+ methods5.agent.session.setConfigOption,
25524
25825
  {
25525
25826
  configId: existing.id,
25526
25827
  sessionId: this.#nativeSessionId,
@@ -25619,7 +25920,7 @@ var AcpProcessSession = class _AcpProcessSession {
25619
25920
  try {
25620
25921
  const response = await this.race(
25621
25922
  this.#connection.agent.request(
25622
- methods4.agent.session.prompt,
25923
+ methods5.agent.session.prompt,
25623
25924
  { prompt, sessionId: this.#nativeSessionId },
25624
25925
  { cancellationSignal: options.signal }
25625
25926
  ),
@@ -25666,7 +25967,7 @@ var AcpProcessSession = class _AcpProcessSession {
25666
25967
  try {
25667
25968
  await this.cancelPendingInteractions();
25668
25969
  if (this.#turn.running) {
25669
- await this.#connection.agent.notify(methods4.agent.session.cancel, {
25970
+ await this.#connection.agent.notify(methods5.agent.session.cancel, {
25670
25971
  sessionId: this.#nativeSessionId
25671
25972
  });
25672
25973
  }
@@ -26022,7 +26323,7 @@ var AcpProcessSession = class _AcpProcessSession {
26022
26323
  if (this.#capabilities.closeSession && this.#nativeSessionId.length > 0) {
26023
26324
  try {
26024
26325
  await this.#connection.agent.request(
26025
- methods4.agent.session.close,
26326
+ methods5.agent.session.close,
26026
26327
  { sessionId: this.#nativeSessionId },
26027
26328
  {
26028
26329
  cancellationSignal: AbortSignal.timeout(
@@ -26659,8 +26960,7 @@ async function publishAgentCatalog(config2, signal) {
26659
26960
  })),
26660
26961
  installableAgents: catalog.installableAgents.map((agent) => ({
26661
26962
  id: agent.id,
26662
- label: agent.label,
26663
- requiresLocalApproval: agent.requiresLocalApproval
26963
+ label: agent.label
26664
26964
  }))
26665
26965
  }),
26666
26966
  dispatcher: environmentProxyDispatcher,
@@ -26701,12 +27001,6 @@ var RequestedInstallation = class extends AgentInstallation {
26701
27001
  super(requestId, agentId);
26702
27002
  }
26703
27003
  };
26704
- var AwaitingLocalApproval = class extends AgentInstallation {
26705
- status = "awaiting_local_approval";
26706
- constructor(requestId, agentId) {
26707
- super(requestId, agentId);
26708
- }
26709
- };
26710
27004
  var RunningInstallation = class extends AgentInstallation {
26711
27005
  stage;
26712
27006
  status = "running";
@@ -26761,9 +27055,9 @@ var InstallationJob = class {
26761
27055
  this.state = new RequestedInstallation(requestId, agentId);
26762
27056
  }
26763
27057
  };
26764
- function specificationFor(specifications, agentId) {
27058
+ function authorizedSpecificationFor(specifications, agentId) {
26765
27059
  for (const specification of specifications) {
26766
- if (specification.id === agentId) {
27060
+ if (specification.id === agentId && specification.supportsInstallation(process.platform, process.arch)) {
26767
27061
  return specification;
26768
27062
  }
26769
27063
  }
@@ -26782,14 +27076,12 @@ function executionFailure(error61) {
26782
27076
  var AgentInstallationManager = class {
26783
27077
  #activeAgents = /* @__PURE__ */ new Map();
26784
27078
  #audit;
26785
- #authorizer;
26786
27079
  #executor;
26787
27080
  #jobs = /* @__PURE__ */ new Map();
26788
27081
  #observer;
26789
27082
  #specifications;
26790
- constructor(specifications, authorizer, executor, observer, audit = new NullInstallationAudit()) {
27083
+ constructor(specifications, executor, observer, audit = new NullInstallationAudit()) {
26791
27084
  this.#audit = audit;
26792
- this.#authorizer = authorizer;
26793
27085
  this.#executor = executor;
26794
27086
  this.#observer = observer;
26795
27087
  this.#specifications = Object.freeze([...specifications]);
@@ -26820,7 +27112,7 @@ var AgentInstallationManager = class {
26820
27112
  command.requestId,
26821
27113
  command.agentId
26822
27114
  );
26823
- const specification = specificationFor(
27115
+ const specification = authorizedSpecificationFor(
26824
27116
  this.#specifications,
26825
27117
  command.agentId
26826
27118
  );
@@ -26923,45 +27215,14 @@ var AgentInstallationManager = class {
26923
27215
  }, INSTALLATION_DEADLINE_MILLISECONDS);
26924
27216
  const signal = job.controller.signal;
26925
27217
  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
27218
  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
27219
  this.#audit.record(
26959
27220
  "agent_installation_authorized",
26960
27221
  job.requestId,
26961
- job.agentId
27222
+ specification.id
26962
27223
  );
26963
27224
  await this.#executor.execute(
26964
- job.agentId,
27225
+ specification.id,
26965
27226
  job.requestId,
26966
27227
  async (stage) => {
26967
27228
  signal.throwIfAborted();
@@ -27231,12 +27492,10 @@ import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27231
27492
  import { resolve as resolve4 } from "node:path";
27232
27493
 
27233
27494
  // 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";
27495
+ import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
27496
+ import { join as join17 } from "node:path";
27497
+
27498
+ // src/agent-installation/fixed-agent-install-recipe.ts
27240
27499
  var FixedAgentInstallRecipe = class {
27241
27500
  assertSupportedPlatform = () => {
27242
27501
  if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
@@ -27257,28 +27516,243 @@ var FixedAgentInstallRecipe = class {
27257
27516
  return executable;
27258
27517
  };
27259
27518
  };
27519
+
27520
+ // src/agent-installation/grok-build-install-recipe.ts
27521
+ import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27522
+ import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute6, join as join15, relative as relative4, sep as sep4 } from "node:path";
27523
+ var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
27524
+ function isContainedPath4(root, candidate) {
27525
+ const difference = relative4(root, candidate);
27526
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute6(difference);
27527
+ }
27528
+ async function resolveLifecycleScript(packageRoot) {
27529
+ try {
27530
+ const canonicalPackageRoot = await realpath7(packageRoot);
27531
+ const script = await realpath7(
27532
+ join15(canonicalPackageRoot, "bin", "postinstall.js")
27533
+ );
27534
+ const metadata = await stat6(script);
27535
+ if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
27536
+ throw new Error("Invalid Grok Build lifecycle script");
27537
+ }
27538
+ return script;
27539
+ } catch (error61) {
27540
+ throw new InstallationManagerError(
27541
+ "agent_verification_failed",
27542
+ "The managed Grok Build lifecycle script is invalid",
27543
+ { cause: error61 }
27544
+ );
27545
+ }
27546
+ }
27547
+ var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
27548
+ #npmInstaller;
27549
+ id = "grok-build";
27550
+ label = "Grok Build";
27551
+ releaseChannel = GROK_BUILD_MANAGED_VERSION;
27552
+ constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27553
+ super();
27554
+ this.#npmInstaller = npmInstaller;
27555
+ }
27556
+ install = async (options) => {
27557
+ this.assertSupportedPlatform();
27558
+ const definition = grokBuildManagedPackage(process.platform, process.arch);
27559
+ const versionRoot = join15(
27560
+ options.stateDirectory,
27561
+ "agents",
27562
+ this.id,
27563
+ GROK_BUILD_MANAGED_VERSION
27564
+ );
27565
+ const packageRoot = join15(versionRoot, "package");
27566
+ const managedHome = join15(versionRoot, "home");
27567
+ try {
27568
+ await mkdir4(managedHome, { mode: 448, recursive: true });
27569
+ const canonicalHome = await realpath7(managedHome);
27570
+ await options.report("downloading");
27571
+ await options.report("verifying");
27572
+ await options.report("installing_agent");
27573
+ await this.#npmInstaller.install(
27574
+ packageRoot,
27575
+ definition,
27576
+ options.environment,
27577
+ options.signal
27578
+ );
27579
+ options.audit.record(
27580
+ "agent_npm_package_verified",
27581
+ options.requestId,
27582
+ this.id,
27583
+ {
27584
+ integrity: definition.integrity,
27585
+ package: definition.packageName,
27586
+ version: definition.version
27587
+ }
27588
+ );
27589
+ const script = await resolveLifecycleScript(
27590
+ join15(packageRoot, "node_modules", "@xai-official", "grok")
27591
+ );
27592
+ await runBoundedProcess({
27593
+ arguments: [script],
27594
+ command: process.execPath,
27595
+ cwd: dirname5(script),
27596
+ environment: {
27597
+ GROK_HOME: canonicalHome,
27598
+ GROK_INSTALL_COMPLETIONS: "0",
27599
+ GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
27600
+ HOME: canonicalHome,
27601
+ PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
27602
+ },
27603
+ outputLimitBytes: 64 * 1024,
27604
+ signal: options.signal,
27605
+ timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
27606
+ });
27607
+ options.audit.record(
27608
+ "agent_lifecycle_step_completed",
27609
+ options.requestId,
27610
+ this.id,
27611
+ {
27612
+ lifecycle: "postinstall",
27613
+ package: definition.packageName,
27614
+ version: definition.version
27615
+ }
27616
+ );
27617
+ return await this.requireInstalledExecutable(
27618
+ join15(canonicalHome, "bin", "grok")
27619
+ );
27620
+ } catch (error61) {
27621
+ if (options.signal.aborted) {
27622
+ options.signal.throwIfAborted();
27623
+ }
27624
+ if (error61 instanceof ManagedNpmPackageError) {
27625
+ if (error61.code === "managed_package_verification_failed") {
27626
+ throw new InstallationManagerError(
27627
+ "agent_verification_failed",
27628
+ "The managed Grok Build packages did not match their pinned artifacts",
27629
+ { cause: error61 }
27630
+ );
27631
+ }
27632
+ if (error61.code === "managed_package_publish_failed") {
27633
+ throw new InstallationManagerError(
27634
+ "agent_publish_failed",
27635
+ "The managed Grok Build package could not be published",
27636
+ { cause: error61 }
27637
+ );
27638
+ }
27639
+ throw new InstallationManagerError(error61.code, error61.message, {
27640
+ cause: error61
27641
+ });
27642
+ }
27643
+ if (error61 instanceof InstallationManagerError) {
27644
+ throw error61;
27645
+ }
27646
+ throw new InstallationManagerError(
27647
+ "agent_install_failed",
27648
+ "The fixed Grok Build installation recipe failed",
27649
+ { cause: error61 }
27650
+ );
27651
+ }
27652
+ };
27653
+ };
27654
+
27655
+ // src/agent-installation/workbuddy-install-recipe.ts
27656
+ import { join as join16 } from "node:path";
27657
+ var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
27658
+ #npmInstaller;
27659
+ id = "workbuddy";
27660
+ label = "WorkBuddy";
27661
+ releaseChannel = WORKBUDDY_MANAGED_VERSION;
27662
+ constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27663
+ super();
27664
+ this.#npmInstaller = npmInstaller;
27665
+ }
27666
+ install = async (options) => {
27667
+ this.assertSupportedPlatform();
27668
+ try {
27669
+ await options.report("downloading");
27670
+ await options.report("verifying");
27671
+ await options.report("installing_agent");
27672
+ const executable = await this.#npmInstaller.install(
27673
+ join16(
27674
+ options.stateDirectory,
27675
+ "agents",
27676
+ this.id,
27677
+ WORKBUDDY_MANAGED_VERSION
27678
+ ),
27679
+ WORKBUDDY_MANAGED_PACKAGE,
27680
+ options.environment,
27681
+ options.signal
27682
+ );
27683
+ options.audit.record(
27684
+ "agent_npm_package_verified",
27685
+ options.requestId,
27686
+ this.id,
27687
+ {
27688
+ integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
27689
+ package: WORKBUDDY_MANAGED_PACKAGE.packageName,
27690
+ version: WORKBUDDY_MANAGED_PACKAGE.version
27691
+ }
27692
+ );
27693
+ return executable;
27694
+ } catch (error61) {
27695
+ if (options.signal.aborted) {
27696
+ options.signal.throwIfAborted();
27697
+ }
27698
+ if (error61 instanceof ManagedNpmPackageError) {
27699
+ if (error61.code === "managed_package_verification_failed") {
27700
+ throw new InstallationManagerError(
27701
+ "agent_verification_failed",
27702
+ "The managed WorkBuddy package did not match its pinned artifact",
27703
+ { cause: error61 }
27704
+ );
27705
+ }
27706
+ if (error61.code === "managed_package_publish_failed") {
27707
+ throw new InstallationManagerError(
27708
+ "agent_publish_failed",
27709
+ "The managed WorkBuddy package could not be published",
27710
+ { cause: error61 }
27711
+ );
27712
+ }
27713
+ throw new InstallationManagerError(error61.code, error61.message, {
27714
+ cause: error61
27715
+ });
27716
+ }
27717
+ if (error61 instanceof InstallationManagerError) {
27718
+ throw error61;
27719
+ }
27720
+ throw new InstallationManagerError(
27721
+ "agent_install_failed",
27722
+ "The fixed WorkBuddy installation recipe failed",
27723
+ { cause: error61 }
27724
+ );
27725
+ }
27726
+ };
27727
+ };
27728
+
27729
+ // src/agent-installation/fixed-agent-install-recipes.ts
27730
+ var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
27731
+ var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
27732
+ var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
27733
+ var MINIMAL_PATH2 = "/usr/bin:/bin";
27260
27734
  var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
27261
27735
  id = "codex";
27262
27736
  label = "Codex";
27263
27737
  releaseChannel = "latest";
27264
27738
  install = async (options) => {
27265
27739
  this.assertSupportedPlatform();
27266
- const root = join14(options.stateDirectory, "agents", this.id);
27267
- const temporaryRoot = join14(options.stateDirectory, "temporary");
27740
+ const root = join17(options.stateDirectory, "agents", this.id);
27741
+ const temporaryRoot = join17(options.stateDirectory, "temporary");
27268
27742
  await Promise.all([
27269
- mkdir4(root, { mode: 448, recursive: true }),
27270
- mkdir4(temporaryRoot, { mode: 448, recursive: true })
27743
+ mkdir5(root, { mode: 448, recursive: true }),
27744
+ mkdir5(temporaryRoot, { mode: 448, recursive: true })
27271
27745
  ]);
27272
27746
  const temporaryDirectory = await mkdtemp3(
27273
- join14(temporaryRoot, ".codex-install-")
27747
+ join17(temporaryRoot, ".codex-install-")
27274
27748
  );
27275
- const installerPath = join14(temporaryDirectory, "install.sh");
27276
- const installDirectory = join14(root, "bin");
27277
- const codexHome = join14(root, "home");
27749
+ const installerPath = join17(temporaryDirectory, "install.sh");
27750
+ const installDirectory = join17(root, "bin");
27751
+ const codexHome = join17(root, "home");
27278
27752
  try {
27279
27753
  await Promise.all([
27280
- mkdir4(installDirectory, { mode: 448, recursive: true }),
27281
- mkdir4(codexHome, { mode: 448, recursive: true })
27754
+ mkdir5(installDirectory, { mode: 448, recursive: true }),
27755
+ mkdir5(codexHome, { mode: 448, recursive: true })
27282
27756
  ]);
27283
27757
  await options.report("downloading");
27284
27758
  const download = await downloadVerifiedFile({
@@ -27318,7 +27792,7 @@ var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
27318
27792
  timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
27319
27793
  });
27320
27794
  return await this.requireInstalledExecutable(
27321
- join14(installDirectory, "codex")
27795
+ join17(installDirectory, "codex")
27322
27796
  );
27323
27797
  } catch (error61) {
27324
27798
  if (options.signal.aborted) {
@@ -27342,17 +27816,17 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27342
27816
  releaseChannel = "stable";
27343
27817
  install = async (options) => {
27344
27818
  this.assertSupportedPlatform();
27345
- const root = join14(options.stateDirectory, "agents", this.id);
27346
- const managedHome = join14(root, "home");
27347
- const temporaryRoot = join14(options.stateDirectory, "temporary");
27819
+ const root = join17(options.stateDirectory, "agents", this.id);
27820
+ const managedHome = join17(root, "home");
27821
+ const temporaryRoot = join17(options.stateDirectory, "temporary");
27348
27822
  await Promise.all([
27349
- mkdir4(managedHome, { mode: 448, recursive: true }),
27350
- mkdir4(temporaryRoot, { mode: 448, recursive: true })
27823
+ mkdir5(managedHome, { mode: 448, recursive: true }),
27824
+ mkdir5(temporaryRoot, { mode: 448, recursive: true })
27351
27825
  ]);
27352
27826
  const temporaryDirectory = await mkdtemp3(
27353
- join14(temporaryRoot, ".claude-install-")
27827
+ join17(temporaryRoot, ".claude-install-")
27354
27828
  );
27355
- const installerPath = join14(temporaryDirectory, "install.sh");
27829
+ const installerPath = join17(temporaryDirectory, "install.sh");
27356
27830
  try {
27357
27831
  await options.report("downloading");
27358
27832
  const download = await downloadVerifiedFile({
@@ -27389,7 +27863,7 @@ var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27389
27863
  timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
27390
27864
  });
27391
27865
  return await this.requireInstalledExecutable(
27392
- join14(managedHome, ".local", "bin", "claude")
27866
+ join17(managedHome, ".local", "bin", "claude")
27393
27867
  );
27394
27868
  } catch (error61) {
27395
27869
  if (options.signal.aborted) {
@@ -27423,7 +27897,7 @@ var PiInstallRecipe = class extends FixedAgentInstallRecipe {
27423
27897
  await options.report("verifying");
27424
27898
  await options.report("installing_agent");
27425
27899
  const executable = await this.#npmInstaller.install(
27426
- join14(
27900
+ join17(
27427
27901
  options.stateDirectory,
27428
27902
  "agents",
27429
27903
  this.id,
@@ -27490,18 +27964,18 @@ var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
27490
27964
  install = async (options) => {
27491
27965
  this.assertSupportedPlatform();
27492
27966
  try {
27493
- const managedHome = join14(
27967
+ const managedHome = join17(
27494
27968
  options.stateDirectory,
27495
27969
  "agents",
27496
27970
  this.id,
27497
27971
  "home"
27498
27972
  );
27499
- await mkdir4(managedHome, { mode: 448, recursive: true });
27973
+ await mkdir5(managedHome, { mode: 448, recursive: true });
27500
27974
  await options.report("downloading");
27501
27975
  await options.report("verifying");
27502
27976
  await options.report("installing_agent");
27503
27977
  const executable = await this.#npmInstaller.install(
27504
- join14(
27978
+ join17(
27505
27979
  options.stateDirectory,
27506
27980
  "agents",
27507
27981
  this.id,
@@ -27573,7 +28047,7 @@ var OpenCodeInstallRecipe = class extends FixedAgentInstallRecipe {
27573
28047
  await options.report("verifying");
27574
28048
  await options.report("installing_agent");
27575
28049
  const executable = await this.#archiveInstaller.install(
27576
- join14(
28050
+ join17(
27577
28051
  options.stateDirectory,
27578
28052
  "agents",
27579
28053
  this.id,
@@ -27632,7 +28106,9 @@ function fixedAgentInstallRecipes() {
27632
28106
  new ClaudeCodeInstallRecipe(),
27633
28107
  new PiInstallRecipe(),
27634
28108
  new DeepSeekHarnessInstallRecipe(),
27635
- new OpenCodeInstallRecipe()
28109
+ new OpenCodeInstallRecipe(),
28110
+ new GrokBuildInstallRecipe(),
28111
+ new WorkBuddyInstallRecipe()
27636
28112
  ]);
27637
28113
  }
27638
28114
 
@@ -27873,41 +28349,6 @@ var FixedInstallationExecutor = class {
27873
28349
  };
27874
28350
  };
27875
28351
 
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
28352
  // src/authorization/local-authorization-error.ts
27912
28353
  var LocalAuthorizationError = class extends Error {
27913
28354
  code = "local_authorization_failed";
@@ -27918,15 +28359,15 @@ var LocalAuthorizationError = class extends Error {
27918
28359
  };
27919
28360
 
27920
28361
  // src/authorization/workspace-directory.ts
27921
- import { readdir, realpath as realpath6, stat as stat6 } from "node:fs/promises";
28362
+ import { readdir, realpath as realpath8, stat as stat7 } from "node:fs/promises";
27922
28363
  import { homedir as homedir2 } from "node:os";
27923
28364
  import {
27924
28365
  basename as basename2,
27925
- dirname as dirname5,
27926
- isAbsolute as isAbsolute5,
27927
- join as join15,
28366
+ dirname as dirname6,
28367
+ isAbsolute as isAbsolute7,
28368
+ join as join18,
27928
28369
  normalize as normalize2,
27929
- relative as relative3
28370
+ relative as relative5
27930
28371
  } from "node:path";
27931
28372
  var WorkspaceDirectoryListing = class {
27932
28373
  directoryId;
@@ -27976,20 +28417,20 @@ var WorkspaceDirectoryService = class {
27976
28417
  if (id === "home") return homedir2();
27977
28418
  if (id.startsWith("path-")) {
27978
28419
  const path2 = decodePath(id, "path-");
27979
- if (isAbsolute5(path2)) return path2;
28420
+ if (isAbsolute7(path2)) return path2;
27980
28421
  }
27981
28422
  throw new LocalAuthorizationError("The directory identifier is invalid");
27982
28423
  };
27983
28424
  resolvePath = async (requested, signal) => {
27984
28425
  signal.throwIfAborted();
27985
- if (!isAbsolute5(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28426
+ if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
27986
28427
  throw new LocalAuthorizationError("The local directory path is invalid");
27987
28428
  try {
27988
- const target = await realpath6(requested);
28429
+ const target = await realpath8(requested);
27989
28430
  signal.throwIfAborted();
27990
- const metadata = await stat6(target);
28431
+ const metadata = await stat7(target);
27991
28432
  signal.throwIfAborted();
27992
- if (!isAbsolute5(target) || normalize2(target) !== target || !metadata.isDirectory())
28433
+ if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
27993
28434
  throw new LocalAuthorizationError(
27994
28435
  "The selected location is not a directory"
27995
28436
  );
@@ -28004,8 +28445,8 @@ var WorkspaceDirectoryService = class {
28004
28445
  }
28005
28446
  };
28006
28447
  label = (path2) => {
28007
- const suffix = relative3(homedir2(), path2);
28008
- return suffix === "" ? "~" : !isAbsolute5(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28448
+ const suffix = relative5(homedir2(), path2);
28449
+ return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28009
28450
  };
28010
28451
  identify = async (bindingId, requestedPath, signal) => {
28011
28452
  this.authorizeMachine(bindingId);
@@ -28033,7 +28474,7 @@ var WorkspaceDirectoryService = class {
28033
28474
  continue;
28034
28475
  }
28035
28476
  try {
28036
- const path2 = await this.resolvePath(join15(target, child.name), signal);
28477
+ const path2 = await this.resolvePath(join18(target, child.name), signal);
28037
28478
  entries.push({ directoryId: encodePath(path2), name: child.name });
28038
28479
  } catch (cause) {
28039
28480
  signal.throwIfAborted();
@@ -28041,7 +28482,7 @@ var WorkspaceDirectoryService = class {
28041
28482
  }
28042
28483
  }
28043
28484
  entries.sort((a, b) => a.name.localeCompare(b.name));
28044
- const parent = dirname5(target);
28485
+ const parent = dirname6(target);
28045
28486
  return new WorkspaceDirectoryListing(
28046
28487
  id,
28047
28488
  this.label(target),
@@ -28834,7 +29275,7 @@ var RelayConnectionLiveness = class {
28834
29275
 
28835
29276
  // src/relay-connection/session-event-outbox.ts
28836
29277
  import { mkdirSync as mkdirSync3 } from "node:fs";
28837
- import { dirname as dirname6 } from "node:path";
29278
+ import { dirname as dirname7 } from "node:path";
28838
29279
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
28839
29280
  function readPendingEnvelope(row) {
28840
29281
  if (typeof row !== "object" || row === null || Array.isArray(row)) {
@@ -28849,7 +29290,7 @@ function readPendingEnvelope(row) {
28849
29290
  var SessionEventOutbox = class {
28850
29291
  #database;
28851
29292
  constructor(path2) {
28852
- mkdirSync3(dirname6(path2), { recursive: true });
29293
+ mkdirSync3(dirname7(path2), { recursive: true });
28853
29294
  this.#database = new DatabaseSync3(path2);
28854
29295
  this.#database.exec(`
28855
29296
  CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
@@ -29141,17 +29582,6 @@ var DaemonInstallationObserver = class {
29141
29582
  if (state instanceof RequestedInstallation) {
29142
29583
  return Promise.resolve();
29143
29584
  }
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
29585
  if (state instanceof RunningInstallation) {
29156
29586
  if (!this.#started.has(state.requestId)) {
29157
29587
  this.#started.add(state.requestId);
@@ -30048,7 +30478,6 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30048
30478
  );
30049
30479
  const installations = new AgentInstallationManager(
30050
30480
  specifications,
30051
- new ConsoleInstallationAuthorizer(stateDirectory),
30052
30481
  installationExecutor,
30053
30482
  installationObserver,
30054
30483
  installationAudit
@@ -30156,7 +30585,7 @@ async function main() {
30156
30585
  if (arguments_.length > 1 || arguments_.length === 1 && arguments_[0] !== "--json") {
30157
30586
  throw new Error("Usage: mobius agents [--json]");
30158
30587
  }
30159
- await mkdir5(loadDefaultWorkspace(), { recursive: true, mode: 448 });
30588
+ await mkdir6(loadDefaultWorkspace(), { recursive: true, mode: 448 });
30160
30589
  const inventory = await discoverLocalAgentInventory({
30161
30590
  defaultWorkspace: loadDefaultWorkspace(),
30162
30591
  environment: process.env,