@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/index.js CHANGED
@@ -2007,8 +2007,8 @@ function emoji() {
2007
2007
  }
2008
2008
  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])$/;
2009
2009
  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}|:))$/;
2010
- var mac = (delimiter3) => {
2011
- const escapedDelim = escapeRegex(delimiter3 ?? ":");
2010
+ var mac = (delimiter2) => {
2011
+ const escapedDelim = escapeRegex(delimiter2 ?? ":");
2012
2012
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
2013
2013
  };
2014
2014
  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])$/;
@@ -18981,13 +18981,13 @@ var SESSION_ELICITATION_RESPOND_KIND = "session.elicitation.respond";
18981
18981
  var SESSION_ELICITATION_RESOLVED_KIND = "session.elicitation.resolved";
18982
18982
  var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
18983
18983
  var AGENT_CONTENT_KIND = "agent.content";
18984
- var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
18985
- var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
18986
- var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
18987
- var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
18988
- var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
18989
- var AGENT_INSTALL_FAILED_KIND = "agent.install.failed";
18990
- var AGENT_INSTALL_CANCELLED_KIND = "agent.install.cancelled";
18984
+ var AGENT_INSTALL_REQUEST_KIND = "agent.integration.install.request";
18985
+ var AGENT_INSTALL_CANCEL_KIND = "agent.integration.install.cancel";
18986
+ var AGENT_INSTALL_STARTED_KIND = "agent.integration.install.started";
18987
+ var AGENT_INSTALL_PROGRESS_KIND = "agent.integration.install.progress";
18988
+ var AGENT_INSTALL_COMPLETED_KIND = "agent.integration.install.completed";
18989
+ var AGENT_INSTALL_FAILED_KIND = "agent.integration.install.failed";
18990
+ var AGENT_INSTALL_CANCELLED_KIND = "agent.integration.install.cancelled";
18991
18991
  var IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
18992
18992
  var DIRECTORY_IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
18993
18993
  var IDENTIFIER = external_exports.string().min(1).max(128).regex(IDENTIFIER_PATTERN);
@@ -21025,6 +21025,22 @@ var InstallableAgentDefinition = class {
21025
21025
  this.label = label;
21026
21026
  }
21027
21027
  };
21028
+ var MissingAgentDefinition = class extends InstallableAgentDefinition {
21029
+ status = "agent_not_installed";
21030
+ constructor(id, label) {
21031
+ super(id, label);
21032
+ }
21033
+ };
21034
+ var AgentIntegrationDefinition = class extends InstallableAgentDefinition {
21035
+ agentPath;
21036
+ agentVersion;
21037
+ status = "integration_not_installed";
21038
+ constructor(id, label, agentPath, agentVersion) {
21039
+ super(id, label);
21040
+ this.agentPath = agentPath;
21041
+ this.agentVersion = agentVersion;
21042
+ }
21043
+ };
21028
21044
  var LocalAgentCatalogSnapshot = class {
21029
21045
  agents;
21030
21046
  installableAgents;
@@ -24525,7 +24541,7 @@ var LocalAuthorizationError = class extends Error {
24525
24541
  import { randomUUID } from "node:crypto";
24526
24542
  import {
24527
24543
  mkdir as mkdir3,
24528
- open as open5,
24544
+ open as open4,
24529
24545
  realpath as realpath6,
24530
24546
  rename as rename3,
24531
24547
  stat as stat5,
@@ -24552,12 +24568,19 @@ var AvailableAgent = class extends AgentDiscovery {
24552
24568
  };
24553
24569
  var UnavailableAgent = class extends AgentDiscovery {
24554
24570
  };
24555
- var MissingAdapter = class extends UnavailableAgent {
24571
+ var UnavailableInstalledAgent = class extends UnavailableAgent {
24572
+ agent;
24573
+ constructor(specification, agent) {
24574
+ super(specification);
24575
+ this.agent = agent;
24576
+ }
24577
+ };
24578
+ var MissingAdapter = class extends UnavailableInstalledAgent {
24556
24579
  code = "adapter_not_found";
24557
24580
  message = "ACP adapter not found";
24558
24581
  status = "missing_adapter";
24559
- constructor(specification) {
24560
- super(specification);
24582
+ constructor(specification, agent) {
24583
+ super(specification, agent);
24561
24584
  }
24562
24585
  };
24563
24586
  var MissingAgent = class extends UnavailableAgent {
@@ -24568,7 +24591,7 @@ var MissingAgent = class extends UnavailableAgent {
24568
24591
  super(specification);
24569
24592
  }
24570
24593
  };
24571
- var ProbeFailed = class extends UnavailableAgent {
24594
+ var AgentProbeFailed = class extends UnavailableAgent {
24572
24595
  code;
24573
24596
  message;
24574
24597
  status = "probe_failed";
@@ -24578,20 +24601,30 @@ var ProbeFailed = class extends UnavailableAgent {
24578
24601
  this.message = message;
24579
24602
  }
24580
24603
  };
24581
- var IncompatibleAdapter = class extends UnavailableAgent {
24604
+ var IntegrationProbeFailed = class extends UnavailableInstalledAgent {
24605
+ code;
24606
+ message;
24607
+ status = "probe_failed";
24608
+ constructor(specification, agent, code, message) {
24609
+ super(specification, agent);
24610
+ this.code = code;
24611
+ this.message = message;
24612
+ }
24613
+ };
24614
+ var IncompatibleAdapter = class extends UnavailableInstalledAgent {
24582
24615
  code = "acp_incompatible";
24583
24616
  message = "ACP adapter is incompatible";
24584
24617
  status = "incompatible_adapter";
24585
- constructor(specification) {
24586
- super(specification);
24618
+ constructor(specification, agent) {
24619
+ super(specification, agent);
24587
24620
  }
24588
24621
  };
24589
- var AuthenticationRequiredAgent = class extends UnavailableAgent {
24622
+ var AuthenticationRequiredAgent = class extends UnavailableInstalledAgent {
24590
24623
  code = "authentication_required";
24591
24624
  message = "Agent authentication is required";
24592
24625
  status = "authentication_required";
24593
- constructor(specification) {
24594
- super(specification);
24626
+ constructor(specification, agent) {
24627
+ super(specification, agent);
24595
24628
  }
24596
24629
  };
24597
24630
  var LocalAgentInventory = class {
@@ -24599,7 +24632,7 @@ var LocalAgentInventory = class {
24599
24632
  discoveries;
24600
24633
  installable;
24601
24634
  unavailable;
24602
- constructor(discoveries, platform = process.platform, architecture = process.arch) {
24635
+ constructor(discoveries) {
24603
24636
  const available = [];
24604
24637
  const unavailable = [];
24605
24638
  for (const discovery of discoveries) {
@@ -24614,13 +24647,8 @@ var LocalAgentInventory = class {
24614
24647
  this.available = Object.freeze(available);
24615
24648
  this.discoveries = Object.freeze([...discoveries]);
24616
24649
  this.installable = Object.freeze(
24617
- unavailable.filter(
24618
- (discovery) => !(discovery instanceof AuthenticationRequiredAgent) && discovery.specification.supportsInstallation(
24619
- platform,
24620
- architecture
24621
- )
24622
- ).map(
24623
- (discovery) => new InstallableAgentDefinition(
24650
+ unavailable.map(
24651
+ (discovery) => discovery instanceof UnavailableInstalledAgent ? discovery.agent : new MissingAgentDefinition(
24624
24652
  discovery.specification.id,
24625
24653
  discovery.specification.label
24626
24654
  )
@@ -25014,7 +25042,6 @@ var LocalAgentSpecification = class {
25014
25042
  createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
25015
25043
  recoveryCommand = () => "";
25016
25044
  resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
25017
- supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
25018
25045
  verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
25019
25046
  };
25020
25047
  var DirectAcpAgentDefinition = class extends LocalAgentSpecification {
@@ -25162,7 +25189,6 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
25162
25189
  ["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
25163
25190
  );
25164
25191
  }
25165
- supportsInstallation = (_platform, _architecture) => false;
25166
25192
  verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
25167
25193
  const capabilities = initialized.agentCapabilities ?? {};
25168
25194
  if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
@@ -25465,14 +25491,14 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
25465
25491
  import { join as join9 } from "node:path";
25466
25492
 
25467
25493
  // src/agent-installation/managed-agent-archive.ts
25468
- import { createHash as createHash2 } from "node:crypto";
25494
+ import { createHash } from "node:crypto";
25469
25495
  import { createReadStream } from "node:fs";
25470
25496
  import {
25471
25497
  chmod,
25472
25498
  copyFile,
25473
25499
  mkdir as mkdir2,
25474
25500
  mkdtemp as mkdtemp2,
25475
- open as open4,
25501
+ open as open3,
25476
25502
  realpath as realpath5,
25477
25503
  rename as rename2,
25478
25504
  rm as rm2,
@@ -25482,208 +25508,16 @@ import {
25482
25508
  import { dirname as dirname4, isAbsolute as isAbsolute4, join as join8, relative as relative3, sep as sep3 } from "node:path";
25483
25509
 
25484
25510
  // src/agent-installation/verified-download.ts
25485
- import { createHash } from "node:crypto";
25486
- import { open as open3, unlink } from "node:fs/promises";
25487
25511
  import { fetch } from "undici";
25488
25512
 
25489
25513
  // src/network/environment-proxy.ts
25490
25514
  import { EnvHttpProxyAgent } from "undici";
25491
25515
  var environmentProxyDispatcher = new EnvHttpProxyAgent();
25492
25516
 
25493
- // src/agent-installation/verified-download.ts
25494
- var MAX_REDIRECTS = 4;
25495
- var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
25496
- var InstallerDownloadError = class extends Error {
25497
- code;
25498
- constructor(code, message, options = {}) {
25499
- super(message, options);
25500
- this.code = code;
25501
- this.name = "InstallerDownloadError";
25502
- }
25503
- };
25504
- var VerifiedDownload = class {
25505
- bytes;
25506
- sha256;
25507
- url;
25508
- constructor(url2, bytes, sha256) {
25509
- this.bytes = bytes;
25510
- this.sha256 = sha256;
25511
- this.url = url2;
25512
- }
25513
- };
25514
- var UndiciInstallerDownloadTransport = class {
25515
- get = async (url2, signal) => await fetch(url2, {
25516
- dispatcher: environmentProxyDispatcher,
25517
- headers: {
25518
- accept: "text/plain, application/octet-stream;q=0.9",
25519
- "user-agent": "Mobius-Agent-Installer/0.0.3"
25520
- },
25521
- method: "GET",
25522
- redirect: "manual",
25523
- signal
25524
- });
25525
- };
25526
- function validateUrl(url2, allowedHosts) {
25527
- if (url2.protocol !== "https:" || url2.username.length > 0 || url2.password.length > 0 || url2.port.length > 0 || !allowedHosts.has(url2.hostname)) {
25528
- throw new InstallerDownloadError(
25529
- "installer_host_not_allowed",
25530
- "The installer download target is not allowed"
25531
- );
25532
- }
25533
- }
25534
- async function fetchInstaller(options, signal, transport) {
25535
- let url2 = new URL(options.url);
25536
- for (let redirectCount = 0; redirectCount <= MAX_REDIRECTS; redirectCount += 1) {
25537
- validateUrl(url2, options.allowedHosts);
25538
- const response = await transport.get(url2, signal);
25539
- if (!REDIRECT_STATUSES.has(response.status)) {
25540
- return { response, url: url2 };
25541
- }
25542
- await response.body?.cancel();
25543
- const location = response.headers.get("location");
25544
- if (location === null || redirectCount === MAX_REDIRECTS) {
25545
- throw new InstallerDownloadError(
25546
- "installer_redirect_invalid",
25547
- "The installer returned an invalid redirect"
25548
- );
25549
- }
25550
- let redirected;
25551
- try {
25552
- redirected = new URL(location, url2);
25553
- } catch (error61) {
25554
- throw new InstallerDownloadError(
25555
- "installer_redirect_invalid",
25556
- "The installer returned an invalid redirect",
25557
- { cause: error61 }
25558
- );
25559
- }
25560
- try {
25561
- validateUrl(redirected, options.allowedHosts);
25562
- } catch (error61) {
25563
- throw new InstallerDownloadError(
25564
- "installer_redirect_not_allowed",
25565
- "The installer redirect left the approved host allowlist",
25566
- { cause: error61 }
25567
- );
25568
- }
25569
- url2 = redirected;
25570
- }
25571
- throw new InstallerDownloadError(
25572
- "installer_redirect_invalid",
25573
- "The installer returned too many redirects"
25574
- );
25575
- }
25576
- async function writeCompleteChunk(handle, chunk) {
25577
- let offset = 0;
25578
- while (offset < chunk.byteLength) {
25579
- const written = await handle.write(
25580
- chunk,
25581
- offset,
25582
- chunk.byteLength - offset
25583
- );
25584
- if (written.bytesWritten < 1) {
25585
- throw new InstallerDownloadError(
25586
- "installer_write_failed",
25587
- "The verified installer could not be stored"
25588
- );
25589
- }
25590
- offset += written.bytesWritten;
25591
- }
25592
- }
25593
- async function downloadVerifiedFile(options, transport = new UndiciInstallerDownloadTransport()) {
25594
- options.signal.throwIfAborted();
25595
- const timeoutSignal = AbortSignal.timeout(options.timeoutMilliseconds);
25596
- const signal = AbortSignal.any([options.signal, timeoutSignal]);
25597
- let handle = null;
25598
- let responseBody = null;
25599
- try {
25600
- const fetched = await fetchInstaller(options, signal, transport);
25601
- responseBody = fetched.response.body;
25602
- if (!fetched.response.ok || fetched.response.body === null) {
25603
- throw new InstallerDownloadError(
25604
- "installer_download_failed",
25605
- "The approved installer could not be downloaded"
25606
- );
25607
- }
25608
- const contentLength = fetched.response.headers.get("content-length");
25609
- if (contentLength !== null) {
25610
- const declaredLength = Number(contentLength);
25611
- if (!Number.isSafeInteger(declaredLength) || declaredLength < 1 || declaredLength > options.maximumBytes) {
25612
- throw new InstallerDownloadError(
25613
- "installer_size_invalid",
25614
- "The installer size is outside the approved limit"
25615
- );
25616
- }
25617
- }
25618
- handle = await open3(options.destination, "wx", 384);
25619
- const digest = createHash("sha256");
25620
- const reader = fetched.response.body.getReader();
25621
- let bytes = 0;
25622
- try {
25623
- while (true) {
25624
- signal.throwIfAborted();
25625
- const chunk = await reader.read();
25626
- if (chunk.done) {
25627
- break;
25628
- }
25629
- bytes += chunk.value.byteLength;
25630
- if (bytes > options.maximumBytes) {
25631
- throw new InstallerDownloadError(
25632
- "installer_size_invalid",
25633
- "The installer exceeded the approved size limit"
25634
- );
25635
- }
25636
- digest.update(chunk.value);
25637
- await writeCompleteChunk(handle, chunk.value);
25638
- }
25639
- } finally {
25640
- await reader.cancel().catch(() => void 0);
25641
- reader.releaseLock();
25642
- }
25643
- if (bytes === 0) {
25644
- throw new InstallerDownloadError(
25645
- "installer_verification_failed",
25646
- "The downloaded installer is empty"
25647
- );
25648
- }
25649
- await handle.sync();
25650
- await handle.close();
25651
- handle = null;
25652
- return new VerifiedDownload(fetched.url, bytes, digest.digest("hex"));
25653
- } catch (error61) {
25654
- if (handle !== null) {
25655
- await handle.close().catch(() => void 0);
25656
- }
25657
- await unlink(options.destination).catch(() => void 0);
25658
- if (options.signal.aborted) {
25659
- options.signal.throwIfAborted();
25660
- }
25661
- if (timeoutSignal.aborted) {
25662
- throw new InstallerDownloadError(
25663
- "installer_download_timeout",
25664
- "The installer download timed out",
25665
- { cause: error61 }
25666
- );
25667
- }
25668
- if (error61 instanceof InstallerDownloadError) {
25669
- throw error61;
25670
- }
25671
- throw new InstallerDownloadError(
25672
- "installer_download_failed",
25673
- "The approved installer could not be downloaded",
25674
- { cause: error61 }
25675
- );
25676
- } finally {
25677
- await responseBody?.cancel().catch(() => void 0);
25678
- }
25679
- }
25680
-
25681
25517
  // src/agent-installation/managed-agent-archive.ts
25682
25518
  var ARCHIVE_DOWNLOAD_LIMIT_BYTES = 128 * 1024 * 1024;
25683
25519
  var ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3;
25684
- var ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS = 6e4;
25685
25520
  var MANIFEST_LIMIT_BYTES = 16 * 1024;
25686
- var MINIMAL_PATH = "/usr/bin:/bin";
25687
25521
  var ManagedAgentArchiveDefinition = class {
25688
25522
  archiveName;
25689
25523
  archiveSha256;
@@ -25722,9 +25556,6 @@ var ManagedAgentArchiveError = class extends Error {
25722
25556
  this.name = "ManagedAgentArchiveError";
25723
25557
  }
25724
25558
  };
25725
- var ManagedAgentArchiveDownloader = class {
25726
- download = async (options) => await downloadVerifiedFile(options);
25727
- };
25728
25559
  function isRecord6(value) {
25729
25560
  return typeof value === "object" && value !== null && !Array.isArray(value);
25730
25561
  }
@@ -25734,7 +25565,7 @@ function isContainedPath3(root, candidate) {
25734
25565
  }
25735
25566
  async function hashFile(path2, signal) {
25736
25567
  signal.throwIfAborted();
25737
- const digest = createHash2("sha256");
25568
+ const digest = createHash("sha256");
25738
25569
  const stream = createReadStream(path2, { signal });
25739
25570
  try {
25740
25571
  for await (const chunk of stream) {
@@ -25765,7 +25596,7 @@ async function hashFile(path2, signal) {
25765
25596
  async function readManifest(path2) {
25766
25597
  let handle;
25767
25598
  try {
25768
- handle = await open4(path2, "r");
25599
+ handle = await open3(path2, "r");
25769
25600
  } catch (error61) {
25770
25601
  throw new ManagedAgentArchiveError(
25771
25602
  "managed_archive_verification_failed",
@@ -25836,144 +25667,6 @@ async function validateManagedAgentArchive(root, definition, signal) {
25836
25667
  );
25837
25668
  }
25838
25669
  }
25839
- function validateArchiveEntries(output2, definition) {
25840
- const entries = output2.split(/\r?\n/).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
25841
- if (entries.length !== 1 || entries[0] !== definition.executableName && entries[0] !== `./${definition.executableName}`) {
25842
- throw new ManagedAgentArchiveError(
25843
- "managed_archive_verification_failed",
25844
- "The managed Agent archive contains unexpected entries"
25845
- );
25846
- }
25847
- }
25848
- var ManagedAgentArchiveInstaller = class {
25849
- #downloader;
25850
- constructor(downloader = new ManagedAgentArchiveDownloader()) {
25851
- this.#downloader = downloader;
25852
- }
25853
- install = async (root, definition, signal) => {
25854
- signal.throwIfAborted();
25855
- try {
25856
- const metadata = await stat4(root);
25857
- if (metadata.isDirectory()) {
25858
- return await validateManagedAgentArchive(root, definition, signal);
25859
- }
25860
- } catch (error61) {
25861
- if (error61 instanceof ManagedAgentArchiveError || !(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
25862
- throw error61;
25863
- }
25864
- }
25865
- const parent = dirname4(root);
25866
- await mkdir2(parent, { mode: 448, recursive: true });
25867
- const working = await mkdtemp2(
25868
- join8(parent, `.${definition.version}.archive-`)
25869
- );
25870
- const staging = await mkdtemp2(
25871
- join8(parent, `.${definition.version}.staging-`)
25872
- );
25873
- try {
25874
- const archivePath = join8(working, definition.archiveName);
25875
- const extractionRoot = join8(working, "extracted");
25876
- await mkdir2(extractionRoot, { mode: 448 });
25877
- const canonicalExtractionRoot = await realpath5(extractionRoot);
25878
- const download = await this.#downloader.download({
25879
- allowedHosts: /* @__PURE__ */ new Set([
25880
- "github.com",
25881
- "objects.githubusercontent.com",
25882
- "release-assets.githubusercontent.com"
25883
- ]),
25884
- destination: archivePath,
25885
- maximumBytes: ARCHIVE_DOWNLOAD_LIMIT_BYTES,
25886
- signal,
25887
- timeoutMilliseconds: ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS,
25888
- url: definition.archiveUrl
25889
- });
25890
- if (download.sha256 !== definition.archiveSha256) {
25891
- throw new ManagedAgentArchiveError(
25892
- "managed_archive_verification_failed",
25893
- "The managed Agent archive checksum is invalid"
25894
- );
25895
- }
25896
- const list = await runBoundedProcess({
25897
- arguments: definition.listArguments(archivePath),
25898
- command: definition.extractor,
25899
- cwd: working,
25900
- environment: { PATH: MINIMAL_PATH },
25901
- outputLimitBytes: 64 * 1024,
25902
- signal,
25903
- timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
25904
- });
25905
- validateArchiveEntries(list.stdout, definition);
25906
- await runBoundedProcess({
25907
- arguments: definition.extractArguments(archivePath, extractionRoot),
25908
- command: definition.extractor,
25909
- cwd: working,
25910
- environment: { PATH: MINIMAL_PATH },
25911
- outputLimitBytes: 64 * 1024,
25912
- signal,
25913
- timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
25914
- });
25915
- const extracted = await realpath5(
25916
- join8(canonicalExtractionRoot, definition.executableName)
25917
- );
25918
- const extractedMetadata = await stat4(extracted);
25919
- if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
25920
- throw new ManagedAgentArchiveError(
25921
- "managed_archive_verification_failed",
25922
- "The managed Agent archive executable is invalid"
25923
- );
25924
- }
25925
- const binDirectory = join8(staging, "bin");
25926
- const executablePath = join8(binDirectory, definition.executableName);
25927
- await mkdir2(binDirectory, { mode: 448 });
25928
- await copyFile(extracted, executablePath);
25929
- await chmod(executablePath, 448);
25930
- const executableSha256 = await hashFile(executablePath, signal);
25931
- await writeFile(
25932
- join8(staging, "archive.json"),
25933
- `${JSON.stringify({
25934
- archiveSha256: definition.archiveSha256,
25935
- archiveUrl: definition.archiveUrl.toString(),
25936
- executableSha256,
25937
- version: definition.version
25938
- })}
25939
- `,
25940
- { mode: 384 }
25941
- );
25942
- await validateManagedAgentArchive(staging, definition, signal);
25943
- try {
25944
- await rename2(staging, root);
25945
- } catch (error61) {
25946
- try {
25947
- return await validateManagedAgentArchive(root, definition, signal);
25948
- } catch {
25949
- throw new ManagedAgentArchiveError(
25950
- "managed_archive_publish_failed",
25951
- "The managed Agent archive could not be published",
25952
- { cause: error61 }
25953
- );
25954
- }
25955
- }
25956
- return await validateManagedAgentArchive(root, definition, signal);
25957
- } catch (error61) {
25958
- if (signal.aborted) {
25959
- signal.throwIfAborted();
25960
- }
25961
- if (error61 instanceof ManagedAgentArchiveError) {
25962
- throw error61;
25963
- }
25964
- throw new ManagedAgentArchiveError(
25965
- "managed_archive_install_failed",
25966
- "The pinned Agent archive could not be installed",
25967
- { cause: error61 }
25968
- );
25969
- } finally {
25970
- await Promise.all([
25971
- rm2(working, { force: true, recursive: true }),
25972
- rm2(staging, { force: true, recursive: true })
25973
- ]);
25974
- }
25975
- };
25976
- };
25977
25670
 
25978
25671
  // src/agent-installation/opencode-managed-release.ts
25979
25672
  var OPENCODE_MANAGED_VERSION = "1.18.29";
@@ -26476,10 +26169,6 @@ async function resolveAdapterExecutables(specification, context) {
26476
26169
  context
26477
26170
  );
26478
26171
  }
26479
- async function resolveAgentExecutable(specification, context) {
26480
- const executables = await resolveAgentExecutables(specification, context);
26481
- return executables[0] ?? null;
26482
- }
26483
26172
  async function resolveAdapterExecutable(specification, context) {
26484
26173
  const executables = await resolveAdapterExecutables(specification, context);
26485
26174
  return executables[0] ?? null;
@@ -26545,41 +26234,41 @@ var DiscoveryAcpHandler = class {
26545
26234
  };
26546
26235
  function readableAcpStream(input2) {
26547
26236
  let byteLength = 0;
26548
- let open6 = true;
26237
+ let open5 = true;
26549
26238
  return new ReadableStream({
26550
26239
  start(controller) {
26551
26240
  input2.on("data", (chunk) => {
26552
- if (!open6) {
26241
+ if (!open5) {
26553
26242
  return;
26554
26243
  }
26555
26244
  if (!(chunk instanceof Uint8Array)) {
26556
- open6 = false;
26245
+ open5 = false;
26557
26246
  controller.error(new Error("ACP adapter produced invalid output"));
26558
26247
  return;
26559
26248
  }
26560
26249
  byteLength += chunk.byteLength;
26561
26250
  if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
26562
- open6 = false;
26251
+ open5 = false;
26563
26252
  controller.error(new Error("ACP adapter output limit exceeded"));
26564
26253
  return;
26565
26254
  }
26566
26255
  controller.enqueue(new Uint8Array(chunk));
26567
26256
  });
26568
26257
  input2.once("end", () => {
26569
- if (open6) {
26570
- open6 = false;
26258
+ if (open5) {
26259
+ open5 = false;
26571
26260
  controller.close();
26572
26261
  }
26573
26262
  });
26574
26263
  input2.once("error", (error61) => {
26575
- if (open6) {
26576
- open6 = false;
26264
+ if (open5) {
26265
+ open5 = false;
26577
26266
  controller.error(error61);
26578
26267
  }
26579
26268
  });
26580
26269
  },
26581
26270
  cancel() {
26582
- open6 = false;
26271
+ open5 = false;
26583
26272
  }
26584
26273
  });
26585
26274
  }
@@ -26708,25 +26397,50 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
26708
26397
  }
26709
26398
 
26710
26399
  // src/agent-catalog/discover-agent.ts
26711
- function probeFailure(specification, executableKind, error61) {
26400
+ function agentProbeFailure(specification, error61) {
26401
+ if (error61 instanceof AgentProbeError) {
26402
+ return new AgentProbeFailed(specification, error61.code, error61.message);
26403
+ }
26404
+ if (error61 instanceof ProcessExecutionError) {
26405
+ const code = error61.code === "process_timeout" ? "agent_probe_timeout" : "agent_probe_failed";
26406
+ return new AgentProbeFailed(
26407
+ specification,
26408
+ code,
26409
+ "Agent version probe failed"
26410
+ );
26411
+ }
26412
+ return new AgentProbeFailed(
26413
+ specification,
26414
+ "agent_probe_failed",
26415
+ "Agent probe failed"
26416
+ );
26417
+ }
26418
+ function integrationProbeFailure(specification, agent, error61) {
26712
26419
  if (error61 instanceof AgentProbeError) {
26713
26420
  if (error61.code === "authentication_required") {
26714
- return new AuthenticationRequiredAgent(specification);
26421
+ return new AuthenticationRequiredAgent(specification, agent);
26715
26422
  }
26716
- return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new ProbeFailed(specification, error61.code, error61.message);
26423
+ return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification, agent) : new IntegrationProbeFailed(
26424
+ specification,
26425
+ agent,
26426
+ error61.code,
26427
+ error61.message
26428
+ );
26717
26429
  }
26718
26430
  if (error61 instanceof ProcessExecutionError) {
26719
- const code = error61.code === "process_timeout" ? `${executableKind}_probe_timeout` : `${executableKind}_probe_failed`;
26720
- return new ProbeFailed(
26431
+ const code = error61.code === "process_timeout" ? "adapter_probe_timeout" : "adapter_probe_failed";
26432
+ return new IntegrationProbeFailed(
26721
26433
  specification,
26434
+ agent,
26722
26435
  code,
26723
- `${executableKind === "agent" ? "Agent" : "Adapter"} version probe failed`
26436
+ "Adapter version probe failed"
26724
26437
  );
26725
26438
  }
26726
- return new ProbeFailed(
26439
+ return new IntegrationProbeFailed(
26727
26440
  specification,
26728
- `${executableKind}_probe_failed`,
26729
- `${executableKind === "agent" ? "Agent" : "Adapter"} probe failed`
26441
+ agent,
26442
+ "adapter_probe_failed",
26443
+ "Adapter probe failed"
26730
26444
  );
26731
26445
  }
26732
26446
  async function discoverAgent(specification, context) {
@@ -26735,12 +26449,6 @@ async function discoverAgent(specification, context) {
26735
26449
  resolveAdapterExecutables(specification, context),
26736
26450
  resolveAgentExecutables(specification, context)
26737
26451
  ]);
26738
- if (specification instanceof DirectAcpAgentDefinition && agents.length === 0) {
26739
- return new MissingAgent(specification);
26740
- }
26741
- if (adapters.length === 0) {
26742
- return new MissingAdapter(specification);
26743
- }
26744
26452
  if (agents.length === 0) {
26745
26453
  return new MissingAgent(specification);
26746
26454
  }
@@ -26760,9 +26468,18 @@ async function discoverAgent(specification, context) {
26760
26468
  if (context.signal.aborted) {
26761
26469
  context.signal.throwIfAborted();
26762
26470
  }
26763
- lastFailure = probeFailure(specification, "agent", error61);
26471
+ lastFailure = agentProbeFailure(specification, error61);
26764
26472
  continue;
26765
26473
  }
26474
+ const installedAgent = new AgentIntegrationDefinition(
26475
+ specification.id,
26476
+ specification.label,
26477
+ agent.identity.requestedPath,
26478
+ agentVersion
26479
+ );
26480
+ if (adapters.length === 0) {
26481
+ return new MissingAdapter(specification, installedAgent);
26482
+ }
26766
26483
  for (const adapter of adapters) {
26767
26484
  if (specification instanceof DirectAcpAgentDefinition && adapter.path !== agent.path) {
26768
26485
  continue;
@@ -26791,7 +26508,11 @@ async function discoverAgent(specification, context) {
26791
26508
  if (context.signal.aborted) {
26792
26509
  context.signal.throwIfAborted();
26793
26510
  }
26794
- lastFailure = probeFailure(specification, "adapter", error61);
26511
+ lastFailure = integrationProbeFailure(
26512
+ specification,
26513
+ installedAgent,
26514
+ error61
26515
+ );
26795
26516
  continue;
26796
26517
  }
26797
26518
  const definition = new LocalAgentDefinition(
@@ -26840,7 +26561,11 @@ async function discoverAgent(specification, context) {
26840
26561
  if (context.signal.aborted) {
26841
26562
  context.signal.throwIfAborted();
26842
26563
  }
26843
- const failure = probeFailure(specification, "adapter", error61);
26564
+ const failure = integrationProbeFailure(
26565
+ specification,
26566
+ installedAgent,
26567
+ error61
26568
+ );
26844
26569
  if (failure instanceof AuthenticationRequiredAgent) {
26845
26570
  return failure;
26846
26571
  }
@@ -26848,7 +26573,7 @@ async function discoverAgent(specification, context) {
26848
26573
  }
26849
26574
  }
26850
26575
  }
26851
- return lastFailure ?? new IncompatibleAdapter(specification);
26576
+ return lastFailure ?? new MissingAgent(specification);
26852
26577
  }
26853
26578
 
26854
26579
  // src/agent-catalog/discover-local-agents.ts
@@ -26859,11 +26584,7 @@ async function discoverLocalAgentInventory(options) {
26859
26584
  async (specification) => await discoverAgent(specification, options)
26860
26585
  )
26861
26586
  );
26862
- return new LocalAgentInventory(
26863
- discoveries,
26864
- options.platform,
26865
- options.architecture
26866
- );
26587
+ return new LocalAgentInventory(discoveries);
26867
26588
  }
26868
26589
 
26869
26590
  // src/pairing/pair-local-machine.ts
@@ -27079,6 +26800,8 @@ function decodeClaimResponse(value) {
27079
26800
  }
27080
26801
  async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
27081
26802
  const agents = localAgents.map((agent) => ({
26803
+ agentPath: agent.agentIdentity.requestedPath,
26804
+ agentVersion: agent.agentVersion,
27082
26805
  id: agent.id,
27083
26806
  label: agent.label
27084
26807
  }));
@@ -27088,10 +26811,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
27088
26811
  response = await fetch2(endpoint, {
27089
26812
  body: JSON.stringify({
27090
26813
  agents,
27091
- installableAgents: installableAgents.map((agent) => ({
27092
- id: agent.id,
27093
- label: agent.label
27094
- })),
26814
+ installableAgents,
27095
26815
  machineName: hostname3(),
27096
26816
  pairingCode: options.code,
27097
26817
  workspaceName: basename(defaultWorkspace) || "Local workspace"
@@ -27174,7 +26894,7 @@ async function readSavedConnection(channelId) {
27174
26894
  `${channelId}.json`
27175
26895
  );
27176
26896
  let encoded = "";
27177
- const handle = await open5(connectionPath, "r");
26897
+ const handle = await open4(connectionPath, "r");
27178
26898
  try {
27179
26899
  const metadata = await handle.stat();
27180
26900
  if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
@@ -27211,7 +26931,7 @@ function assertInventoryUsable(inventory) {
27211
26931
  if (inventory.available.length + inventory.installable.length === 0) {
27212
26932
  throw new PairingClientError(
27213
26933
  "no_supported_agent",
27214
- "No supported Agent is ready or safely installable on this machine"
26934
+ "No supported Agent is available for local discovery"
27215
26935
  );
27216
26936
  }
27217
26937
  }
@@ -27299,7 +27019,7 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
27299
27019
  // src/run-daemon.ts
27300
27020
  import { basename as basename3 } from "node:path";
27301
27021
  import { styleText } from "node:util";
27302
- import { WebSocket as WebSocket2 } from "undici";
27022
+ import { fetch as fetch4, WebSocket as WebSocket2 } from "undici";
27303
27023
 
27304
27024
  // src/agent-catalog/publish-agent-catalog.ts
27305
27025
  import { fetch as fetch3 } from "undici";
@@ -27332,13 +27052,12 @@ async function publishAgentCatalog(config2, signal) {
27332
27052
  response = await fetch3(catalogEndpoint(config2.relayUrl), {
27333
27053
  body: JSON.stringify({
27334
27054
  agents: catalog.agents.map((agent) => ({
27055
+ agentPath: agent.agentIdentity.requestedPath,
27056
+ agentVersion: agent.agentVersion,
27335
27057
  id: agent.id,
27336
27058
  label: agent.label
27337
27059
  })),
27338
- installableAgents: catalog.installableAgents.map((agent) => ({
27339
- id: agent.id,
27340
- label: agent.label
27341
- }))
27060
+ installableAgents: catalog.installableAgents
27342
27061
  }),
27343
27062
  dispatcher: environmentProxyDispatcher,
27344
27063
  headers: { "content-type": "application/json" },
@@ -27434,7 +27153,7 @@ var InstallationJob = class {
27434
27153
  };
27435
27154
  function authorizedSpecificationFor(specifications, agentId) {
27436
27155
  for (const specification of specifications) {
27437
- if (specification.id === agentId && specification.supportsInstallation(process.platform, process.arch)) {
27156
+ if (specification.id === agentId) {
27438
27157
  return specification;
27439
27158
  }
27440
27159
  }
@@ -27446,7 +27165,7 @@ function executionFailure(error61) {
27446
27165
  }
27447
27166
  return new InstallationManagerError(
27448
27167
  "installation_failed",
27449
- "The local Agent installation failed",
27168
+ "The local Agent integration installation failed",
27450
27169
  { cause: error61 }
27451
27170
  );
27452
27171
  }
@@ -27517,7 +27236,7 @@ var AgentInstallationManager = class {
27517
27236
  command.requestId,
27518
27237
  command.agentId,
27519
27238
  "installation_in_progress",
27520
- "An installation for this Agent is already running"
27239
+ "An integration installation for this Agent is already running"
27521
27240
  );
27522
27241
  const job2 = new InstallationJob(command.requestId, command.agentId);
27523
27242
  job2.state = busy;
@@ -27554,7 +27273,7 @@ var AgentInstallationManager = class {
27554
27273
  job.requestId,
27555
27274
  job.agentId
27556
27275
  );
27557
- job.controller.abort(new Error("Agent installation cancelled"));
27276
+ job.controller.abort(new Error("Agent integration installation cancelled"));
27558
27277
  return await job.completion.promise;
27559
27278
  };
27560
27279
  close = async () => {
@@ -27564,7 +27283,7 @@ var AgentInstallationManager = class {
27564
27283
  if (job === void 0) {
27565
27284
  throw new InstallationManagerError(
27566
27285
  "installation_state_invalid",
27567
- "An active Agent installation is unavailable"
27286
+ "An active Agent integration installation is unavailable"
27568
27287
  );
27569
27288
  }
27570
27289
  job.controller.abort(new Error("Mobius daemon stopped"));
@@ -27586,7 +27305,7 @@ var AgentInstallationManager = class {
27586
27305
  job.controller.abort(
27587
27306
  new InstallationManagerError(
27588
27307
  "installation_timeout",
27589
- "The local Agent installation exceeded its deadline"
27308
+ "The local Agent integration installation exceeded its deadline"
27590
27309
  )
27591
27310
  );
27592
27311
  }, INSTALLATION_DEADLINE_MILLISECONDS);
@@ -27676,891 +27395,66 @@ var AgentInstallationManager = class {
27676
27395
  };
27677
27396
  };
27678
27397
 
27679
- // src/agent-installation/automatic-adapter-provisioner.ts
27680
- import { randomUUID as randomUUID2 } from "node:crypto";
27681
- var AUTOMATIC_ADAPTER_FAILURE_CODES = /* @__PURE__ */ new Set([
27682
- "adapter_not_found",
27683
- "adapter_probe_failed",
27684
- "adapter_probe_timeout",
27685
- "acp_incompatible"
27686
- ]);
27687
- var InstalledAutomaticAdapter = class {
27688
- executable;
27689
- requestId;
27690
- specification;
27691
- constructor(specification, requestId, executable) {
27692
- this.executable = executable;
27693
- this.requestId = requestId;
27694
- this.specification = specification;
27398
+ // src/agent-installation/fixed-installation-executor.ts
27399
+ import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27400
+ import { resolve as resolve4 } from "node:path";
27401
+ function findSpecification(specifications, agentId) {
27402
+ for (const specification of specifications) {
27403
+ if (specification.id === agentId) {
27404
+ return specification;
27405
+ }
27695
27406
  }
27696
- };
27697
- function shouldProvisionAdapter(unavailable, options) {
27698
- return unavailable.specification instanceof BridgedAcpAgentDefinition && AUTOMATIC_ADAPTER_FAILURE_CODES.has(unavailable.code) && options.environment[unavailable.specification.adapterOverrideVariable] === void 0 && unavailable.specification.supportsInstallation(
27699
- options.platform ?? process.platform,
27700
- options.architecture ?? process.arch
27407
+ throw new InstallationManagerError(
27408
+ "unknown_agent",
27409
+ "The requested Agent is not supported"
27701
27410
  );
27702
27411
  }
27703
- function stableFailureCode(error61) {
27704
- return error61 instanceof ManagedAdapterInstallError ? error61.code : "adapter_install_failed";
27412
+ function resolveDefaultWorkspace2(path2) {
27413
+ try {
27414
+ const directory = realpathSync2(resolve4(path2));
27415
+ if (!statSync2(directory).isDirectory()) {
27416
+ throw new Error("Default workspace is not a directory");
27417
+ }
27418
+ return directory;
27419
+ } catch (error61) {
27420
+ throw new InstallationManagerError(
27421
+ "unsafe_installation_root",
27422
+ "The default workspace is unavailable or unsafe",
27423
+ { cause: error61 }
27424
+ );
27425
+ }
27705
27426
  }
27706
- function discoveryOptions(options, environment, signal, specifications) {
27707
- return {
27708
- ...options.architecture === void 0 ? {} : { architecture: options.architecture },
27709
- defaultWorkspace: options.defaultWorkspace,
27710
- environment,
27711
- ...options.platform === void 0 ? {} : { platform: options.platform },
27712
- signal,
27713
- specifications
27714
- };
27427
+ function resolveIntegrationStateDirectory(path2) {
27428
+ try {
27429
+ const directory = realpathSync2(resolve4(path2));
27430
+ const metadata = statSync2(directory);
27431
+ if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
27432
+ throw new Error("Installation directory is not user-owned");
27433
+ }
27434
+ return directory;
27435
+ } catch (error61) {
27436
+ throw new InstallationManagerError(
27437
+ "unsafe_installation_root",
27438
+ "The local integration state directory is unavailable or unsafe",
27439
+ { cause: error61 }
27440
+ );
27441
+ }
27715
27442
  }
27716
- var AutomaticAdapterProvisioner = class {
27717
- #adapterInstaller;
27718
- #options;
27719
- #specifications;
27720
- constructor(options, adapterInstaller, specifications = supportedLocalAgentSpecifications()) {
27721
- this.#adapterInstaller = adapterInstaller;
27722
- this.#options = options;
27723
- this.#specifications = Object.freeze([...specifications]);
27443
+ function translateExecutionError(error61) {
27444
+ if (error61 instanceof InstallationManagerError) {
27445
+ return error61;
27724
27446
  }
27725
- prepare = async (signal) => {
27726
- signal.throwIfAborted();
27727
- let inventory = await discoverLocalAgentInventory(
27728
- discoveryOptions(
27729
- this.#options,
27730
- this.#options.environment,
27731
- signal,
27732
- this.#specifications
27733
- )
27734
- );
27735
- const candidates = inventory.unavailable.filter(
27736
- (unavailable) => shouldProvisionAdapter(unavailable, this.#options)
27737
- );
27738
- const attempts = [];
27739
- for (const unavailable of candidates) {
27740
- signal.throwIfAborted();
27741
- const specification = unavailable.specification;
27742
- if (!(specification instanceof BridgedAcpAgentDefinition)) {
27743
- attempts.push(null);
27744
- continue;
27745
- }
27746
- const verifiedAgent = await findVerifiedAgentExecutable(
27747
- specification,
27748
- discoveryOptions(
27749
- this.#options,
27750
- this.#options.environment,
27751
- signal,
27752
- this.#specifications
27753
- )
27754
- );
27755
- if (verifiedAgent === null) {
27756
- attempts.push(null);
27757
- continue;
27758
- }
27759
- const requestId = `automatic-adapter-${randomUUID2()}`;
27760
- this.#options.audit.record(
27761
- "agent_adapter_auto_install_started",
27762
- requestId,
27763
- specification.id,
27764
- {
27765
- agentVersion: verifiedAgent.version,
27766
- adapterVersion: specification.adapterVersion
27767
- }
27768
- );
27769
- process.stdout.write(
27770
- `Installing the pinned ACP adapter for ${specification.label}.
27771
- `
27772
- );
27773
- try {
27774
- const executable = await this.#adapterInstaller.install(
27775
- specification,
27776
- signal
27777
- );
27778
- this.#options.audit.record(
27779
- "agent_adapter_auto_install_completed",
27780
- requestId,
27781
- specification.id,
27782
- { adapterVersion: specification.adapterVersion }
27783
- );
27784
- attempts.push(
27785
- new InstalledAutomaticAdapter(specification, requestId, executable)
27786
- );
27787
- } catch (error61) {
27788
- if (signal.aborted) {
27789
- this.#options.audit.record(
27790
- "agent_adapter_auto_install_cancelled",
27791
- requestId,
27792
- specification.id
27793
- );
27794
- signal.throwIfAborted();
27795
- }
27796
- this.#options.audit.record(
27797
- "agent_adapter_auto_install_failed",
27798
- requestId,
27799
- specification.id,
27800
- { code: stableFailureCode(error61) }
27801
- );
27802
- process.stderr.write(
27803
- `The pinned ACP adapter for ${specification.label} could not be installed automatically; the daemon will continue.
27804
- `
27805
- );
27806
- attempts.push(null);
27807
- }
27808
- }
27809
- signal.throwIfAborted();
27810
- const installed = attempts.filter(
27811
- (attempt) => attempt !== null
27812
- );
27813
- if (installed.length > 0) {
27814
- const verificationEnvironment = {
27815
- ...this.#options.environment
27816
- };
27817
- for (const attempt of installed) {
27818
- verificationEnvironment[attempt.specification.adapterOverrideVariable] = attempt.executable.path;
27819
- }
27820
- inventory = await discoverLocalAgentInventory(
27821
- discoveryOptions(
27822
- this.#options,
27823
- verificationEnvironment,
27824
- signal,
27825
- this.#specifications
27826
- )
27827
- );
27828
- }
27829
- this.#options.catalog.transition(
27830
- inventory.readyAgents(),
27831
- inventory.installable
27832
- );
27833
- for (const attempt of installed) {
27834
- const available = inventory.available.find(
27835
- (candidate) => candidate instanceof AvailableAgent && candidate.specification.id === attempt.specification.id
27836
- );
27837
- if (available === void 0) {
27838
- const unavailable = inventory.unavailable.find(
27839
- (candidate) => candidate.specification.id === attempt.specification.id
27840
- );
27841
- this.#options.audit.record(
27842
- "agent_adapter_auto_install_verification_failed",
27843
- attempt.requestId,
27844
- attempt.specification.id,
27845
- { code: unavailable?.code ?? "agent_verification_failed" }
27846
- );
27847
- continue;
27848
- }
27849
- this.#options.audit.record(
27850
- "agent_adapter_auto_install_verified",
27851
- attempt.requestId,
27852
- attempt.specification.id,
27853
- {
27854
- adapterVersion: available.agent.adapterVersion,
27855
- agentVersion: available.agent.agentVersion
27856
- }
27857
- );
27858
- process.stdout.write(
27859
- `${attempt.specification.label} ACP integration is ready.
27860
- `
27861
- );
27862
- }
27863
- return inventory;
27864
- };
27865
- };
27866
-
27867
- // src/agent-installation/fixed-installation-executor.ts
27868
- import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
27869
- import { resolve as resolve4 } from "node:path";
27870
-
27871
- // src/agent-installation/fixed-agent-install-recipes.ts
27872
- import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
27873
- import { join as join17 } from "node:path";
27874
-
27875
- // src/agent-installation/fixed-agent-install-recipe.ts
27876
- var FixedAgentInstallRecipe = class {
27877
- assertSupportedPlatform = () => {
27878
- if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
27879
- throw new InstallationManagerError(
27880
- "unsupported_install_platform",
27881
- "This Agent installation recipe does not support the local platform"
27882
- );
27883
- }
27884
- };
27885
- requireInstalledExecutable = async (path2) => {
27886
- const executable = await resolveExecutablePath(path2);
27887
- if (executable === null) {
27888
- throw new InstallationManagerError(
27889
- "agent_verification_failed",
27890
- "The Agent installer did not produce a valid executable"
27891
- );
27892
- }
27893
- return executable;
27894
- };
27895
- };
27896
-
27897
- // src/agent-installation/grok-build-install-recipe.ts
27898
- import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
27899
- import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
27900
- var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
27901
- function isContainedPath4(root, candidate) {
27902
- const difference = relative4(root, candidate);
27903
- return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
27904
- }
27905
- async function resolveLifecycleScript(packageRoot) {
27906
- try {
27907
- const canonicalPackageRoot = await realpath7(packageRoot);
27908
- const script = await realpath7(
27909
- join15(canonicalPackageRoot, "bin", "postinstall.js")
27910
- );
27911
- const metadata = await stat6(script);
27912
- if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
27913
- throw new Error("Invalid Grok Build lifecycle script");
27914
- }
27915
- return script;
27916
- } catch (error61) {
27917
- throw new InstallationManagerError(
27918
- "agent_verification_failed",
27919
- "The managed Grok Build lifecycle script is invalid",
27920
- { cause: error61 }
27921
- );
27922
- }
27923
- }
27924
- var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
27925
- #npmInstaller;
27926
- id = "grok-build";
27927
- label = "Grok Build";
27928
- releaseChannel = GROK_BUILD_MANAGED_VERSION;
27929
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
27930
- super();
27931
- this.#npmInstaller = npmInstaller;
27932
- }
27933
- install = async (options) => {
27934
- this.assertSupportedPlatform();
27935
- const definition = grokBuildManagedPackage(process.platform, process.arch);
27936
- const versionRoot = join15(
27937
- options.stateDirectory,
27938
- "agents",
27939
- this.id,
27940
- GROK_BUILD_MANAGED_VERSION
27941
- );
27942
- const packageRoot = join15(versionRoot, "package");
27943
- const managedHome = join15(versionRoot, "home");
27944
- try {
27945
- await mkdir4(managedHome, { mode: 448, recursive: true });
27946
- const canonicalHome = await realpath7(managedHome);
27947
- await options.report("downloading");
27948
- await options.report("verifying");
27949
- await options.report("installing_agent");
27950
- await this.#npmInstaller.install(
27951
- packageRoot,
27952
- definition,
27953
- options.environment,
27954
- options.signal
27955
- );
27956
- options.audit.record(
27957
- "agent_npm_package_verified",
27958
- options.requestId,
27959
- this.id,
27960
- {
27961
- integrity: definition.integrity,
27962
- package: definition.packageName,
27963
- version: definition.version
27964
- }
27965
- );
27966
- const script = await resolveLifecycleScript(
27967
- join15(packageRoot, "node_modules", "@xai-official", "grok")
27968
- );
27969
- await runBoundedProcess({
27970
- arguments: [script],
27971
- command: process.execPath,
27972
- cwd: dirname5(script),
27973
- environment: {
27974
- GROK_HOME: canonicalHome,
27975
- GROK_INSTALL_COMPLETIONS: "0",
27976
- GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
27977
- HOME: canonicalHome,
27978
- PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
27979
- },
27980
- outputLimitBytes: 64 * 1024,
27981
- signal: options.signal,
27982
- timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
27983
- });
27984
- options.audit.record(
27985
- "agent_lifecycle_step_completed",
27986
- options.requestId,
27987
- this.id,
27988
- {
27989
- lifecycle: "postinstall",
27990
- package: definition.packageName,
27991
- version: definition.version
27992
- }
27993
- );
27994
- return await this.requireInstalledExecutable(
27995
- join15(canonicalHome, "bin", "grok")
27996
- );
27997
- } catch (error61) {
27998
- if (options.signal.aborted) {
27999
- options.signal.throwIfAborted();
28000
- }
28001
- if (error61 instanceof ManagedNpmPackageError) {
28002
- if (error61.code === "managed_package_verification_failed") {
28003
- throw new InstallationManagerError(
28004
- "agent_verification_failed",
28005
- "The managed Grok Build packages did not match their pinned artifacts",
28006
- { cause: error61 }
28007
- );
28008
- }
28009
- if (error61.code === "managed_package_publish_failed") {
28010
- throw new InstallationManagerError(
28011
- "agent_publish_failed",
28012
- "The managed Grok Build package could not be published",
28013
- { cause: error61 }
28014
- );
28015
- }
28016
- throw new InstallationManagerError(error61.code, error61.message, {
28017
- cause: error61
28018
- });
28019
- }
28020
- if (error61 instanceof InstallationManagerError) {
28021
- throw error61;
28022
- }
28023
- throw new InstallationManagerError(
28024
- "agent_install_failed",
28025
- "The fixed Grok Build installation recipe failed",
28026
- { cause: error61 }
28027
- );
28028
- }
28029
- };
28030
- };
28031
-
28032
- // src/agent-installation/workbuddy-install-recipe.ts
28033
- import { join as join16 } from "node:path";
28034
- var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
28035
- #npmInstaller;
28036
- id = "workbuddy";
28037
- label = "WorkBuddy";
28038
- releaseChannel = WORKBUDDY_MANAGED_VERSION;
28039
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28040
- super();
28041
- this.#npmInstaller = npmInstaller;
28042
- }
28043
- install = async (options) => {
28044
- this.assertSupportedPlatform();
28045
- try {
28046
- await options.report("downloading");
28047
- await options.report("verifying");
28048
- await options.report("installing_agent");
28049
- const executable = await this.#npmInstaller.install(
28050
- join16(
28051
- options.stateDirectory,
28052
- "agents",
28053
- this.id,
28054
- WORKBUDDY_MANAGED_VERSION
28055
- ),
28056
- WORKBUDDY_MANAGED_PACKAGE,
28057
- options.environment,
28058
- options.signal
28059
- );
28060
- options.audit.record(
28061
- "agent_npm_package_verified",
28062
- options.requestId,
28063
- this.id,
28064
- {
28065
- integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
28066
- package: WORKBUDDY_MANAGED_PACKAGE.packageName,
28067
- version: WORKBUDDY_MANAGED_PACKAGE.version
28068
- }
28069
- );
28070
- return executable;
28071
- } catch (error61) {
28072
- if (options.signal.aborted) {
28073
- options.signal.throwIfAborted();
28074
- }
28075
- if (error61 instanceof ManagedNpmPackageError) {
28076
- if (error61.code === "managed_package_verification_failed") {
28077
- throw new InstallationManagerError(
28078
- "agent_verification_failed",
28079
- "The managed WorkBuddy package did not match its pinned artifact",
28080
- { cause: error61 }
28081
- );
28082
- }
28083
- if (error61.code === "managed_package_publish_failed") {
28084
- throw new InstallationManagerError(
28085
- "agent_publish_failed",
28086
- "The managed WorkBuddy package could not be published",
28087
- { cause: error61 }
28088
- );
28089
- }
28090
- throw new InstallationManagerError(error61.code, error61.message, {
28091
- cause: error61
28092
- });
28093
- }
28094
- if (error61 instanceof InstallationManagerError) {
28095
- throw error61;
28096
- }
28097
- throw new InstallationManagerError(
28098
- "agent_install_failed",
28099
- "The fixed WorkBuddy installation recipe failed",
28100
- { cause: error61 }
28101
- );
28102
- }
28103
- };
28104
- };
28105
-
28106
- // src/agent-installation/fixed-agent-install-recipes.ts
28107
- var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
28108
- var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
28109
- var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
28110
- var MINIMAL_PATH2 = "/usr/bin:/bin";
28111
- var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
28112
- id = "codex";
28113
- label = "Codex";
28114
- releaseChannel = "latest";
28115
- install = async (options) => {
28116
- this.assertSupportedPlatform();
28117
- const root = join17(options.stateDirectory, "agents", this.id);
28118
- const temporaryRoot = join17(options.stateDirectory, "temporary");
28119
- await Promise.all([
28120
- mkdir5(root, { mode: 448, recursive: true }),
28121
- mkdir5(temporaryRoot, { mode: 448, recursive: true })
28122
- ]);
28123
- const temporaryDirectory = await mkdtemp3(
28124
- join17(temporaryRoot, ".codex-install-")
28125
- );
28126
- const installerPath = join17(temporaryDirectory, "install.sh");
28127
- const installDirectory = join17(root, "bin");
28128
- const codexHome = join17(root, "home");
28129
- try {
28130
- await Promise.all([
28131
- mkdir5(installDirectory, { mode: 448, recursive: true }),
28132
- mkdir5(codexHome, { mode: 448, recursive: true })
28133
- ]);
28134
- await options.report("downloading");
28135
- const download = await downloadVerifiedFile({
28136
- allowedHosts: /* @__PURE__ */ new Set(["chatgpt.com", "releases.openai.com"]),
28137
- destination: installerPath,
28138
- maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
28139
- signal: options.signal,
28140
- timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
28141
- url: new URL("https://chatgpt.com/codex/install.sh")
28142
- });
28143
- options.audit.record(
28144
- "agent_installer_download_verified",
28145
- options.requestId,
28146
- this.id,
28147
- {
28148
- bytes: download.bytes.toString(),
28149
- releaseChannel: this.releaseChannel,
28150
- sha256: download.sha256
28151
- }
28152
- );
28153
- await options.report("verifying");
28154
- await options.report("installing_agent");
28155
- await runBoundedProcess({
28156
- arguments: [installerPath],
28157
- command: "/bin/sh",
28158
- cwd: temporaryDirectory,
28159
- environment: {
28160
- CODEX_HOME: codexHome,
28161
- CODEX_INSTALL_DIR: installDirectory,
28162
- CODEX_NON_INTERACTIVE: "1",
28163
- CODEX_RELEASE: this.releaseChannel,
28164
- HOME: codexHome,
28165
- PATH: MINIMAL_PATH2
28166
- },
28167
- outputLimitBytes: 64 * 1024,
28168
- signal: options.signal,
28169
- timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
28170
- });
28171
- return await this.requireInstalledExecutable(
28172
- join17(installDirectory, "codex")
28173
- );
28174
- } catch (error61) {
28175
- if (options.signal.aborted) {
28176
- options.signal.throwIfAborted();
28177
- }
28178
- if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
28179
- throw error61;
28180
- }
28181
- throw new InstallationManagerError(
28182
- "agent_install_failed",
28183
- "The fixed Codex installation recipe failed"
28184
- );
28185
- } finally {
28186
- await rm3(temporaryDirectory, { force: true, recursive: true });
28187
- }
28188
- };
28189
- };
28190
- var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
28191
- id = "claude";
28192
- label = "Claude Code";
28193
- releaseChannel = "stable";
28194
- install = async (options) => {
28195
- this.assertSupportedPlatform();
28196
- const root = join17(options.stateDirectory, "agents", this.id);
28197
- const managedHome = join17(root, "home");
28198
- const temporaryRoot = join17(options.stateDirectory, "temporary");
28199
- await Promise.all([
28200
- mkdir5(managedHome, { mode: 448, recursive: true }),
28201
- mkdir5(temporaryRoot, { mode: 448, recursive: true })
28202
- ]);
28203
- const temporaryDirectory = await mkdtemp3(
28204
- join17(temporaryRoot, ".claude-install-")
28205
- );
28206
- const installerPath = join17(temporaryDirectory, "install.sh");
28207
- try {
28208
- await options.report("downloading");
28209
- const download = await downloadVerifiedFile({
28210
- allowedHosts: /* @__PURE__ */ new Set(["claude.ai"]),
28211
- destination: installerPath,
28212
- maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
28213
- signal: options.signal,
28214
- timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
28215
- url: new URL("https://claude.ai/install.sh")
28216
- });
28217
- options.audit.record(
28218
- "agent_installer_download_verified",
28219
- options.requestId,
28220
- this.id,
28221
- {
28222
- bytes: download.bytes.toString(),
28223
- releaseChannel: this.releaseChannel,
28224
- sha256: download.sha256
28225
- }
28226
- );
28227
- await options.report("verifying");
28228
- await options.report("installing_agent");
28229
- await runBoundedProcess({
28230
- arguments: [installerPath, "stable"],
28231
- command: "/bin/bash",
28232
- cwd: temporaryDirectory,
28233
- environment: {
28234
- HOME: managedHome,
28235
- PATH: MINIMAL_PATH2,
28236
- SHELL: "/bin/bash"
28237
- },
28238
- outputLimitBytes: 64 * 1024,
28239
- signal: options.signal,
28240
- timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
28241
- });
28242
- return await this.requireInstalledExecutable(
28243
- join17(managedHome, ".local", "bin", "claude")
28244
- );
28245
- } catch (error61) {
28246
- if (options.signal.aborted) {
28247
- options.signal.throwIfAborted();
28248
- }
28249
- if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
28250
- throw error61;
28251
- }
28252
- throw new InstallationManagerError(
28253
- "agent_install_failed",
28254
- "The fixed Claude Code installation recipe failed"
28255
- );
28256
- } finally {
28257
- await rm3(temporaryDirectory, { force: true, recursive: true });
28258
- }
28259
- };
28260
- };
28261
- var PiInstallRecipe = class extends FixedAgentInstallRecipe {
28262
- #npmInstaller;
28263
- id = "pi";
28264
- label = "Pi";
28265
- releaseChannel = PI_AGENT_PACKAGE.version;
28266
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28267
- super();
28268
- this.#npmInstaller = npmInstaller;
28269
- }
28270
- install = async (options) => {
28271
- this.assertSupportedPlatform();
28272
- try {
28273
- await options.report("downloading");
28274
- await options.report("verifying");
28275
- await options.report("installing_agent");
28276
- const executable = await this.#npmInstaller.install(
28277
- join17(
28278
- options.stateDirectory,
28279
- "agents",
28280
- this.id,
28281
- PI_AGENT_PACKAGE.version
28282
- ),
28283
- PI_AGENT_PACKAGE,
28284
- options.environment,
28285
- options.signal
28286
- );
28287
- options.audit.record(
28288
- "agent_npm_package_verified",
28289
- options.requestId,
28290
- this.id,
28291
- {
28292
- integrity: PI_AGENT_PACKAGE.integrity,
28293
- package: PI_AGENT_PACKAGE.packageName,
28294
- version: PI_AGENT_PACKAGE.version
28295
- }
28296
- );
28297
- return executable;
28298
- } catch (error61) {
28299
- if (options.signal.aborted) {
28300
- options.signal.throwIfAborted();
28301
- }
28302
- if (error61 instanceof ManagedNpmPackageError) {
28303
- if (error61.code === "managed_package_verification_failed") {
28304
- throw new InstallationManagerError(
28305
- "agent_verification_failed",
28306
- "The managed Pi package did not match its pinned artifact",
28307
- { cause: error61 }
28308
- );
28309
- }
28310
- if (error61.code === "managed_package_publish_failed") {
28311
- throw new InstallationManagerError(
28312
- "agent_publish_failed",
28313
- "The managed Pi package could not be published",
28314
- { cause: error61 }
28315
- );
28316
- }
28317
- throw new InstallationManagerError(error61.code, error61.message, {
28318
- cause: error61
28319
- });
28320
- }
28321
- if (error61 instanceof InstallationManagerError) {
28322
- throw error61;
28323
- }
28324
- throw new InstallationManagerError(
28325
- "agent_install_failed",
28326
- "The fixed Pi installation recipe failed",
28327
- { cause: error61 }
28328
- );
28329
- }
28330
- };
28331
- };
28332
- var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
28333
- #npmInstaller;
28334
- id = "deepseek-harness";
28335
- label = "DeepSeek Harness";
28336
- releaseChannel = DEEPSEEK_HARNESS_PACKAGE.version;
28337
- constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
28338
- super();
28339
- this.#npmInstaller = npmInstaller;
28340
- }
28341
- install = async (options) => {
28342
- this.assertSupportedPlatform();
28343
- try {
28344
- const managedHome = join17(
28345
- options.stateDirectory,
28346
- "agents",
28347
- this.id,
28348
- "home"
28349
- );
28350
- await mkdir5(managedHome, { mode: 448, recursive: true });
28351
- await options.report("downloading");
28352
- await options.report("verifying");
28353
- await options.report("installing_agent");
28354
- const executable = await this.#npmInstaller.install(
28355
- join17(
28356
- options.stateDirectory,
28357
- "agents",
28358
- this.id,
28359
- DEEPSEEK_HARNESS_PACKAGE.version
28360
- ),
28361
- DEEPSEEK_HARNESS_PACKAGE,
28362
- options.environment,
28363
- options.signal
28364
- );
28365
- options.audit.record(
28366
- "agent_npm_package_verified",
28367
- options.requestId,
28368
- this.id,
28369
- {
28370
- integrity: DEEPSEEK_HARNESS_PACKAGE.integrity,
28371
- package: DEEPSEEK_HARNESS_PACKAGE.packageName,
28372
- version: DEEPSEEK_HARNESS_PACKAGE.version
28373
- }
28374
- );
28375
- return executable;
28376
- } catch (error61) {
28377
- if (options.signal.aborted) {
28378
- options.signal.throwIfAborted();
28379
- }
28380
- if (error61 instanceof ManagedNpmPackageError) {
28381
- if (error61.code === "managed_package_verification_failed") {
28382
- throw new InstallationManagerError(
28383
- "agent_verification_failed",
28384
- "The managed DeepSeek Harness package did not match its pinned artifact",
28385
- { cause: error61 }
28386
- );
28387
- }
28388
- if (error61.code === "managed_package_publish_failed") {
28389
- throw new InstallationManagerError(
28390
- "agent_publish_failed",
28391
- "The managed DeepSeek Harness package could not be published",
28392
- { cause: error61 }
28393
- );
28394
- }
28395
- throw new InstallationManagerError(error61.code, error61.message, {
28396
- cause: error61
28397
- });
28398
- }
28399
- if (error61 instanceof InstallationManagerError) {
28400
- throw error61;
28401
- }
28402
- throw new InstallationManagerError(
28403
- "agent_install_failed",
28404
- "The fixed DeepSeek Harness installation recipe failed",
28405
- { cause: error61 }
28406
- );
28407
- }
28408
- };
28409
- };
28410
- var OpenCodeInstallRecipe = class extends FixedAgentInstallRecipe {
28411
- #archiveInstaller;
28412
- id = "opencode";
28413
- label = "OpenCode";
28414
- releaseChannel = OPENCODE_MANAGED_VERSION;
28415
- constructor(archiveInstaller = new ManagedAgentArchiveInstaller()) {
28416
- super();
28417
- this.#archiveInstaller = archiveInstaller;
28418
- }
28419
- install = async (options) => {
28420
- this.assertSupportedPlatform();
28421
- const definition = openCodeManagedArchive(process.platform, process.arch);
28422
- try {
28423
- await options.report("downloading");
28424
- await options.report("verifying");
28425
- await options.report("installing_agent");
28426
- const executable = await this.#archiveInstaller.install(
28427
- join17(
28428
- options.stateDirectory,
28429
- "agents",
28430
- this.id,
28431
- OPENCODE_MANAGED_VERSION
28432
- ),
28433
- definition,
28434
- options.signal
28435
- );
28436
- options.audit.record(
28437
- "agent_archive_verified",
28438
- options.requestId,
28439
- this.id,
28440
- {
28441
- sha256: definition.archiveSha256,
28442
- version: definition.version
28443
- }
28444
- );
28445
- return executable;
28446
- } catch (error61) {
28447
- if (options.signal.aborted) {
28448
- options.signal.throwIfAborted();
28449
- }
28450
- if (error61 instanceof ManagedAgentArchiveError) {
28451
- if (error61.code === "managed_archive_verification_failed") {
28452
- throw new InstallationManagerError(
28453
- "agent_verification_failed",
28454
- "The managed OpenCode archive did not match its pinned artifact",
28455
- { cause: error61 }
28456
- );
28457
- }
28458
- if (error61.code === "managed_archive_publish_failed") {
28459
- throw new InstallationManagerError(
28460
- "agent_publish_failed",
28461
- "The managed OpenCode archive could not be published",
28462
- { cause: error61 }
28463
- );
28464
- }
28465
- throw new InstallationManagerError(error61.code, error61.message, {
28466
- cause: error61
28467
- });
28468
- }
28469
- if (error61 instanceof InstallationManagerError) {
28470
- throw error61;
28471
- }
28472
- throw new InstallationManagerError(
28473
- "agent_install_failed",
28474
- "The fixed OpenCode installation recipe failed",
28475
- { cause: error61 }
28476
- );
28477
- }
28478
- };
28479
- };
28480
- function fixedAgentInstallRecipes() {
28481
- return Object.freeze([
28482
- new CodexInstallRecipe(),
28483
- new ClaudeCodeInstallRecipe(),
28484
- new PiInstallRecipe(),
28485
- new DeepSeekHarnessInstallRecipe(),
28486
- new OpenCodeInstallRecipe(),
28487
- new GrokBuildInstallRecipe(),
28488
- new WorkBuddyInstallRecipe()
28489
- ]);
28490
- }
28491
-
28492
- // src/agent-installation/fixed-installation-executor.ts
28493
- function findSpecification(specifications, agentId) {
28494
- for (const specification of specifications) {
28495
- if (specification.id === agentId) {
28496
- return specification;
28497
- }
28498
- }
28499
- throw new InstallationManagerError(
28500
- "unknown_agent",
28501
- "The requested Agent is not supported"
28502
- );
28503
- }
28504
- function findRecipe(recipes, agentId) {
28505
- for (const recipe of recipes) {
28506
- if (recipe.id === agentId) {
28507
- return recipe;
28508
- }
28509
- }
28510
- throw new InstallationManagerError(
28511
- "agent_not_installable",
28512
- "The requested Agent does not have an approved installation recipe"
28513
- );
28514
- }
28515
- function resolveDefaultWorkspace2(path2) {
28516
- try {
28517
- const directory = realpathSync2(resolve4(path2));
28518
- if (!statSync2(directory).isDirectory()) {
28519
- throw new Error("Default workspace is not a directory");
28520
- }
28521
- return directory;
28522
- } catch (error61) {
28523
- throw new InstallationManagerError(
28524
- "unsafe_installation_root",
28525
- "The default workspace is unavailable or unsafe",
28526
- { cause: error61 }
28527
- );
28528
- }
28529
- }
28530
- function resolveUserInstallationDirectory(path2) {
28531
- try {
28532
- const directory = realpathSync2(resolve4(path2));
28533
- const metadata = statSync2(directory);
28534
- if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
28535
- throw new Error("Installation directory is not user-owned");
28536
- }
28537
- return directory;
28538
- } catch (error61) {
28539
- throw new InstallationManagerError(
28540
- "unsafe_installation_root",
28541
- "The local Agent installation root is unavailable or unsafe",
28542
- { cause: error61 }
28543
- );
28544
- }
28545
- }
28546
- function translateExecutionError(error61) {
28547
- if (error61 instanceof InstallationManagerError) {
28548
- return error61;
28549
- }
28550
- if (error61 instanceof ManagedAdapterInstallError || error61 instanceof InstallerDownloadError || error61 instanceof ProcessExecutionError) {
27447
+ if (error61 instanceof ManagedAdapterInstallError) {
28551
27448
  return new InstallationManagerError(error61.code, error61.message, {
28552
27449
  cause: error61
28553
27450
  });
28554
27451
  }
28555
27452
  return new InstallationManagerError(
28556
27453
  "installation_failed",
28557
- "The fixed local Agent installation failed",
27454
+ "The local Agent integration installation failed",
28558
27455
  { cause: error61 }
28559
27456
  );
28560
27457
  }
28561
- function requiresAgentReplacement(code) {
28562
- return code === "agent_not_found" || code === "agent_probe_failed" || code === "agent_probe_timeout";
28563
- }
28564
27458
  function requiresAdapterReplacement(code) {
28565
27459
  return code === "adapter_not_found" || code === "adapter_probe_failed" || code === "adapter_probe_timeout" || code === "acp_incompatible";
28566
27460
  }
@@ -28571,12 +27465,10 @@ var FixedInstallationExecutor = class {
28571
27465
  #catalog;
28572
27466
  #environment;
28573
27467
  #publishCatalog;
28574
- #recipes;
28575
27468
  #specifications;
28576
- #stateDirectory;
28577
- constructor(options, specifications = supportedLocalAgentSpecifications(), recipes = fixedAgentInstallRecipes(), adapterInstaller) {
27469
+ constructor(options, specifications = supportedLocalAgentSpecifications(), adapterInstaller) {
28578
27470
  const defaultWorkspace = resolveDefaultWorkspace2(options.defaultWorkspace);
28579
- const stateDirectory = resolveUserInstallationDirectory(
27471
+ const stateDirectory = resolveIntegrationStateDirectory(
28580
27472
  options.stateDirectory
28581
27473
  );
28582
27474
  this.#defaultWorkspace = defaultWorkspace;
@@ -28584,9 +27476,7 @@ var FixedInstallationExecutor = class {
28584
27476
  this.#catalog = options.catalog;
28585
27477
  this.#environment = Object.freeze({ ...options.environment });
28586
27478
  this.#publishCatalog = options.publishCatalog;
28587
- this.#recipes = Object.freeze([...recipes]);
28588
27479
  this.#specifications = Object.freeze([...specifications]);
28589
- this.#stateDirectory = stateDirectory;
28590
27480
  this.#adapterInstaller = adapterInstaller ?? new ManagedAdapterInstaller({
28591
27481
  environment: this.#environment,
28592
27482
  stateDirectory
@@ -28595,35 +27485,59 @@ var FixedInstallationExecutor = class {
28595
27485
  execute = async (agentId, requestId, report, signal) => {
28596
27486
  try {
28597
27487
  const specification = findSpecification(this.#specifications, agentId);
28598
- const recipe = findRecipe(this.#recipes, agentId);
28599
- this.#audit.record(
28600
- "agent_installation_recipe_resolved",
28601
- requestId,
28602
- agentId,
28603
- {
28604
- adapterVersion: specification.adapterVersion,
28605
- releaseChannel: recipe.releaseChannel
28606
- }
28607
- );
28608
- const discoveryOptions2 = {
27488
+ const discoveryOptions = {
28609
27489
  defaultWorkspace: this.#defaultWorkspace,
28610
27490
  environment: this.#environment,
28611
27491
  signal
28612
27492
  };
28613
- let agent = await resolveAgentExecutable(specification, discoveryOptions2);
28614
- let installedAgent = false;
28615
- if (agent === null) {
28616
- agent = await recipe.install({
28617
- audit: this.#audit,
28618
- environment: this.#environment,
28619
- report,
28620
- requestId,
28621
- signal,
28622
- stateDirectory: this.#stateDirectory
28623
- });
28624
- installedAgent = true;
27493
+ const initialInventory = await discoverLocalAgentInventory({
27494
+ ...discoveryOptions,
27495
+ specifications: this.#specifications
27496
+ });
27497
+ const previous = this.#catalog.read();
27498
+ this.#catalog.transition(
27499
+ initialInventory.readyAgents(),
27500
+ initialInventory.installable
27501
+ );
27502
+ try {
27503
+ await this.#publishCatalog(signal);
27504
+ } catch (error61) {
27505
+ this.#catalog.transition(previous.agents, previous.installableAgents);
27506
+ throw error61;
27507
+ }
27508
+ const alreadyReady = initialInventory.available.find(
27509
+ (candidate2) => candidate2.specification.id === agentId
27510
+ );
27511
+ if (alreadyReady instanceof AvailableAgent) {
27512
+ return;
27513
+ }
27514
+ const candidate = initialInventory.installable.find(
27515
+ (agent2) => agent2.id === agentId
27516
+ );
27517
+ if (candidate instanceof MissingAgentDefinition) {
27518
+ throw new InstallationManagerError(
27519
+ "agent_not_installed",
27520
+ `Install ${specification.label} on this machine, then try installing the integration again.`
27521
+ );
27522
+ }
27523
+ if (!(candidate instanceof AgentIntegrationDefinition)) {
27524
+ throw new InstallationManagerError(
27525
+ "agent_verification_failed",
27526
+ "The local Agent discovery result is unavailable"
27527
+ );
27528
+ }
27529
+ const verifiedAgent = await findVerifiedAgentExecutable(
27530
+ specification,
27531
+ discoveryOptions
27532
+ );
27533
+ if (verifiedAgent === null) {
27534
+ throw new InstallationManagerError(
27535
+ "agent_not_installed",
27536
+ `Install ${specification.label} on this machine, then try installing the integration again.`
27537
+ );
28625
27538
  }
28626
- let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions2);
27539
+ const agent = verifiedAgent.executable;
27540
+ let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions);
28627
27541
  let installedAdapter = false;
28628
27542
  if (adapter === null) {
28629
27543
  if (!(specification instanceof BridgedAcpAgentDefinition)) {
@@ -28632,6 +27546,12 @@ var FixedInstallationExecutor = class {
28632
27546
  "The direct Agent executable is unavailable"
28633
27547
  );
28634
27548
  }
27549
+ if (this.#environment[specification.adapterOverrideVariable] !== void 0) {
27550
+ throw new InstallationManagerError(
27551
+ "adapter_not_found",
27552
+ "The configured ACP adapter is unavailable"
27553
+ );
27554
+ }
28635
27555
  await report("installing_adapter");
28636
27556
  adapter = await this.#adapterInstaller.install(specification, signal);
28637
27557
  installedAdapter = true;
@@ -28642,8 +27562,8 @@ var FixedInstallationExecutor = class {
28642
27562
  while (true) {
28643
27563
  await report("checking_acp");
28644
27564
  const environment = { ...this.#environment };
28645
- environment[specification.agentOverrideVariable] = agent.path;
28646
- environment[specification.adapterOverrideVariable] = adapter.path;
27565
+ environment[specification.agentOverrideVariable] = agent.identity.requestedPath;
27566
+ environment[specification.adapterOverrideVariable] = adapter.identity.requestedPath;
28647
27567
  const inventory = await discoverLocalAgentInventory({
28648
27568
  defaultWorkspace: this.#defaultWorkspace,
28649
27569
  environment,
@@ -28651,7 +27571,7 @@ var FixedInstallationExecutor = class {
28651
27571
  specifications: this.#specifications
28652
27572
  });
28653
27573
  const verified = inventory.available.find(
28654
- (candidate) => candidate.specification.id === agentId
27574
+ (candidate2) => candidate2.specification.id === agentId
28655
27575
  );
28656
27576
  if (verified instanceof AvailableAgent) {
28657
27577
  this.#audit.record(
@@ -28663,7 +27583,7 @@ var FixedInstallationExecutor = class {
28663
27583
  agentVersion: verified.agent.agentVersion
28664
27584
  }
28665
27585
  );
28666
- const previous = this.#catalog.read();
27586
+ const previousCatalog = this.#catalog.read();
28667
27587
  this.#catalog.transition(
28668
27588
  inventory.readyAgents(),
28669
27589
  inventory.installable
@@ -28672,15 +27592,15 @@ var FixedInstallationExecutor = class {
28672
27592
  await this.#publishCatalog(signal);
28673
27593
  } catch (error61) {
28674
27594
  this.#catalog.transition(
28675
- previous.agents,
28676
- previous.installableAgents
27595
+ previousCatalog.agents,
27596
+ previousCatalog.installableAgents
28677
27597
  );
28678
27598
  throw error61;
28679
27599
  }
28680
27600
  return;
28681
27601
  }
28682
27602
  const unavailable = inventory.unavailable.find(
28683
- (candidate) => candidate.specification.id === agentId
27603
+ (candidate2) => candidate2.specification.id === agentId
28684
27604
  );
28685
27605
  if (unavailable === void 0) {
28686
27606
  throw new InstallationManagerError(
@@ -28688,7 +27608,7 @@ var FixedInstallationExecutor = class {
28688
27608
  "The complete Agent ACP path did not pass verification"
28689
27609
  );
28690
27610
  }
28691
- if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && requiresAdapterReplacement(unavailable.code)) {
27611
+ if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && this.#environment[specification.adapterOverrideVariable] === void 0 && requiresAdapterReplacement(unavailable.code)) {
28692
27612
  await report("installing_adapter");
28693
27613
  adapter = await this.#adapterInstaller.install(specification, signal);
28694
27614
  installedAdapter = true;
@@ -28697,21 +27617,6 @@ var FixedInstallationExecutor = class {
28697
27617
  });
28698
27618
  continue;
28699
27619
  }
28700
- if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
28701
- agent = await recipe.install({
28702
- audit: this.#audit,
28703
- environment: this.#environment,
28704
- report,
28705
- requestId,
28706
- signal,
28707
- stateDirectory: this.#stateDirectory
28708
- });
28709
- installedAgent = true;
28710
- if (specification instanceof DirectAcpAgentDefinition) {
28711
- adapter = agent;
28712
- }
28713
- continue;
28714
- }
28715
27620
  throw new InstallationManagerError(
28716
27621
  unavailable.code,
28717
27622
  unavailable.message
@@ -28727,15 +27632,15 @@ var FixedInstallationExecutor = class {
28727
27632
  };
28728
27633
 
28729
27634
  // src/authorization/workspace-directory.ts
28730
- import { readdir, realpath as realpath8, stat as stat7 } from "node:fs/promises";
27635
+ import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
28731
27636
  import { homedir as homedir2 } from "node:os";
28732
27637
  import {
28733
27638
  basename as basename2,
28734
- dirname as dirname6,
28735
- isAbsolute as isAbsolute8,
28736
- join as join18,
27639
+ dirname as dirname5,
27640
+ isAbsolute as isAbsolute7,
27641
+ join as join15,
28737
27642
  normalize as normalize2,
28738
- relative as relative5
27643
+ relative as relative4
28739
27644
  } from "node:path";
28740
27645
  var WorkspaceDirectoryListing = class {
28741
27646
  directoryId;
@@ -28785,20 +27690,20 @@ var WorkspaceDirectoryService = class {
28785
27690
  if (id === "home") return homedir2();
28786
27691
  if (id.startsWith("path-")) {
28787
27692
  const path2 = decodePath(id, "path-");
28788
- if (isAbsolute8(path2)) return path2;
27693
+ if (isAbsolute7(path2)) return path2;
28789
27694
  }
28790
27695
  throw new LocalAuthorizationError("The directory identifier is invalid");
28791
27696
  };
28792
27697
  resolvePath = async (requested, signal) => {
28793
27698
  signal.throwIfAborted();
28794
- if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested)
27699
+ if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
28795
27700
  throw new LocalAuthorizationError("The local directory path is invalid");
28796
27701
  try {
28797
- const target = await realpath8(requested);
27702
+ const target = await realpath7(requested);
28798
27703
  signal.throwIfAborted();
28799
- const metadata = await stat7(target);
27704
+ const metadata = await stat6(target);
28800
27705
  signal.throwIfAborted();
28801
- if (!isAbsolute8(target) || normalize2(target) !== target || !metadata.isDirectory())
27706
+ if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
28802
27707
  throw new LocalAuthorizationError(
28803
27708
  "The selected location is not a directory"
28804
27709
  );
@@ -28813,8 +27718,8 @@ var WorkspaceDirectoryService = class {
28813
27718
  }
28814
27719
  };
28815
27720
  label = (path2) => {
28816
- const suffix = relative5(homedir2(), path2);
28817
- return suffix === "" ? "~" : !isAbsolute8(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
27721
+ const suffix = relative4(homedir2(), path2);
27722
+ return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
28818
27723
  };
28819
27724
  identify = async (bindingId, requestedPath, signal) => {
28820
27725
  this.authorizeMachine(bindingId);
@@ -28842,7 +27747,7 @@ var WorkspaceDirectoryService = class {
28842
27747
  continue;
28843
27748
  }
28844
27749
  try {
28845
- const path2 = await this.resolvePath(join18(target, child.name), signal);
27750
+ const path2 = await this.resolvePath(join15(target, child.name), signal);
28846
27751
  entries.push({ directoryId: encodePath(path2), name: child.name });
28847
27752
  } catch (cause) {
28848
27753
  signal.throwIfAborted();
@@ -28850,7 +27755,7 @@ var WorkspaceDirectoryService = class {
28850
27755
  }
28851
27756
  }
28852
27757
  entries.sort((a, b) => a.name.localeCompare(b.name));
28853
- const parent = dirname6(target);
27758
+ const parent = dirname5(target);
28854
27759
  return new WorkspaceDirectoryListing(
28855
27760
  id,
28856
27761
  this.label(target),
@@ -28874,7 +27779,7 @@ var WorkspaceDirectoryService = class {
28874
27779
  };
28875
27780
 
28876
27781
  // src/native-sessions/service.ts
28877
- import { randomUUID as randomUUID3 } from "node:crypto";
27782
+ import { randomUUID as randomUUID2 } from "node:crypto";
28878
27783
 
28879
27784
  // src/native-sessions/codex-history.ts
28880
27785
  import { spawn as spawn4 } from "node:child_process";
@@ -29188,7 +28093,7 @@ var NativeSessionService = class {
29188
28093
  for (const info of page.sessions) {
29189
28094
  const authorized = await this.authorizeEntry(command, options, info);
29190
28095
  if (authorized === null) continue;
29191
- const entryId = randomUUID3();
28096
+ const entryId = randomUUID2();
29192
28097
  if (this.#entries.size >= 5e3) this.#entries.clear();
29193
28098
  this.#entries.set(entryId, {
29194
28099
  scope: entryScope,
@@ -29213,7 +28118,7 @@ var NativeSessionService = class {
29213
28118
  {},
29214
28119
  "invalid_native_session_response"
29215
28120
  );
29216
- nextCursor = randomUUID3();
28121
+ nextCursor = randomUUID2();
29217
28122
  if (this.#cursors.size >= 500) this.#cursors.clear();
29218
28123
  this.#cursors.set(nextCursor, {
29219
28124
  scope: cursorScope,
@@ -29533,7 +28438,7 @@ function connectRelay(url2, signal) {
29533
28438
  }
29534
28439
 
29535
28440
  // src/relay-connection/liveness.ts
29536
- import { randomUUID as randomUUID4 } from "node:crypto";
28441
+ import { randomUUID as randomUUID3 } from "node:crypto";
29537
28442
  var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
29538
28443
  var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
29539
28444
  var RelayLivenessState = class {
@@ -29624,7 +28529,7 @@ var RelayConnectionLiveness = class {
29624
28529
  }
29625
28530
  throw new Error("Heartbeat was scheduled in an invalid state");
29626
28531
  }
29627
- const heartbeatId = randomUUID4();
28532
+ const heartbeatId = randomUUID3();
29628
28533
  this.#state = new AwaitingHeartbeatAckState(
29629
28534
  heartbeatId,
29630
28535
  this.#timer.schedule(
@@ -29643,7 +28548,7 @@ var RelayConnectionLiveness = class {
29643
28548
 
29644
28549
  // src/relay-connection/session-event-outbox.ts
29645
28550
  import { mkdirSync as mkdirSync3 } from "node:fs";
29646
- import { dirname as dirname7 } from "node:path";
28551
+ import { dirname as dirname6 } from "node:path";
29647
28552
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
29648
28553
  function readPendingEnvelope(row) {
29649
28554
  if (typeof row !== "object" || row === null || Array.isArray(row)) {
@@ -29658,7 +28563,7 @@ function readPendingEnvelope(row) {
29658
28563
  var SessionEventOutbox = class {
29659
28564
  #database;
29660
28565
  constructor(path2) {
29661
- mkdirSync3(dirname7(path2), { recursive: true });
28566
+ mkdirSync3(dirname6(path2), { recursive: true });
29662
28567
  this.#database = new DatabaseSync3(path2);
29663
28568
  this.#database.exec(`
29664
28569
  CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
@@ -29812,6 +28717,7 @@ var systemDaemonTimer = new SystemDaemonTimer();
29812
28717
  // src/run-daemon.ts
29813
28718
  var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
29814
28719
  var RELAY_CONNECTION_REFRESH_MILLISECONDS = 20 * 60 * 1e3;
28720
+ var ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS = 2e4;
29815
28721
  var RelayConnectionRefreshState = class {
29816
28722
  };
29817
28723
  var ScheduledRelayConnectionRefreshState = class extends RelayConnectionRefreshState {
@@ -30009,7 +28915,7 @@ var DaemonInstallationObserver = class {
30009
28915
  );
30010
28916
  return Promise.resolve();
30011
28917
  }
30012
- throw new Error("Unsupported Agent installation state");
28918
+ throw new Error("Unsupported Agent integration installation state");
30013
28919
  };
30014
28920
  };
30015
28921
  var ResolvedSessionDirectories = class {
@@ -30023,16 +28929,20 @@ var ResolvedSessionDirectories = class {
30023
28929
  }
30024
28930
  };
30025
28931
  var ActiveDaemonTurn = class {
28932
+ attemptId;
30026
28933
  command;
30027
- #connectionController;
28934
+ #controller;
28935
+ #finished = Promise.withResolvers();
30028
28936
  #cancellationRequested = false;
30029
- constructor(command, connectionController) {
28937
+ constructor(command, attemptId) {
28938
+ this.attemptId = attemptId;
30030
28939
  this.command = command;
30031
- this.#connectionController = connectionController;
28940
+ this.#controller = new AbortController();
30032
28941
  }
30033
- abortConnection = () => {
30034
- this.#connectionController.abort();
28942
+ abortDaemon = () => {
28943
+ this.#controller.abort();
30035
28944
  };
28945
+ finish = () => this.#finished.resolve();
30036
28946
  matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
30037
28947
  requestCancellation = () => {
30038
28948
  if (this.#cancellationRequested) {
@@ -30042,25 +28952,118 @@ var ActiveDaemonTurn = class {
30042
28952
  return true;
30043
28953
  };
30044
28954
  get signal() {
30045
- return this.#connectionController.signal;
28955
+ return this.#controller.signal;
28956
+ }
28957
+ get completion() {
28958
+ return this.#finished.promise;
28959
+ }
28960
+ };
28961
+ var ActiveTurnReconciliationError = class extends Error {
28962
+ code = "active_turn_reconciliation_failed";
28963
+ constructor(message, options = {}) {
28964
+ super(message, options);
28965
+ this.name = "ActiveTurnReconciliationError";
30046
28966
  }
30047
28967
  };
28968
+ function activeTurnReconciliationEndpoint(config2, turn) {
28969
+ const endpoint = new URL(config2.relayUrl);
28970
+ endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
28971
+ if (!endpoint.pathname.endsWith("/daemon")) {
28972
+ throw new ActiveTurnReconciliationError("The Relay URL is invalid");
28973
+ }
28974
+ endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
28975
+ endpoint.searchParams.delete("liveness");
28976
+ return endpoint;
28977
+ }
28978
+ async function reconcileActiveTurn(config2, turn, signal) {
28979
+ signal.throwIfAborted();
28980
+ const timeoutSignal = AbortSignal.timeout(
28981
+ ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS
28982
+ );
28983
+ const requestSignal = AbortSignal.any([signal, timeoutSignal]);
28984
+ let response;
28985
+ try {
28986
+ response = await fetch4(activeTurnReconciliationEndpoint(config2, turn), {
28987
+ body: JSON.stringify({ outcome: { kind: "running" } }),
28988
+ dispatcher: environmentProxyDispatcher,
28989
+ headers: { "content-type": "application/json" },
28990
+ method: "POST",
28991
+ signal: requestSignal
28992
+ });
28993
+ } catch (error61) {
28994
+ if (signal.aborted) {
28995
+ signal.throwIfAborted();
28996
+ }
28997
+ throw new ActiveTurnReconciliationError(
28998
+ timeoutSignal.aborted ? "The active Agent turn reconciliation timed out" : "The active Agent turn could not be reconciled",
28999
+ { cause: error61 }
29000
+ );
29001
+ }
29002
+ await response.body?.cancel();
29003
+ if (!response.ok) {
29004
+ throw new ActiveTurnReconciliationError(
29005
+ "The Relay rejected the active Agent turn reconciliation"
29006
+ );
29007
+ }
29008
+ }
29009
+ async function reconcileActiveTurns(config2, turns, signal) {
29010
+ await Promise.all(
29011
+ turns.map(async (turn) => await reconcileActiveTurn(config2, turn, signal))
29012
+ );
29013
+ }
30048
29014
  function send(socket, message) {
30049
29015
  if (socket.readyState !== WebSocket2.OPEN) {
30050
29016
  throw new Error("Relay connection is not open");
30051
29017
  }
30052
29018
  socket.send(message);
30053
29019
  }
30054
- function recordSessionEvent(outbox, socket, sessionId, payload, attemptId = null) {
30055
- const envelope2 = outbox.enqueue(sessionId, payload, attemptId);
30056
- if (socket.readyState === WebSocket2.OPEN) {
30057
- socket.send(envelope2);
29020
+ var DaemonSessionEventConnectionState = class {
29021
+ };
29022
+ var DisconnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
29023
+ disconnect = () => this;
29024
+ send = () => void 0;
29025
+ };
29026
+ var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
29027
+ #socket;
29028
+ constructor(socket) {
29029
+ super();
29030
+ this.#socket = socket;
30058
29031
  }
30059
- }
30060
- function reportFailure(outbox, socket, command, code, message, attemptId = null) {
30061
- recordSessionEvent(
30062
- outbox,
30063
- socket,
29032
+ disconnect = (socket) => socket === this.#socket ? new DisconnectedDaemonSessionEventState() : this;
29033
+ send = (message) => {
29034
+ if (this.#socket.readyState === WebSocket2.OPEN) {
29035
+ try {
29036
+ this.#socket.send(message);
29037
+ } catch {
29038
+ }
29039
+ }
29040
+ };
29041
+ };
29042
+ var DaemonSessionEventPublisher = class {
29043
+ #outbox;
29044
+ #connection = new DisconnectedDaemonSessionEventState();
29045
+ constructor(outbox) {
29046
+ this.#outbox = outbox;
29047
+ }
29048
+ connect = (socket) => {
29049
+ const connection = new ConnectedDaemonSessionEventState(socket);
29050
+ this.#connection = connection;
29051
+ for (const pending of this.#outbox.pending()) {
29052
+ connection.send(pending);
29053
+ }
29054
+ };
29055
+ disconnect = (socket) => {
29056
+ this.#connection = this.#connection.disconnect(socket);
29057
+ };
29058
+ recordAttempt = (sessionId, payload, attemptId) => {
29059
+ this.#connection.send(this.#outbox.enqueue(sessionId, payload, attemptId));
29060
+ };
29061
+ recordRuntime = (sessionId, payload) => {
29062
+ this.#connection.send(this.#outbox.enqueue(sessionId, payload));
29063
+ };
29064
+ };
29065
+ function reportFailure(publisher, command, code, message, attemptId) {
29066
+ publisher.recordAttempt(
30064
29067
  command.sessionId,
30065
29068
  encodeSessionFailedEvent({
30066
29069
  code,
@@ -30156,7 +29159,7 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
30156
29159
  reportOperationFailure(socket, command.requestId, "", error61);
30157
29160
  }
30158
29161
  }
30159
- async function executeSessionPrepare(outbox, socket, command, config2, directories, audit, sessions, signal) {
29162
+ async function executeSessionPrepare(publisher, socket, command, config2, directories, audit, sessions, signal) {
30160
29163
  try {
30161
29164
  const resolved = await resolveSessionDirectories(
30162
29165
  directories,
@@ -30183,9 +29186,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
30183
29186
  event: "session_prepared",
30184
29187
  sessionId: command.sessionId
30185
29188
  });
30186
- recordSessionEvent(
30187
- outbox,
30188
- socket,
29189
+ publisher.recordRuntime(
30189
29190
  command.sessionId,
30190
29191
  encodeSessionReadyEvent({
30191
29192
  additionalDirectories: resolved.additionalDirectoryEntries,
@@ -30216,7 +29217,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
30216
29217
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
30217
29218
  }
30218
29219
  }
30219
- async function executeSessionConfigure(outbox, socket, command, config2, directories, audit, sessions, signal) {
29220
+ async function executeSessionConfigure(publisher, socket, command, config2, directories, audit, sessions, signal) {
30220
29221
  try {
30221
29222
  const resolved = await resolveSessionDirectories(
30222
29223
  directories,
@@ -30242,9 +29243,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
30242
29243
  event: "session_configured",
30243
29244
  sessionId: command.sessionId
30244
29245
  });
30245
- recordSessionEvent(
30246
- outbox,
30247
- socket,
29246
+ publisher.recordRuntime(
30248
29247
  command.sessionId,
30249
29248
  encodeSessionConfigUpdatedEvent({
30250
29249
  configOptions,
@@ -30257,7 +29256,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
30257
29256
  reportOperationFailure(socket, command.requestId, command.sessionId, error61);
30258
29257
  }
30259
29258
  }
30260
- async function executePrompt(outbox, socket, command, config2, directories, audit, sessions, attemptId, signal) {
29259
+ async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, signal) {
30261
29260
  try {
30262
29261
  const resolved = await resolveSessionDirectories(
30263
29262
  directories,
@@ -30273,9 +29272,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30273
29272
  sessionId: command.sessionId
30274
29273
  });
30275
29274
  outbox.transitionExecution(command.commandId, "running");
30276
- recordSessionEvent(
30277
- outbox,
30278
- socket,
29275
+ publisher.recordAttempt(
30279
29276
  command.sessionId,
30280
29277
  encodeSessionStartedEvent({
30281
29278
  commandId: command.commandId,
@@ -30292,9 +29289,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30292
29289
  cwd: resolved.cwd,
30293
29290
  images: command.images,
30294
29291
  onActivity: (activity) => {
30295
- recordSessionEvent(
30296
- outbox,
30297
- socket,
29292
+ publisher.recordAttempt(
30298
29293
  command.sessionId,
30299
29294
  encodeAgentActivityEvent({
30300
29295
  activityId: activity.activityId,
@@ -30318,9 +29313,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30318
29313
  return Promise.resolve();
30319
29314
  },
30320
29315
  onText: (text) => {
30321
- recordSessionEvent(
30322
- outbox,
30323
- socket,
29316
+ publisher.recordAttempt(
30324
29317
  command.sessionId,
30325
29318
  encodeAgentMessageDeltaEvent({
30326
29319
  commandId: command.commandId,
@@ -30337,9 +29330,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30337
29330
  sessionId: command.sessionId,
30338
29331
  signal
30339
29332
  });
30340
- recordSessionEvent(
30341
- outbox,
30342
- socket,
29333
+ publisher.recordAttempt(
30343
29334
  command.sessionId,
30344
29335
  encodeSessionCompletedEvent({
30345
29336
  commandId: command.commandId,
@@ -30366,8 +29357,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
30366
29357
  });
30367
29358
  const code = operationErrorCode(error61);
30368
29359
  reportFailure(
30369
- outbox,
30370
- socket,
29360
+ publisher,
30371
29361
  command,
30372
29362
  code === "session_operation_failed" ? "agent_execution_failed" : code,
30373
29363
  code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error61),
@@ -30413,29 +29403,15 @@ async function publishAgentCatalogUntilAvailable(config2, signal, timer) {
30413
29403
  }
30414
29404
  }
30415
29405
  }
30416
- async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, onConnected, signal, timer) {
29406
+ async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, activeTurns, activeAttemptIds, onConnected, signal, timer) {
30417
29407
  const relayUrl = new URL(config2.relayUrl);
30418
29408
  relayUrl.searchParams.set("liveness", "1");
30419
29409
  const socket = await connectRelay(relayUrl, signal);
29410
+ const reconnectingTurns = [...activeTurns.values()];
30420
29411
  onConnected();
30421
- const activeTurns = /* @__PURE__ */ new Map();
30422
- const activeAttemptIds = /* @__PURE__ */ new Map();
30423
29412
  const connectionController = new AbortController();
30424
29413
  const nativeRequests = /* @__PURE__ */ new Map();
30425
- const record2 = (sessionId, payload) => {
30426
- recordSessionEvent(
30427
- outbox,
30428
- socket,
30429
- sessionId,
30430
- payload,
30431
- activeAttemptIds.get(sessionId) ?? null
30432
- );
30433
- };
30434
- sessions.setObserver(new DaemonAcpObserver(record2));
30435
29414
  installationObserver.connect(socket);
30436
- for (const pending of outbox.pending()) {
30437
- send(socket, pending);
30438
- }
30439
29415
  try {
30440
29416
  await new Promise((resolve5, reject) => {
30441
29417
  let finished = false;
@@ -30447,11 +29423,8 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30447
29423
  socket.removeEventListener("error", handleError);
30448
29424
  socket.removeEventListener("message", handleMessage);
30449
29425
  installationObserver.disconnect(socket);
29426
+ publisher.disconnect(socket);
30450
29427
  connectionController.abort();
30451
- for (const turn of activeTurns.values()) {
30452
- turn.abortConnection();
30453
- }
30454
- activeTurns.clear();
30455
29428
  };
30456
29429
  const resolveConnection = () => {
30457
29430
  if (finished) {
@@ -30670,7 +29643,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30670
29643
  if (kind === SESSION_PREPARE_KIND) {
30671
29644
  const command2 = decodeSessionPrepareCommand(encoded);
30672
29645
  void executeSessionPrepare(
30673
- outbox,
29646
+ publisher,
30674
29647
  socket,
30675
29648
  command2,
30676
29649
  config2,
@@ -30684,7 +29657,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30684
29657
  if (kind === SESSION_CONFIGURE_KIND) {
30685
29658
  const command2 = decodeSessionConfigureCommand(encoded);
30686
29659
  void executeSessionConfigure(
30687
- outbox,
29660
+ publisher,
30688
29661
  socket,
30689
29662
  command2,
30690
29663
  config2,
@@ -30734,7 +29707,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30734
29707
  if (kind === AGENT_INSTALL_REQUEST_KIND) {
30735
29708
  const command2 = decodeAgentInstallRequestCommand(encoded);
30736
29709
  void installations.request(command2, signal).catch((error61) => {
30737
- console.error("Mobius Agent installation failed", error61);
29710
+ console.error(
29711
+ "Mobius Agent integration installation failed",
29712
+ error61
29713
+ );
30738
29714
  });
30739
29715
  return;
30740
29716
  }
@@ -30760,12 +29736,12 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30760
29736
  if (receipt.kind === "duplicate") {
30761
29737
  return;
30762
29738
  }
30763
- const turn = new ActiveDaemonTurn(command, new AbortController());
29739
+ const turn = new ActiveDaemonTurn(command, receipt.attemptId);
30764
29740
  activeTurns.set(command.commandId, turn);
30765
29741
  activeAttemptIds.set(command.sessionId, receipt.attemptId);
30766
29742
  void executePrompt(
30767
29743
  outbox,
30768
- socket,
29744
+ publisher,
30769
29745
  command,
30770
29746
  config2,
30771
29747
  directories,
@@ -30780,6 +29756,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30780
29756
  if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
30781
29757
  activeAttemptIds.delete(command.sessionId);
30782
29758
  }
29759
+ turn.finish();
30783
29760
  connectionRefresh.afterTurnFinished();
30784
29761
  });
30785
29762
  } catch (error61) {
@@ -30791,6 +29768,28 @@ async function runRelayConnection(config2, directories, audit, sessions, install
30791
29768
  socket.addEventListener("close", handleClose);
30792
29769
  socket.addEventListener("error", handleError);
30793
29770
  socket.addEventListener("message", handleMessage);
29771
+ void reconcileActiveTurns(
29772
+ config2,
29773
+ reconnectingTurns,
29774
+ connectionController.signal
29775
+ ).then(
29776
+ () => {
29777
+ if (finished) {
29778
+ return;
29779
+ }
29780
+ publisher.connect(socket);
29781
+ void Promise.all(
29782
+ reconnectingTurns.map((turn) => turn.completion)
29783
+ ).then(connectionRefresh.afterTurnFinished);
29784
+ },
29785
+ () => {
29786
+ if (finished) {
29787
+ return;
29788
+ }
29789
+ socket.close(1011, "Active Agent turn reconciliation failed");
29790
+ rejectConnection();
29791
+ }
29792
+ );
30794
29793
  if (signal.aborted) {
30795
29794
  stop();
30796
29795
  }
@@ -30814,23 +29813,21 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30814
29813
  publishCatalog: async (installationSignal) => await publishAgentCatalog(config2, installationSignal),
30815
29814
  stateDirectory
30816
29815
  });
30817
- await new AutomaticAdapterProvisioner(
30818
- {
30819
- defaultWorkspace: config2.defaultWorkspace,
30820
- audit: installationAudit,
30821
- catalog: config2.catalog,
30822
- environment: process.env
30823
- },
30824
- new ManagedAdapterInstaller({
30825
- environment: process.env,
30826
- stateDirectory
30827
- }),
30828
- specifications
30829
- ).prepare(signal);
30830
29816
  const sessionStore = new SqliteAcpSessionStore(config2.auditDatabasePath);
30831
29817
  const outbox = new SessionEventOutbox(config2.auditDatabasePath);
29818
+ const publisher = new DaemonSessionEventPublisher(outbox);
29819
+ const activeTurns = /* @__PURE__ */ new Map();
29820
+ const activeAttemptIds = /* @__PURE__ */ new Map();
29821
+ const recordSessionEvent = (sessionId, payload) => {
29822
+ const attemptId = activeAttemptIds.get(sessionId);
29823
+ if (attemptId === void 0) {
29824
+ publisher.recordRuntime(sessionId, payload);
29825
+ return;
29826
+ }
29827
+ publisher.recordAttempt(sessionId, payload, attemptId);
29828
+ };
30832
29829
  const sessions = new AcpSessionManager(
30833
- new NullAcpSessionObserver(),
29830
+ new DaemonAcpObserver(recordSessionEvent),
30834
29831
  sessionStore
30835
29832
  );
30836
29833
  const directories = new WorkspaceDirectoryService(
@@ -30886,6 +29883,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30886
29883
  installationObserver,
30887
29884
  nativeSessions,
30888
29885
  outbox,
29886
+ publisher,
29887
+ activeTurns,
29888
+ activeAttemptIds,
30889
29889
  announceConnection,
30890
29890
  signal,
30891
29891
  timer
@@ -30903,6 +29903,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
30903
29903
  await waitForRelayRetry(signal, timer);
30904
29904
  }
30905
29905
  } finally {
29906
+ const turns = [...activeTurns.values()];
29907
+ for (const turn of turns) {
29908
+ turn.abortDaemon();
29909
+ }
29910
+ await Promise.all(turns.map((turn) => turn.completion));
30906
29911
  try {
30907
29912
  await catalogPublication;
30908
29913
  } finally {