@openma/common 0.0.0-stage → 0.9.0

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 (328) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +391 -2
  3. package/dist/acp-artifacts/binary.d.ts +35 -0
  4. package/dist/acp-artifacts/binary.d.ts.map +1 -0
  5. package/dist/acp-artifacts/binary.js +120 -0
  6. package/dist/acp-artifacts/binary.js.map +1 -0
  7. package/dist/acp-artifacts/index.d.ts +7 -0
  8. package/dist/acp-artifacts/index.d.ts.map +1 -0
  9. package/dist/acp-artifacts/index.js +7 -0
  10. package/dist/acp-artifacts/index.js.map +1 -0
  11. package/dist/acp-artifacts/node-abi.d.ts +3 -0
  12. package/dist/acp-artifacts/node-abi.d.ts.map +1 -0
  13. package/dist/acp-artifacts/node-abi.js +17 -0
  14. package/dist/acp-artifacts/node-abi.js.map +1 -0
  15. package/dist/acp-artifacts/npm-cli.d.ts +3 -0
  16. package/dist/acp-artifacts/npm-cli.d.ts.map +1 -0
  17. package/dist/acp-artifacts/npm-cli.js +9 -0
  18. package/dist/acp-artifacts/npm-cli.js.map +1 -0
  19. package/dist/acp-artifacts/npm.d.ts +37 -0
  20. package/dist/acp-artifacts/npm.d.ts.map +1 -0
  21. package/dist/acp-artifacts/npm.js +167 -0
  22. package/dist/acp-artifacts/npm.js.map +1 -0
  23. package/dist/acp-artifacts/registry.d.ts +45 -0
  24. package/dist/acp-artifacts/registry.d.ts.map +1 -0
  25. package/dist/acp-artifacts/registry.js +206 -0
  26. package/dist/acp-artifacts/registry.js.map +1 -0
  27. package/dist/acp-artifacts/shared.d.ts +45 -0
  28. package/dist/acp-artifacts/shared.d.ts.map +1 -0
  29. package/dist/acp-artifacts/shared.js +157 -0
  30. package/dist/acp-artifacts/shared.js.map +1 -0
  31. package/dist/acp-artifacts/uvx.d.ts +32 -0
  32. package/dist/acp-artifacts/uvx.d.ts.map +1 -0
  33. package/dist/acp-artifacts/uvx.js +95 -0
  34. package/dist/acp-artifacts/uvx.js.map +1 -0
  35. package/dist/acp-fork/index.d.ts +51 -0
  36. package/dist/acp-fork/index.d.ts.map +1 -0
  37. package/dist/acp-fork/index.js +116 -0
  38. package/dist/acp-fork/index.js.map +1 -0
  39. package/dist/acp-harnesses/agent-setup.d.ts +118 -0
  40. package/dist/acp-harnesses/agent-setup.d.ts.map +1 -0
  41. package/dist/acp-harnesses/agent-setup.js +717 -0
  42. package/dist/acp-harnesses/agent-setup.js.map +1 -0
  43. package/dist/acp-harnesses/custom-agents.d.ts +81 -0
  44. package/dist/acp-harnesses/custom-agents.d.ts.map +1 -0
  45. package/dist/acp-harnesses/custom-agents.js +361 -0
  46. package/dist/acp-harnesses/custom-agents.js.map +1 -0
  47. package/dist/acp-harnesses/headless-launch.d.ts +34 -0
  48. package/dist/acp-harnesses/headless-launch.d.ts.map +1 -0
  49. package/dist/acp-harnesses/headless-launch.js +67 -0
  50. package/dist/acp-harnesses/headless-launch.js.map +1 -0
  51. package/dist/acp-harnesses/index.d.ts +18 -0
  52. package/dist/acp-harnesses/index.d.ts.map +1 -0
  53. package/dist/acp-harnesses/index.js +58 -0
  54. package/dist/acp-harnesses/index.js.map +1 -0
  55. package/dist/acp-harnesses/install-state.d.ts +86 -0
  56. package/dist/acp-harnesses/install-state.d.ts.map +1 -0
  57. package/dist/acp-harnesses/install-state.js +322 -0
  58. package/dist/acp-harnesses/install-state.js.map +1 -0
  59. package/dist/acp-harnesses/installer.d.ts +145 -0
  60. package/dist/acp-harnesses/installer.d.ts.map +1 -0
  61. package/dist/acp-harnesses/installer.js +716 -0
  62. package/dist/acp-harnesses/installer.js.map +1 -0
  63. package/dist/acp-harnesses/known-agents.d.ts +154 -0
  64. package/dist/acp-harnesses/known-agents.d.ts.map +1 -0
  65. package/dist/acp-harnesses/known-agents.js +240 -0
  66. package/dist/acp-harnesses/known-agents.js.map +1 -0
  67. package/dist/acp-harnesses/launcher.d.ts +27 -0
  68. package/dist/acp-harnesses/launcher.d.ts.map +1 -0
  69. package/dist/acp-harnesses/launcher.js +64 -0
  70. package/dist/acp-harnesses/launcher.js.map +1 -0
  71. package/dist/acp-harnesses/registry-fetch.d.ts +42 -0
  72. package/dist/acp-harnesses/registry-fetch.d.ts.map +1 -0
  73. package/dist/acp-harnesses/registry-fetch.js +132 -0
  74. package/dist/acp-harnesses/registry-fetch.js.map +1 -0
  75. package/dist/acp-harnesses/registry.d.ts +36 -0
  76. package/dist/acp-harnesses/registry.d.ts.map +1 -0
  77. package/dist/acp-harnesses/registry.js +307 -0
  78. package/dist/acp-harnesses/registry.js.map +1 -0
  79. package/dist/acp-runtime/errors.d.ts +7 -0
  80. package/dist/acp-runtime/errors.d.ts.map +1 -0
  81. package/dist/acp-runtime/errors.js +17 -0
  82. package/dist/acp-runtime/errors.js.map +1 -0
  83. package/dist/acp-runtime/fork-support.d.ts +8 -0
  84. package/dist/acp-runtime/fork-support.d.ts.map +1 -0
  85. package/dist/acp-runtime/fork-support.js +20 -0
  86. package/dist/acp-runtime/fork-support.js.map +1 -0
  87. package/dist/acp-runtime/index.d.ts +11 -0
  88. package/dist/acp-runtime/index.d.ts.map +1 -0
  89. package/dist/acp-runtime/index.js +6 -0
  90. package/dist/acp-runtime/index.js.map +1 -0
  91. package/dist/acp-runtime/probe.d.ts +103 -0
  92. package/dist/acp-runtime/probe.d.ts.map +1 -0
  93. package/dist/acp-runtime/probe.js +872 -0
  94. package/dist/acp-runtime/probe.js.map +1 -0
  95. package/dist/acp-runtime/runtime.d.ts +7 -0
  96. package/dist/acp-runtime/runtime.d.ts.map +1 -0
  97. package/dist/acp-runtime/runtime.js +26 -0
  98. package/dist/acp-runtime/runtime.js.map +1 -0
  99. package/dist/acp-runtime/session.d.ts +87 -0
  100. package/dist/acp-runtime/session.d.ts.map +1 -0
  101. package/dist/acp-runtime/session.js +1071 -0
  102. package/dist/acp-runtime/session.js.map +1 -0
  103. package/dist/acp-runtime/spawners/node.d.ts +5 -0
  104. package/dist/acp-runtime/spawners/node.d.ts.map +1 -0
  105. package/dist/acp-runtime/spawners/node.js +244 -0
  106. package/dist/acp-runtime/spawners/node.js.map +1 -0
  107. package/dist/acp-runtime/types.d.ts +180 -0
  108. package/dist/acp-runtime/types.d.ts.map +1 -0
  109. package/dist/acp-runtime/types.js +2 -0
  110. package/dist/acp-runtime/types.js.map +1 -0
  111. package/dist/agent-contract/acp.d.ts +4 -0
  112. package/dist/agent-contract/acp.d.ts.map +1 -0
  113. package/dist/agent-contract/acp.js +273 -0
  114. package/dist/agent-contract/acp.js.map +1 -0
  115. package/dist/agent-contract/index.d.ts +125 -0
  116. package/dist/agent-contract/index.d.ts.map +1 -0
  117. package/dist/agent-contract/index.js +102 -0
  118. package/dist/agent-contract/index.js.map +1 -0
  119. package/dist/agent-contract/managed.d.ts +5 -0
  120. package/dist/agent-contract/managed.d.ts.map +1 -0
  121. package/dist/agent-contract/managed.js +242 -0
  122. package/dist/agent-contract/managed.js.map +1 -0
  123. package/dist/agent-ui/index.d.ts +170 -0
  124. package/dist/agent-ui/index.d.ts.map +1 -0
  125. package/dist/agent-ui/index.js +853 -0
  126. package/dist/agent-ui/index.js.map +1 -0
  127. package/dist/agent-ui/presentation.d.ts +30 -0
  128. package/dist/agent-ui/presentation.d.ts.map +1 -0
  129. package/dist/agent-ui/presentation.js +79 -0
  130. package/dist/agent-ui/presentation.js.map +1 -0
  131. package/dist/agent-ui/react.d.ts +50 -0
  132. package/dist/agent-ui/react.d.ts.map +1 -0
  133. package/dist/agent-ui/react.js +334 -0
  134. package/dist/agent-ui/react.js.map +1 -0
  135. package/dist/brand/index.d.ts +17 -0
  136. package/dist/brand/index.d.ts.map +1 -0
  137. package/dist/brand/index.js +119 -0
  138. package/dist/brand/index.js.map +1 -0
  139. package/dist/brand/openma-logo-mark.svg +7 -0
  140. package/dist/brand/tokens.css +77 -0
  141. package/dist/brand/website.css +67 -0
  142. package/dist/chat-ui/acp.d.ts +26 -0
  143. package/dist/chat-ui/acp.d.ts.map +1 -0
  144. package/dist/chat-ui/acp.js +166 -0
  145. package/dist/chat-ui/acp.js.map +1 -0
  146. package/dist/chat-ui/components.d.ts +230 -0
  147. package/dist/chat-ui/components.d.ts.map +1 -0
  148. package/dist/chat-ui/components.js +561 -0
  149. package/dist/chat-ui/components.js.map +1 -0
  150. package/dist/chat-ui/composer-drafts.d.ts +21 -0
  151. package/dist/chat-ui/composer-drafts.d.ts.map +1 -0
  152. package/dist/chat-ui/composer-drafts.js +58 -0
  153. package/dist/chat-ui/composer-drafts.js.map +1 -0
  154. package/dist/chat-ui/controller.d.ts +61 -0
  155. package/dist/chat-ui/controller.d.ts.map +1 -0
  156. package/dist/chat-ui/controller.js +218 -0
  157. package/dist/chat-ui/controller.js.map +1 -0
  158. package/dist/chat-ui/index.d.ts +8 -0
  159. package/dist/chat-ui/index.d.ts.map +1 -0
  160. package/dist/chat-ui/index.js +8 -0
  161. package/dist/chat-ui/index.js.map +1 -0
  162. package/dist/chat-ui/markdown.d.ts +37 -0
  163. package/dist/chat-ui/markdown.d.ts.map +1 -0
  164. package/dist/chat-ui/markdown.js +33 -0
  165. package/dist/chat-ui/markdown.js.map +1 -0
  166. package/dist/chat-ui/presentation.d.ts +34 -0
  167. package/dist/chat-ui/presentation.d.ts.map +1 -0
  168. package/dist/chat-ui/presentation.js +191 -0
  169. package/dist/chat-ui/presentation.js.map +1 -0
  170. package/dist/chat-ui/styles.css +815 -0
  171. package/dist/chat-ui/utils.d.ts +14 -0
  172. package/dist/chat-ui/utils.d.ts.map +1 -0
  173. package/dist/chat-ui/utils.js +71 -0
  174. package/dist/chat-ui/utils.js.map +1 -0
  175. package/dist/local-runtime/checkpoint.d.ts +28 -0
  176. package/dist/local-runtime/checkpoint.d.ts.map +1 -0
  177. package/dist/local-runtime/checkpoint.js +2 -0
  178. package/dist/local-runtime/checkpoint.js.map +1 -0
  179. package/dist/local-runtime/daemon-connection.d.ts +27 -0
  180. package/dist/local-runtime/daemon-connection.d.ts.map +1 -0
  181. package/dist/local-runtime/daemon-connection.js +161 -0
  182. package/dist/local-runtime/daemon-connection.js.map +1 -0
  183. package/dist/local-runtime/daemon-host.d.ts +39 -0
  184. package/dist/local-runtime/daemon-host.d.ts.map +1 -0
  185. package/dist/local-runtime/daemon-host.js +88 -0
  186. package/dist/local-runtime/daemon-host.js.map +1 -0
  187. package/dist/local-runtime/index.d.ts +6 -0
  188. package/dist/local-runtime/index.d.ts.map +1 -0
  189. package/dist/local-runtime/index.js +5 -0
  190. package/dist/local-runtime/index.js.map +1 -0
  191. package/dist/local-runtime/runtime.d.ts +36 -0
  192. package/dist/local-runtime/runtime.d.ts.map +1 -0
  193. package/dist/local-runtime/runtime.js +82 -0
  194. package/dist/local-runtime/runtime.js.map +1 -0
  195. package/dist/local-runtime/session-host.d.ts +62 -0
  196. package/dist/local-runtime/session-host.d.ts.map +1 -0
  197. package/dist/local-runtime/session-host.js +477 -0
  198. package/dist/local-runtime/session-host.js.map +1 -0
  199. package/dist/managed-runtime/acp-subagents.d.ts +14 -0
  200. package/dist/managed-runtime/acp-subagents.d.ts.map +1 -0
  201. package/dist/managed-runtime/acp-subagents.js +67 -0
  202. package/dist/managed-runtime/acp-subagents.js.map +1 -0
  203. package/dist/managed-runtime/claimed-environment-work.d.ts +61 -0
  204. package/dist/managed-runtime/claimed-environment-work.d.ts.map +1 -0
  205. package/dist/managed-runtime/claimed-environment-work.js +170 -0
  206. package/dist/managed-runtime/claimed-environment-work.js.map +1 -0
  207. package/dist/managed-runtime/contracts.d.ts +31 -0
  208. package/dist/managed-runtime/contracts.d.ts.map +1 -0
  209. package/dist/managed-runtime/contracts.js +2 -0
  210. package/dist/managed-runtime/contracts.js.map +1 -0
  211. package/dist/managed-runtime/http-control.d.ts +67 -0
  212. package/dist/managed-runtime/http-control.d.ts.map +1 -0
  213. package/dist/managed-runtime/http-control.js +465 -0
  214. package/dist/managed-runtime/http-control.js.map +1 -0
  215. package/dist/managed-runtime/index.d.ts +89 -0
  216. package/dist/managed-runtime/index.d.ts.map +1 -0
  217. package/dist/managed-runtime/index.js +215 -0
  218. package/dist/managed-runtime/index.js.map +1 -0
  219. package/dist/managed-runtime/input-identity.d.ts +2 -0
  220. package/dist/managed-runtime/input-identity.d.ts.map +1 -0
  221. package/dist/managed-runtime/input-identity.js +2 -0
  222. package/dist/managed-runtime/input-identity.js.map +1 -0
  223. package/dist/managed-runtime/managed-event-projector.d.ts +24 -0
  224. package/dist/managed-runtime/managed-event-projector.d.ts.map +1 -0
  225. package/dist/managed-runtime/managed-event-projector.js +333 -0
  226. package/dist/managed-runtime/managed-event-projector.js.map +1 -0
  227. package/dist/managed-runtime/semantic-recovery.d.ts +61 -0
  228. package/dist/managed-runtime/semantic-recovery.d.ts.map +1 -0
  229. package/dist/managed-runtime/semantic-recovery.js +167 -0
  230. package/dist/managed-runtime/semantic-recovery.js.map +1 -0
  231. package/dist/project-ui/CreateProjectDialog.d.ts +15 -0
  232. package/dist/project-ui/CreateProjectDialog.d.ts.map +1 -0
  233. package/dist/project-ui/CreateProjectDialog.js +87 -0
  234. package/dist/project-ui/CreateProjectDialog.js.map +1 -0
  235. package/dist/project-ui/ProjectComposer.d.ts +13 -0
  236. package/dist/project-ui/ProjectComposer.d.ts.map +1 -0
  237. package/dist/project-ui/ProjectComposer.js +70 -0
  238. package/dist/project-ui/ProjectComposer.js.map +1 -0
  239. package/dist/project-ui/ProjectConversation.d.ts +10 -0
  240. package/dist/project-ui/ProjectConversation.d.ts.map +1 -0
  241. package/dist/project-ui/ProjectConversation.js +28 -0
  242. package/dist/project-ui/ProjectConversation.js.map +1 -0
  243. package/dist/project-ui/ProjectMessageAttachments.d.ts +4 -0
  244. package/dist/project-ui/ProjectMessageAttachments.d.ts.map +1 -0
  245. package/dist/project-ui/ProjectMessageAttachments.js +28 -0
  246. package/dist/project-ui/ProjectMessageAttachments.js.map +1 -0
  247. package/dist/project-ui/ProjectSettings.d.ts +8 -0
  248. package/dist/project-ui/ProjectSettings.d.ts.map +1 -0
  249. package/dist/project-ui/ProjectSettings.js +65 -0
  250. package/dist/project-ui/ProjectSettings.js.map +1 -0
  251. package/dist/project-ui/Projects.d.ts +18 -0
  252. package/dist/project-ui/Projects.d.ts.map +1 -0
  253. package/dist/project-ui/Projects.js +377 -0
  254. package/dist/project-ui/Projects.js.map +1 -0
  255. package/dist/project-ui/client.d.ts +234 -0
  256. package/dist/project-ui/client.d.ts.map +1 -0
  257. package/dist/project-ui/client.js +42 -0
  258. package/dist/project-ui/client.js.map +1 -0
  259. package/dist/project-ui/controls.d.ts +15 -0
  260. package/dist/project-ui/controls.d.ts.map +1 -0
  261. package/dist/project-ui/controls.js +17 -0
  262. package/dist/project-ui/controls.js.map +1 -0
  263. package/dist/project-ui/index.d.ts +20 -0
  264. package/dist/project-ui/index.d.ts.map +1 -0
  265. package/dist/project-ui/index.js +17 -0
  266. package/dist/project-ui/index.js.map +1 -0
  267. package/dist/project-ui/project-coordinator.d.ts +3 -0
  268. package/dist/project-ui/project-coordinator.d.ts.map +1 -0
  269. package/dist/project-ui/project-coordinator.js +12 -0
  270. package/dist/project-ui/project-coordinator.js.map +1 -0
  271. package/dist/project-ui/project-goals.d.ts +48 -0
  272. package/dist/project-ui/project-goals.d.ts.map +1 -0
  273. package/dist/project-ui/project-goals.js +169 -0
  274. package/dist/project-ui/project-goals.js.map +1 -0
  275. package/dist/project-ui/projects-query.d.ts +19 -0
  276. package/dist/project-ui/projects-query.d.ts.map +1 -0
  277. package/dist/project-ui/projects-query.js +132 -0
  278. package/dist/project-ui/projects-query.js.map +1 -0
  279. package/dist/project-ui/styles.css +847 -0
  280. package/dist/protocol/acp/index.d.ts +52 -0
  281. package/dist/protocol/acp/index.d.ts.map +1 -0
  282. package/dist/protocol/acp/index.js +1056 -0
  283. package/dist/protocol/acp/index.js.map +1 -0
  284. package/dist/protocol/cursor-cloud/index.d.ts +74 -0
  285. package/dist/protocol/cursor-cloud/index.d.ts.map +1 -0
  286. package/dist/protocol/cursor-cloud/index.js +249 -0
  287. package/dist/protocol/cursor-cloud/index.js.map +1 -0
  288. package/dist/protocol/managed/index.d.ts +32 -0
  289. package/dist/protocol/managed/index.d.ts.map +1 -0
  290. package/dist/protocol/managed/index.js +646 -0
  291. package/dist/protocol/managed/index.js.map +1 -0
  292. package/dist/protocol/managed/input-identity.d.ts +3 -0
  293. package/dist/protocol/managed/input-identity.d.ts.map +1 -0
  294. package/dist/protocol/managed/input-identity.js +6 -0
  295. package/dist/protocol/managed/input-identity.js.map +1 -0
  296. package/dist/protocol/openai-agents/index.d.ts +102 -0
  297. package/dist/protocol/openai-agents/index.d.ts.map +1 -0
  298. package/dist/protocol/openai-agents/index.js +142 -0
  299. package/dist/protocol/openai-agents/index.js.map +1 -0
  300. package/dist/session-events/acp-system-notices.d.ts +10 -0
  301. package/dist/session-events/acp-system-notices.d.ts.map +1 -0
  302. package/dist/session-events/acp-system-notices.js +46 -0
  303. package/dist/session-events/acp-system-notices.js.map +1 -0
  304. package/dist/session-events/acp.d.ts +214 -0
  305. package/dist/session-events/acp.d.ts.map +1 -0
  306. package/dist/session-events/acp.js +956 -0
  307. package/dist/session-events/acp.js.map +1 -0
  308. package/dist/session-events/managed.d.ts +141 -0
  309. package/dist/session-events/managed.d.ts.map +1 -0
  310. package/dist/session-events/managed.js +324 -0
  311. package/dist/session-events/managed.js.map +1 -0
  312. package/dist/session-events/openma.d.ts +304 -0
  313. package/dist/session-events/openma.d.ts.map +1 -0
  314. package/dist/session-events/openma.js +438 -0
  315. package/dist/session-events/openma.js.map +1 -0
  316. package/dist/session-kernel/index.d.ts +118 -0
  317. package/dist/session-kernel/index.d.ts.map +1 -0
  318. package/dist/session-kernel/index.js +215 -0
  319. package/dist/session-kernel/index.js.map +1 -0
  320. package/dist/session-orchestrator/index.d.ts +71 -0
  321. package/dist/session-orchestrator/index.d.ts.map +1 -0
  322. package/dist/session-orchestrator/index.js +177 -0
  323. package/dist/session-orchestrator/index.js.map +1 -0
  324. package/dist/session-ui/index.d.ts +96 -0
  325. package/dist/session-ui/index.d.ts.map +1 -0
  326. package/dist/session-ui/index.js +277 -0
  327. package/dist/session-ui/index.js.map +1 -0
  328. package/package.json +222 -4
@@ -0,0 +1,717 @@
1
+ import { spawn } from "node:child_process";
2
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { basename, delimiter, dirname, join } from "node:path";
4
+ import { detectEntry, getKnownAgents, loadRegistry, } from "./registry.js";
5
+ import { installAcpRegistryAgent, installManagedAdapter, latestNpmPackageVersion, npmPackageNameFromSpec, readAcpHarnessInstallState, repairRelocatedAcpRegistryShim, uninstallAcpRegistryAgent, uninstallManagedAdapter, usesOpenMaNpmLatestSource, } from "./installer.js";
6
+ import { authenticateAgent, disposeAllAcpProbes, probeAgentSessionConfig, probeAgentAuthStatus, } from "../acp-runtime/probe.js";
7
+ const NO_LIVE_PROBE_PLAN = {
8
+ trigger: "list",
9
+ refreshRegistry: false,
10
+ auth: { target: "ids", ids: [] },
11
+ capabilities: { target: "ids", ids: [] },
12
+ };
13
+ export function createAcpAgentSetupService(deps) {
14
+ return new AcpAgentSetupServiceImpl(deps);
15
+ }
16
+ class AcpAgentSetupServiceImpl {
17
+ deps;
18
+ nextOperationId = 1;
19
+ probeCachePromise = null;
20
+ probeCacheWrite = Promise.resolve();
21
+ authCache = new Map();
22
+ capabilityInspections = new Map();
23
+ constructor(deps) {
24
+ this.deps = deps;
25
+ }
26
+ dispose() {
27
+ return disposeAllAcpProbes();
28
+ }
29
+ async warmup() {
30
+ await this.repairRelocatedRegistryShims();
31
+ await this.collectAgentSnapshot({
32
+ trigger: "startup",
33
+ refreshRegistry: true,
34
+ auth: { target: "ids", ids: [] },
35
+ capabilities: { target: "detected" },
36
+ });
37
+ }
38
+ async repairRelocatedRegistryShims() {
39
+ const entries = this.catalogEntries().filter((entry) => entry.installSource === "registry" && entry.registryId);
40
+ await Promise.all(entries.map(async (entry) => {
41
+ try {
42
+ await repairRelocatedAcpRegistryShim({
43
+ registryId: entry.registryId,
44
+ shimName: basename(entry.spec.command),
45
+ binDir: this.deps.acpBinDir,
46
+ installRoot: this.deps.acpInstallRoot,
47
+ });
48
+ }
49
+ catch (error) {
50
+ if (process.env.NODE_ENV !== "test") {
51
+ process.stderr.write(`! ACP shim repair skipped for ${entry.id}: ${errorMessage(error)}\n`);
52
+ }
53
+ }
54
+ }));
55
+ }
56
+ async refreshEnabledAgents() {
57
+ const enabledAgentIds = this.deps.getEnabledAgentIds?.() ?? [];
58
+ return this.collectAgentSnapshot({
59
+ trigger: "manual",
60
+ refreshRegistry: true,
61
+ auth: { target: "ids", ids: enabledAgentIds },
62
+ capabilities: { target: "ids", ids: enabledAgentIds },
63
+ });
64
+ }
65
+ async listAgents() {
66
+ return this.collectAgentSnapshot(NO_LIVE_PROBE_PLAN);
67
+ }
68
+ async collectAgentSnapshot(plan) {
69
+ const operationId = `setup-${this.nextOperationId++}`;
70
+ const operationStartedAt = Date.now();
71
+ await this.refreshRegistry({ refresh: plan.refreshRegistry });
72
+ const probeCache = await this.loadProbeCache();
73
+ const entries = this.catalogEntries();
74
+ const detected = (await Promise.all(entries.map((entry) => detectEntry(entry, this.resolveOptions()))))
75
+ .filter((entry) => entry !== null);
76
+ const detectedById = new Map(detected.map((agent) => [agent.id, agent]));
77
+ const authAgentIds = new Set(plan.auth.target === "ids" ? plan.auth.ids : []);
78
+ const capabilityAgentIds = new Set(plan.capabilities.target === "ids" ? plan.capabilities.ids : []);
79
+ const result = await Promise.all(entries.map(async (entry) => {
80
+ const detectedEntry = detectedById.get(entry.id);
81
+ const shouldProbeAuth = Boolean(detectedEntry) &&
82
+ (plan.auth.target === "detected" || authAgentIds.has(entry.id));
83
+ let auth = detectedEntry ? this.authCache.get(entry.id) : undefined;
84
+ const shouldProbeCapabilities = Boolean(detectedEntry) &&
85
+ (plan.capabilities.target === "detected"
86
+ || capabilityAgentIds.has(entry.id));
87
+ let sessionConfig;
88
+ if (detectedEntry && shouldProbeCapabilities) {
89
+ const startedAt = Date.now();
90
+ let outcome = "settled";
91
+ let errorDetail;
92
+ logSetupOperation({
93
+ operationId,
94
+ trigger: plan.trigger,
95
+ scope: "full",
96
+ agentId: entry.id,
97
+ outcome: "started",
98
+ durationMs: 0,
99
+ });
100
+ try {
101
+ sessionConfig = await this.probeSessionConfig(detectedEntry);
102
+ auth = setupAuthFromProbeStatus(sessionConfig.auth);
103
+ if (auth) {
104
+ this.authCache.set(entry.id, auth);
105
+ }
106
+ else {
107
+ this.authCache.delete(entry.id);
108
+ }
109
+ this.capabilityInspections.set(entry.id, {
110
+ status: setupAuthBlocksCapabilities(auth)
111
+ ? "blocked-auth"
112
+ : "ready",
113
+ inspected_at: new Date().toISOString(),
114
+ });
115
+ }
116
+ catch (error) {
117
+ outcome = "degraded";
118
+ errorDetail = errorMessage(error);
119
+ this.capabilityInspections.set(entry.id, {
120
+ status: "degraded",
121
+ error: errorDetail,
122
+ inspected_at: new Date().toISOString(),
123
+ });
124
+ // Keep the last confirmed state across a transient probe failure.
125
+ }
126
+ finally {
127
+ logSetupOperation({
128
+ operationId,
129
+ trigger: plan.trigger,
130
+ scope: "full",
131
+ agentId: entry.id,
132
+ outcome,
133
+ durationMs: Date.now() - startedAt,
134
+ ...(errorDetail ? { detail: errorDetail } : {}),
135
+ });
136
+ }
137
+ }
138
+ else if (detectedEntry && shouldProbeAuth) {
139
+ const startedAt = Date.now();
140
+ let outcome = "settled";
141
+ logSetupOperation({
142
+ operationId,
143
+ trigger: plan.trigger,
144
+ scope: "auth",
145
+ agentId: entry.id,
146
+ outcome: "started",
147
+ durationMs: 0,
148
+ });
149
+ try {
150
+ auth = await this.probeAuth(detectedEntry);
151
+ if (auth) {
152
+ this.authCache.set(entry.id, auth);
153
+ }
154
+ else {
155
+ this.authCache.delete(entry.id);
156
+ }
157
+ }
158
+ catch {
159
+ outcome = "degraded";
160
+ // Keep the last confirmed state across a transient probe failure.
161
+ }
162
+ finally {
163
+ logSetupOperation({
164
+ operationId,
165
+ trigger: plan.trigger,
166
+ scope: "auth",
167
+ agentId: entry.id,
168
+ outcome,
169
+ durationMs: Date.now() - startedAt,
170
+ });
171
+ }
172
+ }
173
+ const cachedProbe = detectedEntry ? probeCache[entry.id] : undefined;
174
+ if (!auth && cachedProbe?.auth) {
175
+ auth = cachedProbe.auth;
176
+ this.authCache.set(entry.id, auth);
177
+ }
178
+ const usableSessionConfig = sessionConfig && !setupAuthBlocksCapabilities(auth)
179
+ ? sessionConfig
180
+ : undefined;
181
+ if (usableSessionConfig) {
182
+ await this.persistProbe(entry.id, {
183
+ config_options: usableSessionConfig.configOptions,
184
+ available_commands: usableSessionConfig.availableCommands,
185
+ ...(usableSessionConfig.modes
186
+ ? { session_modes: usableSessionConfig.modes }
187
+ : {}),
188
+ ...(auth ? { auth } : {}),
189
+ });
190
+ }
191
+ else if (auth && (shouldProbeAuth || shouldProbeCapabilities)) {
192
+ await this.persistProbe(entry.id, { auth });
193
+ }
194
+ const configOptions = usableSessionConfig?.configOptions ??
195
+ cachedProbe?.config_options ??
196
+ entry.configOptions;
197
+ const availableCommands = usableSessionConfig?.availableCommands ??
198
+ cachedProbe?.available_commands;
199
+ const sessionModes = usableSessionConfig?.modes ??
200
+ cachedProbe?.session_modes;
201
+ const installInfo = await readAcpHarnessInstallState({
202
+ entry,
203
+ binDir: this.deps.acpBinDir,
204
+ installRoot: this.deps.acpInstallRoot,
205
+ fetchImpl: this.deps.fetchImpl,
206
+ npmRegistryUrls: this.deps.npmRegistryUrls,
207
+ });
208
+ return {
209
+ id: entry.id,
210
+ label: entry.label,
211
+ ...(entry.icon ? { icon: entry.icon } : {}),
212
+ command: detectedEntry?.spec.command ?? entry.spec.command,
213
+ installHint: entry.installHint,
214
+ homepage: entry.homepage,
215
+ featured: entry.featured,
216
+ detected: !!detectedEntry,
217
+ available: !!detectedEntry,
218
+ installed: installInfo.installed,
219
+ ...(installInfo.installedVersion ? { installedVersion: installInfo.installedVersion } : {}),
220
+ ...(installInfo.latestVersion ? { latestVersion: installInfo.latestVersion } : {}),
221
+ ...(installInfo.updateAvailable ? { updateAvailable: true } : {}),
222
+ installable: !entry.custom && Boolean(entry.installSource || entry.downloadUrl || entry.install),
223
+ ...(entry.installSource ? { installSource: entry.installSource } : {}),
224
+ ...(entry.custom ? { custom: true } : {}),
225
+ ...(auth ? { auth } : {}),
226
+ ...(configOptions ? { config_options: configOptions } : {}),
227
+ ...(availableCommands ? { available_commands: availableCommands } : {}),
228
+ ...(sessionModes ? { session_modes: sessionModes } : {}),
229
+ ...(detectedEntry && this.capabilityInspections.has(entry.id)
230
+ ? {
231
+ capability_inspection: this.capabilityInspections.get(entry.id),
232
+ }
233
+ : {}),
234
+ };
235
+ }));
236
+ logSetupOperation({
237
+ operationId,
238
+ trigger: plan.trigger,
239
+ scope: "snapshot",
240
+ agentId: "*",
241
+ outcome: "settled",
242
+ durationMs: Date.now() - operationStartedAt,
243
+ });
244
+ return result;
245
+ }
246
+ async installAgent(id) {
247
+ await this.refreshRegistry({ refresh: true });
248
+ const entry = this.requireEntry(id);
249
+ const targetVersion = await this.resolveManagedInstallTargetVersion(entry);
250
+ await this.installEntry(entry, targetVersion);
251
+ return this.collectAgentSnapshot({
252
+ trigger: "install",
253
+ refreshRegistry: false,
254
+ auth: { target: "ids", ids: [id] },
255
+ capabilities: { target: "ids", ids: [id] },
256
+ });
257
+ }
258
+ async upgradeAgent(id) {
259
+ await this.refreshRegistry({ refresh: false });
260
+ const entry = this.requireEntry(id);
261
+ const installInfo = await readAcpHarnessInstallState({
262
+ entry,
263
+ binDir: this.deps.acpBinDir,
264
+ installRoot: this.deps.acpInstallRoot,
265
+ fetchImpl: this.deps.fetchImpl,
266
+ npmRegistryUrls: this.deps.npmRegistryUrls,
267
+ });
268
+ if (!installInfo.installed) {
269
+ throw new Error(`${entry.label} is not installed by ${this.managedByName()}`);
270
+ }
271
+ const targetVersion = await this.resolveManagedInstallTargetVersion(entry, installInfo.latestVersion);
272
+ await this.installEntry(entry, targetVersion);
273
+ return this.collectAgentSnapshot({
274
+ trigger: "update",
275
+ refreshRegistry: false,
276
+ auth: { target: "ids", ids: [id] },
277
+ capabilities: { target: "ids", ids: [id] },
278
+ });
279
+ }
280
+ async resolveManagedInstallTargetVersion(entry, registryLatestVersion) {
281
+ if (usesOpenMaNpmLatestSource(entry) && entry.registryDistribution?.npx) {
282
+ const packageName = npmPackageNameFromSpec(entry.registryDistribution.npx.package);
283
+ const latest = await latestNpmPackageVersion(packageName, {
284
+ fetchImpl: this.deps.fetchImpl,
285
+ npmRegistryUrls: this.deps.npmRegistryUrls,
286
+ });
287
+ if (!latest) {
288
+ throw new Error(`Could not resolve npm latest version for ${packageName}`);
289
+ }
290
+ return latest;
291
+ }
292
+ return registryLatestVersion ?? entry.version;
293
+ }
294
+ async installEntry(entry, targetVersion) {
295
+ if (entry.installSource === "registry") {
296
+ if (!entry.registryId)
297
+ throw new Error(`${entry.label} is missing an ACP registry id`);
298
+ const registryDistribution = targetVersion && entry.registryDistribution?.npx
299
+ ? {
300
+ ...entry.registryDistribution,
301
+ npx: {
302
+ ...entry.registryDistribution.npx,
303
+ package: `${npmPackageNameFromSpec(entry.registryDistribution.npx.package)}@${targetVersion}`,
304
+ },
305
+ }
306
+ : entry.registryDistribution;
307
+ await installAcpRegistryAgent({
308
+ registryId: entry.registryId,
309
+ ...(registryDistribution ? {
310
+ registryAgent: {
311
+ id: entry.registryId,
312
+ name: entry.label,
313
+ ...(targetVersion
314
+ ? { version: targetVersion }
315
+ : entry.version
316
+ ? { version: entry.version }
317
+ : {}),
318
+ distribution: registryDistribution,
319
+ },
320
+ } : {}),
321
+ shimName: basename(entry.spec.command),
322
+ binDir: this.deps.acpBinDir,
323
+ installRoot: this.deps.acpInstallRoot,
324
+ fetchImpl: this.deps.fetchImpl,
325
+ npmCommand: this.deps.npmCommand,
326
+ npmCommandArgs: this.deps.npmCommandArgs,
327
+ npmEnv: this.deps.npmEnv,
328
+ npmRegistryUrls: this.deps.npmRegistryUrls,
329
+ shimArgs: entry.spec.args,
330
+ shimEnv: entry.spec.env,
331
+ env: this.spawnEnv(),
332
+ });
333
+ }
334
+ else if (entry.installSource === "adapter" && entry.downloadUrl) {
335
+ await installManagedAdapter({
336
+ id: entry.id,
337
+ label: entry.label,
338
+ command: entry.spec.command,
339
+ args: entry.spec.args,
340
+ downloadUrl: entry.downloadUrl,
341
+ binDir: this.deps.acpBinDir,
342
+ fetchImpl: this.deps.fetchImpl,
343
+ });
344
+ }
345
+ else {
346
+ throw new Error(`${entry.label} is not installable from ${this.managedByName()}`);
347
+ }
348
+ }
349
+ async uninstallAgent(id) {
350
+ await this.refreshRegistry({ refresh: true });
351
+ const entry = this.requireEntry(id);
352
+ if (entry.installSource === "registry") {
353
+ if (!entry.registryId)
354
+ throw new Error(`${entry.label} is missing an ACP registry id`);
355
+ await uninstallAcpRegistryAgent({
356
+ registryId: entry.registryId,
357
+ shimName: basename(entry.spec.command),
358
+ binDir: this.deps.acpBinDir,
359
+ installRoot: this.deps.acpInstallRoot,
360
+ });
361
+ }
362
+ else if (entry.installSource === "adapter") {
363
+ await uninstallManagedAdapter({
364
+ command: entry.spec.command,
365
+ binDir: this.deps.acpBinDir,
366
+ });
367
+ }
368
+ else {
369
+ throw new Error(`${entry.label} is not managed by ${this.managedByName()}`);
370
+ }
371
+ this.authCache.delete(id);
372
+ return this.collectAgentSnapshot({
373
+ ...NO_LIVE_PROBE_PLAN,
374
+ trigger: "uninstall",
375
+ refreshRegistry: true,
376
+ });
377
+ }
378
+ async authenticateAgent(id, options = {}) {
379
+ await this.refreshRegistry({ refresh: false });
380
+ const entry = await this.detectCatalogEntry(id);
381
+ if (!entry)
382
+ throw new Error(`ACP agent is not available: ${id}`);
383
+ const result = await authenticateAgent({
384
+ agent: entry.spec,
385
+ env: this.spawnEnv(),
386
+ ...(this.deps.probeCwd ? { cwd: this.deps.probeCwd } : {}),
387
+ timeoutMs: 120_000,
388
+ agentAuthLaunchGraceMs: 2_000,
389
+ backgroundAuthTimeoutMs: 10 * 60_000,
390
+ methodId: options.methodId,
391
+ ...(options.secret ? { secret: options.secret } : {}),
392
+ ...(options.values ? { values: options.values } : {}),
393
+ ...(options.gateway ? { gateway: options.gateway } : {}),
394
+ launchInteractiveAuth: this.deps.launchInteractiveAuth,
395
+ });
396
+ if (result.status === "completed") {
397
+ const existing = this.authCache.get(id);
398
+ const auth = {
399
+ status: "configured",
400
+ message: "Authentication completed",
401
+ ...(options.methodId
402
+ ? { methodId: options.methodId }
403
+ : existing?.methodId
404
+ ? { methodId: existing.methodId }
405
+ : {}),
406
+ ...(existing?.methodName ? { methodName: existing.methodName } : {}),
407
+ ...(existing?.methods ? { methods: existing.methods } : {}),
408
+ };
409
+ this.authCache.set(id, auth);
410
+ await this.persistProbe(id, { auth });
411
+ }
412
+ // Authentication is an explicit lifecycle of its own. Do not follow it
413
+ // with another disposable ACP probe; the next real session is the source
414
+ // of truth if a browser/terminal flow is still finishing.
415
+ return this.listAgents();
416
+ }
417
+ async observeAuth(id, observation) {
418
+ const auth = mergeObservedAuth(this.authCache.get(id), observation);
419
+ this.authCache.set(id, auth);
420
+ await this.persistProbe(id, { auth });
421
+ return auth;
422
+ }
423
+ async observeSessionConfig(id, snapshot) {
424
+ await this.persistProbe(id, snapshot);
425
+ }
426
+ async refreshRegistry(options) {
427
+ if (this.deps.refreshRegistry) {
428
+ await this.deps.refreshRegistry({ refresh: options.refresh });
429
+ return;
430
+ }
431
+ await loadRegistry({
432
+ cachePath: this.deps.registryCachePath,
433
+ forceRefresh: options.refresh === true,
434
+ cacheOnly: options.refresh !== true,
435
+ }).catch(() => undefined);
436
+ }
437
+ resolveOptions() {
438
+ return {
439
+ env: this.spawnEnv(),
440
+ managedBinDirs: [this.deps.acpBinDir],
441
+ };
442
+ }
443
+ spawnEnv() {
444
+ const path = [this.deps.acpBinDir, process.env.PATH].filter(Boolean).join(delimiter);
445
+ return {
446
+ ...process.env,
447
+ ...this.deps.env,
448
+ // A setup probe is a fresh harness process. Do not let a parent Claude
449
+ // session make the child believe it is already running inside one.
450
+ CLAUDECODE: undefined,
451
+ CLAUDE_CODE_ENTRYPOINT: undefined,
452
+ CLAUDE_CODE_SSE_PORT: undefined,
453
+ OPENMA_ACP_BIN_DIR: this.deps.acpBinDir,
454
+ PATH: path,
455
+ };
456
+ }
457
+ requireEntry(id) {
458
+ const entry = this.catalogEntries().find((candidate) => candidate.id === id);
459
+ if (!entry)
460
+ throw new Error(`Unknown ACP agent: ${id}`);
461
+ return entry;
462
+ }
463
+ catalogEntries() {
464
+ return catalogEntriesWithOverrides(getKnownAgents(), this.deps.agentOverrides?.() ?? []);
465
+ }
466
+ async detectCatalogEntry(id) {
467
+ const entry = this.catalogEntries().find((candidate) => candidate.id === id);
468
+ if (!entry)
469
+ return null;
470
+ return await detectEntry(entry, this.resolveOptions());
471
+ }
472
+ async probeAuth(entry) {
473
+ const status = await probeAgentAuthStatus({
474
+ agent: entry.spec,
475
+ env: this.spawnEnv(),
476
+ ...(this.deps.probeCwd ? { cwd: this.deps.probeCwd } : {}),
477
+ timeoutMs: this.deps.authInspectionTimeoutMs ?? 15_000,
478
+ });
479
+ return setupAuthFromProbeStatus(status);
480
+ }
481
+ async probeSessionConfig(entry) {
482
+ return probeAgentSessionConfig({
483
+ agent: entry.spec,
484
+ env: this.spawnEnv(),
485
+ ...(this.deps.probeCwd ? { cwd: this.deps.probeCwd } : {}),
486
+ timeoutMs: this.deps.capabilityInspectionTimeoutMs ?? 90_000,
487
+ });
488
+ }
489
+ probeCachePath() {
490
+ return this.deps.probeCachePath ??
491
+ join(dirname(this.deps.registryCachePath), "agent-probe-cache.json");
492
+ }
493
+ loadProbeCache() {
494
+ if (this.probeCachePromise)
495
+ return this.probeCachePromise;
496
+ this.probeCachePromise = readFile(this.probeCachePath(), "utf8")
497
+ .then((raw) => parseProbeCache(raw))
498
+ .catch(() => ({}));
499
+ return this.probeCachePromise;
500
+ }
501
+ async persistProbe(id, patch) {
502
+ const cache = await this.loadProbeCache();
503
+ const prev = cache[id];
504
+ cache[id] = {
505
+ config_options: patch.config_options ?? prev?.config_options ?? [],
506
+ available_commands: patch.available_commands ?? prev?.available_commands ?? [],
507
+ ...(patch.session_modes !== undefined
508
+ ? { session_modes: patch.session_modes }
509
+ : prev?.session_modes
510
+ ? { session_modes: prev.session_modes }
511
+ : {}),
512
+ ...(patch.auth ? { auth: patch.auth } : prev?.auth ? { auth: prev.auth } : {}),
513
+ updated_at: new Date().toISOString(),
514
+ };
515
+ const path = this.probeCachePath();
516
+ const tempPath = `${path}.tmp-${process.pid}`;
517
+ const serialized = JSON.stringify({ version: 1, agents: cache }, null, 2);
518
+ const write = async () => {
519
+ await mkdir(dirname(path), { recursive: true });
520
+ await writeFile(tempPath, serialized, "utf8");
521
+ await rename(tempPath, path);
522
+ };
523
+ this.probeCacheWrite = this.probeCacheWrite.then(write, write);
524
+ await this.probeCacheWrite;
525
+ }
526
+ managedByName() {
527
+ return this.deps.managedByName?.trim() || "this host";
528
+ }
529
+ }
530
+ function parseProbeCache(raw) {
531
+ const parsed = JSON.parse(raw);
532
+ if (parsed.version !== 1 || !parsed.agents || typeof parsed.agents !== "object") {
533
+ return {};
534
+ }
535
+ return Object.fromEntries(Object.entries(parsed.agents).flatMap(([id, value]) => Array.isArray(value.config_options) && Array.isArray(value.available_commands)
536
+ ? [[id, {
537
+ config_options: value.config_options,
538
+ available_commands: value.available_commands,
539
+ ...(value.session_modes ? { session_modes: value.session_modes } : {}),
540
+ ...(value.auth ? { auth: value.auth } : {}),
541
+ updated_at: typeof value.updated_at === "string" ? value.updated_at : "",
542
+ }]]
543
+ : value.auth
544
+ ? [[id, {
545
+ config_options: Array.isArray(value.config_options) ? value.config_options : [],
546
+ available_commands: Array.isArray(value.available_commands)
547
+ ? value.available_commands
548
+ : [],
549
+ ...(value.session_modes ? { session_modes: value.session_modes } : {}),
550
+ auth: value.auth,
551
+ updated_at: typeof value.updated_at === "string" ? value.updated_at : "",
552
+ }]]
553
+ : []));
554
+ }
555
+ function catalogEntriesWithOverrides(entries, overrides) {
556
+ const overrideById = new Map(overrides.map((override) => [override.id, override]));
557
+ const knownIds = new Set(entries.map((entry) => entry.id));
558
+ const merged = entries.map((entry) => applyAgentOverride(entry, overrideById.get(entry.id)));
559
+ for (const override of overrides) {
560
+ if (knownIds.has(override.id))
561
+ continue;
562
+ const command = override.command?.trim();
563
+ if (!command)
564
+ continue;
565
+ const env = overrideEnv(override);
566
+ merged.push({
567
+ id: override.id,
568
+ label: override.label?.trim() || override.id,
569
+ spec: {
570
+ command,
571
+ ...(override.args ? { args: [...override.args] } : {}),
572
+ ...(env ? { env } : {}),
573
+ },
574
+ custom: true,
575
+ });
576
+ }
577
+ return merged;
578
+ }
579
+ function applyAgentOverride(entry, override) {
580
+ if (!override)
581
+ return entry;
582
+ const env = {
583
+ ...(entry.spec.env ?? {}),
584
+ ...(overrideEnv(override) ?? {}),
585
+ };
586
+ return {
587
+ ...entry,
588
+ ...(override.label?.trim() ? { label: override.label.trim() } : {}),
589
+ spec: {
590
+ ...entry.spec,
591
+ ...(override.command?.trim() ? { command: override.command.trim() } : {}),
592
+ ...(override.args ? { args: [...override.args] } : {}),
593
+ ...(Object.keys(env).length > 0 ? { env } : {}),
594
+ },
595
+ };
596
+ }
597
+ function overrideEnv(override) {
598
+ if (!override.env)
599
+ return undefined;
600
+ const entries = Array.isArray(override.env)
601
+ ? override.env
602
+ .filter((item) => item.name.length > 0)
603
+ .map((item) => [item.name, item.value])
604
+ : Object.entries(override.env)
605
+ .filter((entry) => entry[0].length > 0 && typeof entry[1] === "string");
606
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
607
+ }
608
+ function mergeObservedAuth(existing, observation) {
609
+ const methodId = observation.methodId ?? existing?.methodId;
610
+ const prefix = observation.status === "configured"
611
+ ? methodId ? `ACP auth is configured (${methodId}).` : "ACP auth is configured."
612
+ : observation.status === "needs-auth"
613
+ ? methodId ? `Authentication required (${methodId}).` : "Authentication required."
614
+ : "Could not verify auth.";
615
+ return {
616
+ status: observation.status,
617
+ message: observation.message ?? prefix,
618
+ ...(methodId ? { methodId } : {}),
619
+ ...(existing?.methodName ? { methodName: existing.methodName } : {}),
620
+ ...(existing?.methods ? { methods: existing.methods } : {}),
621
+ };
622
+ }
623
+ function setupAuthFromProbeStatus(status) {
624
+ if (status.status === "none")
625
+ return undefined;
626
+ const method = status.methodName ?? status.methodId;
627
+ const prefix = status.status === "configured"
628
+ ? method ? `ACP auth is configured (${method}).` : "ACP auth is configured."
629
+ : status.status === "needs-auth"
630
+ ? method ? `Authentication required (${method}).` : "Authentication required."
631
+ : "Could not verify auth.";
632
+ return {
633
+ status: status.status,
634
+ message: status.message ? `${prefix} ${status.message}` : prefix,
635
+ ...(status.methodId ? { methodId: status.methodId } : {}),
636
+ ...(status.methodName ? { methodName: status.methodName } : {}),
637
+ ...(status.methods ? { methods: status.methods.map((methodInfo) => ({
638
+ id: methodInfo.id,
639
+ ...(methodInfo.name ? { name: methodInfo.name } : {}),
640
+ ...(methodInfo.description ? { description: methodInfo.description } : {}),
641
+ ...(methodInfo.type ? { type: methodInfo.type } : {}),
642
+ ...(methodInfo.form ? { form: methodInfo.form } : {}),
643
+ ...(methodInfo.vars ? { vars: methodInfo.vars } : {}),
644
+ ...(methodInfo.link ? { link: methodInfo.link } : {}),
645
+ })) } : {}),
646
+ };
647
+ }
648
+ function setupAuthBlocksCapabilities(auth) {
649
+ return auth?.status === "needs-auth" || auth?.status === "unknown";
650
+ }
651
+ function logSetupOperation(fields) {
652
+ if (process.env.NODE_ENV === "test")
653
+ return;
654
+ const detail = fields.detail
655
+ ? ` error=${JSON.stringify(fields.detail.replace(/\s+/g, " ").slice(0, 500))}`
656
+ : "";
657
+ process.stderr.write(`[agent-lifecycle] op=${fields.operationId} trigger=${fields.trigger} scope=${fields.scope} agent=${fields.agentId} outcome=${fields.outcome} total_ms=${fields.durationMs}${detail}\n`);
658
+ }
659
+ function errorMessage(error) {
660
+ return error instanceof Error ? error.message : String(error);
661
+ }
662
+ export function launchTerminalAuth(options, launchOptions = {}) {
663
+ const shellCommand = terminalAuthShellCommand(options, launchOptions.returnInstruction);
664
+ if (process.platform === "darwin") {
665
+ return spawnDetached("osascript", [
666
+ "-e", `tell application "Terminal"`,
667
+ "-e", "activate",
668
+ "-e", `do script ${JSON.stringify(shellCommand)}`,
669
+ "-e", "end tell",
670
+ ], options.env);
671
+ }
672
+ const terminal = process.platform === "win32" ? null : (process.env.TERMINAL || "x-terminal-emulator");
673
+ if (!terminal) {
674
+ throw new Error(`Interactive auth launch is not supported on ${process.platform}. Run ${[options.command, ...options.args].join(" ")} manually.`);
675
+ }
676
+ return spawnDetached(terminal, ["-e", "sh", "-lc", shellCommand], options.env);
677
+ }
678
+ function spawnDetached(command, args, env) {
679
+ return new Promise((resolve, reject) => {
680
+ const child = spawn(command, args, {
681
+ env: {
682
+ ...process.env,
683
+ ...Object.fromEntries(Object.entries(env ?? {}).filter((entry) => typeof entry[1] === "string")),
684
+ },
685
+ detached: true,
686
+ stdio: "ignore",
687
+ });
688
+ child.once("error", reject);
689
+ child.once("spawn", () => {
690
+ child.unref();
691
+ resolve();
692
+ });
693
+ });
694
+ }
695
+ function terminalAuthShellCommand(options, returnInstruction) {
696
+ const parts = [];
697
+ if (options.cwd) {
698
+ parts.push("cd", shellQuote(options.cwd), "&&");
699
+ }
700
+ const envEntries = Object.entries(options.env ?? {})
701
+ .filter((entry) => typeof entry[1] === "string" && entry[0].length > 0);
702
+ if (envEntries.length > 0) {
703
+ parts.push("env");
704
+ for (const [key, value] of envEntries)
705
+ parts.push(`${key}=${shellQuote(value)}`);
706
+ }
707
+ parts.push(shellQuote(options.command), ...options.args.map(shellQuote));
708
+ if (returnInstruction?.trim()) {
709
+ parts.push(";");
710
+ parts.push("printf", shellQuote(`\\n${returnInstruction.trim()}\\n`));
711
+ }
712
+ return parts.join(" ");
713
+ }
714
+ function shellQuote(value) {
715
+ return `'${value.replace(/'/g, "'\\''")}'`;
716
+ }
717
+ //# sourceMappingURL=agent-setup.js.map