@moxt-ai/mobius 0.0.28 → 0.0.30

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 (59) hide show
  1. package/dist/agent-catalog/acp-readiness-probe.d.ts.map +1 -1
  2. package/dist/agent-catalog/acp-readiness-probe.js +2 -2
  3. package/dist/agent-catalog/acp-readiness-probe.js.map +1 -1
  4. package/dist/agent-catalog/agent-specification.d.ts +3 -0
  5. package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
  6. package/dist/agent-catalog/agent-specification.js +3 -0
  7. package/dist/agent-catalog/agent-specification.js.map +1 -1
  8. package/dist/agent-catalog/agents/copilot-cli-agent.d.ts +18 -0
  9. package/dist/agent-catalog/agents/copilot-cli-agent.d.ts.map +1 -0
  10. package/dist/agent-catalog/agents/copilot-cli-agent.js +29 -0
  11. package/dist/agent-catalog/agents/copilot-cli-agent.js.map +1 -0
  12. package/dist/agent-catalog/agents/gemini-cli-agent.d.ts +14 -0
  13. package/dist/agent-catalog/agents/gemini-cli-agent.d.ts.map +1 -0
  14. package/dist/agent-catalog/agents/gemini-cli-agent.js +30 -0
  15. package/dist/agent-catalog/agents/gemini-cli-agent.js.map +1 -0
  16. package/dist/agent-catalog/agents/hermes-agent.d.ts +18 -0
  17. package/dist/agent-catalog/agents/hermes-agent.d.ts.map +1 -0
  18. package/dist/agent-catalog/agents/hermes-agent.js +32 -0
  19. package/dist/agent-catalog/agents/hermes-agent.js.map +1 -0
  20. package/dist/agent-catalog/agents/resolve-user-local-executable.d.ts +4 -0
  21. package/dist/agent-catalog/agents/resolve-user-local-executable.d.ts.map +1 -0
  22. package/dist/agent-catalog/agents/resolve-user-local-executable.js +14 -0
  23. package/dist/agent-catalog/agents/resolve-user-local-executable.js.map +1 -0
  24. package/dist/agent-catalog/agents/supported-agent-specifications.d.ts.map +1 -1
  25. package/dist/agent-catalog/agents/supported-agent-specifications.js +6 -0
  26. package/dist/agent-catalog/agents/supported-agent-specifications.js.map +1 -1
  27. package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
  28. package/dist/agent-catalog/discover-agent.js +2 -2
  29. package/dist/agent-catalog/discover-agent.js.map +1 -1
  30. package/dist/agent-catalog/discover-local-agents.d.ts +3 -0
  31. package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
  32. package/dist/agent-catalog/discover-local-agents.js +3 -0
  33. package/dist/agent-catalog/discover-local-agents.js.map +1 -1
  34. package/dist/agent-catalog/executable-discovery.d.ts +1 -2
  35. package/dist/agent-catalog/executable-discovery.d.ts.map +1 -1
  36. package/dist/agent-catalog/executable-discovery.js +4 -6
  37. package/dist/agent-catalog/executable-discovery.js.map +1 -1
  38. package/dist/agent-catalog/version-output.d.ts +2 -0
  39. package/dist/agent-catalog/version-output.d.ts.map +1 -0
  40. package/dist/agent-catalog/version-output.js +4 -0
  41. package/dist/agent-catalog/version-output.js.map +1 -0
  42. package/dist/bots/bot-approve-command.d.ts +2 -0
  43. package/dist/bots/bot-approve-command.d.ts.map +1 -0
  44. package/dist/bots/bot-approve-command.js +78 -0
  45. package/dist/bots/bot-approve-command.js.map +1 -0
  46. package/dist/bots/local-bot-grant-store.d.ts +7 -0
  47. package/dist/bots/local-bot-grant-store.d.ts.map +1 -1
  48. package/dist/bots/local-bot-grant-store.js +89 -0
  49. package/dist/bots/local-bot-grant-store.js.map +1 -1
  50. package/dist/cli.js +1300 -941
  51. package/dist/cli.js.map +4 -4
  52. package/dist/index.js +476 -236
  53. package/dist/index.js.map +4 -4
  54. package/dist/run-daemon.d.ts.map +1 -1
  55. package/dist/run-daemon.js +18 -14
  56. package/dist/run-daemon.js.map +1 -1
  57. package/dist/runtime.js +488 -246
  58. package/dist/runtime.js.map +4 -4
  59. package/package.json +1 -1
package/dist/runtime.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/runtime.ts
8
8
  import { mkdir as mkdir5, realpath as realpath9, stat as stat9 } from "node:fs/promises";
9
- import { dirname as dirname8, join as join17, resolve as resolve5 } from "node:path";
9
+ import { dirname as dirname8, join as join18, resolve as resolve5 } from "node:path";
10
10
 
11
11
  // src/agent-catalog/local-agent.ts
12
12
  import { realpathSync, statSync } from "node:fs";
@@ -1029,6 +1029,13 @@ var ManagedNpmPackageInstaller = class {
1029
1029
 
1030
1030
  // src/agent-catalog/agent-specification.ts
1031
1031
  import { join as join3 } from "node:path";
1032
+
1033
+ // src/agent-catalog/version-output.ts
1034
+ function normalizeVersionOutput(output2) {
1035
+ return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
1036
+ }
1037
+
1038
+ // src/agent-catalog/agent-specification.ts
1032
1039
  var VERSION_PROBE_TIMEOUT_MILLISECONDS = 3e3;
1033
1040
  var ACP_PROBE_TIMEOUT_MILLISECONDS = 5e3;
1034
1041
  var DEFAULT_PROMPT_TIMEOUT_MILLISECONDS = 30 * 60 * 1e3;
@@ -1037,6 +1044,8 @@ var LocalAgentSpecification = class {
1037
1044
  authenticationCommand = () => "";
1038
1045
  adapterVersionArguments = ["--version"];
1039
1046
  agentVersionArguments = ["--version"];
1047
+ normalizeAdapterVersion = normalizeVersionOutput;
1048
+ normalizeAgentVersion = normalizeVersionOutput;
1040
1049
  promptTimeoutMilliseconds = DEFAULT_PROMPT_TIMEOUT_MILLISECONDS;
1041
1050
  versionProbeTimeoutMilliseconds = VERSION_PROBE_TIMEOUT_MILLISECONDS;
1042
1051
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
@@ -1148,6 +1157,20 @@ var AgentProbeError = class extends Error {
1148
1157
  }
1149
1158
  };
1150
1159
 
1160
+ // src/agent-catalog/agents/resolve-user-local-executable.ts
1161
+ import { isAbsolute as isAbsolute2, join as join4 } from "node:path";
1162
+ async function resolveUserLocalExecutable(executableName, context) {
1163
+ context.signal.throwIfAborted();
1164
+ const platform = context.platform ?? process.platform;
1165
+ const homeDirectory = context.environment["HOME"];
1166
+ if (platform === "win32" || homeDirectory === void 0 || !isAbsolute2(homeDirectory)) {
1167
+ return [];
1168
+ }
1169
+ const executable = await resolveExecutablePath(join4(homeDirectory, ".local", "bin", executableName), platform);
1170
+ context.signal.throwIfAborted();
1171
+ return executable === null ? [] : [executable];
1172
+ }
1173
+
1151
1174
  // src/agent-catalog/agents/verify-session-creation.ts
1152
1175
  import { methods } from "@agentclientprotocol/sdk";
1153
1176
  async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
@@ -1172,6 +1195,37 @@ async function verifySessionCreation(connection, capabilities, defaultWorkspace,
1172
1195
  }
1173
1196
  }
1174
1197
 
1198
+ // src/agent-catalog/agents/copilot-cli-agent.ts
1199
+ var COPILOT_CLI_TESTED_VERSION = "1.0.83";
1200
+ var CopilotCliAgentSpecification = class extends DirectAcpAgentDefinition {
1201
+ acpProbeTimeoutMilliseconds = 2e4;
1202
+ adapterVersion = COPILOT_CLI_TESTED_VERSION;
1203
+ authenticationCommand = () => "copilot login";
1204
+ agentExecutable = "copilot";
1205
+ id = "github-copilot-cli";
1206
+ label = "GitHub Copilot CLI";
1207
+ versionProbeTimeoutMilliseconds = 1e4;
1208
+ constructor() {
1209
+ super(
1210
+ "MOBIUS_COPILOT_PATH",
1211
+ ["--no-auto-update", "--acp", "--stdio"],
1212
+ ["agents", "github-copilot-cli", COPILOT_CLI_TESTED_VERSION, "bin", "copilot"]
1213
+ );
1214
+ }
1215
+ createLaunchEnvironment = async (_agent, _context) => Object.freeze({ COPILOT_AUTO_UPDATE: "false" });
1216
+ resolveInstalledAgentExecutables = async (context) => await resolveUserLocalExecutable(this.agentExecutable, context);
1217
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1218
+ const capabilities = initialized.agentCapabilities ?? {};
1219
+ if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || (initialized.authMethods ?? []).length === 0) {
1220
+ throw new AgentProbeError(
1221
+ "acp_incompatible",
1222
+ "GitHub Copilot CLI reported an unsupported ACP capability set"
1223
+ );
1224
+ }
1225
+ await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
1226
+ };
1227
+ };
1228
+
1175
1229
  // src/agent-catalog/agents/cursor-cli-agent.ts
1176
1230
  var CURSOR_CLI_TESTED_VERSION = "2026.09.02-c22c1a3";
1177
1231
  var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
@@ -1198,7 +1252,7 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
1198
1252
 
1199
1253
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1200
1254
  import { realpath as realpath3, stat as stat3 } from "node:fs/promises";
1201
- import { isAbsolute as isAbsolute2, join as join5, normalize } from "node:path";
1255
+ import { isAbsolute as isAbsolute3, join as join6, normalize } from "node:path";
1202
1256
 
1203
1257
  // src/agent-installation/deepseek-managed-package.ts
1204
1258
  var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
@@ -1216,18 +1270,18 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
1216
1270
 
1217
1271
  // src/storage/state-directory.ts
1218
1272
  import { homedir } from "node:os";
1219
- import { join as join4, resolve as resolve2 } from "node:path";
1273
+ import { join as join5, resolve as resolve2 } from "node:path";
1220
1274
  function readStateDirectory(environment = process.env) {
1221
1275
  const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
1222
1276
  if (configured !== void 0 && configured.length > 0) {
1223
1277
  return resolve2(configured);
1224
1278
  }
1225
- return join4(homedir(), ".mobius");
1279
+ return join5(homedir(), ".mobius");
1226
1280
  }
1227
1281
 
1228
1282
  // src/agent-catalog/agents/deepseek-harness-agent.ts
1229
1283
  async function validateAgentHome(path2) {
1230
- if (!isAbsolute2(path2) || normalize(path2) !== path2) {
1284
+ if (!isAbsolute3(path2) || normalize(path2) !== path2) {
1231
1285
  throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
1232
1286
  }
1233
1287
  try {
@@ -1277,7 +1331,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1277
1331
  context.signal
1278
1332
  );
1279
1333
  if (managed.path === agent.path) {
1280
- selectedHome = join5(readStateDirectory(context.environment), "agents", this.id, "home");
1334
+ selectedHome = join6(readStateDirectory(context.environment), "agents", this.id, "home");
1281
1335
  }
1282
1336
  } catch {
1283
1337
  context.signal.throwIfAborted();
@@ -1293,7 +1347,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1293
1347
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
1294
1348
  signal.throwIfAborted();
1295
1349
  const executable = await validateManagedNpmPackage(
1296
- join5(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1350
+ join6(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
1297
1351
  DEEPSEEK_HARNESS_PACKAGE
1298
1352
  );
1299
1353
  signal.throwIfAborted();
@@ -1313,9 +1367,41 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
1313
1367
  };
1314
1368
  };
1315
1369
 
1370
+ // src/agent-catalog/agents/gemini-cli-agent.ts
1371
+ var GEMINI_CLI_TESTED_VERSION = "0.59.0";
1372
+ var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
1373
+ acpProbeTimeoutMilliseconds = 2e4;
1374
+ adapterVersion = GEMINI_CLI_TESTED_VERSION;
1375
+ authenticationCommand = () => "gemini";
1376
+ agentExecutable = "gemini";
1377
+ id = "gemini-cli";
1378
+ label = "Gemini CLI";
1379
+ versionProbeTimeoutMilliseconds = 1e4;
1380
+ constructor() {
1381
+ super(
1382
+ "MOBIUS_GEMINI_PATH",
1383
+ ["--acp"],
1384
+ [
1385
+ "agents",
1386
+ "gemini-cli",
1387
+ GEMINI_CLI_TESTED_VERSION,
1388
+ "bin",
1389
+ process.platform === "win32" ? "gemini.cmd" : "gemini"
1390
+ ]
1391
+ );
1392
+ }
1393
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1394
+ const capabilities = initialized.agentCapabilities ?? {};
1395
+ if (capabilities.loadSession !== true || (initialized.authMethods ?? []).length === 0) {
1396
+ throw new AgentProbeError("acp_incompatible", "Gemini CLI reported an unsupported ACP capability set");
1397
+ }
1398
+ await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
1399
+ };
1400
+ };
1401
+
1316
1402
  // src/agent-catalog/agents/grok-build-agent.ts
1317
1403
  import { realpath as realpath4 } from "node:fs/promises";
1318
- import { isAbsolute as isAbsolute3, join as join6, relative as relative2, sep as sep2 } from "node:path";
1404
+ import { isAbsolute as isAbsolute4, join as join7, relative as relative2, sep as sep2 } from "node:path";
1319
1405
 
1320
1406
  // src/agent-installation/grok-managed-package.ts
1321
1407
  var GROK_BUILD_MANAGED_VERSION = "1.0.21";
@@ -1378,7 +1464,7 @@ function grokBuildManagedPackage(platform, architecture) {
1378
1464
  // src/agent-catalog/agents/grok-build-agent.ts
1379
1465
  function isContainedPath2(root, candidate) {
1380
1466
  const difference = relative2(root, candidate);
1381
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
1467
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute4(difference);
1382
1468
  }
1383
1469
  var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1384
1470
  adapterVersion = GROK_BUILD_MANAGED_VERSION;
@@ -1406,7 +1492,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1406
1492
  if (managed.path === agent.path) {
1407
1493
  return Object.freeze({
1408
1494
  GROK_HOME: await realpath4(
1409
- join6(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
1495
+ join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
1410
1496
  )
1411
1497
  });
1412
1498
  }
@@ -1417,9 +1503,9 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1417
1503
  };
1418
1504
  resolveManagedAgent = async (stateDirectory, platform, signal) => {
1419
1505
  signal.throwIfAborted();
1420
- const versionRoot = await realpath4(join6(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
1421
- await validateManagedNpmPackage(join6(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
1422
- const executable = await resolveExecutablePath(join6(versionRoot, "home", "bin", "grok"), platform);
1506
+ const versionRoot = await realpath4(join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
1507
+ await validateManagedNpmPackage(join7(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
1508
+ const executable = await resolveExecutablePath(join7(versionRoot, "home", "bin", "grok"), platform);
1423
1509
  signal.throwIfAborted();
1424
1510
  if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
1425
1511
  throw new AgentProbeError("managed_agent_invalid", "The managed Grok Build executable is invalid");
@@ -1436,14 +1522,39 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1436
1522
  };
1437
1523
  };
1438
1524
 
1525
+ // src/agent-catalog/agents/hermes-agent.ts
1526
+ var HERMES_TESTED_VERSION = "0.21.1";
1527
+ var HermesAgentSpecification = class extends DirectAcpAgentDefinition {
1528
+ acpProbeTimeoutMilliseconds = 2e4;
1529
+ adapterVersion = HERMES_TESTED_VERSION;
1530
+ adapterVersionArguments = ["acp", "--version"];
1531
+ authenticationCommand = () => "hermes acp --setup";
1532
+ agentExecutable = "hermes";
1533
+ agentVersionArguments = ["acp", "--version"];
1534
+ id = "hermes";
1535
+ label = "Hermes Agent";
1536
+ constructor() {
1537
+ super("MOBIUS_HERMES_PATH", ["acp"], ["agents", "hermes", HERMES_TESTED_VERSION, "bin", "hermes"]);
1538
+ }
1539
+ resolveInstalledAgentExecutables = async (context) => await resolveUserLocalExecutable(this.agentExecutable, context);
1540
+ verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1541
+ const capabilities = initialized.agentCapabilities ?? {};
1542
+ const session = capabilities.sessionCapabilities;
1543
+ if (capabilities.loadSession !== true || session?.fork == null || session.list == null || session.resume == null || (initialized.authMethods ?? []).length === 0) {
1544
+ throw new AgentProbeError("acp_incompatible", "Hermes Agent reported an unsupported ACP capability set");
1545
+ }
1546
+ await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
1547
+ };
1548
+ };
1549
+
1439
1550
  // src/agent-catalog/agents/opencode-agent.ts
1440
- import { join as join8 } from "node:path";
1551
+ import { join as join9 } from "node:path";
1441
1552
 
1442
1553
  // src/agent-installation/managed-agent-archive.ts
1443
1554
  import { createHash } from "node:crypto";
1444
1555
  import { createReadStream } from "node:fs";
1445
1556
  import { chmod, copyFile, mkdir as mkdir2, mkdtemp as mkdtemp2, open as open2, realpath as realpath5, rename as rename2, rm as rm2, stat as stat4, writeFile } from "node:fs/promises";
1446
- import { dirname as dirname2, isAbsolute as isAbsolute4, join as join7, relative as relative3, sep as sep3 } from "node:path";
1557
+ import { dirname as dirname2, isAbsolute as isAbsolute5, join as join8, relative as relative3, sep as sep3 } from "node:path";
1447
1558
 
1448
1559
  // src/agent-installation/verified-download.ts
1449
1560
  import { fetch } from "undici";
@@ -1549,7 +1660,7 @@ function isRecord3(value) {
1549
1660
  }
1550
1661
  function isContainedPath3(root, candidate) {
1551
1662
  const difference = relative3(root, candidate);
1552
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute4(difference);
1663
+ return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute5(difference);
1553
1664
  }
1554
1665
  async function hashFile(path2, signal) {
1555
1666
  signal.throwIfAborted();
@@ -1628,11 +1739,11 @@ async function validateManagedAgentArchive(root, definition, signal) {
1628
1739
  if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
1629
1740
  throw new Error("Managed Agent root is not user-owned");
1630
1741
  }
1631
- const manifest = await readManifest(join7(rootPath, "archive.json"));
1742
+ const manifest = await readManifest(join8(rootPath, "archive.json"));
1632
1743
  if (manifest["archiveSha256"] !== definition.archiveSha256 || manifest["archiveUrl"] !== definition.archiveUrl.toString() || manifest["version"] !== definition.version || typeof manifest["executableSha256"] !== "string") {
1633
1744
  throw new Error("Managed Agent archive identity is invalid");
1634
1745
  }
1635
- const executable = await resolveExecutablePath(join7(rootPath, "bin", definition.executableName));
1746
+ const executable = await resolveExecutablePath(join8(rootPath, "bin", definition.executableName));
1636
1747
  if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
1637
1748
  throw new Error("Managed Agent executable is invalid");
1638
1749
  }
@@ -1724,7 +1835,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
1724
1835
  }
1725
1836
  createLaunchEnvironment = async (_agent, _context) => Object.freeze({ OPENCODE_DISABLE_AUTOUPDATE: "1" });
1726
1837
  resolveManagedAgent = async (stateDirectory, platform, signal) => await validateManagedAgentArchive(
1727
- join8(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
1838
+ join9(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
1728
1839
  openCodeManagedArchive(platform, process.arch),
1729
1840
  signal
1730
1841
  );
@@ -1742,7 +1853,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
1742
1853
  };
1743
1854
 
1744
1855
  // src/agent-catalog/agents/pi-agent.ts
1745
- import { join as join9 } from "node:path";
1856
+ import { join as join10 } from "node:path";
1746
1857
  import {
1747
1858
  methods as methods2
1748
1859
  } from "@agentclientprotocol/sdk";
@@ -1801,7 +1912,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
1801
1912
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
1802
1913
  signal.throwIfAborted();
1803
1914
  const executable = await validateManagedNpmPackage(
1804
- join9(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
1915
+ join10(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
1805
1916
  PI_AGENT_PACKAGE
1806
1917
  );
1807
1918
  signal.throwIfAborted();
@@ -1839,7 +1950,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
1839
1950
  };
1840
1951
 
1841
1952
  // src/agent-catalog/agents/workbuddy-agent.ts
1842
- import { isAbsolute as isAbsolute5, join as join10 } from "node:path";
1953
+ import { isAbsolute as isAbsolute6, join as join11 } from "node:path";
1843
1954
 
1844
1955
  // src/agent-installation/workbuddy-managed-package.ts
1845
1956
  var WORKBUDDY_MANAGED_VERSION = "2.146.0";
@@ -1892,7 +2003,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
1892
2003
  resolveManagedAgent = async (stateDirectory, _platform, signal) => {
1893
2004
  signal.throwIfAborted();
1894
2005
  const executable = await validateManagedNpmPackage(
1895
- join10(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
2006
+ join11(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
1896
2007
  WORKBUDDY_MANAGED_PACKAGE
1897
2008
  );
1898
2009
  signal.throwIfAborted();
@@ -1903,10 +2014,10 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
1903
2014
  if ((context.platform ?? process.platform) !== "darwin") {
1904
2015
  return [];
1905
2016
  }
1906
- const requestedPaths = [join10("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
2017
+ const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
1907
2018
  const homeDirectory = context.environment["HOME"];
1908
- if (homeDirectory !== void 0 && isAbsolute5(homeDirectory)) {
1909
- requestedPaths.unshift(join10(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
2019
+ if (homeDirectory !== void 0 && isAbsolute6(homeDirectory)) {
2020
+ requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
1910
2021
  }
1911
2022
  const executables = [];
1912
2023
  for (const requestedPath of requestedPaths) {
@@ -1932,12 +2043,15 @@ function supportedLocalAgentSpecifications() {
1932
2043
  return Object.freeze([
1933
2044
  new CodexAgentSpecification(),
1934
2045
  new ClaudeCodeAgentSpecification(),
2046
+ new CopilotCliAgentSpecification(),
1935
2047
  new PiAgentSpecification(),
1936
2048
  new DeepSeekHarnessAgentSpecification(),
2049
+ new HermesAgentSpecification(),
1937
2050
  new OpenCodeAgentSpecification(),
1938
2051
  new CursorCliAgentSpecification(),
1939
2052
  new GrokBuildAgentSpecification(),
1940
- new WorkBuddyAgentSpecification()
2053
+ new WorkBuddyAgentSpecification(),
2054
+ new GeminiCliAgentSpecification()
1941
2055
  ]);
1942
2056
  }
1943
2057
 
@@ -1977,11 +2091,173 @@ var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
1977
2091
  outcome: { outcome: "cancelled" }
1978
2092
  })).onNotification("cursor/update_todos", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/task", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/generate_image", discardExtensionParams, async () => Promise.resolve());
1979
2093
 
2094
+ // src/agent-catalog/acp-readiness-probe.ts
2095
+ var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
2096
+ var VerifiedAcpReadiness = class {
2097
+ adapterVersion;
2098
+ capabilities;
2099
+ constructor(adapterVersion, capabilities) {
2100
+ this.adapterVersion = adapterVersion;
2101
+ this.capabilities = capabilities;
2102
+ }
2103
+ };
2104
+ var DiscoveryAcpHandler = class {
2105
+ onElicitation = (_request, _signal) => Promise.reject(new Error("ACP probe does not accept elicitations"));
2106
+ onElicitationComplete = (_notification) => Promise.resolve();
2107
+ onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
2108
+ onUpdate = (_notification) => Promise.resolve();
2109
+ };
2110
+ function readableAcpStream(input2) {
2111
+ let byteLength = 0;
2112
+ let open5 = true;
2113
+ return new ReadableStream({
2114
+ start(controller) {
2115
+ input2.on("data", (chunk) => {
2116
+ if (!open5) {
2117
+ return;
2118
+ }
2119
+ if (!(chunk instanceof Uint8Array)) {
2120
+ open5 = false;
2121
+ controller.error(new Error("ACP adapter produced invalid output"));
2122
+ return;
2123
+ }
2124
+ byteLength += chunk.byteLength;
2125
+ if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
2126
+ open5 = false;
2127
+ controller.error(new Error("ACP adapter output limit exceeded"));
2128
+ return;
2129
+ }
2130
+ controller.enqueue(new Uint8Array(chunk));
2131
+ });
2132
+ input2.once("end", () => {
2133
+ if (open5) {
2134
+ open5 = false;
2135
+ controller.close();
2136
+ }
2137
+ });
2138
+ input2.once("error", (error61) => {
2139
+ if (open5) {
2140
+ open5 = false;
2141
+ controller.error(error61);
2142
+ }
2143
+ });
2144
+ },
2145
+ cancel() {
2146
+ open5 = false;
2147
+ }
2148
+ });
2149
+ }
2150
+ function writableAcpStream(output2) {
2151
+ return new WritableStream({
2152
+ write(chunk) {
2153
+ return new Promise((resolveWrite, rejectWrite) => {
2154
+ output2.write(chunk, (error61) => {
2155
+ if (error61) {
2156
+ rejectWrite(error61);
2157
+ return;
2158
+ }
2159
+ resolveWrite();
2160
+ });
2161
+ });
2162
+ }
2163
+ });
2164
+ }
2165
+ async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
2166
+ signal.throwIfAborted();
2167
+ const controller = new AbortController();
2168
+ let timedOut = false;
2169
+ const timeout = setTimeout(() => {
2170
+ timedOut = true;
2171
+ controller.abort(new Error("ACP probe timed out"));
2172
+ }, specification.acpProbeTimeoutMilliseconds);
2173
+ const abort = () => controller.abort(signal.reason);
2174
+ signal.addEventListener("abort", abort, { once: true });
2175
+ if (signal.aborted) {
2176
+ abort();
2177
+ }
2178
+ const child = spawn2(agent.adapterPath, [...agent.arguments], {
2179
+ cwd: defaultWorkspace,
2180
+ detached: process.platform !== "win32",
2181
+ env: { ...environment, ...agent.environment },
2182
+ shell: false,
2183
+ stdio: ["pipe", "pipe", "pipe"]
2184
+ });
2185
+ const processExit = new Promise((_resolve, reject) => {
2186
+ const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
2187
+ child.once("error", reject);
2188
+ child.once("exit", rejectExit);
2189
+ if (child.exitCode !== null || child.signalCode !== null) {
2190
+ rejectExit();
2191
+ }
2192
+ });
2193
+ const stdin = child.stdin;
2194
+ const stdout = child.stdout;
2195
+ const stderr = child.stderr;
2196
+ if (stdin === null || stdout === null || stderr === null) {
2197
+ await stopProcessTree(child);
2198
+ throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
2199
+ }
2200
+ let stderrBytes = 0;
2201
+ const consumeStderr = (chunk) => {
2202
+ stderrBytes += chunk.byteLength;
2203
+ if (stderrBytes > ACP_OUTPUT_LIMIT_BYTES) {
2204
+ controller.abort(new Error("ACP adapter output limit exceeded"));
2205
+ }
2206
+ };
2207
+ stderr.on("data", consumeStderr);
2208
+ const connection = createAcpClient(new DiscoveryAcpHandler()).connect(
2209
+ ndJsonStream(writableAcpStream(stdin), readableAcpStream(stdout))
2210
+ );
2211
+ try {
2212
+ const initialized = await Promise.race([
2213
+ connection.agent.request(
2214
+ methods4.agent.initialize,
2215
+ {
2216
+ clientCapabilities: {},
2217
+ clientInfo: { name: "mobius", version: "0.0.3" },
2218
+ protocolVersion: PROTOCOL_VERSION
2219
+ },
2220
+ { cancellationSignal: controller.signal }
2221
+ ),
2222
+ processExit
2223
+ ]);
2224
+ if (initialized.protocolVersion !== PROTOCOL_VERSION) {
2225
+ throw new AgentProbeError("acp_incompatible", "ACP adapter selected an unsupported protocol version");
2226
+ }
2227
+ await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
2228
+ return new VerifiedAcpReadiness(
2229
+ normalizeVersionOutput(initialized.agentInfo?.version ?? ""),
2230
+ normalizeAcpCapabilities(initialized)
2231
+ );
2232
+ } catch (error61) {
2233
+ if (signal.aborted) {
2234
+ signal.throwIfAborted();
2235
+ }
2236
+ if (timedOut) {
2237
+ throw new AgentProbeError("adapter_probe_timeout", "ACP adapter probe timed out", { cause: error61 });
2238
+ }
2239
+ if (error61 instanceof AgentProbeError) {
2240
+ throw error61;
2241
+ }
2242
+ if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
2243
+ throw new AgentProbeError("authentication_required", "Agent authentication is required", { cause: error61 });
2244
+ }
2245
+ throw new AgentProbeError("acp_incompatible", "ACP adapter initialization failed", { cause: error61 });
2246
+ } finally {
2247
+ clearTimeout(timeout);
2248
+ signal.removeEventListener("abort", abort);
2249
+ connection.close();
2250
+ stdin.end();
2251
+ stderr.removeListener("data", consumeStderr);
2252
+ await stopProcessTree(child);
2253
+ }
2254
+ }
2255
+
1980
2256
  // src/agent-catalog/executable-discovery.ts
1981
- import { isAbsolute as isAbsolute6, join as join12 } from "node:path";
2257
+ import { isAbsolute as isAbsolute7, join as join13 } from "node:path";
1982
2258
 
1983
2259
  // src/agent-installation/managed-adapter-installer.ts
1984
- import { join as join11 } from "node:path";
2260
+ import { join as join12 } from "node:path";
1985
2261
  var ManagedAdapterInstallError = class extends Error {
1986
2262
  code;
1987
2263
  constructor(code, message, options = {}) {
@@ -2038,7 +2314,7 @@ var ManagedAdapterInstaller = class {
2038
2314
  this.#stateDirectory = options.stateDirectory;
2039
2315
  }
2040
2316
  install = async (specification, signal) => {
2041
- const root = join11(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
2317
+ const root = join12(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
2042
2318
  try {
2043
2319
  return await this.#npmInstaller.install(
2044
2320
  root,
@@ -2072,7 +2348,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
2072
2348
  let managed;
2073
2349
  try {
2074
2350
  managed = await validateManagedAdapter(
2075
- join12(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
2351
+ join13(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
2076
2352
  specification
2077
2353
  );
2078
2354
  } catch {
@@ -2083,7 +2359,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
2083
2359
  async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
2084
2360
  const override = context.environment[overrideVariable];
2085
2361
  if (override !== void 0) {
2086
- if (override.length === 0 || !isAbsolute6(override)) {
2362
+ if (override.length === 0 || !isAbsolute7(override)) {
2087
2363
  return [];
2088
2364
  }
2089
2365
  const executable = await resolveExecutablePath(override, context.platform);
@@ -2137,10 +2413,7 @@ async function resolveAdapterExecutable(specification, context) {
2137
2413
  const executables = await resolveAdapterExecutables(specification, context);
2138
2414
  return executables[0] ?? null;
2139
2415
  }
2140
- function normalizedVersion(output2) {
2141
- return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
2142
- }
2143
- async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal, timeoutMilliseconds) {
2416
+ async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal, timeoutMilliseconds, normalize4 = normalizeVersionOutput) {
2144
2417
  const result = await runBoundedProcess({
2145
2418
  arguments: arguments_,
2146
2419
  command: executable.path,
@@ -2149,7 +2422,7 @@ async function probeVersion(executable, arguments_, environment, defaultWorkspac
2149
2422
  signal,
2150
2423
  timeoutMilliseconds
2151
2424
  });
2152
- const version2 = normalizedVersion(result.stdout || result.stderr);
2425
+ const version2 = normalize4(result.stdout || result.stderr);
2153
2426
  if (version2.length === 0) {
2154
2427
  throw new ProcessExecutionError("process_exit_failed", "The executable did not report a version");
2155
2428
  }
@@ -2173,7 +2446,8 @@ async function findVerifiedAgentExecutable(specification, context) {
2173
2446
  context.environment,
2174
2447
  context.defaultWorkspace,
2175
2448
  context.signal,
2176
- specification.versionProbeTimeoutMilliseconds
2449
+ specification.versionProbeTimeoutMilliseconds,
2450
+ specification.normalizeAgentVersion
2177
2451
  );
2178
2452
  return new VerifiedAgentExecutable(executable, version2);
2179
2453
  } catch {
@@ -2185,168 +2459,6 @@ async function findVerifiedAgentExecutable(specification, context) {
2185
2459
  return null;
2186
2460
  }
2187
2461
 
2188
- // src/agent-catalog/acp-readiness-probe.ts
2189
- var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
2190
- var VerifiedAcpReadiness = class {
2191
- adapterVersion;
2192
- capabilities;
2193
- constructor(adapterVersion, capabilities) {
2194
- this.adapterVersion = adapterVersion;
2195
- this.capabilities = capabilities;
2196
- }
2197
- };
2198
- var DiscoveryAcpHandler = class {
2199
- onElicitation = (_request, _signal) => Promise.reject(new Error("ACP probe does not accept elicitations"));
2200
- onElicitationComplete = (_notification) => Promise.resolve();
2201
- onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
2202
- onUpdate = (_notification) => Promise.resolve();
2203
- };
2204
- function readableAcpStream(input2) {
2205
- let byteLength = 0;
2206
- let open5 = true;
2207
- return new ReadableStream({
2208
- start(controller) {
2209
- input2.on("data", (chunk) => {
2210
- if (!open5) {
2211
- return;
2212
- }
2213
- if (!(chunk instanceof Uint8Array)) {
2214
- open5 = false;
2215
- controller.error(new Error("ACP adapter produced invalid output"));
2216
- return;
2217
- }
2218
- byteLength += chunk.byteLength;
2219
- if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
2220
- open5 = false;
2221
- controller.error(new Error("ACP adapter output limit exceeded"));
2222
- return;
2223
- }
2224
- controller.enqueue(new Uint8Array(chunk));
2225
- });
2226
- input2.once("end", () => {
2227
- if (open5) {
2228
- open5 = false;
2229
- controller.close();
2230
- }
2231
- });
2232
- input2.once("error", (error61) => {
2233
- if (open5) {
2234
- open5 = false;
2235
- controller.error(error61);
2236
- }
2237
- });
2238
- },
2239
- cancel() {
2240
- open5 = false;
2241
- }
2242
- });
2243
- }
2244
- function writableAcpStream(output2) {
2245
- return new WritableStream({
2246
- write(chunk) {
2247
- return new Promise((resolveWrite, rejectWrite) => {
2248
- output2.write(chunk, (error61) => {
2249
- if (error61) {
2250
- rejectWrite(error61);
2251
- return;
2252
- }
2253
- resolveWrite();
2254
- });
2255
- });
2256
- }
2257
- });
2258
- }
2259
- async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
2260
- signal.throwIfAborted();
2261
- const controller = new AbortController();
2262
- let timedOut = false;
2263
- const timeout = setTimeout(() => {
2264
- timedOut = true;
2265
- controller.abort(new Error("ACP probe timed out"));
2266
- }, specification.acpProbeTimeoutMilliseconds);
2267
- const abort = () => controller.abort(signal.reason);
2268
- signal.addEventListener("abort", abort, { once: true });
2269
- if (signal.aborted) {
2270
- abort();
2271
- }
2272
- const child = spawn2(agent.adapterPath, [...agent.arguments], {
2273
- cwd: defaultWorkspace,
2274
- detached: process.platform !== "win32",
2275
- env: { ...environment, ...agent.environment },
2276
- shell: false,
2277
- stdio: ["pipe", "pipe", "pipe"]
2278
- });
2279
- const processExit = new Promise((_resolve, reject) => {
2280
- const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
2281
- child.once("error", reject);
2282
- child.once("exit", rejectExit);
2283
- if (child.exitCode !== null || child.signalCode !== null) {
2284
- rejectExit();
2285
- }
2286
- });
2287
- const stdin = child.stdin;
2288
- const stdout = child.stdout;
2289
- const stderr = child.stderr;
2290
- if (stdin === null || stdout === null || stderr === null) {
2291
- await stopProcessTree(child);
2292
- throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
2293
- }
2294
- let stderrBytes = 0;
2295
- const consumeStderr = (chunk) => {
2296
- stderrBytes += chunk.byteLength;
2297
- if (stderrBytes > ACP_OUTPUT_LIMIT_BYTES) {
2298
- controller.abort(new Error("ACP adapter output limit exceeded"));
2299
- }
2300
- };
2301
- stderr.on("data", consumeStderr);
2302
- const connection = createAcpClient(new DiscoveryAcpHandler()).connect(
2303
- ndJsonStream(writableAcpStream(stdin), readableAcpStream(stdout))
2304
- );
2305
- try {
2306
- const initialized = await Promise.race([
2307
- connection.agent.request(
2308
- methods4.agent.initialize,
2309
- {
2310
- clientCapabilities: {},
2311
- clientInfo: { name: "mobius", version: "0.0.3" },
2312
- protocolVersion: PROTOCOL_VERSION
2313
- },
2314
- { cancellationSignal: controller.signal }
2315
- ),
2316
- processExit
2317
- ]);
2318
- if (initialized.protocolVersion !== PROTOCOL_VERSION) {
2319
- throw new AgentProbeError("acp_incompatible", "ACP adapter selected an unsupported protocol version");
2320
- }
2321
- await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
2322
- return new VerifiedAcpReadiness(
2323
- normalizedVersion(initialized.agentInfo?.version ?? ""),
2324
- normalizeAcpCapabilities(initialized)
2325
- );
2326
- } catch (error61) {
2327
- if (signal.aborted) {
2328
- signal.throwIfAborted();
2329
- }
2330
- if (timedOut) {
2331
- throw new AgentProbeError("adapter_probe_timeout", "ACP adapter probe timed out", { cause: error61 });
2332
- }
2333
- if (error61 instanceof AgentProbeError) {
2334
- throw error61;
2335
- }
2336
- if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
2337
- throw new AgentProbeError("authentication_required", "Agent authentication is required", { cause: error61 });
2338
- }
2339
- throw new AgentProbeError("acp_incompatible", "ACP adapter initialization failed", { cause: error61 });
2340
- } finally {
2341
- clearTimeout(timeout);
2342
- signal.removeEventListener("abort", abort);
2343
- connection.close();
2344
- stdin.end();
2345
- stderr.removeListener("data", consumeStderr);
2346
- await stopProcessTree(child);
2347
- }
2348
- }
2349
-
2350
2462
  // src/agent-catalog/discover-agent.ts
2351
2463
  function agentProbeFailure(specification, error61) {
2352
2464
  if (error61 instanceof AgentProbeError) {
@@ -2390,7 +2502,8 @@ async function discoverAgent(specification, context) {
2390
2502
  context.environment,
2391
2503
  context.defaultWorkspace,
2392
2504
  context.signal,
2393
- specification.versionProbeTimeoutMilliseconds
2505
+ specification.versionProbeTimeoutMilliseconds,
2506
+ specification.normalizeAgentVersion
2394
2507
  );
2395
2508
  } catch (error61) {
2396
2509
  if (context.signal.aborted) {
@@ -2426,7 +2539,8 @@ async function discoverAgent(specification, context) {
2426
2539
  },
2427
2540
  context.defaultWorkspace,
2428
2541
  context.signal,
2429
- specification.versionProbeTimeoutMilliseconds
2542
+ specification.versionProbeTimeoutMilliseconds,
2543
+ specification.normalizeAdapterVersion
2430
2544
  );
2431
2545
  }
2432
2546
  } catch (error61) {
@@ -2549,7 +2663,7 @@ var AuditStore = class {
2549
2663
  };
2550
2664
 
2551
2665
  // src/config.ts
2552
- import { join as join13 } from "node:path";
2666
+ import { join as join14 } from "node:path";
2553
2667
 
2554
2668
  // ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
2555
2669
  var external_exports = {};
@@ -21419,6 +21533,28 @@ function date4(params) {
21419
21533
 
21420
21534
  // ../protocol/src/prompt-usage.ts
21421
21535
  var TOKEN_COUNT = external_exports.number().int().nonnegative();
21536
+ function normalizeQuotaTokenCount(value) {
21537
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
21538
+ return value;
21539
+ }
21540
+ if (Reflect.has(value, "inputTokens") || Reflect.has(value, "outputTokens") || Reflect.has(value, "totalTokens")) {
21541
+ return value;
21542
+ }
21543
+ if (!Reflect.has(value, "input_tokens") && !Reflect.has(value, "output_tokens")) {
21544
+ return value;
21545
+ }
21546
+ const inputTokens = Reflect.get(value, "input_tokens");
21547
+ const outputTokens = Reflect.get(value, "output_tokens");
21548
+ const reportedTotal = Reflect.get(value, "total_tokens");
21549
+ return {
21550
+ cachedInputTokens: Reflect.get(value, "cached_input_tokens"),
21551
+ cachedWriteTokens: Reflect.get(value, "cached_write_tokens"),
21552
+ inputTokens,
21553
+ outputTokens,
21554
+ reasoningOutputTokens: Reflect.get(value, "reasoning_output_tokens"),
21555
+ totalTokens: reportedTotal === void 0 && typeof inputTokens === "number" && typeof outputTokens === "number" ? inputTokens + outputTokens : reportedTotal
21556
+ };
21557
+ }
21422
21558
  var promptUsageSchema = external_exports.object({
21423
21559
  cachedReadTokens: TOKEN_COUNT.nullish(),
21424
21560
  cachedWriteTokens: TOKEN_COUNT.nullish(),
@@ -21427,14 +21563,17 @@ var promptUsageSchema = external_exports.object({
21427
21563
  thoughtTokens: TOKEN_COUNT.nullish(),
21428
21564
  totalTokens: TOKEN_COUNT
21429
21565
  }).readonly();
21430
- var quotaTokenCountSchema = external_exports.object({
21431
- cachedInputTokens: TOKEN_COUNT,
21432
- cachedWriteTokens: TOKEN_COUNT.optional(),
21433
- inputTokens: TOKEN_COUNT,
21434
- outputTokens: TOKEN_COUNT,
21435
- reasoningOutputTokens: TOKEN_COUNT,
21436
- totalTokens: TOKEN_COUNT
21437
- }).readonly();
21566
+ var quotaTokenCountSchema = external_exports.preprocess(
21567
+ normalizeQuotaTokenCount,
21568
+ external_exports.object({
21569
+ cachedInputTokens: TOKEN_COUNT.optional(),
21570
+ cachedWriteTokens: TOKEN_COUNT.optional(),
21571
+ inputTokens: TOKEN_COUNT,
21572
+ outputTokens: TOKEN_COUNT,
21573
+ reasoningOutputTokens: TOKEN_COUNT.optional(),
21574
+ totalTokens: TOKEN_COUNT
21575
+ }).readonly()
21576
+ );
21438
21577
  var promptMetadataSchema = external_exports.object({
21439
21578
  quota: external_exports.object({
21440
21579
  model_usage: external_exports.array(
@@ -23062,7 +23201,7 @@ var decodeSessionEventRejection = (encoded) => decode5(encoded, eventRejectionSc
23062
23201
  // src/config.ts
23063
23202
  function loadDefaultWorkspace(environment = process.env) {
23064
23203
  const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
23065
- return configuredWorkspace ?? join13(readStateDirectory(environment), "workspace");
23204
+ return configuredWorkspace ?? join14(readStateDirectory(environment), "workspace");
23066
23205
  }
23067
23206
  function createDaemonConfig(connection, agents = [], installableAgents = []) {
23068
23207
  return {
@@ -23079,7 +23218,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
23079
23218
 
23080
23219
  // src/run-daemon.ts
23081
23220
  import { randomUUID as randomUUID4 } from "node:crypto";
23082
- import { basename as basename4, join as join15 } from "node:path";
23221
+ import { basename as basename4, join as join16 } from "node:path";
23083
23222
  import { styleText } from "node:util";
23084
23223
  import { fetch as fetch6, WebSocket as WebSocket2 } from "undici";
23085
23224
 
@@ -23094,7 +23233,7 @@ import {
23094
23233
 
23095
23234
  // src/authorization/local-raster.ts
23096
23235
  import { readFile, realpath as realpath6, stat as stat5 } from "node:fs/promises";
23097
- import { basename, isAbsolute as isAbsolute7, normalize as normalize2, relative as relative4, sep as sep4 } from "node:path";
23236
+ import { basename, isAbsolute as isAbsolute8, normalize as normalize2, relative as relative4, sep as sep4 } from "node:path";
23098
23237
  import { fileURLToPath } from "node:url";
23099
23238
  var MAX_LOCAL_RASTER_BYTES = 3e6;
23100
23239
  var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
@@ -23137,17 +23276,17 @@ function sniffRasterMime(bytes) {
23137
23276
  }
23138
23277
  function isInsideRoot(root, target) {
23139
23278
  const relation = relative4(root, target);
23140
- return relation !== ".." && !relation.startsWith(`..${sep4}`) && !isAbsolute7(relation);
23279
+ return relation !== ".." && !relation.startsWith(`..${sep4}`) && !isAbsolute8(relation);
23141
23280
  }
23142
23281
  async function resolveCanonicalPath(requested, signal) {
23143
23282
  signal.throwIfAborted();
23144
- if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested) {
23283
+ if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested) {
23145
23284
  return null;
23146
23285
  }
23147
23286
  try {
23148
23287
  const target = await realpath6(requested);
23149
23288
  signal.throwIfAborted();
23150
- if (!isAbsolute7(target) || normalize2(target) !== target) {
23289
+ if (!isAbsolute8(target) || normalize2(target) !== target) {
23151
23290
  return null;
23152
23291
  }
23153
23292
  return target;
@@ -27677,7 +27816,7 @@ var LocalAuthorizationError = class extends Error {
27677
27816
  // src/authorization/workspace-directory.ts
27678
27817
  import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27679
27818
  import { homedir as homedir2 } from "node:os";
27680
- import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute8, join as join14, normalize as normalize3, relative as relative5 } from "node:path";
27819
+ import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, normalize as normalize3, relative as relative5 } from "node:path";
27681
27820
  var WorkspaceDirectoryListing = class {
27682
27821
  directoryId;
27683
27822
  directoryLabel;
@@ -27729,7 +27868,7 @@ var WorkspaceDirectoryService = class {
27729
27868
  }
27730
27869
  if (id.startsWith("path-")) {
27731
27870
  const path2 = decodePath(id, "path-");
27732
- if (isAbsolute8(path2)) {
27871
+ if (isAbsolute9(path2)) {
27733
27872
  return path2;
27734
27873
  }
27735
27874
  }
@@ -27737,7 +27876,7 @@ var WorkspaceDirectoryService = class {
27737
27876
  };
27738
27877
  resolvePath = async (requested, signal) => {
27739
27878
  signal.throwIfAborted();
27740
- if (!isAbsolute8(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
27879
+ if (!isAbsolute9(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
27741
27880
  throw new LocalAuthorizationError("The local directory path is invalid");
27742
27881
  }
27743
27882
  try {
@@ -27745,7 +27884,7 @@ var WorkspaceDirectoryService = class {
27745
27884
  signal.throwIfAborted();
27746
27885
  const metadata = await stat6(target);
27747
27886
  signal.throwIfAborted();
27748
- if (!isAbsolute8(target) || normalize3(target) !== target || !metadata.isDirectory()) {
27887
+ if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
27749
27888
  throw new LocalAuthorizationError("The selected location is not a directory");
27750
27889
  }
27751
27890
  return target;
@@ -27761,7 +27900,7 @@ var WorkspaceDirectoryService = class {
27761
27900
  };
27762
27901
  label = (path2) => {
27763
27902
  const suffix = relative5(homedir2(), path2);
27764
- return suffix === "" ? "~" : !isAbsolute8(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
27903
+ return suffix === "" ? "~" : !isAbsolute9(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
27765
27904
  };
27766
27905
  identify = async (bindingId, requestedPath, signal) => {
27767
27906
  this.authorizeMachine(bindingId);
@@ -27791,7 +27930,7 @@ var WorkspaceDirectoryService = class {
27791
27930
  continue;
27792
27931
  }
27793
27932
  try {
27794
- const path2 = await this.resolvePath(join14(target, child.name), signal);
27933
+ const path2 = await this.resolvePath(join15(target, child.name), signal);
27795
27934
  entries.push({ directoryId: encodePath(path2), name: child.name });
27796
27935
  } catch (cause) {
27797
27936
  signal.throwIfAborted();
@@ -27830,6 +27969,18 @@ import { createHash as createHash3, randomUUID } from "node:crypto";
27830
27969
  import { stat as stat7 } from "node:fs/promises";
27831
27970
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
27832
27971
  var LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS = 90 * 24 * 60 * 60 * 1e3;
27972
+ var identifier2 = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/);
27973
+ var savedApprovalSchema = external_exports.object({
27974
+ local_grant_id: identifier2,
27975
+ bot_id: identifier2,
27976
+ binding_id: identifier2,
27977
+ binding_revision: external_exports.number().int().positive(),
27978
+ agent_ref: identifier2,
27979
+ workspace_ref: external_exports.string().min(1).max(2048),
27980
+ revocation_epoch: external_exports.number().int().nonnegative(),
27981
+ agent_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/),
27982
+ workspace_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/)
27983
+ }).readonly();
27833
27984
  var LocalBotAuthorizationError = class extends Error {
27834
27985
  code;
27835
27986
  constructor(code, message, options = {}) {
@@ -27934,6 +28085,17 @@ function parseTargets(encoded) {
27934
28085
  }
27935
28086
  var LocalBotGrantStore = class {
27936
28087
  #database;
28088
+ static containsBot = (path2, botId) => {
28089
+ const database = new DatabaseSync3(path2, { readOnly: true });
28090
+ try {
28091
+ if (database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'local_bot_grants'").get() === void 0) {
28092
+ return false;
28093
+ }
28094
+ return database.prepare("SELECT local_grant_id FROM local_bot_grants WHERE bot_id = ? LIMIT 1").get(botId) !== void 0;
28095
+ } finally {
28096
+ database.close();
28097
+ }
28098
+ };
27937
28099
  constructor(path2) {
27938
28100
  this.#database = new DatabaseSync3(path2);
27939
28101
  this.#database.exec(`
@@ -27967,6 +28129,78 @@ var LocalBotGrantStore = class {
27967
28129
  ) STRICT;
27968
28130
  `);
27969
28131
  }
28132
+ /** Only the local CLI may invoke this explicit approval transition. */
28133
+ reapprove = async (botId, catalog, directories, bindingAuthorityId, now, signal) => {
28134
+ signal.throwIfAborted();
28135
+ if (!identifier2.safeParse(botId).success) {
28136
+ throw new LocalBotAuthorizationError("invalid_request", "The Bot ID is invalid");
28137
+ }
28138
+ const row = this.#database.prepare("SELECT * FROM local_bot_grants WHERE bot_id = ? ORDER BY binding_revision DESC LIMIT 1").get(botId);
28139
+ if (row === void 0) {
28140
+ throw new LocalBotAuthorizationError("bot_not_found", "This machine has no saved approval for that Bot");
28141
+ }
28142
+ const parsed = savedApprovalSchema.safeParse(row);
28143
+ if (!parsed.success) {
28144
+ throw new LocalBotAuthorizationError("local_grant_invalid", "The saved Bot approval is invalid", {
28145
+ cause: parsed.error
28146
+ });
28147
+ }
28148
+ const saved = parsed.data;
28149
+ const agent = catalog.find(saved.agent_ref);
28150
+ if (!agent.capabilities.embeddedContextPrompt) {
28151
+ throw new LocalBotAuthorizationError("binding_incompatible", "The local Agent cannot apply Bot context");
28152
+ }
28153
+ const [adapterUnchanged, agentUnchanged] = await Promise.all([
28154
+ revalidateExecutable(agent.adapterIdentity),
28155
+ revalidateExecutable(agent.agentIdentity)
28156
+ ]);
28157
+ signal.throwIfAborted();
28158
+ if (!adapterUnchanged || !agentUnchanged) {
28159
+ throw new LocalBotAuthorizationError(
28160
+ "binding_incompatible",
28161
+ "The local Agent executable changed before approval"
28162
+ );
28163
+ }
28164
+ const workspacePath = await directories.resolve(bindingAuthorityId, saved.workspace_ref, signal);
28165
+ const workspaceIdentityDigest = await workspaceDigest(workspacePath);
28166
+ signal.throwIfAborted();
28167
+ this.#database.exec("BEGIN IMMEDIATE");
28168
+ try {
28169
+ const result = this.#database.prepare(`UPDATE local_bot_grants
28170
+ SET agent_identity_digest = ?, workspace_identity_digest = ?, workspace_path = ?,
28171
+ revoked_at = NULL, expires_at = ?, revocation_epoch = revocation_epoch + 1
28172
+ WHERE local_grant_id = ? AND revocation_epoch = ?
28173
+ AND agent_identity_digest = ? AND workspace_identity_digest = ?
28174
+ AND binding_revision = (SELECT MAX(binding_revision) FROM local_bot_grants WHERE bot_id = ?)`).run(
28175
+ agentDigest(agent),
28176
+ workspaceIdentityDigest,
28177
+ workspacePath,
28178
+ now + LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS,
28179
+ saved.local_grant_id,
28180
+ saved.revocation_epoch,
28181
+ saved.agent_identity_digest,
28182
+ saved.workspace_identity_digest,
28183
+ botId
28184
+ );
28185
+ if (result.changes !== 1) {
28186
+ throw new LocalBotAuthorizationError(
28187
+ "binding_not_approved",
28188
+ "The Bot binding changed during approval; run the command again"
28189
+ );
28190
+ }
28191
+ this.#database.prepare(`INSERT INTO audit_events (recorded_at, event, command_id, session_id, details_json)
28192
+ VALUES (?, 'bot_binding_locally_reapproved', ?, '', ?)`).run(
28193
+ new Date(now).toISOString(),
28194
+ saved.binding_id,
28195
+ JSON.stringify({ botId, bindingId: saved.binding_id, agentRef: saved.agent_ref })
28196
+ );
28197
+ this.#database.exec("COMMIT");
28198
+ } catch (cause) {
28199
+ this.#database.exec("ROLLBACK");
28200
+ throw cause;
28201
+ }
28202
+ return { bindingId: saved.binding_id, workspacePath, agentRef: saved.agent_ref };
28203
+ };
27970
28204
  approve = async (request, catalog, directories, bindingAuthorityId, now, signal) => {
27971
28205
  signal.throwIfAborted();
27972
28206
  const existing = this.#database.prepare(
@@ -28302,7 +28536,7 @@ var BotExecutionContextRegistry = class {
28302
28536
  // src/bots/bot-outbound-ipc.ts
28303
28537
  import { chmod as chmod2, mkdir as mkdir3, unlink } from "node:fs/promises";
28304
28538
  import { createServer } from "node:net";
28305
- import { dirname as dirname6, isAbsolute as isAbsolute9 } from "node:path";
28539
+ import { dirname as dirname6, isAbsolute as isAbsolute10 } from "node:path";
28306
28540
  import { fetch as fetch4 } from "undici";
28307
28541
  var BOT_IPC_REQUEST_LIMIT = 32 * 1024;
28308
28542
  var BOT_IPC_TIMEOUT_MILLISECONDS = 2e4;
@@ -28400,7 +28634,7 @@ var BotOutboundIpcServer = class {
28400
28634
  #usesFilesystemSocket;
28401
28635
  constructor(socketPath, relayUrl, registry2) {
28402
28636
  const usesFilesystemSocket = !socketPath.startsWith(WINDOWS_NAMED_PIPE_PREFIX);
28403
- if (usesFilesystemSocket && !isAbsolute9(socketPath)) {
28637
+ if (usesFilesystemSocket && !isAbsolute10(socketPath)) {
28404
28638
  throw new Error("The Bot IPC path must be absolute");
28405
28639
  }
28406
28640
  this.#registry = registry2;
@@ -30340,7 +30574,7 @@ function botIpcSocketPath() {
30340
30574
  if (process.platform === "win32") {
30341
30575
  return `\\\\.\\pipe\\mobius-bot-${randomUUID4()}`;
30342
30576
  }
30343
- return join15("/tmp", `mobius-bot-${randomUUID4()}.sock`);
30577
+ return join16("/tmp", `mobius-bot-${randomUUID4()}.sock`);
30344
30578
  }
30345
30579
  var DaemonAcpObserver = class {
30346
30580
  #config;
@@ -31010,7 +31244,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
31010
31244
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
31011
31245
  }
31012
31246
  }
31013
- async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, timer, signal) {
31247
+ async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, activateAttempt, timer, signal) {
31014
31248
  const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
31015
31249
  publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
31016
31250
  });
@@ -31039,6 +31273,7 @@ async function executePrompt(outbox, publisher, command, config2, directories, a
31039
31273
  }),
31040
31274
  attemptId
31041
31275
  );
31276
+ activateAttempt();
31042
31277
  const attachments = await resolvePromptArtifacts(config2, command, signal);
31043
31278
  let stopReason;
31044
31279
  if (command.disposition === SessionPromptDisposition.Steer) {
@@ -31150,7 +31385,7 @@ function botExecutionAgent(agent, contextHandle, socketPath) {
31150
31385
  agent.capabilities
31151
31386
  );
31152
31387
  }
31153
- async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, timer, signal) {
31388
+ async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, activateAttempt, timer, signal) {
31154
31389
  const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
31155
31390
  publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
31156
31391
  });
@@ -31231,6 +31466,7 @@ async function executeBotPrompt(outbox, publisher, command, config2, directories
31231
31466
  }),
31232
31467
  attemptId
31233
31468
  );
31469
+ activateAttempt();
31234
31470
  const result = await sessions.runPrompt({
31235
31471
  additionalDirectories: resolved.additionalDirectories,
31236
31472
  agent,
@@ -31424,11 +31660,13 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31424
31660
  }
31425
31661
  const turn = new ActiveDaemonTurn(command, receipt.attemptId);
31426
31662
  activeTurns.set(command.commandId, turn);
31427
- if (trackActiveAttempt) {
31428
- activeAttemptIds.set(command.sessionId, receipt.attemptId);
31429
- }
31663
+ const activateAttempt = () => {
31664
+ if (trackActiveAttempt) {
31665
+ activeAttemptIds.set(command.sessionId, receipt.attemptId);
31666
+ }
31667
+ };
31430
31668
  try {
31431
- await execute(receipt.attemptId, turn.signal);
31669
+ await execute(receipt.attemptId, activateAttempt, turn.signal);
31432
31670
  } finally {
31433
31671
  activeTurns.delete(command.commandId);
31434
31672
  if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
@@ -31513,7 +31751,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31513
31751
  delivery,
31514
31752
  command,
31515
31753
  true,
31516
- (attemptId, executionSignal) => executeBotPrompt(
31754
+ (attemptId, activateAttempt, executionSignal) => executeBotPrompt(
31517
31755
  outbox,
31518
31756
  publisher,
31519
31757
  command,
@@ -31526,6 +31764,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31526
31764
  applicator,
31527
31765
  ipc,
31528
31766
  attemptId,
31767
+ activateAttempt,
31529
31768
  timer,
31530
31769
  executionSignal
31531
31770
  )
@@ -31538,7 +31777,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31538
31777
  delivery,
31539
31778
  command,
31540
31779
  command.disposition !== SessionPromptDisposition.Steer,
31541
- (attemptId, executionSignal) => executePrompt(
31780
+ (attemptId, activateAttempt, executionSignal) => executePrompt(
31542
31781
  outbox,
31543
31782
  publisher,
31544
31783
  command,
@@ -31547,6 +31786,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
31547
31786
  audit,
31548
31787
  sessions,
31549
31788
  attemptId,
31789
+ activateAttempt,
31550
31790
  timer,
31551
31791
  executionSignal
31552
31792
  )
@@ -32048,7 +32288,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
32048
32288
  }
32049
32289
  const turn2 = new ActiveDaemonTurn(command2, receipt2.attemptId);
32050
32290
  activeTurns.set(command2.commandId, turn2);
32051
- activeAttemptIds.set(command2.sessionId, receipt2.attemptId);
32052
32291
  void executeBotPrompt(
32053
32292
  outbox,
32054
32293
  publisher,
@@ -32062,6 +32301,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
32062
32301
  applicator,
32063
32302
  ipc,
32064
32303
  receipt2.attemptId,
32304
+ () => activeAttemptIds.set(command2.sessionId, receipt2.attemptId),
32065
32305
  timer,
32066
32306
  turn2.signal
32067
32307
  ).catch((error61) => {
@@ -32088,9 +32328,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
32088
32328
  }
32089
32329
  const turn = new ActiveDaemonTurn(command, receipt.attemptId);
32090
32330
  activeTurns.set(command.commandId, turn);
32091
- if (command.disposition !== SessionPromptDisposition.Steer) {
32092
- activeAttemptIds.set(command.sessionId, receipt.attemptId);
32093
- }
32094
32331
  void executePrompt(
32095
32332
  outbox,
32096
32333
  publisher,
@@ -32100,6 +32337,11 @@ async function runRelayConnection(config2, directories, audit, sessions, install
32100
32337
  audit,
32101
32338
  sessions,
32102
32339
  receipt.attemptId,
32340
+ () => {
32341
+ if (command.disposition !== SessionPromptDisposition.Steer) {
32342
+ activeAttemptIds.set(command.sessionId, receipt.attemptId);
32343
+ }
32344
+ },
32103
32345
  timer,
32104
32346
  turn.signal
32105
32347
  ).catch((error61) => {
@@ -32288,7 +32530,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
32288
32530
  import { randomUUID as randomUUID5 } from "node:crypto";
32289
32531
  import { mkdir as mkdir4, open as open4, realpath as realpath8, rename as rename3, stat as stat8, writeFile as writeFile2 } from "node:fs/promises";
32290
32532
  import { hostname as hostname3 } from "node:os";
32291
- import { basename as basename5, join as join16, resolve as resolve4 } from "node:path";
32533
+ import { basename as basename5, join as join17, resolve as resolve4 } from "node:path";
32292
32534
  import { fetch as fetch7 } from "undici";
32293
32535
  var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
32294
32536
  var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
@@ -32443,10 +32685,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
32443
32685
  return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
32444
32686
  }
32445
32687
  async function persistConnection(channelId, relayOrigin, runtimeCredential2, defaultWorkspace, environment) {
32446
- const connectionsDirectory = join16(readStateDirectory(environment), "connections");
32688
+ const connectionsDirectory = join17(readStateDirectory(environment), "connections");
32447
32689
  await mkdir4(connectionsDirectory, { mode: 448, recursive: true });
32448
- const connectionPath = join16(connectionsDirectory, `${channelId}.json`);
32449
- const temporaryPath = join16(connectionsDirectory, `.${channelId}.${randomUUID5()}.tmp`);
32690
+ const connectionPath = join17(connectionsDirectory, `${channelId}.json`);
32691
+ const temporaryPath = join17(connectionsDirectory, `.${channelId}.${randomUUID5()}.tmp`);
32450
32692
  await writeFile2(
32451
32693
  temporaryPath,
32452
32694
  `${JSON.stringify(
@@ -32484,7 +32726,7 @@ function decodeSavedConnection(value, expectedChannelId) {
32484
32726
  };
32485
32727
  }
32486
32728
  async function readSavedConnection(channelId, environment) {
32487
- const connectionPath = join16(readStateDirectory(environment), "connections", `${channelId}.json`);
32729
+ const connectionPath = join17(readStateDirectory(environment), "connections", `${channelId}.json`);
32488
32730
  let encoded = "";
32489
32731
  const handle = await open4(connectionPath, "r");
32490
32732
  try {
@@ -32520,7 +32762,7 @@ function buildPairedDaemon(connection, connectionPath, inventory, environment) {
32520
32762
  const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
32521
32763
  relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
32522
32764
  relayUrl.searchParams.set("token", connection.runtimeCredential);
32523
- const auditDatabasePath = join16(readStateDirectory(environment), "audit", `${connection.channelId}.sqlite`);
32765
+ const auditDatabasePath = join17(readStateDirectory(environment), "audit", `${connection.channelId}.sqlite`);
32524
32766
  return {
32525
32767
  channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
32526
32768
  config: createDaemonConfig(
@@ -32579,7 +32821,7 @@ async function pairMobiusRuntime(options, signal, environment = process.env) {
32579
32821
  }
32580
32822
  async function resumeMobiusRuntime(channelId, signal, environment = process.env) {
32581
32823
  const normalizedChannelId = validatePairingId(channelId);
32582
- const connectionPath = join16(readStateDirectory(environment), "connections", `${normalizedChannelId}.json`);
32824
+ const connectionPath = join17(readStateDirectory(environment), "connections", `${normalizedChannelId}.json`);
32583
32825
  const connection = await readSavedConnection(normalizedChannelId, environment);
32584
32826
  const inventory = await discoverLocalAgentInventory({
32585
32827
  defaultWorkspace: connection.defaultWorkspace,
@@ -32654,7 +32896,7 @@ function loadMobiusRuntimeConnection(environment = process.env) {
32654
32896
  throw new MobiusRuntimeConfigurationError("MOBIUS_CHANNEL_ID is invalid");
32655
32897
  }
32656
32898
  return Object.freeze({
32657
- auditDatabasePath: environment["MOBIUS_AUDIT_DATABASE"]?.trim() || join17(readStateDirectory(environment), "audit", `${channelId}.sqlite`),
32899
+ auditDatabasePath: environment["MOBIUS_AUDIT_DATABASE"]?.trim() || join18(readStateDirectory(environment), "audit", `${channelId}.sqlite`),
32658
32900
  channelId,
32659
32901
  defaultWorkspace: loadDefaultWorkspace(environment),
32660
32902
  relayUrl: requiredEnvironmentValue(environment, "MOBIUS_RELAY_URL"),