@moxt-ai/mobius 0.0.17 → 0.0.18

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 (72) hide show
  1. package/dist/agent-catalog/agent-discovery.d.ts +19 -9
  2. package/dist/agent-catalog/agent-discovery.d.ts.map +1 -1
  3. package/dist/agent-catalog/agent-discovery.js +32 -16
  4. package/dist/agent-catalog/agent-discovery.js.map +1 -1
  5. package/dist/agent-catalog/agent-specification.d.ts +0 -1
  6. package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
  7. package/dist/agent-catalog/agent-specification.js +0 -2
  8. package/dist/agent-catalog/agent-specification.js.map +1 -1
  9. package/dist/agent-catalog/agents/cursor-cli-agent.d.ts +0 -1
  10. package/dist/agent-catalog/agents/cursor-cli-agent.d.ts.map +1 -1
  11. package/dist/agent-catalog/agents/cursor-cli-agent.js +0 -1
  12. package/dist/agent-catalog/agents/cursor-cli-agent.js.map +1 -1
  13. package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
  14. package/dist/agent-catalog/discover-agent.js +30 -21
  15. package/dist/agent-catalog/discover-agent.js.map +1 -1
  16. package/dist/agent-catalog/discover-local-agents.d.ts +0 -1
  17. package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
  18. package/dist/agent-catalog/discover-local-agents.js +1 -1
  19. package/dist/agent-catalog/discover-local-agents.js.map +1 -1
  20. package/dist/agent-catalog/local-agent.d.ts +12 -1
  21. package/dist/agent-catalog/local-agent.d.ts.map +1 -1
  22. package/dist/agent-catalog/local-agent.js +16 -0
  23. package/dist/agent-catalog/local-agent.js.map +1 -1
  24. package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
  25. package/dist/agent-catalog/publish-agent-catalog.js +3 -4
  26. package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
  27. package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -1
  28. package/dist/agent-installation/agent-installation-manager.js +6 -7
  29. package/dist/agent-installation/agent-installation-manager.js.map +1 -1
  30. package/dist/agent-installation/fixed-installation-executor.d.ts +2 -3
  31. package/dist/agent-installation/fixed-installation-executor.d.ts.map +1 -1
  32. package/dist/agent-installation/fixed-installation-executor.js +47 -67
  33. package/dist/agent-installation/fixed-installation-executor.js.map +1 -1
  34. package/dist/agent-installation/managed-agent-archive.d.ts +2 -5
  35. package/dist/agent-installation/managed-agent-archive.d.ts.map +1 -1
  36. package/dist/agent-installation/managed-agent-archive.js +1 -1
  37. package/dist/agent-installation/managed-agent-archive.js.map +1 -1
  38. package/dist/agent-installation/verified-download.d.ts +0 -4
  39. package/dist/agent-installation/verified-download.d.ts.map +1 -1
  40. package/dist/agent-installation/verified-download.js +1 -1
  41. package/dist/agent-installation/verified-download.js.map +1 -1
  42. package/dist/cli.js +455 -1450
  43. package/dist/cli.js.map +4 -4
  44. package/dist/index.js +448 -1443
  45. package/dist/index.js.map +4 -4
  46. package/dist/pairing/pair-local-machine.d.ts.map +1 -1
  47. package/dist/pairing/pair-local-machine.js +4 -5
  48. package/dist/pairing/pair-local-machine.js.map +1 -1
  49. package/dist/run-daemon.d.ts.map +1 -1
  50. package/dist/run-daemon.js +162 -57
  51. package/dist/run-daemon.js.map +1 -1
  52. package/package.json +1 -1
  53. package/dist/agent-installation/automatic-adapter-provisioner.d.ts +0 -19
  54. package/dist/agent-installation/automatic-adapter-provisioner.d.ts.map +0 -1
  55. package/dist/agent-installation/automatic-adapter-provisioner.js +0 -125
  56. package/dist/agent-installation/automatic-adapter-provisioner.js.map +0 -1
  57. package/dist/agent-installation/fixed-agent-install-recipe.d.ts +0 -20
  58. package/dist/agent-installation/fixed-agent-install-recipe.d.ts.map +0 -1
  59. package/dist/agent-installation/fixed-agent-install-recipe.js +0 -18
  60. package/dist/agent-installation/fixed-agent-install-recipe.js.map +0 -1
  61. package/dist/agent-installation/fixed-agent-install-recipes.d.ts +0 -26
  62. package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +0 -1
  63. package/dist/agent-installation/fixed-agent-install-recipes.js +0 -301
  64. package/dist/agent-installation/fixed-agent-install-recipes.js.map +0 -1
  65. package/dist/agent-installation/grok-build-install-recipe.d.ts +0 -12
  66. package/dist/agent-installation/grok-build-install-recipe.d.ts.map +0 -1
  67. package/dist/agent-installation/grok-build-install-recipe.js +0 -102
  68. package/dist/agent-installation/grok-build-install-recipe.js.map +0 -1
  69. package/dist/agent-installation/workbuddy-install-recipe.d.ts +0 -12
  70. package/dist/agent-installation/workbuddy-install-recipe.d.ts.map +0 -1
  71. package/dist/agent-installation/workbuddy-install-recipe.js +0 -51
  72. package/dist/agent-installation/workbuddy-install-recipe.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 mkdir6 } from "node:fs/promises";
9
+ import { mkdir as mkdir4 } from "node:fs/promises";
10
10
 
11
11
  // src/agent-catalog/local-agent.ts
12
12
  import { realpathSync, statSync } from "node:fs";
@@ -526,6 +526,22 @@ var InstallableAgentDefinition = class {
526
526
  this.label = label;
527
527
  }
528
528
  };
529
+ var MissingAgentDefinition = class extends InstallableAgentDefinition {
530
+ status = "agent_not_installed";
531
+ constructor(id, label) {
532
+ super(id, label);
533
+ }
534
+ };
535
+ var AgentIntegrationDefinition = class extends InstallableAgentDefinition {
536
+ agentPath;
537
+ agentVersion;
538
+ status = "integration_not_installed";
539
+ constructor(id, label, agentPath, agentVersion) {
540
+ super(id, label);
541
+ this.agentPath = agentPath;
542
+ this.agentVersion = agentVersion;
543
+ }
544
+ };
529
545
  var LocalAgentCatalogSnapshot = class {
530
546
  agents;
531
547
  installableAgents;
@@ -595,12 +611,19 @@ var AvailableAgent = class extends AgentDiscovery {
595
611
  };
596
612
  var UnavailableAgent = class extends AgentDiscovery {
597
613
  };
598
- var MissingAdapter = class extends UnavailableAgent {
614
+ var UnavailableInstalledAgent = class extends UnavailableAgent {
615
+ agent;
616
+ constructor(specification, agent) {
617
+ super(specification);
618
+ this.agent = agent;
619
+ }
620
+ };
621
+ var MissingAdapter = class extends UnavailableInstalledAgent {
599
622
  code = "adapter_not_found";
600
623
  message = "ACP adapter not found";
601
624
  status = "missing_adapter";
602
- constructor(specification) {
603
- super(specification);
625
+ constructor(specification, agent) {
626
+ super(specification, agent);
604
627
  }
605
628
  };
606
629
  var MissingAgent = class extends UnavailableAgent {
@@ -611,7 +634,7 @@ var MissingAgent = class extends UnavailableAgent {
611
634
  super(specification);
612
635
  }
613
636
  };
614
- var ProbeFailed = class extends UnavailableAgent {
637
+ var AgentProbeFailed = class extends UnavailableAgent {
615
638
  code;
616
639
  message;
617
640
  status = "probe_failed";
@@ -621,20 +644,30 @@ var ProbeFailed = class extends UnavailableAgent {
621
644
  this.message = message;
622
645
  }
623
646
  };
624
- var IncompatibleAdapter = class extends UnavailableAgent {
647
+ var IntegrationProbeFailed = class extends UnavailableInstalledAgent {
648
+ code;
649
+ message;
650
+ status = "probe_failed";
651
+ constructor(specification, agent, code, message) {
652
+ super(specification, agent);
653
+ this.code = code;
654
+ this.message = message;
655
+ }
656
+ };
657
+ var IncompatibleAdapter = class extends UnavailableInstalledAgent {
625
658
  code = "acp_incompatible";
626
659
  message = "ACP adapter is incompatible";
627
660
  status = "incompatible_adapter";
628
- constructor(specification) {
629
- super(specification);
661
+ constructor(specification, agent) {
662
+ super(specification, agent);
630
663
  }
631
664
  };
632
- var AuthenticationRequiredAgent = class extends UnavailableAgent {
665
+ var AuthenticationRequiredAgent = class extends UnavailableInstalledAgent {
633
666
  code = "authentication_required";
634
667
  message = "Agent authentication is required";
635
668
  status = "authentication_required";
636
- constructor(specification) {
637
- super(specification);
669
+ constructor(specification, agent) {
670
+ super(specification, agent);
638
671
  }
639
672
  };
640
673
  var LocalAgentInventory = class {
@@ -642,7 +675,7 @@ var LocalAgentInventory = class {
642
675
  discoveries;
643
676
  installable;
644
677
  unavailable;
645
- constructor(discoveries, platform = process.platform, architecture = process.arch) {
678
+ constructor(discoveries) {
646
679
  const available = [];
647
680
  const unavailable = [];
648
681
  for (const discovery of discoveries) {
@@ -657,13 +690,8 @@ var LocalAgentInventory = class {
657
690
  this.available = Object.freeze(available);
658
691
  this.discoveries = Object.freeze([...discoveries]);
659
692
  this.installable = Object.freeze(
660
- unavailable.filter(
661
- (discovery) => !(discovery instanceof AuthenticationRequiredAgent) && discovery.specification.supportsInstallation(
662
- platform,
663
- architecture
664
- )
665
- ).map(
666
- (discovery) => new InstallableAgentDefinition(
693
+ unavailable.map(
694
+ (discovery) => discovery instanceof UnavailableInstalledAgent ? discovery.agent : new MissingAgentDefinition(
667
695
  discovery.specification.id,
668
696
  discovery.specification.label
669
697
  )
@@ -1132,7 +1160,6 @@ var LocalAgentSpecification = class {
1132
1160
  createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
1133
1161
  recoveryCommand = () => "";
1134
1162
  resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
1135
- supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
1136
1163
  verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
1137
1164
  };
1138
1165
  var DirectAcpAgentDefinition = class extends LocalAgentSpecification {
@@ -1280,7 +1307,6 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
1280
1307
  ["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
1281
1308
  );
1282
1309
  }
1283
- supportsInstallation = (_platform, _architecture) => false;
1284
1310
  verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
1285
1311
  const capabilities = initialized.agentCapabilities ?? {};
1286
1312
  if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
@@ -1594,14 +1620,14 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
1594
1620
  import { join as join8 } from "node:path";
1595
1621
 
1596
1622
  // src/agent-installation/managed-agent-archive.ts
1597
- import { createHash as createHash2 } from "node:crypto";
1623
+ import { createHash } from "node:crypto";
1598
1624
  import { createReadStream } from "node:fs";
1599
1625
  import {
1600
1626
  chmod,
1601
1627
  copyFile,
1602
1628
  mkdir as mkdir2,
1603
1629
  mkdtemp as mkdtemp2,
1604
- open as open3,
1630
+ open as open2,
1605
1631
  realpath as realpath5,
1606
1632
  rename as rename2,
1607
1633
  rm as rm2,
@@ -1611,208 +1637,16 @@ import {
1611
1637
  import { dirname as dirname2, isAbsolute as isAbsolute4, join as join7, relative as relative3, sep as sep3 } from "node:path";
1612
1638
 
1613
1639
  // src/agent-installation/verified-download.ts
1614
- import { createHash } from "node:crypto";
1615
- import { open as open2, unlink } from "node:fs/promises";
1616
1640
  import { fetch } from "undici";
1617
1641
 
1618
1642
  // src/network/environment-proxy.ts
1619
1643
  import { EnvHttpProxyAgent } from "undici";
1620
1644
  var environmentProxyDispatcher = new EnvHttpProxyAgent();
1621
1645
 
1622
- // src/agent-installation/verified-download.ts
1623
- var MAX_REDIRECTS = 4;
1624
- var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
1625
- var InstallerDownloadError = class extends Error {
1626
- code;
1627
- constructor(code, message, options = {}) {
1628
- super(message, options);
1629
- this.code = code;
1630
- this.name = "InstallerDownloadError";
1631
- }
1632
- };
1633
- var VerifiedDownload = class {
1634
- bytes;
1635
- sha256;
1636
- url;
1637
- constructor(url2, bytes, sha256) {
1638
- this.bytes = bytes;
1639
- this.sha256 = sha256;
1640
- this.url = url2;
1641
- }
1642
- };
1643
- var UndiciInstallerDownloadTransport = class {
1644
- get = async (url2, signal) => await fetch(url2, {
1645
- dispatcher: environmentProxyDispatcher,
1646
- headers: {
1647
- accept: "text/plain, application/octet-stream;q=0.9",
1648
- "user-agent": "Mobius-Agent-Installer/0.0.3"
1649
- },
1650
- method: "GET",
1651
- redirect: "manual",
1652
- signal
1653
- });
1654
- };
1655
- function validateUrl(url2, allowedHosts) {
1656
- if (url2.protocol !== "https:" || url2.username.length > 0 || url2.password.length > 0 || url2.port.length > 0 || !allowedHosts.has(url2.hostname)) {
1657
- throw new InstallerDownloadError(
1658
- "installer_host_not_allowed",
1659
- "The installer download target is not allowed"
1660
- );
1661
- }
1662
- }
1663
- async function fetchInstaller(options, signal, transport) {
1664
- let url2 = new URL(options.url);
1665
- for (let redirectCount = 0; redirectCount <= MAX_REDIRECTS; redirectCount += 1) {
1666
- validateUrl(url2, options.allowedHosts);
1667
- const response = await transport.get(url2, signal);
1668
- if (!REDIRECT_STATUSES.has(response.status)) {
1669
- return { response, url: url2 };
1670
- }
1671
- await response.body?.cancel();
1672
- const location = response.headers.get("location");
1673
- if (location === null || redirectCount === MAX_REDIRECTS) {
1674
- throw new InstallerDownloadError(
1675
- "installer_redirect_invalid",
1676
- "The installer returned an invalid redirect"
1677
- );
1678
- }
1679
- let redirected;
1680
- try {
1681
- redirected = new URL(location, url2);
1682
- } catch (error61) {
1683
- throw new InstallerDownloadError(
1684
- "installer_redirect_invalid",
1685
- "The installer returned an invalid redirect",
1686
- { cause: error61 }
1687
- );
1688
- }
1689
- try {
1690
- validateUrl(redirected, options.allowedHosts);
1691
- } catch (error61) {
1692
- throw new InstallerDownloadError(
1693
- "installer_redirect_not_allowed",
1694
- "The installer redirect left the approved host allowlist",
1695
- { cause: error61 }
1696
- );
1697
- }
1698
- url2 = redirected;
1699
- }
1700
- throw new InstallerDownloadError(
1701
- "installer_redirect_invalid",
1702
- "The installer returned too many redirects"
1703
- );
1704
- }
1705
- async function writeCompleteChunk(handle, chunk) {
1706
- let offset = 0;
1707
- while (offset < chunk.byteLength) {
1708
- const written = await handle.write(
1709
- chunk,
1710
- offset,
1711
- chunk.byteLength - offset
1712
- );
1713
- if (written.bytesWritten < 1) {
1714
- throw new InstallerDownloadError(
1715
- "installer_write_failed",
1716
- "The verified installer could not be stored"
1717
- );
1718
- }
1719
- offset += written.bytesWritten;
1720
- }
1721
- }
1722
- async function downloadVerifiedFile(options, transport = new UndiciInstallerDownloadTransport()) {
1723
- options.signal.throwIfAborted();
1724
- const timeoutSignal = AbortSignal.timeout(options.timeoutMilliseconds);
1725
- const signal = AbortSignal.any([options.signal, timeoutSignal]);
1726
- let handle = null;
1727
- let responseBody = null;
1728
- try {
1729
- const fetched = await fetchInstaller(options, signal, transport);
1730
- responseBody = fetched.response.body;
1731
- if (!fetched.response.ok || fetched.response.body === null) {
1732
- throw new InstallerDownloadError(
1733
- "installer_download_failed",
1734
- "The approved installer could not be downloaded"
1735
- );
1736
- }
1737
- const contentLength = fetched.response.headers.get("content-length");
1738
- if (contentLength !== null) {
1739
- const declaredLength = Number(contentLength);
1740
- if (!Number.isSafeInteger(declaredLength) || declaredLength < 1 || declaredLength > options.maximumBytes) {
1741
- throw new InstallerDownloadError(
1742
- "installer_size_invalid",
1743
- "The installer size is outside the approved limit"
1744
- );
1745
- }
1746
- }
1747
- handle = await open2(options.destination, "wx", 384);
1748
- const digest = createHash("sha256");
1749
- const reader = fetched.response.body.getReader();
1750
- let bytes = 0;
1751
- try {
1752
- while (true) {
1753
- signal.throwIfAborted();
1754
- const chunk = await reader.read();
1755
- if (chunk.done) {
1756
- break;
1757
- }
1758
- bytes += chunk.value.byteLength;
1759
- if (bytes > options.maximumBytes) {
1760
- throw new InstallerDownloadError(
1761
- "installer_size_invalid",
1762
- "The installer exceeded the approved size limit"
1763
- );
1764
- }
1765
- digest.update(chunk.value);
1766
- await writeCompleteChunk(handle, chunk.value);
1767
- }
1768
- } finally {
1769
- await reader.cancel().catch(() => void 0);
1770
- reader.releaseLock();
1771
- }
1772
- if (bytes === 0) {
1773
- throw new InstallerDownloadError(
1774
- "installer_verification_failed",
1775
- "The downloaded installer is empty"
1776
- );
1777
- }
1778
- await handle.sync();
1779
- await handle.close();
1780
- handle = null;
1781
- return new VerifiedDownload(fetched.url, bytes, digest.digest("hex"));
1782
- } catch (error61) {
1783
- if (handle !== null) {
1784
- await handle.close().catch(() => void 0);
1785
- }
1786
- await unlink(options.destination).catch(() => void 0);
1787
- if (options.signal.aborted) {
1788
- options.signal.throwIfAborted();
1789
- }
1790
- if (timeoutSignal.aborted) {
1791
- throw new InstallerDownloadError(
1792
- "installer_download_timeout",
1793
- "The installer download timed out",
1794
- { cause: error61 }
1795
- );
1796
- }
1797
- if (error61 instanceof InstallerDownloadError) {
1798
- throw error61;
1799
- }
1800
- throw new InstallerDownloadError(
1801
- "installer_download_failed",
1802
- "The approved installer could not be downloaded",
1803
- { cause: error61 }
1804
- );
1805
- } finally {
1806
- await responseBody?.cancel().catch(() => void 0);
1807
- }
1808
- }
1809
-
1810
1646
  // src/agent-installation/managed-agent-archive.ts
1811
1647
  var ARCHIVE_DOWNLOAD_LIMIT_BYTES = 128 * 1024 * 1024;
1812
1648
  var ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3;
1813
- var ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS = 6e4;
1814
1649
  var MANIFEST_LIMIT_BYTES = 16 * 1024;
1815
- var MINIMAL_PATH = "/usr/bin:/bin";
1816
1650
  var ManagedAgentArchiveDefinition = class {
1817
1651
  archiveName;
1818
1652
  archiveSha256;
@@ -1851,9 +1685,6 @@ var ManagedAgentArchiveError = class extends Error {
1851
1685
  this.name = "ManagedAgentArchiveError";
1852
1686
  }
1853
1687
  };
1854
- var ManagedAgentArchiveDownloader = class {
1855
- download = async (options) => await downloadVerifiedFile(options);
1856
- };
1857
1688
  function isRecord2(value) {
1858
1689
  return typeof value === "object" && value !== null && !Array.isArray(value);
1859
1690
  }
@@ -1863,7 +1694,7 @@ function isContainedPath3(root, candidate) {
1863
1694
  }
1864
1695
  async function hashFile(path2, signal) {
1865
1696
  signal.throwIfAborted();
1866
- const digest = createHash2("sha256");
1697
+ const digest = createHash("sha256");
1867
1698
  const stream = createReadStream(path2, { signal });
1868
1699
  try {
1869
1700
  for await (const chunk of stream) {
@@ -1894,7 +1725,7 @@ async function hashFile(path2, signal) {
1894
1725
  async function readManifest(path2) {
1895
1726
  let handle;
1896
1727
  try {
1897
- handle = await open3(path2, "r");
1728
+ handle = await open2(path2, "r");
1898
1729
  } catch (error61) {
1899
1730
  throw new ManagedAgentArchiveError(
1900
1731
  "managed_archive_verification_failed",
@@ -1965,144 +1796,6 @@ async function validateManagedAgentArchive(root, definition, signal) {
1965
1796
  );
1966
1797
  }
1967
1798
  }
1968
- function validateArchiveEntries(output2, definition) {
1969
- const entries = output2.split(/\r?\n/).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
1970
- if (entries.length !== 1 || entries[0] !== definition.executableName && entries[0] !== `./${definition.executableName}`) {
1971
- throw new ManagedAgentArchiveError(
1972
- "managed_archive_verification_failed",
1973
- "The managed Agent archive contains unexpected entries"
1974
- );
1975
- }
1976
- }
1977
- var ManagedAgentArchiveInstaller = class {
1978
- #downloader;
1979
- constructor(downloader = new ManagedAgentArchiveDownloader()) {
1980
- this.#downloader = downloader;
1981
- }
1982
- install = async (root, definition, signal) => {
1983
- signal.throwIfAborted();
1984
- try {
1985
- const metadata = await stat4(root);
1986
- if (metadata.isDirectory()) {
1987
- return await validateManagedAgentArchive(root, definition, signal);
1988
- }
1989
- } catch (error61) {
1990
- if (error61 instanceof ManagedAgentArchiveError || !(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
1991
- throw error61;
1992
- }
1993
- }
1994
- const parent = dirname2(root);
1995
- await mkdir2(parent, { mode: 448, recursive: true });
1996
- const working = await mkdtemp2(
1997
- join7(parent, `.${definition.version}.archive-`)
1998
- );
1999
- const staging = await mkdtemp2(
2000
- join7(parent, `.${definition.version}.staging-`)
2001
- );
2002
- try {
2003
- const archivePath = join7(working, definition.archiveName);
2004
- const extractionRoot = join7(working, "extracted");
2005
- await mkdir2(extractionRoot, { mode: 448 });
2006
- const canonicalExtractionRoot = await realpath5(extractionRoot);
2007
- const download = await this.#downloader.download({
2008
- allowedHosts: /* @__PURE__ */ new Set([
2009
- "github.com",
2010
- "objects.githubusercontent.com",
2011
- "release-assets.githubusercontent.com"
2012
- ]),
2013
- destination: archivePath,
2014
- maximumBytes: ARCHIVE_DOWNLOAD_LIMIT_BYTES,
2015
- signal,
2016
- timeoutMilliseconds: ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS,
2017
- url: definition.archiveUrl
2018
- });
2019
- if (download.sha256 !== definition.archiveSha256) {
2020
- throw new ManagedAgentArchiveError(
2021
- "managed_archive_verification_failed",
2022
- "The managed Agent archive checksum is invalid"
2023
- );
2024
- }
2025
- const list = await runBoundedProcess({
2026
- arguments: definition.listArguments(archivePath),
2027
- command: definition.extractor,
2028
- cwd: working,
2029
- environment: { PATH: MINIMAL_PATH },
2030
- outputLimitBytes: 64 * 1024,
2031
- signal,
2032
- timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
2033
- });
2034
- validateArchiveEntries(list.stdout, definition);
2035
- await runBoundedProcess({
2036
- arguments: definition.extractArguments(archivePath, extractionRoot),
2037
- command: definition.extractor,
2038
- cwd: working,
2039
- environment: { PATH: MINIMAL_PATH },
2040
- outputLimitBytes: 64 * 1024,
2041
- signal,
2042
- timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
2043
- });
2044
- const extracted = await realpath5(
2045
- join7(canonicalExtractionRoot, definition.executableName)
2046
- );
2047
- const extractedMetadata = await stat4(extracted);
2048
- if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
2049
- throw new ManagedAgentArchiveError(
2050
- "managed_archive_verification_failed",
2051
- "The managed Agent archive executable is invalid"
2052
- );
2053
- }
2054
- const binDirectory = join7(staging, "bin");
2055
- const executablePath = join7(binDirectory, definition.executableName);
2056
- await mkdir2(binDirectory, { mode: 448 });
2057
- await copyFile(extracted, executablePath);
2058
- await chmod(executablePath, 448);
2059
- const executableSha256 = await hashFile(executablePath, signal);
2060
- await writeFile(
2061
- join7(staging, "archive.json"),
2062
- `${JSON.stringify({
2063
- archiveSha256: definition.archiveSha256,
2064
- archiveUrl: definition.archiveUrl.toString(),
2065
- executableSha256,
2066
- version: definition.version
2067
- })}
2068
- `,
2069
- { mode: 384 }
2070
- );
2071
- await validateManagedAgentArchive(staging, definition, signal);
2072
- try {
2073
- await rename2(staging, root);
2074
- } catch (error61) {
2075
- try {
2076
- return await validateManagedAgentArchive(root, definition, signal);
2077
- } catch {
2078
- throw new ManagedAgentArchiveError(
2079
- "managed_archive_publish_failed",
2080
- "The managed Agent archive could not be published",
2081
- { cause: error61 }
2082
- );
2083
- }
2084
- }
2085
- return await validateManagedAgentArchive(root, definition, signal);
2086
- } catch (error61) {
2087
- if (signal.aborted) {
2088
- signal.throwIfAborted();
2089
- }
2090
- if (error61 instanceof ManagedAgentArchiveError) {
2091
- throw error61;
2092
- }
2093
- throw new ManagedAgentArchiveError(
2094
- "managed_archive_install_failed",
2095
- "The pinned Agent archive could not be installed",
2096
- { cause: error61 }
2097
- );
2098
- } finally {
2099
- await Promise.all([
2100
- rm2(working, { force: true, recursive: true }),
2101
- rm2(staging, { force: true, recursive: true })
2102
- ]);
2103
- }
2104
- };
2105
- };
2106
1799
 
2107
1800
  // src/agent-installation/opencode-managed-release.ts
2108
1801
  var OPENCODE_MANAGED_VERSION = "1.18.29";
@@ -2644,10 +2337,6 @@ async function resolveAdapterExecutables(specification, context) {
2644
2337
  context
2645
2338
  );
2646
2339
  }
2647
- async function resolveAgentExecutable(specification, context) {
2648
- const executables = await resolveAgentExecutables(specification, context);
2649
- return executables[0] ?? null;
2650
- }
2651
2340
  async function resolveAdapterExecutable(specification, context) {
2652
2341
  const executables = await resolveAdapterExecutables(specification, context);
2653
2342
  return executables[0] ?? null;
@@ -2713,41 +2402,41 @@ var DiscoveryAcpHandler = class {
2713
2402
  };
2714
2403
  function readableAcpStream(input2) {
2715
2404
  let byteLength = 0;
2716
- let open6 = true;
2405
+ let open5 = true;
2717
2406
  return new ReadableStream({
2718
2407
  start(controller) {
2719
2408
  input2.on("data", (chunk) => {
2720
- if (!open6) {
2409
+ if (!open5) {
2721
2410
  return;
2722
2411
  }
2723
2412
  if (!(chunk instanceof Uint8Array)) {
2724
- open6 = false;
2413
+ open5 = false;
2725
2414
  controller.error(new Error("ACP adapter produced invalid output"));
2726
2415
  return;
2727
2416
  }
2728
2417
  byteLength += chunk.byteLength;
2729
2418
  if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
2730
- open6 = false;
2419
+ open5 = false;
2731
2420
  controller.error(new Error("ACP adapter output limit exceeded"));
2732
2421
  return;
2733
2422
  }
2734
2423
  controller.enqueue(new Uint8Array(chunk));
2735
2424
  });
2736
2425
  input2.once("end", () => {
2737
- if (open6) {
2738
- open6 = false;
2426
+ if (open5) {
2427
+ open5 = false;
2739
2428
  controller.close();
2740
2429
  }
2741
2430
  });
2742
2431
  input2.once("error", (error61) => {
2743
- if (open6) {
2744
- open6 = false;
2432
+ if (open5) {
2433
+ open5 = false;
2745
2434
  controller.error(error61);
2746
2435
  }
2747
2436
  });
2748
2437
  },
2749
2438
  cancel() {
2750
- open6 = false;
2439
+ open5 = false;
2751
2440
  }
2752
2441
  });
2753
2442
  }
@@ -2876,25 +2565,50 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
2876
2565
  }
2877
2566
 
2878
2567
  // src/agent-catalog/discover-agent.ts
2879
- function probeFailure(specification, executableKind, error61) {
2568
+ function agentProbeFailure(specification, error61) {
2569
+ if (error61 instanceof AgentProbeError) {
2570
+ return new AgentProbeFailed(specification, error61.code, error61.message);
2571
+ }
2572
+ if (error61 instanceof ProcessExecutionError) {
2573
+ const code = error61.code === "process_timeout" ? "agent_probe_timeout" : "agent_probe_failed";
2574
+ return new AgentProbeFailed(
2575
+ specification,
2576
+ code,
2577
+ "Agent version probe failed"
2578
+ );
2579
+ }
2580
+ return new AgentProbeFailed(
2581
+ specification,
2582
+ "agent_probe_failed",
2583
+ "Agent probe failed"
2584
+ );
2585
+ }
2586
+ function integrationProbeFailure(specification, agent, error61) {
2880
2587
  if (error61 instanceof AgentProbeError) {
2881
2588
  if (error61.code === "authentication_required") {
2882
- return new AuthenticationRequiredAgent(specification);
2589
+ return new AuthenticationRequiredAgent(specification, agent);
2883
2590
  }
2884
- return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new ProbeFailed(specification, error61.code, error61.message);
2591
+ return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification, agent) : new IntegrationProbeFailed(
2592
+ specification,
2593
+ agent,
2594
+ error61.code,
2595
+ error61.message
2596
+ );
2885
2597
  }
2886
2598
  if (error61 instanceof ProcessExecutionError) {
2887
- const code = error61.code === "process_timeout" ? `${executableKind}_probe_timeout` : `${executableKind}_probe_failed`;
2888
- return new ProbeFailed(
2599
+ const code = error61.code === "process_timeout" ? "adapter_probe_timeout" : "adapter_probe_failed";
2600
+ return new IntegrationProbeFailed(
2889
2601
  specification,
2602
+ agent,
2890
2603
  code,
2891
- `${executableKind === "agent" ? "Agent" : "Adapter"} version probe failed`
2604
+ "Adapter version probe failed"
2892
2605
  );
2893
2606
  }
2894
- return new ProbeFailed(
2607
+ return new IntegrationProbeFailed(
2895
2608
  specification,
2896
- `${executableKind}_probe_failed`,
2897
- `${executableKind === "agent" ? "Agent" : "Adapter"} probe failed`
2609
+ agent,
2610
+ "adapter_probe_failed",
2611
+ "Adapter probe failed"
2898
2612
  );
2899
2613
  }
2900
2614
  async function discoverAgent(specification, context) {
@@ -2903,12 +2617,6 @@ async function discoverAgent(specification, context) {
2903
2617
  resolveAdapterExecutables(specification, context),
2904
2618
  resolveAgentExecutables(specification, context)
2905
2619
  ]);
2906
- if (specification instanceof DirectAcpAgentDefinition && agents.length === 0) {
2907
- return new MissingAgent(specification);
2908
- }
2909
- if (adapters.length === 0) {
2910
- return new MissingAdapter(specification);
2911
- }
2912
2620
  if (agents.length === 0) {
2913
2621
  return new MissingAgent(specification);
2914
2622
  }
@@ -2928,9 +2636,18 @@ async function discoverAgent(specification, context) {
2928
2636
  if (context.signal.aborted) {
2929
2637
  context.signal.throwIfAborted();
2930
2638
  }
2931
- lastFailure = probeFailure(specification, "agent", error61);
2639
+ lastFailure = agentProbeFailure(specification, error61);
2932
2640
  continue;
2933
2641
  }
2642
+ const installedAgent = new AgentIntegrationDefinition(
2643
+ specification.id,
2644
+ specification.label,
2645
+ agent.identity.requestedPath,
2646
+ agentVersion
2647
+ );
2648
+ if (adapters.length === 0) {
2649
+ return new MissingAdapter(specification, installedAgent);
2650
+ }
2934
2651
  for (const adapter of adapters) {
2935
2652
  if (specification instanceof DirectAcpAgentDefinition && adapter.path !== agent.path) {
2936
2653
  continue;
@@ -2959,7 +2676,11 @@ async function discoverAgent(specification, context) {
2959
2676
  if (context.signal.aborted) {
2960
2677
  context.signal.throwIfAborted();
2961
2678
  }
2962
- lastFailure = probeFailure(specification, "adapter", error61);
2679
+ lastFailure = integrationProbeFailure(
2680
+ specification,
2681
+ installedAgent,
2682
+ error61
2683
+ );
2963
2684
  continue;
2964
2685
  }
2965
2686
  const definition = new LocalAgentDefinition(
@@ -3008,7 +2729,11 @@ async function discoverAgent(specification, context) {
3008
2729
  if (context.signal.aborted) {
3009
2730
  context.signal.throwIfAborted();
3010
2731
  }
3011
- const failure = probeFailure(specification, "adapter", error61);
2732
+ const failure = integrationProbeFailure(
2733
+ specification,
2734
+ installedAgent,
2735
+ error61
2736
+ );
3012
2737
  if (failure instanceof AuthenticationRequiredAgent) {
3013
2738
  return failure;
3014
2739
  }
@@ -3016,7 +2741,7 @@ async function discoverAgent(specification, context) {
3016
2741
  }
3017
2742
  }
3018
2743
  }
3019
- return lastFailure ?? new IncompatibleAdapter(specification);
2744
+ return lastFailure ?? new MissingAgent(specification);
3020
2745
  }
3021
2746
 
3022
2747
  // src/agent-catalog/discover-local-agents.ts
@@ -3027,11 +2752,7 @@ async function discoverLocalAgentInventory(options) {
3027
2752
  async (specification) => await discoverAgent(specification, options)
3028
2753
  )
3029
2754
  );
3030
- return new LocalAgentInventory(
3031
- discoveries,
3032
- options.platform,
3033
- options.architecture
3034
- );
2755
+ return new LocalAgentInventory(discoveries);
3035
2756
  }
3036
2757
 
3037
2758
  // src/audit/audit-store.ts
@@ -5047,8 +4768,8 @@ function emoji() {
5047
4768
  }
5048
4769
  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])$/;
5049
4770
  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}|:))$/;
5050
- var mac = (delimiter3) => {
5051
- const escapedDelim = escapeRegex(delimiter3 ?? ":");
4771
+ var mac = (delimiter2) => {
4772
+ const escapedDelim = escapeRegex(delimiter2 ?? ":");
5052
4773
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
5053
4774
  };
5054
4775
  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])$/;
@@ -8105,7 +7826,7 @@ function bucketFor(state, inst) {
8105
7826
  return bucket;
8106
7827
  }
8107
7828
  var handoff;
8108
- var open4 = [];
7829
+ var open3 = [];
8109
7830
  var memo = {
8110
7831
  alloc(_inst, payload, empty) {
8111
7832
  const bucket = handoff;
@@ -8114,7 +7835,7 @@ var memo = {
8114
7835
  handoff = void 0;
8115
7836
  const entry = { value: empty, issues: null };
8116
7837
  bucket.set(payload.value, entry);
8117
- open4.push(entry);
7838
+ open3.push(entry);
8118
7839
  return empty;
8119
7840
  },
8120
7841
  guard(inst) {
@@ -8180,10 +7901,10 @@ var memo = {
8180
7901
  return payload;
8181
7902
  }
8182
7903
  handoff = bucket;
8183
- const depth = open4.length;
7904
+ const depth = open3.length;
8184
7905
  const result = base(payload, ctx);
8185
7906
  handoff = void 0;
8186
- const entry = open4.length > depth ? open4.pop() : void 0;
7907
+ const entry = open3.length > depth ? open3.pop() : void 0;
8187
7908
  if (result instanceof Promise) {
8188
7909
  return result.then((r) => {
8189
7910
  if (entry)
@@ -22021,13 +21742,13 @@ var SESSION_ELICITATION_RESPOND_KIND = "session.elicitation.respond";
22021
21742
  var SESSION_ELICITATION_RESOLVED_KIND = "session.elicitation.resolved";
22022
21743
  var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
22023
21744
  var AGENT_CONTENT_KIND = "agent.content";
22024
- var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
22025
- var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
22026
- var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
22027
- var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
22028
- var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
22029
- var AGENT_INSTALL_FAILED_KIND = "agent.install.failed";
22030
- var AGENT_INSTALL_CANCELLED_KIND = "agent.install.cancelled";
21745
+ var AGENT_INSTALL_REQUEST_KIND = "agent.integration.install.request";
21746
+ var AGENT_INSTALL_CANCEL_KIND = "agent.integration.install.cancel";
21747
+ var AGENT_INSTALL_STARTED_KIND = "agent.integration.install.started";
21748
+ var AGENT_INSTALL_PROGRESS_KIND = "agent.integration.install.progress";
21749
+ var AGENT_INSTALL_COMPLETED_KIND = "agent.integration.install.completed";
21750
+ var AGENT_INSTALL_FAILED_KIND = "agent.integration.install.failed";
21751
+ var AGENT_INSTALL_CANCELLED_KIND = "agent.integration.install.cancelled";
22031
21752
  var IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
22032
21753
  var DIRECTORY_IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
22033
21754
  var IDENTIFIER = external_exports.string().min(1).max(128).regex(IDENTIFIER_PATTERN);
@@ -23569,7 +23290,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
23569
23290
  import { randomUUID } from "node:crypto";
23570
23291
  import {
23571
23292
  mkdir as mkdir3,
23572
- open as open5,
23293
+ open as open4,
23573
23294
  realpath as realpath6,
23574
23295
  rename as rename3,
23575
23296
  stat as stat5,
@@ -23790,6 +23511,8 @@ function decodeClaimResponse(value) {
23790
23511
  }
23791
23512
  async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
23792
23513
  const agents = localAgents.map((agent) => ({
23514
+ agentPath: agent.agentIdentity.requestedPath,
23515
+ agentVersion: agent.agentVersion,
23793
23516
  id: agent.id,
23794
23517
  label: agent.label
23795
23518
  }));
@@ -23799,10 +23522,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
23799
23522
  response = await fetch2(endpoint, {
23800
23523
  body: JSON.stringify({
23801
23524
  agents,
23802
- installableAgents: installableAgents.map((agent) => ({
23803
- id: agent.id,
23804
- label: agent.label
23805
- })),
23525
+ installableAgents,
23806
23526
  machineName: hostname3(),
23807
23527
  pairingCode: options.code,
23808
23528
  workspaceName: basename(defaultWorkspace) || "Local workspace"
@@ -23885,7 +23605,7 @@ async function readSavedConnection(channelId) {
23885
23605
  `${channelId}.json`
23886
23606
  );
23887
23607
  let encoded = "";
23888
- const handle = await open5(connectionPath, "r");
23608
+ const handle = await open4(connectionPath, "r");
23889
23609
  try {
23890
23610
  const metadata = await handle.stat();
23891
23611
  if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
@@ -23922,7 +23642,7 @@ function assertInventoryUsable(inventory) {
23922
23642
  if (inventory.available.length + inventory.installable.length === 0) {
23923
23643
  throw new PairingClientError(
23924
23644
  "no_supported_agent",
23925
- "No supported Agent is ready or safely installable on this machine"
23645
+ "No supported Agent is available for local discovery"
23926
23646
  );
23927
23647
  }
23928
23648
  }
@@ -24010,7 +23730,7 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
24010
23730
  // src/run-daemon.ts
24011
23731
  import { basename as basename3 } from "node:path";
24012
23732
  import { styleText } from "node:util";
24013
- import { WebSocket as WebSocket2 } from "undici";
23733
+ import { fetch as fetch4, WebSocket as WebSocket2 } from "undici";
24014
23734
 
24015
23735
  // src/acp/session-manager.ts
24016
23736
  import { spawn as spawn3 } from "node:child_process";
@@ -27342,13 +27062,12 @@ async function publishAgentCatalog(config2, signal) {
27342
27062
  response = await fetch3(catalogEndpoint(config2.relayUrl), {
27343
27063
  body: JSON.stringify({
27344
27064
  agents: catalog.agents.map((agent) => ({
27065
+ agentPath: agent.agentIdentity.requestedPath,
27066
+ agentVersion: agent.agentVersion,
27345
27067
  id: agent.id,
27346
27068
  label: agent.label
27347
27069
  })),
27348
- installableAgents: catalog.installableAgents.map((agent) => ({
27349
- id: agent.id,
27350
- label: agent.label
27351
- }))
27070
+ installableAgents: catalog.installableAgents
27352
27071
  }),
27353
27072
  dispatcher: environmentProxyDispatcher,
27354
27073
  headers: { "content-type": "application/json" },
@@ -27444,7 +27163,7 @@ var InstallationJob = class {
27444
27163
  };
27445
27164
  function authorizedSpecificationFor(specifications, agentId) {
27446
27165
  for (const specification of specifications) {
27447
- if (specification.id === agentId && specification.supportsInstallation(process.platform, process.arch)) {
27166
+ if (specification.id === agentId) {
27448
27167
  return specification;
27449
27168
  }
27450
27169
  }
@@ -27456,7 +27175,7 @@ function executionFailure(error61) {
27456
27175
  }
27457
27176
  return new InstallationManagerError(
27458
27177
  "installation_failed",
27459
- "The local Agent installation failed",
27178
+ "The local Agent integration installation failed",
27460
27179
  { cause: error61 }
27461
27180
  );
27462
27181
  }
@@ -27527,7 +27246,7 @@ var AgentInstallationManager = class {
27527
27246
  command.requestId,
27528
27247
  command.agentId,
27529
27248
  "installation_in_progress",
27530
- "An installation for this Agent is already running"
27249
+ "An integration installation for this Agent is already running"
27531
27250
  );
27532
27251
  const job2 = new InstallationJob(command.requestId, command.agentId);
27533
27252
  job2.state = busy;
@@ -27564,7 +27283,7 @@ var AgentInstallationManager = class {
27564
27283
  job.requestId,
27565
27284
  job.agentId
27566
27285
  );
27567
- job.controller.abort(new Error("Agent installation cancelled"));
27286
+ job.controller.abort(new Error("Agent integration installation cancelled"));
27568
27287
  return await job.completion.promise;
27569
27288
  };
27570
27289
  close = async () => {
@@ -27574,7 +27293,7 @@ var AgentInstallationManager = class {
27574
27293
  if (job === void 0) {
27575
27294
  throw new InstallationManagerError(
27576
27295
  "installation_state_invalid",
27577
- "An active Agent installation is unavailable"
27296
+ "An active Agent integration installation is unavailable"
27578
27297
  );
27579
27298
  }
27580
27299
  job.controller.abort(new Error("Mobius daemon stopped"));
@@ -27596,7 +27315,7 @@ var AgentInstallationManager = class {
27596
27315
  job.controller.abort(
27597
27316
  new InstallationManagerError(
27598
27317
  "installation_timeout",
27599
- "The local Agent installation exceeded its deadline"
27318
+ "The local Agent integration installation exceeded its deadline"
27600
27319
  )
27601
27320
  );
27602
27321
  }, INSTALLATION_DEADLINE_MILLISECONDS);
@@ -27686,891 +27405,66 @@ var AgentInstallationManager = class {
27686
27405
  };
27687
27406
  };
27688
27407
 
27689
- // src/agent-installation/automatic-adapter-provisioner.ts
27690
- import { randomUUID as randomUUID2 } from "node:crypto";
27691
- var AUTOMATIC_ADAPTER_FAILURE_CODES = /* @__PURE__ */ new Set([
27692
- "adapter_not_found",
27693
- "adapter_probe_failed",
27694
- "adapter_probe_timeout",
27695
- "acp_incompatible"
27696
- ]);
27697
- var InstalledAutomaticAdapter = class {
27698
- executable;
27699
- requestId;
27700
- specification;
27701
- constructor(specification, requestId, executable) {
27702
- this.executable = executable;
27703
- this.requestId = requestId;
27704
- this.specification = specification;
27408
+ // src/agent-installation/fixed-installation-executor.ts
27409
+ import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27410
+ import { resolve as resolve4 } from "node:path";
27411
+ function findSpecification(specifications, agentId) {
27412
+ for (const specification of specifications) {
27413
+ if (specification.id === agentId) {
27414
+ return specification;
27415
+ }
27705
27416
  }
27706
- };
27707
- function shouldProvisionAdapter(unavailable, options) {
27708
- return unavailable.specification instanceof BridgedAcpAgentDefinition && AUTOMATIC_ADAPTER_FAILURE_CODES.has(unavailable.code) && options.environment[unavailable.specification.adapterOverrideVariable] === void 0 && unavailable.specification.supportsInstallation(
27709
- options.platform ?? process.platform,
27710
- options.architecture ?? process.arch
27417
+ throw new InstallationManagerError(
27418
+ "unknown_agent",
27419
+ "The requested Agent is not supported"
27711
27420
  );
27712
27421
  }
27713
- function stableFailureCode(error61) {
27714
- return error61 instanceof ManagedAdapterInstallError ? error61.code : "adapter_install_failed";
27422
+ function resolveDefaultWorkspace2(path2) {
27423
+ try {
27424
+ const directory = realpathSync2(resolve4(path2));
27425
+ if (!statSync2(directory).isDirectory()) {
27426
+ throw new Error("Default workspace is not a directory");
27427
+ }
27428
+ return directory;
27429
+ } catch (error61) {
27430
+ throw new InstallationManagerError(
27431
+ "unsafe_installation_root",
27432
+ "The default workspace is unavailable or unsafe",
27433
+ { cause: error61 }
27434
+ );
27435
+ }
27715
27436
  }
27716
- function discoveryOptions(options, environment, signal, specifications) {
27717
- return {
27718
- ...options.architecture === void 0 ? {} : { architecture: options.architecture },
27719
- defaultWorkspace: options.defaultWorkspace,
27720
- environment,
27721
- ...options.platform === void 0 ? {} : { platform: options.platform },
27722
- signal,
27723
- specifications
27724
- };
27437
+ function resolveIntegrationStateDirectory(path2) {
27438
+ try {
27439
+ const directory = realpathSync2(resolve4(path2));
27440
+ const metadata = statSync2(directory);
27441
+ if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
27442
+ throw new Error("Installation directory is not user-owned");
27443
+ }
27444
+ return directory;
27445
+ } catch (error61) {
27446
+ throw new InstallationManagerError(
27447
+ "unsafe_installation_root",
27448
+ "The local integration state directory is unavailable or unsafe",
27449
+ { cause: error61 }
27450
+ );
27451
+ }
27725
27452
  }
27726
- var AutomaticAdapterProvisioner = class {
27727
- #adapterInstaller;
27728
- #options;
27729
- #specifications;
27730
- constructor(options, adapterInstaller, specifications = supportedLocalAgentSpecifications()) {
27731
- this.#adapterInstaller = adapterInstaller;
27732
- this.#options = options;
27733
- this.#specifications = Object.freeze([...specifications]);
27453
+ function translateExecutionError(error61) {
27454
+ if (error61 instanceof InstallationManagerError) {
27455
+ return error61;
27734
27456
  }
27735
- prepare = async (signal) => {
27736
- signal.throwIfAborted();
27737
- let inventory = await discoverLocalAgentInventory(
27738
- discoveryOptions(
27739
- this.#options,
27740
- this.#options.environment,
27741
- signal,
27742
- this.#specifications
27743
- )
27744
- );
27745
- const candidates = inventory.unavailable.filter(
27746
- (unavailable) => shouldProvisionAdapter(unavailable, this.#options)
27747
- );
27748
- const attempts = [];
27749
- for (const unavailable of candidates) {
27750
- signal.throwIfAborted();
27751
- const specification = unavailable.specification;
27752
- if (!(specification instanceof BridgedAcpAgentDefinition)) {
27753
- attempts.push(null);
27754
- continue;
27755
- }
27756
- const verifiedAgent = await findVerifiedAgentExecutable(
27757
- specification,
27758
- discoveryOptions(
27759
- this.#options,
27760
- this.#options.environment,
27761
- signal,
27762
- this.#specifications
27763
- )
27764
- );
27765
- if (verifiedAgent === null) {
27766
- attempts.push(null);
27767
- continue;
27768
- }
27769
- const requestId = `automatic-adapter-${randomUUID2()}`;
27770
- this.#options.audit.record(
27771
- "agent_adapter_auto_install_started",
27772
- requestId,
27773
- specification.id,
27774
- {
27775
- agentVersion: verifiedAgent.version,
27776
- adapterVersion: specification.adapterVersion
27777
- }
27778
- );
27779
- process.stdout.write(
27780
- `Installing the pinned ACP adapter for ${specification.label}.
27781
- `
27782
- );
27783
- try {
27784
- const executable = await this.#adapterInstaller.install(
27785
- specification,
27786
- signal
27787
- );
27788
- this.#options.audit.record(
27789
- "agent_adapter_auto_install_completed",
27790
- requestId,
27791
- specification.id,
27792
- { adapterVersion: specification.adapterVersion }
27793
- );
27794
- attempts.push(
27795
- new InstalledAutomaticAdapter(specification, requestId, executable)
27796
- );
27797
- } catch (error61) {
27798
- if (signal.aborted) {
27799
- this.#options.audit.record(
27800
- "agent_adapter_auto_install_cancelled",
27801
- requestId,
27802
- specification.id
27803
- );
27804
- signal.throwIfAborted();
27805
- }
27806
- this.#options.audit.record(
27807
- "agent_adapter_auto_install_failed",
27808
- requestId,
27809
- specification.id,
27810
- { code: stableFailureCode(error61) }
27811
- );
27812
- process.stderr.write(
27813
- `The pinned ACP adapter for ${specification.label} could not be installed automatically; the daemon will continue.
27814
- `
27815
- );
27816
- attempts.push(null);
27817
- }
27818
- }
27819
- signal.throwIfAborted();
27820
- const installed = attempts.filter(
27821
- (attempt) => attempt !== null
27822
- );
27823
- if (installed.length > 0) {
27824
- const verificationEnvironment = {
27825
- ...this.#options.environment
27826
- };
27827
- for (const attempt of installed) {
27828
- verificationEnvironment[attempt.specification.adapterOverrideVariable] = attempt.executable.path;
27829
- }
27830
- inventory = await discoverLocalAgentInventory(
27831
- discoveryOptions(
27832
- this.#options,
27833
- verificationEnvironment,
27834
- signal,
27835
- this.#specifications
27836
- )
27837
- );
27838
- }
27839
- this.#options.catalog.transition(
27840
- inventory.readyAgents(),
27841
- inventory.installable
27842
- );
27843
- for (const attempt of installed) {
27844
- const available = inventory.available.find(
27845
- (candidate) => candidate instanceof AvailableAgent && candidate.specification.id === attempt.specification.id
27846
- );
27847
- if (available === void 0) {
27848
- const unavailable = inventory.unavailable.find(
27849
- (candidate) => candidate.specification.id === attempt.specification.id
27850
- );
27851
- this.#options.audit.record(
27852
- "agent_adapter_auto_install_verification_failed",
27853
- attempt.requestId,
27854
- attempt.specification.id,
27855
- { code: unavailable?.code ?? "agent_verification_failed" }
27856
- );
27857
- continue;
27858
- }
27859
- this.#options.audit.record(
27860
- "agent_adapter_auto_install_verified",
27861
- attempt.requestId,
27862
- attempt.specification.id,
27863
- {
27864
- adapterVersion: available.agent.adapterVersion,
27865
- agentVersion: available.agent.agentVersion
27866
- }
27867
- );
27868
- process.stdout.write(
27869
- `${attempt.specification.label} ACP integration is ready.
27870
- `
27871
- );
27872
- }
27873
- return inventory;
27874
- };
27875
- };
27876
-
27877
- // src/agent-installation/fixed-installation-executor.ts
27878
- import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27879
- import { resolve as resolve4 } from "node:path";
27880
-
27881
- // src/agent-installation/fixed-agent-install-recipes.ts
27882
- import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
27883
- import { join as join17 } from "node:path";
27884
-
27885
- // src/agent-installation/fixed-agent-install-recipe.ts
27886
- var FixedAgentInstallRecipe = class {
27887
- assertSupportedPlatform = () => {
27888
- if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
27889
- throw new InstallationManagerError(
27890
- "unsupported_install_platform",
27891
- "This Agent installation recipe does not support the local platform"
27892
- );
27893
- }
27894
- };
27895
- requireInstalledExecutable = async (path2) => {
27896
- const executable = await resolveExecutablePath(path2);
27897
- if (executable === null) {
27898
- throw new InstallationManagerError(
27899
- "agent_verification_failed",
27900
- "The Agent installer did not produce a valid executable"
27901
- );
27902
- }
27903
- return executable;
27904
- };
27905
- };
27906
-
27907
- // src/agent-installation/grok-build-install-recipe.ts
27908
- import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27909
- import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
27910
- var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
27911
- function isContainedPath4(root, candidate) {
27912
- const difference = relative4(root, candidate);
27913
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
27914
- }
27915
- async function resolveLifecycleScript(packageRoot) {
27916
- try {
27917
- const canonicalPackageRoot = await realpath7(packageRoot);
27918
- const script = await realpath7(
27919
- join15(canonicalPackageRoot, "bin", "postinstall.js")
27920
- );
27921
- const metadata = await stat6(script);
27922
- if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
27923
- throw new Error("Invalid Grok Build lifecycle script");
27924
- }
27925
- return script;
27926
- } catch (error61) {
27927
- throw new InstallationManagerError(
27928
- "agent_verification_failed",
27929
- "The managed Grok Build lifecycle script is invalid",
27930
- { cause: error61 }
27931
- );
27932
- }
27933
- }
27934
- var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
27935
- #npmInstaller;
27936
- id = "grok-build";
27937
- label = "Grok Build";
27938
- releaseChannel = GROK_BUILD_MANAGED_VERSION;
27939
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27940
- super();
27941
- this.#npmInstaller = npmInstaller;
27942
- }
27943
- install = async (options) => {
27944
- this.assertSupportedPlatform();
27945
- const definition = grokBuildManagedPackage(process.platform, process.arch);
27946
- const versionRoot = join15(
27947
- options.stateDirectory,
27948
- "agents",
27949
- this.id,
27950
- GROK_BUILD_MANAGED_VERSION
27951
- );
27952
- const packageRoot = join15(versionRoot, "package");
27953
- const managedHome = join15(versionRoot, "home");
27954
- try {
27955
- await mkdir4(managedHome, { mode: 448, recursive: true });
27956
- const canonicalHome = await realpath7(managedHome);
27957
- await options.report("downloading");
27958
- await options.report("verifying");
27959
- await options.report("installing_agent");
27960
- await this.#npmInstaller.install(
27961
- packageRoot,
27962
- definition,
27963
- options.environment,
27964
- options.signal
27965
- );
27966
- options.audit.record(
27967
- "agent_npm_package_verified",
27968
- options.requestId,
27969
- this.id,
27970
- {
27971
- integrity: definition.integrity,
27972
- package: definition.packageName,
27973
- version: definition.version
27974
- }
27975
- );
27976
- const script = await resolveLifecycleScript(
27977
- join15(packageRoot, "node_modules", "@xai-official", "grok")
27978
- );
27979
- await runBoundedProcess({
27980
- arguments: [script],
27981
- command: process.execPath,
27982
- cwd: dirname5(script),
27983
- environment: {
27984
- GROK_HOME: canonicalHome,
27985
- GROK_INSTALL_COMPLETIONS: "0",
27986
- GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
27987
- HOME: canonicalHome,
27988
- PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
27989
- },
27990
- outputLimitBytes: 64 * 1024,
27991
- signal: options.signal,
27992
- timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
27993
- });
27994
- options.audit.record(
27995
- "agent_lifecycle_step_completed",
27996
- options.requestId,
27997
- this.id,
27998
- {
27999
- lifecycle: "postinstall",
28000
- package: definition.packageName,
28001
- version: definition.version
28002
- }
28003
- );
28004
- return await this.requireInstalledExecutable(
28005
- join15(canonicalHome, "bin", "grok")
28006
- );
28007
- } catch (error61) {
28008
- if (options.signal.aborted) {
28009
- options.signal.throwIfAborted();
28010
- }
28011
- if (error61 instanceof ManagedNpmPackageError) {
28012
- if (error61.code === "managed_package_verification_failed") {
28013
- throw new InstallationManagerError(
28014
- "agent_verification_failed",
28015
- "The managed Grok Build packages did not match their pinned artifacts",
28016
- { cause: error61 }
28017
- );
28018
- }
28019
- if (error61.code === "managed_package_publish_failed") {
28020
- throw new InstallationManagerError(
28021
- "agent_publish_failed",
28022
- "The managed Grok Build package could not be published",
28023
- { cause: error61 }
28024
- );
28025
- }
28026
- throw new InstallationManagerError(error61.code, error61.message, {
28027
- cause: error61
28028
- });
28029
- }
28030
- if (error61 instanceof InstallationManagerError) {
28031
- throw error61;
28032
- }
28033
- throw new InstallationManagerError(
28034
- "agent_install_failed",
28035
- "The fixed Grok Build installation recipe failed",
28036
- { cause: error61 }
28037
- );
28038
- }
28039
- };
28040
- };
28041
-
28042
- // src/agent-installation/workbuddy-install-recipe.ts
28043
- import { join as join16 } from "node:path";
28044
- var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
28045
- #npmInstaller;
28046
- id = "workbuddy";
28047
- label = "WorkBuddy";
28048
- releaseChannel = WORKBUDDY_MANAGED_VERSION;
28049
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28050
- super();
28051
- this.#npmInstaller = npmInstaller;
28052
- }
28053
- install = async (options) => {
28054
- this.assertSupportedPlatform();
28055
- try {
28056
- await options.report("downloading");
28057
- await options.report("verifying");
28058
- await options.report("installing_agent");
28059
- const executable = await this.#npmInstaller.install(
28060
- join16(
28061
- options.stateDirectory,
28062
- "agents",
28063
- this.id,
28064
- WORKBUDDY_MANAGED_VERSION
28065
- ),
28066
- WORKBUDDY_MANAGED_PACKAGE,
28067
- options.environment,
28068
- options.signal
28069
- );
28070
- options.audit.record(
28071
- "agent_npm_package_verified",
28072
- options.requestId,
28073
- this.id,
28074
- {
28075
- integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
28076
- package: WORKBUDDY_MANAGED_PACKAGE.packageName,
28077
- version: WORKBUDDY_MANAGED_PACKAGE.version
28078
- }
28079
- );
28080
- return executable;
28081
- } catch (error61) {
28082
- if (options.signal.aborted) {
28083
- options.signal.throwIfAborted();
28084
- }
28085
- if (error61 instanceof ManagedNpmPackageError) {
28086
- if (error61.code === "managed_package_verification_failed") {
28087
- throw new InstallationManagerError(
28088
- "agent_verification_failed",
28089
- "The managed WorkBuddy package did not match its pinned artifact",
28090
- { cause: error61 }
28091
- );
28092
- }
28093
- if (error61.code === "managed_package_publish_failed") {
28094
- throw new InstallationManagerError(
28095
- "agent_publish_failed",
28096
- "The managed WorkBuddy package could not be published",
28097
- { cause: error61 }
28098
- );
28099
- }
28100
- throw new InstallationManagerError(error61.code, error61.message, {
28101
- cause: error61
28102
- });
28103
- }
28104
- if (error61 instanceof InstallationManagerError) {
28105
- throw error61;
28106
- }
28107
- throw new InstallationManagerError(
28108
- "agent_install_failed",
28109
- "The fixed WorkBuddy installation recipe failed",
28110
- { cause: error61 }
28111
- );
28112
- }
28113
- };
28114
- };
28115
-
28116
- // src/agent-installation/fixed-agent-install-recipes.ts
28117
- var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
28118
- var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
28119
- var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
28120
- var MINIMAL_PATH2 = "/usr/bin:/bin";
28121
- var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
28122
- id = "codex";
28123
- label = "Codex";
28124
- releaseChannel = "latest";
28125
- install = async (options) => {
28126
- this.assertSupportedPlatform();
28127
- const root = join17(options.stateDirectory, "agents", this.id);
28128
- const temporaryRoot = join17(options.stateDirectory, "temporary");
28129
- await Promise.all([
28130
- mkdir5(root, { mode: 448, recursive: true }),
28131
- mkdir5(temporaryRoot, { mode: 448, recursive: true })
28132
- ]);
28133
- const temporaryDirectory = await mkdtemp3(
28134
- join17(temporaryRoot, ".codex-install-")
28135
- );
28136
- const installerPath = join17(temporaryDirectory, "install.sh");
28137
- const installDirectory = join17(root, "bin");
28138
- const codexHome = join17(root, "home");
28139
- try {
28140
- await Promise.all([
28141
- mkdir5(installDirectory, { mode: 448, recursive: true }),
28142
- mkdir5(codexHome, { mode: 448, recursive: true })
28143
- ]);
28144
- await options.report("downloading");
28145
- const download = await downloadVerifiedFile({
28146
- allowedHosts: /* @__PURE__ */ new Set(["chatgpt.com", "releases.openai.com"]),
28147
- destination: installerPath,
28148
- maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
28149
- signal: options.signal,
28150
- timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
28151
- url: new URL("https://chatgpt.com/codex/install.sh")
28152
- });
28153
- options.audit.record(
28154
- "agent_installer_download_verified",
28155
- options.requestId,
28156
- this.id,
28157
- {
28158
- bytes: download.bytes.toString(),
28159
- releaseChannel: this.releaseChannel,
28160
- sha256: download.sha256
28161
- }
28162
- );
28163
- await options.report("verifying");
28164
- await options.report("installing_agent");
28165
- await runBoundedProcess({
28166
- arguments: [installerPath],
28167
- command: "/bin/sh",
28168
- cwd: temporaryDirectory,
28169
- environment: {
28170
- CODEX_HOME: codexHome,
28171
- CODEX_INSTALL_DIR: installDirectory,
28172
- CODEX_NON_INTERACTIVE: "1",
28173
- CODEX_RELEASE: this.releaseChannel,
28174
- HOME: codexHome,
28175
- PATH: MINIMAL_PATH2
28176
- },
28177
- outputLimitBytes: 64 * 1024,
28178
- signal: options.signal,
28179
- timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
28180
- });
28181
- return await this.requireInstalledExecutable(
28182
- join17(installDirectory, "codex")
28183
- );
28184
- } catch (error61) {
28185
- if (options.signal.aborted) {
28186
- options.signal.throwIfAborted();
28187
- }
28188
- if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
28189
- throw error61;
28190
- }
28191
- throw new InstallationManagerError(
28192
- "agent_install_failed",
28193
- "The fixed Codex installation recipe failed"
28194
- );
28195
- } finally {
28196
- await rm3(temporaryDirectory, { force: true, recursive: true });
28197
- }
28198
- };
28199
- };
28200
- var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
28201
- id = "claude";
28202
- label = "Claude Code";
28203
- releaseChannel = "stable";
28204
- install = async (options) => {
28205
- this.assertSupportedPlatform();
28206
- const root = join17(options.stateDirectory, "agents", this.id);
28207
- const managedHome = join17(root, "home");
28208
- const temporaryRoot = join17(options.stateDirectory, "temporary");
28209
- await Promise.all([
28210
- mkdir5(managedHome, { mode: 448, recursive: true }),
28211
- mkdir5(temporaryRoot, { mode: 448, recursive: true })
28212
- ]);
28213
- const temporaryDirectory = await mkdtemp3(
28214
- join17(temporaryRoot, ".claude-install-")
28215
- );
28216
- const installerPath = join17(temporaryDirectory, "install.sh");
28217
- try {
28218
- await options.report("downloading");
28219
- const download = await downloadVerifiedFile({
28220
- allowedHosts: /* @__PURE__ */ new Set(["claude.ai"]),
28221
- destination: installerPath,
28222
- maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
28223
- signal: options.signal,
28224
- timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
28225
- url: new URL("https://claude.ai/install.sh")
28226
- });
28227
- options.audit.record(
28228
- "agent_installer_download_verified",
28229
- options.requestId,
28230
- this.id,
28231
- {
28232
- bytes: download.bytes.toString(),
28233
- releaseChannel: this.releaseChannel,
28234
- sha256: download.sha256
28235
- }
28236
- );
28237
- await options.report("verifying");
28238
- await options.report("installing_agent");
28239
- await runBoundedProcess({
28240
- arguments: [installerPath, "stable"],
28241
- command: "/bin/bash",
28242
- cwd: temporaryDirectory,
28243
- environment: {
28244
- HOME: managedHome,
28245
- PATH: MINIMAL_PATH2,
28246
- SHELL: "/bin/bash"
28247
- },
28248
- outputLimitBytes: 64 * 1024,
28249
- signal: options.signal,
28250
- timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
28251
- });
28252
- return await this.requireInstalledExecutable(
28253
- join17(managedHome, ".local", "bin", "claude")
28254
- );
28255
- } catch (error61) {
28256
- if (options.signal.aborted) {
28257
- options.signal.throwIfAborted();
28258
- }
28259
- if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
28260
- throw error61;
28261
- }
28262
- throw new InstallationManagerError(
28263
- "agent_install_failed",
28264
- "The fixed Claude Code installation recipe failed"
28265
- );
28266
- } finally {
28267
- await rm3(temporaryDirectory, { force: true, recursive: true });
28268
- }
28269
- };
28270
- };
28271
- var PiInstallRecipe = class extends FixedAgentInstallRecipe {
28272
- #npmInstaller;
28273
- id = "pi";
28274
- label = "Pi";
28275
- releaseChannel = PI_AGENT_PACKAGE.version;
28276
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28277
- super();
28278
- this.#npmInstaller = npmInstaller;
28279
- }
28280
- install = async (options) => {
28281
- this.assertSupportedPlatform();
28282
- try {
28283
- await options.report("downloading");
28284
- await options.report("verifying");
28285
- await options.report("installing_agent");
28286
- const executable = await this.#npmInstaller.install(
28287
- join17(
28288
- options.stateDirectory,
28289
- "agents",
28290
- this.id,
28291
- PI_AGENT_PACKAGE.version
28292
- ),
28293
- PI_AGENT_PACKAGE,
28294
- options.environment,
28295
- options.signal
28296
- );
28297
- options.audit.record(
28298
- "agent_npm_package_verified",
28299
- options.requestId,
28300
- this.id,
28301
- {
28302
- integrity: PI_AGENT_PACKAGE.integrity,
28303
- package: PI_AGENT_PACKAGE.packageName,
28304
- version: PI_AGENT_PACKAGE.version
28305
- }
28306
- );
28307
- return executable;
28308
- } catch (error61) {
28309
- if (options.signal.aborted) {
28310
- options.signal.throwIfAborted();
28311
- }
28312
- if (error61 instanceof ManagedNpmPackageError) {
28313
- if (error61.code === "managed_package_verification_failed") {
28314
- throw new InstallationManagerError(
28315
- "agent_verification_failed",
28316
- "The managed Pi package did not match its pinned artifact",
28317
- { cause: error61 }
28318
- );
28319
- }
28320
- if (error61.code === "managed_package_publish_failed") {
28321
- throw new InstallationManagerError(
28322
- "agent_publish_failed",
28323
- "The managed Pi package could not be published",
28324
- { cause: error61 }
28325
- );
28326
- }
28327
- throw new InstallationManagerError(error61.code, error61.message, {
28328
- cause: error61
28329
- });
28330
- }
28331
- if (error61 instanceof InstallationManagerError) {
28332
- throw error61;
28333
- }
28334
- throw new InstallationManagerError(
28335
- "agent_install_failed",
28336
- "The fixed Pi installation recipe failed",
28337
- { cause: error61 }
28338
- );
28339
- }
28340
- };
28341
- };
28342
- var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
28343
- #npmInstaller;
28344
- id = "deepseek-harness";
28345
- label = "DeepSeek Harness";
28346
- releaseChannel = DEEPSEEK_HARNESS_PACKAGE.version;
28347
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28348
- super();
28349
- this.#npmInstaller = npmInstaller;
28350
- }
28351
- install = async (options) => {
28352
- this.assertSupportedPlatform();
28353
- try {
28354
- const managedHome = join17(
28355
- options.stateDirectory,
28356
- "agents",
28357
- this.id,
28358
- "home"
28359
- );
28360
- await mkdir5(managedHome, { mode: 448, recursive: true });
28361
- await options.report("downloading");
28362
- await options.report("verifying");
28363
- await options.report("installing_agent");
28364
- const executable = await this.#npmInstaller.install(
28365
- join17(
28366
- options.stateDirectory,
28367
- "agents",
28368
- this.id,
28369
- DEEPSEEK_HARNESS_PACKAGE.version
28370
- ),
28371
- DEEPSEEK_HARNESS_PACKAGE,
28372
- options.environment,
28373
- options.signal
28374
- );
28375
- options.audit.record(
28376
- "agent_npm_package_verified",
28377
- options.requestId,
28378
- this.id,
28379
- {
28380
- integrity: DEEPSEEK_HARNESS_PACKAGE.integrity,
28381
- package: DEEPSEEK_HARNESS_PACKAGE.packageName,
28382
- version: DEEPSEEK_HARNESS_PACKAGE.version
28383
- }
28384
- );
28385
- return executable;
28386
- } catch (error61) {
28387
- if (options.signal.aborted) {
28388
- options.signal.throwIfAborted();
28389
- }
28390
- if (error61 instanceof ManagedNpmPackageError) {
28391
- if (error61.code === "managed_package_verification_failed") {
28392
- throw new InstallationManagerError(
28393
- "agent_verification_failed",
28394
- "The managed DeepSeek Harness package did not match its pinned artifact",
28395
- { cause: error61 }
28396
- );
28397
- }
28398
- if (error61.code === "managed_package_publish_failed") {
28399
- throw new InstallationManagerError(
28400
- "agent_publish_failed",
28401
- "The managed DeepSeek Harness package could not be published",
28402
- { cause: error61 }
28403
- );
28404
- }
28405
- throw new InstallationManagerError(error61.code, error61.message, {
28406
- cause: error61
28407
- });
28408
- }
28409
- if (error61 instanceof InstallationManagerError) {
28410
- throw error61;
28411
- }
28412
- throw new InstallationManagerError(
28413
- "agent_install_failed",
28414
- "The fixed DeepSeek Harness installation recipe failed",
28415
- { cause: error61 }
28416
- );
28417
- }
28418
- };
28419
- };
28420
- var OpenCodeInstallRecipe = class extends FixedAgentInstallRecipe {
28421
- #archiveInstaller;
28422
- id = "opencode";
28423
- label = "OpenCode";
28424
- releaseChannel = OPENCODE_MANAGED_VERSION;
28425
- constructor(archiveInstaller = new ManagedAgentArchiveInstaller()) {
28426
- super();
28427
- this.#archiveInstaller = archiveInstaller;
28428
- }
28429
- install = async (options) => {
28430
- this.assertSupportedPlatform();
28431
- const definition = openCodeManagedArchive(process.platform, process.arch);
28432
- try {
28433
- await options.report("downloading");
28434
- await options.report("verifying");
28435
- await options.report("installing_agent");
28436
- const executable = await this.#archiveInstaller.install(
28437
- join17(
28438
- options.stateDirectory,
28439
- "agents",
28440
- this.id,
28441
- OPENCODE_MANAGED_VERSION
28442
- ),
28443
- definition,
28444
- options.signal
28445
- );
28446
- options.audit.record(
28447
- "agent_archive_verified",
28448
- options.requestId,
28449
- this.id,
28450
- {
28451
- sha256: definition.archiveSha256,
28452
- version: definition.version
28453
- }
28454
- );
28455
- return executable;
28456
- } catch (error61) {
28457
- if (options.signal.aborted) {
28458
- options.signal.throwIfAborted();
28459
- }
28460
- if (error61 instanceof ManagedAgentArchiveError) {
28461
- if (error61.code === "managed_archive_verification_failed") {
28462
- throw new InstallationManagerError(
28463
- "agent_verification_failed",
28464
- "The managed OpenCode archive did not match its pinned artifact",
28465
- { cause: error61 }
28466
- );
28467
- }
28468
- if (error61.code === "managed_archive_publish_failed") {
28469
- throw new InstallationManagerError(
28470
- "agent_publish_failed",
28471
- "The managed OpenCode archive could not be published",
28472
- { cause: error61 }
28473
- );
28474
- }
28475
- throw new InstallationManagerError(error61.code, error61.message, {
28476
- cause: error61
28477
- });
28478
- }
28479
- if (error61 instanceof InstallationManagerError) {
28480
- throw error61;
28481
- }
28482
- throw new InstallationManagerError(
28483
- "agent_install_failed",
28484
- "The fixed OpenCode installation recipe failed",
28485
- { cause: error61 }
28486
- );
28487
- }
28488
- };
28489
- };
28490
- function fixedAgentInstallRecipes() {
28491
- return Object.freeze([
28492
- new CodexInstallRecipe(),
28493
- new ClaudeCodeInstallRecipe(),
28494
- new PiInstallRecipe(),
28495
- new DeepSeekHarnessInstallRecipe(),
28496
- new OpenCodeInstallRecipe(),
28497
- new GrokBuildInstallRecipe(),
28498
- new WorkBuddyInstallRecipe()
28499
- ]);
28500
- }
28501
-
28502
- // src/agent-installation/fixed-installation-executor.ts
28503
- function findSpecification(specifications, agentId) {
28504
- for (const specification of specifications) {
28505
- if (specification.id === agentId) {
28506
- return specification;
28507
- }
28508
- }
28509
- throw new InstallationManagerError(
28510
- "unknown_agent",
28511
- "The requested Agent is not supported"
28512
- );
28513
- }
28514
- function findRecipe(recipes, agentId) {
28515
- for (const recipe of recipes) {
28516
- if (recipe.id === agentId) {
28517
- return recipe;
28518
- }
28519
- }
28520
- throw new InstallationManagerError(
28521
- "agent_not_installable",
28522
- "The requested Agent does not have an approved installation recipe"
28523
- );
28524
- }
28525
- function resolveDefaultWorkspace2(path2) {
28526
- try {
28527
- const directory = realpathSync2(resolve4(path2));
28528
- if (!statSync2(directory).isDirectory()) {
28529
- throw new Error("Default workspace is not a directory");
28530
- }
28531
- return directory;
28532
- } catch (error61) {
28533
- throw new InstallationManagerError(
28534
- "unsafe_installation_root",
28535
- "The default workspace is unavailable or unsafe",
28536
- { cause: error61 }
28537
- );
28538
- }
28539
- }
28540
- function resolveUserInstallationDirectory(path2) {
28541
- try {
28542
- const directory = realpathSync2(resolve4(path2));
28543
- const metadata = statSync2(directory);
28544
- if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
28545
- throw new Error("Installation directory is not user-owned");
28546
- }
28547
- return directory;
28548
- } catch (error61) {
28549
- throw new InstallationManagerError(
28550
- "unsafe_installation_root",
28551
- "The local Agent installation root is unavailable or unsafe",
28552
- { cause: error61 }
28553
- );
28554
- }
28555
- }
28556
- function translateExecutionError(error61) {
28557
- if (error61 instanceof InstallationManagerError) {
28558
- return error61;
28559
- }
28560
- if (error61 instanceof ManagedAdapterInstallError || error61 instanceof InstallerDownloadError || error61 instanceof ProcessExecutionError) {
27457
+ if (error61 instanceof ManagedAdapterInstallError) {
28561
27458
  return new InstallationManagerError(error61.code, error61.message, {
28562
27459
  cause: error61
28563
27460
  });
28564
27461
  }
28565
27462
  return new InstallationManagerError(
28566
27463
  "installation_failed",
28567
- "The fixed local Agent installation failed",
27464
+ "The local Agent integration installation failed",
28568
27465
  { cause: error61 }
28569
27466
  );
28570
27467
  }
28571
- function requiresAgentReplacement(code) {
28572
- return code === "agent_not_found" || code === "agent_probe_failed" || code === "agent_probe_timeout";
28573
- }
28574
27468
  function requiresAdapterReplacement(code) {
28575
27469
  return code === "adapter_not_found" || code === "adapter_probe_failed" || code === "adapter_probe_timeout" || code === "acp_incompatible";
28576
27470
  }
@@ -28581,12 +27475,10 @@ var FixedInstallationExecutor = class {
28581
27475
  #catalog;
28582
27476
  #environment;
28583
27477
  #publishCatalog;
28584
- #recipes;
28585
27478
  #specifications;
28586
- #stateDirectory;
28587
- constructor(options, specifications = supportedLocalAgentSpecifications(), recipes = fixedAgentInstallRecipes(), adapterInstaller) {
27479
+ constructor(options, specifications = supportedLocalAgentSpecifications(), adapterInstaller) {
28588
27480
  const defaultWorkspace = resolveDefaultWorkspace2(options.defaultWorkspace);
28589
- const stateDirectory = resolveUserInstallationDirectory(
27481
+ const stateDirectory = resolveIntegrationStateDirectory(
28590
27482
  options.stateDirectory
28591
27483
  );
28592
27484
  this.#defaultWorkspace = defaultWorkspace;
@@ -28594,9 +27486,7 @@ var FixedInstallationExecutor = class {
28594
27486
  this.#catalog = options.catalog;
28595
27487
  this.#environment = Object.freeze({ ...options.environment });
28596
27488
  this.#publishCatalog = options.publishCatalog;
28597
- this.#recipes = Object.freeze([...recipes]);
28598
27489
  this.#specifications = Object.freeze([...specifications]);
28599
- this.#stateDirectory = stateDirectory;
28600
27490
  this.#adapterInstaller = adapterInstaller ?? new ManagedAdapterInstaller({
28601
27491
  environment: this.#environment,
28602
27492
  stateDirectory
@@ -28605,35 +27495,59 @@ var FixedInstallationExecutor = class {
28605
27495
  execute = async (agentId, requestId, report, signal) => {
28606
27496
  try {
28607
27497
  const specification = findSpecification(this.#specifications, agentId);
28608
- const recipe = findRecipe(this.#recipes, agentId);
28609
- this.#audit.record(
28610
- "agent_installation_recipe_resolved",
28611
- requestId,
28612
- agentId,
28613
- {
28614
- adapterVersion: specification.adapterVersion,
28615
- releaseChannel: recipe.releaseChannel
28616
- }
28617
- );
28618
- const discoveryOptions2 = {
27498
+ const discoveryOptions = {
28619
27499
  defaultWorkspace: this.#defaultWorkspace,
28620
27500
  environment: this.#environment,
28621
27501
  signal
28622
27502
  };
28623
- let agent = await resolveAgentExecutable(specification, discoveryOptions2);
28624
- let installedAgent = false;
28625
- if (agent === null) {
28626
- agent = await recipe.install({
28627
- audit: this.#audit,
28628
- environment: this.#environment,
28629
- report,
28630
- requestId,
28631
- signal,
28632
- stateDirectory: this.#stateDirectory
28633
- });
28634
- installedAgent = true;
27503
+ const initialInventory = await discoverLocalAgentInventory({
27504
+ ...discoveryOptions,
27505
+ specifications: this.#specifications
27506
+ });
27507
+ const previous = this.#catalog.read();
27508
+ this.#catalog.transition(
27509
+ initialInventory.readyAgents(),
27510
+ initialInventory.installable
27511
+ );
27512
+ try {
27513
+ await this.#publishCatalog(signal);
27514
+ } catch (error61) {
27515
+ this.#catalog.transition(previous.agents, previous.installableAgents);
27516
+ throw error61;
27517
+ }
27518
+ const alreadyReady = initialInventory.available.find(
27519
+ (candidate2) => candidate2.specification.id === agentId
27520
+ );
27521
+ if (alreadyReady instanceof AvailableAgent) {
27522
+ return;
27523
+ }
27524
+ const candidate = initialInventory.installable.find(
27525
+ (agent2) => agent2.id === agentId
27526
+ );
27527
+ if (candidate instanceof MissingAgentDefinition) {
27528
+ throw new InstallationManagerError(
27529
+ "agent_not_installed",
27530
+ `Install ${specification.label} on this machine, then try installing the integration again.`
27531
+ );
27532
+ }
27533
+ if (!(candidate instanceof AgentIntegrationDefinition)) {
27534
+ throw new InstallationManagerError(
27535
+ "agent_verification_failed",
27536
+ "The local Agent discovery result is unavailable"
27537
+ );
28635
27538
  }
28636
- let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions2);
27539
+ const verifiedAgent = await findVerifiedAgentExecutable(
27540
+ specification,
27541
+ discoveryOptions
27542
+ );
27543
+ if (verifiedAgent === null) {
27544
+ throw new InstallationManagerError(
27545
+ "agent_not_installed",
27546
+ `Install ${specification.label} on this machine, then try installing the integration again.`
27547
+ );
27548
+ }
27549
+ const agent = verifiedAgent.executable;
27550
+ let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions);
28637
27551
  let installedAdapter = false;
28638
27552
  if (adapter === null) {
28639
27553
  if (!(specification instanceof BridgedAcpAgentDefinition)) {
@@ -28642,6 +27556,12 @@ var FixedInstallationExecutor = class {
28642
27556
  "The direct Agent executable is unavailable"
28643
27557
  );
28644
27558
  }
27559
+ if (this.#environment[specification.adapterOverrideVariable] !== void 0) {
27560
+ throw new InstallationManagerError(
27561
+ "adapter_not_found",
27562
+ "The configured ACP adapter is unavailable"
27563
+ );
27564
+ }
28645
27565
  await report("installing_adapter");
28646
27566
  adapter = await this.#adapterInstaller.install(specification, signal);
28647
27567
  installedAdapter = true;
@@ -28652,8 +27572,8 @@ var FixedInstallationExecutor = class {
28652
27572
  while (true) {
28653
27573
  await report("checking_acp");
28654
27574
  const environment = { ...this.#environment };
28655
- environment[specification.agentOverrideVariable] = agent.path;
28656
- environment[specification.adapterOverrideVariable] = adapter.path;
27575
+ environment[specification.agentOverrideVariable] = agent.identity.requestedPath;
27576
+ environment[specification.adapterOverrideVariable] = adapter.identity.requestedPath;
28657
27577
  const inventory = await discoverLocalAgentInventory({
28658
27578
  defaultWorkspace: this.#defaultWorkspace,
28659
27579
  environment,
@@ -28661,7 +27581,7 @@ var FixedInstallationExecutor = class {
28661
27581
  specifications: this.#specifications
28662
27582
  });
28663
27583
  const verified = inventory.available.find(
28664
- (candidate) => candidate.specification.id === agentId
27584
+ (candidate2) => candidate2.specification.id === agentId
28665
27585
  );
28666
27586
  if (verified instanceof AvailableAgent) {
28667
27587
  this.#audit.record(
@@ -28673,7 +27593,7 @@ var FixedInstallationExecutor = class {
28673
27593
  agentVersion: verified.agent.agentVersion
28674
27594
  }
28675
27595
  );
28676
- const previous = this.#catalog.read();
27596
+ const previousCatalog = this.#catalog.read();
28677
27597
  this.#catalog.transition(
28678
27598
  inventory.readyAgents(),
28679
27599
  inventory.installable
@@ -28682,15 +27602,15 @@ var FixedInstallationExecutor = class {
28682
27602
  await this.#publishCatalog(signal);
28683
27603
  } catch (error61) {
28684
27604
  this.#catalog.transition(
28685
- previous.agents,
28686
- previous.installableAgents
27605
+ previousCatalog.agents,
27606
+ previousCatalog.installableAgents
28687
27607
  );
28688
27608
  throw error61;
28689
27609
  }
28690
27610
  return;
28691
27611
  }
28692
27612
  const unavailable = inventory.unavailable.find(
28693
- (candidate) => candidate.specification.id === agentId
27613
+ (candidate2) => candidate2.specification.id === agentId
28694
27614
  );
28695
27615
  if (unavailable === void 0) {
28696
27616
  throw new InstallationManagerError(
@@ -28698,7 +27618,7 @@ var FixedInstallationExecutor = class {
28698
27618
  "The complete Agent ACP path did not pass verification"
28699
27619
  );
28700
27620
  }
28701
- if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && requiresAdapterReplacement(unavailable.code)) {
27621
+ if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && this.#environment[specification.adapterOverrideVariable] === void 0 && requiresAdapterReplacement(unavailable.code)) {
28702
27622
  await report("installing_adapter");
28703
27623
  adapter = await this.#adapterInstaller.install(specification, signal);
28704
27624
  installedAdapter = true;
@@ -28707,21 +27627,6 @@ var FixedInstallationExecutor = class {
28707
27627
  });
28708
27628
  continue;
28709
27629
  }
28710
- if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
28711
- agent = await recipe.install({
28712
- audit: this.#audit,
28713
- environment: this.#environment,
28714
- report,
28715
- requestId,
28716
- signal,
28717
- stateDirectory: this.#stateDirectory
28718
- });
28719
- installedAgent = true;
28720
- if (specification instanceof DirectAcpAgentDefinition) {
28721
- adapter = agent;
28722
- }
28723
- continue;
28724
- }
28725
27630
  throw new InstallationManagerError(
28726
27631
  unavailable.code,
28727
27632
  unavailable.message
@@ -28746,15 +27651,15 @@ var LocalAuthorizationError = class extends Error {
28746
27651
  };
28747
27652
 
28748
27653
  // src/authorization/workspace-directory.ts
28749
- import { readdir, realpath as realpath8, stat as stat7 } from "node:fs/promises";
27654
+ import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
28750
27655
  import { homedir as homedir2 } from "node:os";
28751
27656
  import {
28752
27657
  basename as basename2,
28753
- dirname as dirname6,
28754
- isAbsolute as isAbsolute8,
28755
- join as join18,
27658
+ dirname as dirname5,
27659
+ isAbsolute as isAbsolute7,
27660
+ join as join15,
28756
27661
  normalize as normalize2,
28757
- relative as relative5
27662
+ relative as relative4
28758
27663
  } from "node:path";
28759
27664
  var WorkspaceDirectoryListing = class {
28760
27665
  directoryId;
@@ -28804,20 +27709,20 @@ var WorkspaceDirectoryService = class {
28804
27709
  if (id === "home") return homedir2();
28805
27710
  if (id.startsWith("path-")) {
28806
27711
  const path2 = decodePath(id, "path-");
28807
- if (isAbsolute8(path2)) return path2;
27712
+ if (isAbsolute7(path2)) return path2;
28808
27713
  }
28809
27714
  throw new LocalAuthorizationError("The directory identifier is invalid");
28810
27715
  };
28811
27716
  resolvePath = async (requested, signal) => {
28812
27717
  signal.throwIfAborted();
28813
- if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested)
27718
+ if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28814
27719
  throw new LocalAuthorizationError("The local directory path is invalid");
28815
27720
  try {
28816
- const target = await realpath8(requested);
27721
+ const target = await realpath7(requested);
28817
27722
  signal.throwIfAborted();
28818
- const metadata = await stat7(target);
27723
+ const metadata = await stat6(target);
28819
27724
  signal.throwIfAborted();
28820
- if (!isAbsolute8(target) || normalize2(target) !== target || !metadata.isDirectory())
27725
+ if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
28821
27726
  throw new LocalAuthorizationError(
28822
27727
  "The selected location is not a directory"
28823
27728
  );
@@ -28832,8 +27737,8 @@ var WorkspaceDirectoryService = class {
28832
27737
  }
28833
27738
  };
28834
27739
  label = (path2) => {
28835
- const suffix = relative5(homedir2(), path2);
28836
- return suffix === "" ? "~" : !isAbsolute8(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
27740
+ const suffix = relative4(homedir2(), path2);
27741
+ return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28837
27742
  };
28838
27743
  identify = async (bindingId, requestedPath, signal) => {
28839
27744
  this.authorizeMachine(bindingId);
@@ -28861,7 +27766,7 @@ var WorkspaceDirectoryService = class {
28861
27766
  continue;
28862
27767
  }
28863
27768
  try {
28864
- const path2 = await this.resolvePath(join18(target, child.name), signal);
27769
+ const path2 = await this.resolvePath(join15(target, child.name), signal);
28865
27770
  entries.push({ directoryId: encodePath(path2), name: child.name });
28866
27771
  } catch (cause) {
28867
27772
  signal.throwIfAborted();
@@ -28869,7 +27774,7 @@ var WorkspaceDirectoryService = class {
28869
27774
  }
28870
27775
  }
28871
27776
  entries.sort((a, b) => a.name.localeCompare(b.name));
28872
- const parent = dirname6(target);
27777
+ const parent = dirname5(target);
28873
27778
  return new WorkspaceDirectoryListing(
28874
27779
  id,
28875
27780
  this.label(target),
@@ -28893,7 +27798,7 @@ var WorkspaceDirectoryService = class {
28893
27798
  };
28894
27799
 
28895
27800
  // src/native-sessions/service.ts
28896
- import { randomUUID as randomUUID3 } from "node:crypto";
27801
+ import { randomUUID as randomUUID2 } from "node:crypto";
28897
27802
 
28898
27803
  // src/native-sessions/codex-history.ts
28899
27804
  import { spawn as spawn4 } from "node:child_process";
@@ -29207,7 +28112,7 @@ var NativeSessionService = class {
29207
28112
  for (const info of page.sessions) {
29208
28113
  const authorized = await this.authorizeEntry(command, options, info);
29209
28114
  if (authorized === null) continue;
29210
- const entryId = randomUUID3();
28115
+ const entryId = randomUUID2();
29211
28116
  if (this.#entries.size >= 5e3) this.#entries.clear();
29212
28117
  this.#entries.set(entryId, {
29213
28118
  scope: entryScope,
@@ -29232,7 +28137,7 @@ var NativeSessionService = class {
29232
28137
  {},
29233
28138
  "invalid_native_session_response"
29234
28139
  );
29235
- nextCursor = randomUUID3();
28140
+ nextCursor = randomUUID2();
29236
28141
  if (this.#cursors.size >= 500) this.#cursors.clear();
29237
28142
  this.#cursors.set(nextCursor, {
29238
28143
  scope: cursorScope,
@@ -29552,7 +28457,7 @@ function connectRelay(url2, signal) {
29552
28457
  }
29553
28458
 
29554
28459
  // src/relay-connection/liveness.ts
29555
- import { randomUUID as randomUUID4 } from "node:crypto";
28460
+ import { randomUUID as randomUUID3 } from "node:crypto";
29556
28461
  var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
29557
28462
  var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
29558
28463
  var RelayLivenessState = class {
@@ -29643,7 +28548,7 @@ var RelayConnectionLiveness = class {
29643
28548
  }
29644
28549
  throw new Error("Heartbeat was scheduled in an invalid state");
29645
28550
  }
29646
- const heartbeatId = randomUUID4();
28551
+ const heartbeatId = randomUUID3();
29647
28552
  this.#state = new AwaitingHeartbeatAckState(
29648
28553
  heartbeatId,
29649
28554
  this.#timer.schedule(
@@ -29662,7 +28567,7 @@ var RelayConnectionLiveness = class {
29662
28567
 
29663
28568
  // src/relay-connection/session-event-outbox.ts
29664
28569
  import { mkdirSync as mkdirSync3 } from "node:fs";
29665
- import { dirname as dirname7 } from "node:path";
28570
+ import { dirname as dirname6 } from "node:path";
29666
28571
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
29667
28572
  function readPendingEnvelope(row) {
29668
28573
  if (typeof row !== "object" || row === null || Array.isArray(row)) {
@@ -29677,7 +28582,7 @@ function readPendingEnvelope(row) {
29677
28582
  var SessionEventOutbox = class {
29678
28583
  #database;
29679
28584
  constructor(path2) {
29680
- mkdirSync3(dirname7(path2), { recursive: true });
28585
+ mkdirSync3(dirname6(path2), { recursive: true });
29681
28586
  this.#database = new DatabaseSync3(path2);
29682
28587
  this.#database.exec(`
29683
28588
  CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
@@ -29831,6 +28736,7 @@ var systemDaemonTimer = new SystemDaemonTimer();
29831
28736
  // src/run-daemon.ts
29832
28737
  var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
29833
28738
  var RELAY_CONNECTION_REFRESH_MILLISECONDS = 20 * 60 * 1e3;
28739
+ var ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS = 2e4;
29834
28740
  var RelayConnectionRefreshState = class {
29835
28741
  };
29836
28742
  var ScheduledRelayConnectionRefreshState = class extends RelayConnectionRefreshState {
@@ -30028,7 +28934,7 @@ var DaemonInstallationObserver = class {
30028
28934
  );
30029
28935
  return Promise.resolve();
30030
28936
  }
30031
- throw new Error("Unsupported Agent installation state");
28937
+ throw new Error("Unsupported Agent integration installation state");
30032
28938
  };
30033
28939
  };
30034
28940
  var ResolvedSessionDirectories = class {
@@ -30042,16 +28948,20 @@ var ResolvedSessionDirectories = class {
30042
28948
  }
30043
28949
  };
30044
28950
  var ActiveDaemonTurn = class {
28951
+ attemptId;
30045
28952
  command;
30046
- #connectionController;
28953
+ #controller;
28954
+ #finished = Promise.withResolvers();
30047
28955
  #cancellationRequested = false;
30048
- constructor(command, connectionController) {
28956
+ constructor(command, attemptId) {
28957
+ this.attemptId = attemptId;
30049
28958
  this.command = command;
30050
- this.#connectionController = connectionController;
28959
+ this.#controller = new AbortController();
30051
28960
  }
30052
- abortConnection = () => {
30053
- this.#connectionController.abort();
28961
+ abortDaemon = () => {
28962
+ this.#controller.abort();
30054
28963
  };
28964
+ finish = () => this.#finished.resolve();
30055
28965
  matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
30056
28966
  requestCancellation = () => {
30057
28967
  if (this.#cancellationRequested) {
@@ -30061,25 +28971,118 @@ var ActiveDaemonTurn = class {
30061
28971
  return true;
30062
28972
  };
30063
28973
  get signal() {
30064
- return this.#connectionController.signal;
28974
+ return this.#controller.signal;
28975
+ }
28976
+ get completion() {
28977
+ return this.#finished.promise;
28978
+ }
28979
+ };
28980
+ var ActiveTurnReconciliationError = class extends Error {
28981
+ code = "active_turn_reconciliation_failed";
28982
+ constructor(message, options = {}) {
28983
+ super(message, options);
28984
+ this.name = "ActiveTurnReconciliationError";
30065
28985
  }
30066
28986
  };
28987
+ function activeTurnReconciliationEndpoint(config2, turn) {
28988
+ const endpoint = new URL(config2.relayUrl);
28989
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
28990
+ if (!endpoint.pathname.endsWith("/daemon")) {
28991
+ throw new ActiveTurnReconciliationError("The Relay URL is invalid");
28992
+ }
28993
+ endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
28994
+ endpoint.searchParams.delete("liveness");
28995
+ return endpoint;
28996
+ }
28997
+ async function reconcileActiveTurn(config2, turn, signal) {
28998
+ signal.throwIfAborted();
28999
+ const timeoutSignal = AbortSignal.timeout(
29000
+ ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS
29001
+ );
29002
+ const requestSignal = AbortSignal.any([signal, timeoutSignal]);
29003
+ let response;
29004
+ try {
29005
+ response = await fetch4(activeTurnReconciliationEndpoint(config2, turn), {
29006
+ body: JSON.stringify({ outcome: { kind: "running" } }),
29007
+ dispatcher: environmentProxyDispatcher,
29008
+ headers: { "content-type": "application/json" },
29009
+ method: "POST",
29010
+ signal: requestSignal
29011
+ });
29012
+ } catch (error61) {
29013
+ if (signal.aborted) {
29014
+ signal.throwIfAborted();
29015
+ }
29016
+ throw new ActiveTurnReconciliationError(
29017
+ timeoutSignal.aborted ? "The active Agent turn reconciliation timed out" : "The active Agent turn could not be reconciled",
29018
+ { cause: error61 }
29019
+ );
29020
+ }
29021
+ await response.body?.cancel();
29022
+ if (!response.ok) {
29023
+ throw new ActiveTurnReconciliationError(
29024
+ "The Relay rejected the active Agent turn reconciliation"
29025
+ );
29026
+ }
29027
+ }
29028
+ async function reconcileActiveTurns(config2, turns, signal) {
29029
+ await Promise.all(
29030
+ turns.map(async (turn) => await reconcileActiveTurn(config2, turn, signal))
29031
+ );
29032
+ }
30067
29033
  function send(socket, message) {
30068
29034
  if (socket.readyState !== WebSocket2.OPEN) {
30069
29035
  throw new Error("Relay connection is not open");
30070
29036
  }
30071
29037
  socket.send(message);
30072
29038
  }
30073
- function recordSessionEvent(outbox, socket, sessionId, payload, attemptId = null) {
30074
- const envelope2 = outbox.enqueue(sessionId, payload, attemptId);
30075
- if (socket.readyState === WebSocket2.OPEN) {
30076
- socket.send(envelope2);
29039
+ var DaemonSessionEventConnectionState = class {
29040
+ };
29041
+ var DisconnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
29042
+ disconnect = () => this;
29043
+ send = () => void 0;
29044
+ };
29045
+ var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
29046
+ #socket;
29047
+ constructor(socket) {
29048
+ super();
29049
+ this.#socket = socket;
30077
29050
  }
30078
- }
30079
- function reportFailure(outbox, socket, command, code, message, attemptId = null) {
30080
- recordSessionEvent(
30081
- outbox,
30082
- socket,
29051
+ disconnect = (socket) => socket === this.#socket ? new DisconnectedDaemonSessionEventState() : this;
29052
+ send = (message) => {
29053
+ if (this.#socket.readyState === WebSocket2.OPEN) {
29054
+ try {
29055
+ this.#socket.send(message);
29056
+ } catch {
29057
+ }
29058
+ }
29059
+ };
29060
+ };
29061
+ var DaemonSessionEventPublisher = class {
29062
+ #outbox;
29063
+ #connection = new DisconnectedDaemonSessionEventState();
29064
+ constructor(outbox) {
29065
+ this.#outbox = outbox;
29066
+ }
29067
+ connect = (socket) => {
29068
+ const connection = new ConnectedDaemonSessionEventState(socket);
29069
+ this.#connection = connection;
29070
+ for (const pending of this.#outbox.pending()) {
29071
+ connection.send(pending);
29072
+ }
29073
+ };
29074
+ disconnect = (socket) => {
29075
+ this.#connection = this.#connection.disconnect(socket);
29076
+ };
29077
+ recordAttempt = (sessionId, payload, attemptId) => {
29078
+ this.#connection.send(this.#outbox.enqueue(sessionId, payload, attemptId));
29079
+ };
29080
+ recordRuntime = (sessionId, payload) => {
29081
+ this.#connection.send(this.#outbox.enqueue(sessionId, payload));
29082
+ };
29083
+ };
29084
+ function reportFailure(publisher, command, code, message, attemptId) {
29085
+ publisher.recordAttempt(
30083
29086
  command.sessionId,
30084
29087
  encodeSessionFailedEvent({
30085
29088
  code,
@@ -30175,7 +29178,7 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
30175
29178
  reportOperationFailure(socket, command.requestId, "", error61);
30176
29179
  }
30177
29180
  }
30178
- async function executeSessionPrepare(outbox, socket, command, config2, directories, audit, sessions, signal) {
29181
+ async function executeSessionPrepare(publisher, socket, command, config2, directories, audit, sessions, signal) {
30179
29182
  try {
30180
29183
  const resolved = await resolveSessionDirectories(
30181
29184
  directories,
@@ -30202,9 +29205,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
30202
29205
  event: "session_prepared",
30203
29206
  sessionId: command.sessionId
30204
29207
  });
30205
- recordSessionEvent(
30206
- outbox,
30207
- socket,
29208
+ publisher.recordRuntime(
30208
29209
  command.sessionId,
30209
29210
  encodeSessionReadyEvent({
30210
29211
  additionalDirectories: resolved.additionalDirectoryEntries,
@@ -30235,7 +29236,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
30235
29236
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
30236
29237
  }
30237
29238
  }
30238
- async function executeSessionConfigure(outbox, socket, command, config2, directories, audit, sessions, signal) {
29239
+ async function executeSessionConfigure(publisher, socket, command, config2, directories, audit, sessions, signal) {
30239
29240
  try {
30240
29241
  const resolved = await resolveSessionDirectories(
30241
29242
  directories,
@@ -30261,9 +29262,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
30261
29262
  event: "session_configured",
30262
29263
  sessionId: command.sessionId
30263
29264
  });
30264
- recordSessionEvent(
30265
- outbox,
30266
- socket,
29265
+ publisher.recordRuntime(
30267
29266
  command.sessionId,
30268
29267
  encodeSessionConfigUpdatedEvent({
30269
29268
  configOptions,
@@ -30276,7 +29275,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
30276
29275
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
30277
29276
  }
30278
29277
  }
30279
- async function executePrompt(outbox, socket, command, config2, directories, audit, sessions, attemptId, signal) {
29278
+ async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, signal) {
30280
29279
  try {
30281
29280
  const resolved = await resolveSessionDirectories(
30282
29281
  directories,
@@ -30292,9 +29291,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30292
29291
  sessionId: command.sessionId
30293
29292
  });
30294
29293
  outbox.transitionExecution(command.commandId, "running");
30295
- recordSessionEvent(
30296
- outbox,
30297
- socket,
29294
+ publisher.recordAttempt(
30298
29295
  command.sessionId,
30299
29296
  encodeSessionStartedEvent({
30300
29297
  commandId: command.commandId,
@@ -30311,9 +29308,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30311
29308
  cwd: resolved.cwd,
30312
29309
  images: command.images,
30313
29310
  onActivity: (activity) => {
30314
- recordSessionEvent(
30315
- outbox,
30316
- socket,
29311
+ publisher.recordAttempt(
30317
29312
  command.sessionId,
30318
29313
  encodeAgentActivityEvent({
30319
29314
  activityId: activity.activityId,
@@ -30337,9 +29332,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30337
29332
  return Promise.resolve();
30338
29333
  },
30339
29334
  onText: (text) => {
30340
- recordSessionEvent(
30341
- outbox,
30342
- socket,
29335
+ publisher.recordAttempt(
30343
29336
  command.sessionId,
30344
29337
  encodeAgentMessageDeltaEvent({
30345
29338
  commandId: command.commandId,
@@ -30356,9 +29349,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30356
29349
  sessionId: command.sessionId,
30357
29350
  signal
30358
29351
  });
30359
- recordSessionEvent(
30360
- outbox,
30361
- socket,
29352
+ publisher.recordAttempt(
30362
29353
  command.sessionId,
30363
29354
  encodeSessionCompletedEvent({
30364
29355
  commandId: command.commandId,
@@ -30385,8 +29376,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30385
29376
  });
30386
29377
  const code = operationErrorCode(error61);
30387
29378
  reportFailure(
30388
- outbox,
30389
- socket,
29379
+ publisher,
30390
29380
  command,
30391
29381
  code === "session_operation_failed" ? "agent_execution_failed" : code,
30392
29382
  code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error61),
@@ -30432,29 +29422,15 @@ async function publishAgentCatalogUntilAvailable(config2, signal, timer) {
30432
29422
  }
30433
29423
  }
30434
29424
  }
30435
- async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, onConnected, signal, timer) {
29425
+ async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, activeTurns, activeAttemptIds, onConnected, signal, timer) {
30436
29426
  const relayUrl = new URL(config2.relayUrl);
30437
29427
  relayUrl.searchParams.set("liveness", "1");
30438
29428
  const socket = await connectRelay(relayUrl, signal);
29429
+ const reconnectingTurns = [...activeTurns.values()];
30439
29430
  onConnected();
30440
- const activeTurns = /* @__PURE__ */ new Map();
30441
- const activeAttemptIds = /* @__PURE__ */ new Map();
30442
29431
  const connectionController = new AbortController();
30443
29432
  const nativeRequests = /* @__PURE__ */ new Map();
30444
- const record2 = (sessionId, payload) => {
30445
- recordSessionEvent(
30446
- outbox,
30447
- socket,
30448
- sessionId,
30449
- payload,
30450
- activeAttemptIds.get(sessionId) ?? null
30451
- );
30452
- };
30453
- sessions.setObserver(new DaemonAcpObserver(record2));
30454
29433
  installationObserver.connect(socket);
30455
- for (const pending of outbox.pending()) {
30456
- send(socket, pending);
30457
- }
30458
29434
  try {
30459
29435
  await new Promise((resolve5, reject) => {
30460
29436
  let finished = false;
@@ -30466,11 +29442,8 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30466
29442
  socket.removeEventListener("error", handleError);
30467
29443
  socket.removeEventListener("message", handleMessage);
30468
29444
  installationObserver.disconnect(socket);
29445
+ publisher.disconnect(socket);
30469
29446
  connectionController.abort();
30470
- for (const turn of activeTurns.values()) {
30471
- turn.abortConnection();
30472
- }
30473
- activeTurns.clear();
30474
29447
  };
30475
29448
  const resolveConnection = () => {
30476
29449
  if (finished) {
@@ -30689,7 +29662,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30689
29662
  if (kind === SESSION_PREPARE_KIND) {
30690
29663
  const command2 = decodeSessionPrepareCommand(encoded);
30691
29664
  void executeSessionPrepare(
30692
- outbox,
29665
+ publisher,
30693
29666
  socket,
30694
29667
  command2,
30695
29668
  config2,
@@ -30703,7 +29676,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30703
29676
  if (kind === SESSION_CONFIGURE_KIND) {
30704
29677
  const command2 = decodeSessionConfigureCommand(encoded);
30705
29678
  void executeSessionConfigure(
30706
- outbox,
29679
+ publisher,
30707
29680
  socket,
30708
29681
  command2,
30709
29682
  config2,
@@ -30753,7 +29726,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30753
29726
  if (kind === AGENT_INSTALL_REQUEST_KIND) {
30754
29727
  const command2 = decodeAgentInstallRequestCommand(encoded);
30755
29728
  void installations.request(command2, signal).catch((error61) => {
30756
- console.error("Mobius Agent installation failed", error61);
29729
+ console.error(
29730
+ "Mobius Agent integration installation failed",
29731
+ error61
29732
+ );
30757
29733
  });
30758
29734
  return;
30759
29735
  }
@@ -30779,12 +29755,12 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30779
29755
  if (receipt.kind === "duplicate") {
30780
29756
  return;
30781
29757
  }
30782
- const turn = new ActiveDaemonTurn(command, new AbortController());
29758
+ const turn = new ActiveDaemonTurn(command, receipt.attemptId);
30783
29759
  activeTurns.set(command.commandId, turn);
30784
29760
  activeAttemptIds.set(command.sessionId, receipt.attemptId);
30785
29761
  void executePrompt(
30786
29762
  outbox,
30787
- socket,
29763
+ publisher,
30788
29764
  command,
30789
29765
  config2,
30790
29766
  directories,
@@ -30799,6 +29775,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30799
29775
  if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
30800
29776
  activeAttemptIds.delete(command.sessionId);
30801
29777
  }
29778
+ turn.finish();
30802
29779
  connectionRefresh.afterTurnFinished();
30803
29780
  });
30804
29781
  } catch (error61) {
@@ -30810,6 +29787,28 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30810
29787
  socket.addEventListener("close", handleClose);
30811
29788
  socket.addEventListener("error", handleError);
30812
29789
  socket.addEventListener("message", handleMessage);
29790
+ void reconcileActiveTurns(
29791
+ config2,
29792
+ reconnectingTurns,
29793
+ connectionController.signal
29794
+ ).then(
29795
+ () => {
29796
+ if (finished) {
29797
+ return;
29798
+ }
29799
+ publisher.connect(socket);
29800
+ void Promise.all(
29801
+ reconnectingTurns.map((turn) => turn.completion)
29802
+ ).then(connectionRefresh.afterTurnFinished);
29803
+ },
29804
+ () => {
29805
+ if (finished) {
29806
+ return;
29807
+ }
29808
+ socket.close(1011, "Active Agent turn reconciliation failed");
29809
+ rejectConnection();
29810
+ }
29811
+ );
30813
29812
  if (signal.aborted) {
30814
29813
  stop();
30815
29814
  }
@@ -30833,23 +29832,21 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30833
29832
  publishCatalog: async (installationSignal) => await publishAgentCatalog(config2, installationSignal),
30834
29833
  stateDirectory
30835
29834
  });
30836
- await new AutomaticAdapterProvisioner(
30837
- {
30838
- defaultWorkspace: config2.defaultWorkspace,
30839
- audit: installationAudit,
30840
- catalog: config2.catalog,
30841
- environment: process.env
30842
- },
30843
- new ManagedAdapterInstaller({
30844
- environment: process.env,
30845
- stateDirectory
30846
- }),
30847
- specifications
30848
- ).prepare(signal);
30849
29835
  const sessionStore = new SqliteAcpSessionStore(config2.auditDatabasePath);
30850
29836
  const outbox = new SessionEventOutbox(config2.auditDatabasePath);
29837
+ const publisher = new DaemonSessionEventPublisher(outbox);
29838
+ const activeTurns = /* @__PURE__ */ new Map();
29839
+ const activeAttemptIds = /* @__PURE__ */ new Map();
29840
+ const recordSessionEvent = (sessionId, payload) => {
29841
+ const attemptId = activeAttemptIds.get(sessionId);
29842
+ if (attemptId === void 0) {
29843
+ publisher.recordRuntime(sessionId, payload);
29844
+ return;
29845
+ }
29846
+ publisher.recordAttempt(sessionId, payload, attemptId);
29847
+ };
30851
29848
  const sessions = new AcpSessionManager(
30852
- new NullAcpSessionObserver(),
29849
+ new DaemonAcpObserver(recordSessionEvent),
30853
29850
  sessionStore
30854
29851
  );
30855
29852
  const directories = new WorkspaceDirectoryService(
@@ -30905,6 +29902,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30905
29902
  installationObserver,
30906
29903
  nativeSessions,
30907
29904
  outbox,
29905
+ publisher,
29906
+ activeTurns,
29907
+ activeAttemptIds,
30908
29908
  announceConnection,
30909
29909
  signal,
30910
29910
  timer
@@ -30922,6 +29922,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30922
29922
  await waitForRelayRetry(signal, timer);
30923
29923
  }
30924
29924
  } finally {
29925
+ const turns = [...activeTurns.values()];
29926
+ for (const turn of turns) {
29927
+ turn.abortDaemon();
29928
+ }
29929
+ await Promise.all(turns.map((turn) => turn.completion));
30925
29930
  try {
30926
29931
  await catalogPublication;
30927
29932
  } finally {
@@ -30956,7 +29961,7 @@ Usage:
30956
29961
  Commands:
30957
29962
  pair Pair this machine and start its local daemon
30958
29963
  start Start the local daemon for a saved channel
30959
- agents Show locally available and installable Agents
29964
+ agents Show detected, missing, and integration-ready Agents
30960
29965
 
30961
29966
  Pairing grants this browser access to the machine with your user account's permissions.
30962
29967
  New conversations default to ~/.mobius/workspace; choose other directories in the browser.
@@ -30972,7 +29977,7 @@ async function main() {
30972
29977
  if (arguments_.length > 1 || arguments_.length === 1 && arguments_[0] !== "--json") {
30973
29978
  throw new Error("Usage: mobius agents [--json]");
30974
29979
  }
30975
- await mkdir6(loadDefaultWorkspace(), { recursive: true, mode: 448 });
29980
+ await mkdir4(loadDefaultWorkspace(), { recursive: true, mode: 448 });
30976
29981
  const inventory = await discoverLocalAgentInventory({
30977
29982
  defaultWorkspace: loadDefaultWorkspace(),
30978
29983
  environment: process.env,