@cuna_labs/cli 0.1.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 (624) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +9 -0
  3. package/README.md +169 -0
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/capability-evidence.d.ts +19 -0
  6. package/dist/api/capability-evidence.d.ts.map +1 -0
  7. package/dist/api/capability-evidence.js +38 -0
  8. package/dist/api/capability-evidence.js.map +1 -0
  9. package/dist/api/client.d.ts +167 -0
  10. package/dist/api/client.d.ts.map +1 -0
  11. package/dist/api/client.js +937 -0
  12. package/dist/api/client.js.map +1 -0
  13. package/dist/api/contracts.d.ts +345 -0
  14. package/dist/api/contracts.d.ts.map +1 -0
  15. package/dist/api/contracts.js +976 -0
  16. package/dist/api/contracts.js.map +1 -0
  17. package/dist/api/execution-workspaces.d.ts +17 -0
  18. package/dist/api/execution-workspaces.d.ts.map +1 -0
  19. package/dist/api/execution-workspaces.js +46 -0
  20. package/dist/api/execution-workspaces.js.map +1 -0
  21. package/dist/api/http.d.ts +76 -0
  22. package/dist/api/http.d.ts.map +1 -0
  23. package/dist/api/http.js +838 -0
  24. package/dist/api/http.js.map +1 -0
  25. package/dist/api/managed-executions.d.ts +37 -0
  26. package/dist/api/managed-executions.d.ts.map +1 -0
  27. package/dist/api/managed-executions.js +80 -0
  28. package/dist/api/managed-executions.js.map +1 -0
  29. package/dist/api/observer-v2-schema.d.ts +206 -0
  30. package/dist/api/observer-v2-schema.d.ts.map +1 -0
  31. package/dist/api/observer-v2-schema.js +264 -0
  32. package/dist/api/observer-v2-schema.js.map +1 -0
  33. package/dist/api/observer-v2.d.ts +33 -0
  34. package/dist/api/observer-v2.d.ts.map +1 -0
  35. package/dist/api/observer-v2.js +60 -0
  36. package/dist/api/observer-v2.js.map +1 -0
  37. package/dist/api/owner-observe-grants-v2-schema.d.ts +678 -0
  38. package/dist/api/owner-observe-grants-v2-schema.d.ts.map +1 -0
  39. package/dist/api/owner-observe-grants-v2-schema.js +887 -0
  40. package/dist/api/owner-observe-grants-v2-schema.js.map +1 -0
  41. package/dist/api/owner-observe-grants-v2.d.ts +268 -0
  42. package/dist/api/owner-observe-grants-v2.d.ts.map +1 -0
  43. package/dist/api/owner-observe-grants-v2.js +604 -0
  44. package/dist/api/owner-observe-grants-v2.js.map +1 -0
  45. package/dist/api/provider-v2-schema.d.ts +293 -0
  46. package/dist/api/provider-v2-schema.d.ts.map +1 -0
  47. package/dist/api/provider-v2-schema.js +381 -0
  48. package/dist/api/provider-v2-schema.js.map +1 -0
  49. package/dist/api/provider-v2.d.ts +55 -0
  50. package/dist/api/provider-v2.d.ts.map +1 -0
  51. package/dist/api/provider-v2.js +54 -0
  52. package/dist/api/provider-v2.js.map +1 -0
  53. package/dist/api/remote-workspace.d.ts +29 -0
  54. package/dist/api/remote-workspace.d.ts.map +1 -0
  55. package/dist/api/remote-workspace.js +62 -0
  56. package/dist/api/remote-workspace.js.map +1 -0
  57. package/dist/api/supervisor-live-update.d.ts +248 -0
  58. package/dist/api/supervisor-live-update.d.ts.map +1 -0
  59. package/dist/api/supervisor-live-update.js +434 -0
  60. package/dist/api/supervisor-live-update.js.map +1 -0
  61. package/dist/api/terminal-reason.d.ts +5 -0
  62. package/dist/api/terminal-reason.d.ts.map +1 -0
  63. package/dist/api/terminal-reason.js +12 -0
  64. package/dist/api/terminal-reason.js.map +1 -0
  65. package/dist/auth/browser-handoff.d.ts +59 -0
  66. package/dist/auth/browser-handoff.d.ts.map +1 -0
  67. package/dist/auth/browser-handoff.js +33 -0
  68. package/dist/auth/browser-handoff.js.map +1 -0
  69. package/dist/auth/browser.d.ts +11 -0
  70. package/dist/auth/browser.d.ts.map +1 -0
  71. package/dist/auth/browser.js +47 -0
  72. package/dist/auth/browser.js.map +1 -0
  73. package/dist/auth/human-client.d.ts +39 -0
  74. package/dist/auth/human-client.d.ts.map +1 -0
  75. package/dist/auth/human-client.js +66 -0
  76. package/dist/auth/human-client.js.map +1 -0
  77. package/dist/auth/human-contracts.d.ts +52 -0
  78. package/dist/auth/human-contracts.d.ts.map +1 -0
  79. package/dist/auth/human-contracts.js +229 -0
  80. package/dist/auth/human-contracts.js.map +1 -0
  81. package/dist/auth/human-session.d.ts +48 -0
  82. package/dist/auth/human-session.d.ts.map +1 -0
  83. package/dist/auth/human-session.js +902 -0
  84. package/dist/auth/human-session.js.map +1 -0
  85. package/dist/auth/onboarding-state.d.ts +31 -0
  86. package/dist/auth/onboarding-state.d.ts.map +1 -0
  87. package/dist/auth/onboarding-state.js +52 -0
  88. package/dist/auth/onboarding-state.js.map +1 -0
  89. package/dist/auth/pkce.d.ts +15 -0
  90. package/dist/auth/pkce.d.ts.map +1 -0
  91. package/dist/auth/pkce.js +19 -0
  92. package/dist/auth/pkce.js.map +1 -0
  93. package/dist/bin/cuna.d.ts +3 -0
  94. package/dist/bin/cuna.d.ts.map +1 -0
  95. package/dist/bin/cuna.js +4 -0
  96. package/dist/bin/cuna.js.map +1 -0
  97. package/dist/build-identity.d.ts +20 -0
  98. package/dist/build-identity.d.ts.map +1 -0
  99. package/dist/build-identity.js +77 -0
  100. package/dist/build-identity.js.map +1 -0
  101. package/dist/cli/command-help.d.ts +9 -0
  102. package/dist/cli/command-help.d.ts.map +1 -0
  103. package/dist/cli/command-help.js +324 -0
  104. package/dist/cli/command-help.js.map +1 -0
  105. package/dist/cli/help.d.ts +40 -0
  106. package/dist/cli/help.d.ts.map +1 -0
  107. package/dist/cli/help.js +256 -0
  108. package/dist/cli/help.js.map +1 -0
  109. package/dist/cli/output.d.ts +28 -0
  110. package/dist/cli/output.d.ts.map +1 -0
  111. package/dist/cli/output.js +95 -0
  112. package/dist/cli/output.js.map +1 -0
  113. package/dist/cli/parser.d.ts +65 -0
  114. package/dist/cli/parser.d.ts.map +1 -0
  115. package/dist/cli/parser.js +294 -0
  116. package/dist/cli/parser.js.map +1 -0
  117. package/dist/cli/process-entrypoint.d.ts +18 -0
  118. package/dist/cli/process-entrypoint.d.ts.map +1 -0
  119. package/dist/cli/process-entrypoint.js +26 -0
  120. package/dist/cli/process-entrypoint.js.map +1 -0
  121. package/dist/cli/run.d.ts +114 -0
  122. package/dist/cli/run.d.ts.map +1 -0
  123. package/dist/cli/run.js +1969 -0
  124. package/dist/cli/run.js.map +1 -0
  125. package/dist/commands/commands.d.ts +74 -0
  126. package/dist/commands/commands.d.ts.map +1 -0
  127. package/dist/commands/commands.js +2814 -0
  128. package/dist/commands/commands.js.map +1 -0
  129. package/dist/config/config.d.ts +86 -0
  130. package/dist/config/config.d.ts.map +1 -0
  131. package/dist/config/config.js +323 -0
  132. package/dist/config/config.js.map +1 -0
  133. package/dist/config/infra-contract-witness.d.ts +29 -0
  134. package/dist/config/infra-contract-witness.d.ts.map +1 -0
  135. package/dist/config/infra-contract-witness.js +30 -0
  136. package/dist/config/infra-contract-witness.js.map +1 -0
  137. package/dist/core/browser-url.d.ts +2 -0
  138. package/dist/core/browser-url.d.ts.map +1 -0
  139. package/dist/core/browser-url.js +20 -0
  140. package/dist/core/browser-url.js.map +1 -0
  141. package/dist/core/deployed-wire-compatibility.d.ts +15 -0
  142. package/dist/core/deployed-wire-compatibility.d.ts.map +1 -0
  143. package/dist/core/deployed-wire-compatibility.js +15 -0
  144. package/dist/core/deployed-wire-compatibility.js.map +1 -0
  145. package/dist/core/errors.d.ts +59 -0
  146. package/dist/core/errors.d.ts.map +1 -0
  147. package/dist/core/errors.js +82 -0
  148. package/dist/core/errors.js.map +1 -0
  149. package/dist/core/exit-codes.d.ts +68 -0
  150. package/dist/core/exit-codes.d.ts.map +1 -0
  151. package/dist/core/exit-codes.js +84 -0
  152. package/dist/core/exit-codes.js.map +1 -0
  153. package/dist/core/instant.d.ts +60 -0
  154. package/dist/core/instant.d.ts.map +1 -0
  155. package/dist/core/instant.js +90 -0
  156. package/dist/core/instant.js.map +1 -0
  157. package/dist/core/namespace.d.ts +171 -0
  158. package/dist/core/namespace.d.ts.map +1 -0
  159. package/dist/core/namespace.js +227 -0
  160. package/dist/core/namespace.js.map +1 -0
  161. package/dist/core/observation-budget.d.ts +185 -0
  162. package/dist/core/observation-budget.d.ts.map +1 -0
  163. package/dist/core/observation-budget.js +209 -0
  164. package/dist/core/observation-budget.js.map +1 -0
  165. package/dist/core/product-web.d.ts +81 -0
  166. package/dist/core/product-web.d.ts.map +1 -0
  167. package/dist/core/product-web.js +87 -0
  168. package/dist/core/product-web.js.map +1 -0
  169. package/dist/core/validation.d.ts +90 -0
  170. package/dist/core/validation.d.ts.map +1 -0
  171. package/dist/core/validation.js +199 -0
  172. package/dist/core/validation.js.map +1 -0
  173. package/dist/credentials/contracts.d.ts +82 -0
  174. package/dist/credentials/contracts.d.ts.map +1 -0
  175. package/dist/credentials/contracts.js +2 -0
  176. package/dist/credentials/contracts.js.map +1 -0
  177. package/dist/credentials/errors.d.ts +19 -0
  178. package/dist/credentials/errors.d.ts.map +1 -0
  179. package/dist/credentials/errors.js +16 -0
  180. package/dist/credentials/errors.js.map +1 -0
  181. package/dist/credentials/index.d.ts +6 -0
  182. package/dist/credentials/index.d.ts.map +1 -0
  183. package/dist/credentials/index.js +6 -0
  184. package/dist/credentials/index.js.map +1 -0
  185. package/dist/credentials/local-session.d.ts +101 -0
  186. package/dist/credentials/local-session.d.ts.map +1 -0
  187. package/dist/credentials/local-session.js +839 -0
  188. package/dist/credentials/local-session.js.map +1 -0
  189. package/dist/credentials/secret-material.d.ts +17 -0
  190. package/dist/credentials/secret-material.d.ts.map +1 -0
  191. package/dist/credentials/secret-material.js +49 -0
  192. package/dist/credentials/secret-material.js.map +1 -0
  193. package/dist/credentials/vault.d.ts +41 -0
  194. package/dist/credentials/vault.d.ts.map +1 -0
  195. package/dist/credentials/vault.js +719 -0
  196. package/dist/credentials/vault.js.map +1 -0
  197. package/dist/daemon/endpoint.d.ts +29 -0
  198. package/dist/daemon/endpoint.d.ts.map +1 -0
  199. package/dist/daemon/endpoint.js +66 -0
  200. package/dist/daemon/endpoint.js.map +1 -0
  201. package/dist/daemon/journal.d.ts +62 -0
  202. package/dist/daemon/journal.d.ts.map +1 -0
  203. package/dist/daemon/journal.js +299 -0
  204. package/dist/daemon/journal.js.map +1 -0
  205. package/dist/daemon/lease.d.ts +25 -0
  206. package/dist/daemon/lease.d.ts.map +1 -0
  207. package/dist/daemon/lease.js +94 -0
  208. package/dist/daemon/lease.js.map +1 -0
  209. package/dist/daemon/lifecycle.d.ts +14 -0
  210. package/dist/daemon/lifecycle.d.ts.map +1 -0
  211. package/dist/daemon/lifecycle.js +29 -0
  212. package/dist/daemon/lifecycle.js.map +1 -0
  213. package/dist/daemon/protocol.d.ts +65 -0
  214. package/dist/daemon/protocol.d.ts.map +1 -0
  215. package/dist/daemon/protocol.js +194 -0
  216. package/dist/daemon/protocol.js.map +1 -0
  217. package/dist/daemon/supervisor.d.ts +29 -0
  218. package/dist/daemon/supervisor.d.ts.map +1 -0
  219. package/dist/daemon/supervisor.js +87 -0
  220. package/dist/daemon/supervisor.js.map +1 -0
  221. package/dist/daemon/views.d.ts +31 -0
  222. package/dist/daemon/views.d.ts.map +1 -0
  223. package/dist/daemon/views.js +86 -0
  224. package/dist/daemon/views.js.map +1 -0
  225. package/dist/index.d.ts +38 -0
  226. package/dist/index.d.ts.map +1 -0
  227. package/dist/index.js +38 -0
  228. package/dist/index.js.map +1 -0
  229. package/dist/journey/api-effects.d.ts +59 -0
  230. package/dist/journey/api-effects.d.ts.map +1 -0
  231. package/dist/journey/api-effects.js +386 -0
  232. package/dist/journey/api-effects.js.map +1 -0
  233. package/dist/journey/derived-identity.d.ts +91 -0
  234. package/dist/journey/derived-identity.d.ts.map +1 -0
  235. package/dist/journey/derived-identity.js +123 -0
  236. package/dist/journey/derived-identity.js.map +1 -0
  237. package/dist/journey/index.d.ts +6 -0
  238. package/dist/journey/index.d.ts.map +1 -0
  239. package/dist/journey/index.js +6 -0
  240. package/dist/journey/index.js.map +1 -0
  241. package/dist/journey/intent.d.ts +36 -0
  242. package/dist/journey/intent.d.ts.map +1 -0
  243. package/dist/journey/intent.js +191 -0
  244. package/dist/journey/intent.js.map +1 -0
  245. package/dist/journey/orchestrator.d.ts +140 -0
  246. package/dist/journey/orchestrator.d.ts.map +1 -0
  247. package/dist/journey/orchestrator.js +415 -0
  248. package/dist/journey/orchestrator.js.map +1 -0
  249. package/dist/journey/provider-launch-intent.d.ts +12 -0
  250. package/dist/journey/provider-launch-intent.d.ts.map +1 -0
  251. package/dist/journey/provider-launch-intent.js +40 -0
  252. package/dist/journey/provider-launch-intent.js.map +1 -0
  253. package/dist/journey/remote-workspace.d.ts +34 -0
  254. package/dist/journey/remote-workspace.d.ts.map +1 -0
  255. package/dist/journey/remote-workspace.js +91 -0
  256. package/dist/journey/remote-workspace.js.map +1 -0
  257. package/dist/journey/root-entry.d.ts +56 -0
  258. package/dist/journey/root-entry.d.ts.map +1 -0
  259. package/dist/journey/root-entry.js +19 -0
  260. package/dist/journey/root-entry.js.map +1 -0
  261. package/dist/journey/selection.d.ts +165 -0
  262. package/dist/journey/selection.d.ts.map +1 -0
  263. package/dist/journey/selection.js +565 -0
  264. package/dist/journey/selection.js.map +1 -0
  265. package/dist/journey/session-failure.d.ts +4 -0
  266. package/dist/journey/session-failure.d.ts.map +1 -0
  267. package/dist/journey/session-failure.js +28 -0
  268. package/dist/journey/session-failure.js.map +1 -0
  269. package/dist/journey/workspace-effects.d.ts +30 -0
  270. package/dist/journey/workspace-effects.d.ts.map +1 -0
  271. package/dist/journey/workspace-effects.js +348 -0
  272. package/dist/journey/workspace-effects.js.map +1 -0
  273. package/dist/local-actions/broker.d.ts +32 -0
  274. package/dist/local-actions/broker.d.ts.map +1 -0
  275. package/dist/local-actions/broker.js +400 -0
  276. package/dist/local-actions/broker.js.map +1 -0
  277. package/dist/local-actions/browser-action.d.ts +78 -0
  278. package/dist/local-actions/browser-action.d.ts.map +1 -0
  279. package/dist/local-actions/browser-action.js +307 -0
  280. package/dist/local-actions/browser-action.js.map +1 -0
  281. package/dist/local-actions/callback-relay.d.ts +45 -0
  282. package/dist/local-actions/callback-relay.d.ts.map +1 -0
  283. package/dist/local-actions/callback-relay.js +265 -0
  284. package/dist/local-actions/callback-relay.js.map +1 -0
  285. package/dist/local-actions/clipboard.d.ts +3 -0
  286. package/dist/local-actions/clipboard.d.ts.map +1 -0
  287. package/dist/local-actions/clipboard.js +18 -0
  288. package/dist/local-actions/clipboard.js.map +1 -0
  289. package/dist/local-actions/contracts.d.ts +63 -0
  290. package/dist/local-actions/contracts.d.ts.map +1 -0
  291. package/dist/local-actions/contracts.js +18 -0
  292. package/dist/local-actions/contracts.js.map +1 -0
  293. package/dist/local-actions/desktop-presentation.d.ts +141 -0
  294. package/dist/local-actions/desktop-presentation.d.ts.map +1 -0
  295. package/dist/local-actions/desktop-presentation.js +253 -0
  296. package/dist/local-actions/desktop-presentation.js.map +1 -0
  297. package/dist/local-actions/device-selection.d.ts +43 -0
  298. package/dist/local-actions/device-selection.d.ts.map +1 -0
  299. package/dist/local-actions/device-selection.js +154 -0
  300. package/dist/local-actions/device-selection.js.map +1 -0
  301. package/dist/local-actions/executor.d.ts +49 -0
  302. package/dist/local-actions/executor.d.ts.map +1 -0
  303. package/dist/local-actions/executor.js +329 -0
  304. package/dist/local-actions/executor.js.map +1 -0
  305. package/dist/local-actions/file-transfers.d.ts +141 -0
  306. package/dist/local-actions/file-transfers.d.ts.map +1 -0
  307. package/dist/local-actions/file-transfers.js +446 -0
  308. package/dist/local-actions/file-transfers.js.map +1 -0
  309. package/dist/local-actions/foreground-notifications.d.ts +45 -0
  310. package/dist/local-actions/foreground-notifications.d.ts.map +1 -0
  311. package/dist/local-actions/foreground-notifications.js +163 -0
  312. package/dist/local-actions/foreground-notifications.js.map +1 -0
  313. package/dist/local-actions/git-signing.d.ts +39 -0
  314. package/dist/local-actions/git-signing.d.ts.map +1 -0
  315. package/dist/local-actions/git-signing.js +135 -0
  316. package/dist/local-actions/git-signing.js.map +1 -0
  317. package/dist/local-actions/index.d.ts +19 -0
  318. package/dist/local-actions/index.d.ts.map +1 -0
  319. package/dist/local-actions/index.js +19 -0
  320. package/dist/local-actions/index.js.map +1 -0
  321. package/dist/local-actions/local-service-actions.d.ts +87 -0
  322. package/dist/local-actions/local-service-actions.d.ts.map +1 -0
  323. package/dist/local-actions/local-service-actions.js +347 -0
  324. package/dist/local-actions/local-service-actions.js.map +1 -0
  325. package/dist/local-actions/loopback.d.ts +5 -0
  326. package/dist/local-actions/loopback.d.ts.map +1 -0
  327. package/dist/local-actions/loopback.js +15 -0
  328. package/dist/local-actions/loopback.js.map +1 -0
  329. package/dist/local-actions/policy-store.d.ts +7 -0
  330. package/dist/local-actions/policy-store.d.ts.map +1 -0
  331. package/dist/local-actions/policy-store.js +70 -0
  332. package/dist/local-actions/policy-store.js.map +1 -0
  333. package/dist/local-actions/policy.d.ts +21 -0
  334. package/dist/local-actions/policy.d.ts.map +1 -0
  335. package/dist/local-actions/policy.js +43 -0
  336. package/dist/local-actions/policy.js.map +1 -0
  337. package/dist/local-actions/private-port-forward.d.ts +36 -0
  338. package/dist/local-actions/private-port-forward.d.ts.map +1 -0
  339. package/dist/local-actions/private-port-forward.js +154 -0
  340. package/dist/local-actions/private-port-forward.js.map +1 -0
  341. package/dist/local-actions/provider-mcp-config.d.ts +101 -0
  342. package/dist/local-actions/provider-mcp-config.d.ts.map +1 -0
  343. package/dist/local-actions/provider-mcp-config.js +166 -0
  344. package/dist/local-actions/provider-mcp-config.js.map +1 -0
  345. package/dist/local-actions/providers.d.ts +12 -0
  346. package/dist/local-actions/providers.d.ts.map +1 -0
  347. package/dist/local-actions/providers.js +42 -0
  348. package/dist/local-actions/providers.js.map +1 -0
  349. package/dist/local-actions/schemas.d.ts +4 -0
  350. package/dist/local-actions/schemas.d.ts.map +1 -0
  351. package/dist/local-actions/schemas.js +314 -0
  352. package/dist/local-actions/schemas.js.map +1 -0
  353. package/dist/local-actions/sensitive-consent.d.ts +32 -0
  354. package/dist/local-actions/sensitive-consent.d.ts.map +1 -0
  355. package/dist/local-actions/sensitive-consent.js +47 -0
  356. package/dist/local-actions/sensitive-consent.js.map +1 -0
  357. package/dist/machines/command-launch.d.ts +17 -0
  358. package/dist/machines/command-launch.d.ts.map +1 -0
  359. package/dist/machines/command-launch.js +52 -0
  360. package/dist/machines/command-launch.js.map +1 -0
  361. package/dist/machines/execution-receipt.d.ts +18 -0
  362. package/dist/machines/execution-receipt.d.ts.map +1 -0
  363. package/dist/machines/execution-receipt.js +87 -0
  364. package/dist/machines/execution-receipt.js.map +1 -0
  365. package/dist/machines/executions-screen.d.ts +6 -0
  366. package/dist/machines/executions-screen.d.ts.map +1 -0
  367. package/dist/machines/executions-screen.js +410 -0
  368. package/dist/machines/executions-screen.js.map +1 -0
  369. package/dist/machines/explorer.d.ts +75 -0
  370. package/dist/machines/explorer.d.ts.map +1 -0
  371. package/dist/machines/explorer.js +1726 -0
  372. package/dist/machines/explorer.js.map +1 -0
  373. package/dist/machines/live-supervisor-update.d.ts +325 -0
  374. package/dist/machines/live-supervisor-update.d.ts.map +1 -0
  375. package/dist/machines/live-supervisor-update.js +513 -0
  376. package/dist/machines/live-supervisor-update.js.map +1 -0
  377. package/dist/machines/machine-first.d.ts +123 -0
  378. package/dist/machines/machine-first.d.ts.map +1 -0
  379. package/dist/machines/machine-first.js +119 -0
  380. package/dist/machines/machine-first.js.map +1 -0
  381. package/dist/machines/opencode-supervisor.d.ts +51 -0
  382. package/dist/machines/opencode-supervisor.d.ts.map +1 -0
  383. package/dist/machines/opencode-supervisor.js +124 -0
  384. package/dist/machines/opencode-supervisor.js.map +1 -0
  385. package/dist/machines/pagination.d.ts +4 -0
  386. package/dist/machines/pagination.d.ts.map +1 -0
  387. package/dist/machines/pagination.js +7 -0
  388. package/dist/machines/pagination.js.map +1 -0
  389. package/dist/machines/provider-availability.d.ts +42 -0
  390. package/dist/machines/provider-availability.d.ts.map +1 -0
  391. package/dist/machines/provider-availability.js +82 -0
  392. package/dist/machines/provider-availability.js.map +1 -0
  393. package/dist/machines/provider-screen.d.ts +12 -0
  394. package/dist/machines/provider-screen.d.ts.map +1 -0
  395. package/dist/machines/provider-screen.js +129 -0
  396. package/dist/machines/provider-screen.js.map +1 -0
  397. package/dist/machines/session-actionability.d.ts +86 -0
  398. package/dist/machines/session-actionability.d.ts.map +1 -0
  399. package/dist/machines/session-actionability.js +125 -0
  400. package/dist/machines/session-actionability.js.map +1 -0
  401. package/dist/machines/session-visibility.d.ts +139 -0
  402. package/dist/machines/session-visibility.d.ts.map +1 -0
  403. package/dist/machines/session-visibility.js +109 -0
  404. package/dist/machines/session-visibility.js.map +1 -0
  405. package/dist/platform/adapter.d.ts +62 -0
  406. package/dist/platform/adapter.d.ts.map +1 -0
  407. package/dist/platform/adapter.js +240 -0
  408. package/dist/platform/adapter.js.map +1 -0
  409. package/dist/platform/support.d.ts +12 -0
  410. package/dist/platform/support.d.ts.map +1 -0
  411. package/dist/platform/support.js +25 -0
  412. package/dist/platform/support.js.map +1 -0
  413. package/dist/pty/contracts.d.ts +45 -0
  414. package/dist/pty/contracts.d.ts.map +1 -0
  415. package/dist/pty/contracts.js +2 -0
  416. package/dist/pty/contracts.js.map +1 -0
  417. package/dist/pty/evidence-gate.d.ts +14 -0
  418. package/dist/pty/evidence-gate.d.ts.map +1 -0
  419. package/dist/pty/evidence-gate.js +35 -0
  420. package/dist/pty/evidence-gate.js.map +1 -0
  421. package/dist/pty/index.d.ts +5 -0
  422. package/dist/pty/index.d.ts.map +1 -0
  423. package/dist/pty/index.js +5 -0
  424. package/dist/pty/index.js.map +1 -0
  425. package/dist/pty/node-host-terminal.d.ts +14 -0
  426. package/dist/pty/node-host-terminal.d.ts.map +1 -0
  427. package/dist/pty/node-host-terminal.js +173 -0
  428. package/dist/pty/node-host-terminal.js.map +1 -0
  429. package/dist/pty/node-process.d.ts +26 -0
  430. package/dist/pty/node-process.d.ts.map +1 -0
  431. package/dist/pty/node-process.js +102 -0
  432. package/dist/pty/node-process.js.map +1 -0
  433. package/dist/runtime/api-terminal-control-plane.d.ts +7 -0
  434. package/dist/runtime/api-terminal-control-plane.d.ts.map +1 -0
  435. package/dist/runtime/api-terminal-control-plane.js +95 -0
  436. package/dist/runtime/api-terminal-control-plane.js.map +1 -0
  437. package/dist/runtime/backoff.d.ts +17 -0
  438. package/dist/runtime/backoff.d.ts.map +1 -0
  439. package/dist/runtime/backoff.js +61 -0
  440. package/dist/runtime/backoff.js.map +1 -0
  441. package/dist/runtime/boundary.d.ts +171 -0
  442. package/dist/runtime/boundary.d.ts.map +1 -0
  443. package/dist/runtime/boundary.js +1858 -0
  444. package/dist/runtime/boundary.js.map +1 -0
  445. package/dist/runtime/capability-gate.d.ts +25 -0
  446. package/dist/runtime/capability-gate.d.ts.map +1 -0
  447. package/dist/runtime/capability-gate.js +77 -0
  448. package/dist/runtime/capability-gate.js.map +1 -0
  449. package/dist/runtime/contracts.d.ts +25 -0
  450. package/dist/runtime/contracts.d.ts.map +1 -0
  451. package/dist/runtime/contracts.js +66 -0
  452. package/dist/runtime/contracts.js.map +1 -0
  453. package/dist/runtime/errors.d.ts +20 -0
  454. package/dist/runtime/errors.d.ts.map +1 -0
  455. package/dist/runtime/errors.js +22 -0
  456. package/dist/runtime/errors.js.map +1 -0
  457. package/dist/runtime/index.d.ts +9 -0
  458. package/dist/runtime/index.d.ts.map +1 -0
  459. package/dist/runtime/index.js +9 -0
  460. package/dist/runtime/index.js.map +1 -0
  461. package/dist/runtime/node-foreground-session.d.ts +50 -0
  462. package/dist/runtime/node-foreground-session.d.ts.map +1 -0
  463. package/dist/runtime/node-foreground-session.js +431 -0
  464. package/dist/runtime/node-foreground-session.js.map +1 -0
  465. package/dist/runtime/node-websocket-connector.d.ts +6 -0
  466. package/dist/runtime/node-websocket-connector.d.ts.map +1 -0
  467. package/dist/runtime/node-websocket-connector.js +344 -0
  468. package/dist/runtime/node-websocket-connector.js.map +1 -0
  469. package/dist/runtime/observer-screen.d.ts +6 -0
  470. package/dist/runtime/observer-screen.d.ts.map +1 -0
  471. package/dist/runtime/observer-screen.js +144 -0
  472. package/dist/runtime/observer-screen.js.map +1 -0
  473. package/dist/runtime/owner-grant-operations.d.ts +136 -0
  474. package/dist/runtime/owner-grant-operations.d.ts.map +1 -0
  475. package/dist/runtime/owner-grant-operations.js +216 -0
  476. package/dist/runtime/owner-grant-operations.js.map +1 -0
  477. package/dist/runtime/owner-grants-screen.d.ts +40 -0
  478. package/dist/runtime/owner-grants-screen.d.ts.map +1 -0
  479. package/dist/runtime/owner-grants-screen.js +987 -0
  480. package/dist/runtime/owner-grants-screen.js.map +1 -0
  481. package/dist/runtime/terminal-transport.d.ts +85 -0
  482. package/dist/runtime/terminal-transport.d.ts.map +1 -0
  483. package/dist/runtime/terminal-transport.js +152 -0
  484. package/dist/runtime/terminal-transport.js.map +1 -0
  485. package/dist/sync/continuous-sync-supervisor.d.ts +107 -0
  486. package/dist/sync/continuous-sync-supervisor.d.ts.map +1 -0
  487. package/dist/sync/continuous-sync-supervisor.js +1117 -0
  488. package/dist/sync/continuous-sync-supervisor.js.map +1 -0
  489. package/dist/sync/index.d.ts +9 -0
  490. package/dist/sync/index.d.ts.map +1 -0
  491. package/dist/sync/index.js +9 -0
  492. package/dist/sync/index.js.map +1 -0
  493. package/dist/sync/journal.d.ts +57 -0
  494. package/dist/sync/journal.d.ts.map +1 -0
  495. package/dist/sync/journal.js +685 -0
  496. package/dist/sync/journal.js.map +1 -0
  497. package/dist/sync/revisions.d.ts +118 -0
  498. package/dist/sync/revisions.d.ts.map +1 -0
  499. package/dist/sync/revisions.js +364 -0
  500. package/dist/sync/revisions.js.map +1 -0
  501. package/dist/sync/supervisor.d.ts +107 -0
  502. package/dist/sync/supervisor.d.ts.map +1 -0
  503. package/dist/sync/supervisor.js +246 -0
  504. package/dist/sync/supervisor.js.map +1 -0
  505. package/dist/sync/workspace-sync-client.d.ts +18 -0
  506. package/dist/sync/workspace-sync-client.d.ts.map +1 -0
  507. package/dist/sync/workspace-sync-client.js +150 -0
  508. package/dist/sync/workspace-sync-client.js.map +1 -0
  509. package/dist/sync/workspace-sync-coordinator.d.ts +76 -0
  510. package/dist/sync/workspace-sync-coordinator.d.ts.map +1 -0
  511. package/dist/sync/workspace-sync-coordinator.js +621 -0
  512. package/dist/sync/workspace-sync-coordinator.js.map +1 -0
  513. package/dist/sync/workspace-sync-product-service.d.ts +79 -0
  514. package/dist/sync/workspace-sync-product-service.d.ts.map +1 -0
  515. package/dist/sync/workspace-sync-product-service.js +398 -0
  516. package/dist/sync/workspace-sync-product-service.js.map +1 -0
  517. package/dist/sync/workspace-sync-protocol.d.ts +145 -0
  518. package/dist/sync/workspace-sync-protocol.d.ts.map +1 -0
  519. package/dist/sync/workspace-sync-protocol.js +347 -0
  520. package/dist/sync/workspace-sync-protocol.js.map +1 -0
  521. package/dist/terminal/appbar.d.ts +40 -0
  522. package/dist/terminal/appbar.d.ts.map +1 -0
  523. package/dist/terminal/appbar.js +55 -0
  524. package/dist/terminal/appbar.js.map +1 -0
  525. package/dist/terminal/cell-width.d.ts +3 -0
  526. package/dist/terminal/cell-width.d.ts.map +1 -0
  527. package/dist/terminal/cell-width.js +53 -0
  528. package/dist/terminal/cell-width.js.map +1 -0
  529. package/dist/terminal/codec.d.ts +107 -0
  530. package/dist/terminal/codec.d.ts.map +1 -0
  531. package/dist/terminal/codec.js +538 -0
  532. package/dist/terminal/codec.js.map +1 -0
  533. package/dist/terminal/foreground.d.ts +135 -0
  534. package/dist/terminal/foreground.d.ts.map +1 -0
  535. package/dist/terminal/foreground.js +2097 -0
  536. package/dist/terminal/foreground.js.map +1 -0
  537. package/dist/terminal/generated/terminal-wire-v1.d.ts +26 -0
  538. package/dist/terminal/generated/terminal-wire-v1.d.ts.map +1 -0
  539. package/dist/terminal/generated/terminal-wire-v1.js +27 -0
  540. package/dist/terminal/generated/terminal-wire-v1.js.map +1 -0
  541. package/dist/terminal/mode.d.ts +33 -0
  542. package/dist/terminal/mode.d.ts.map +1 -0
  543. package/dist/terminal/mode.js +99 -0
  544. package/dist/terminal/mode.js.map +1 -0
  545. package/dist/terminal/passthrough.d.ts +47 -0
  546. package/dist/terminal/passthrough.d.ts.map +1 -0
  547. package/dist/terminal/passthrough.js +666 -0
  548. package/dist/terminal/passthrough.js.map +1 -0
  549. package/dist/terminal/resume.d.ts +58 -0
  550. package/dist/terminal/resume.d.ts.map +1 -0
  551. package/dist/terminal/resume.js +185 -0
  552. package/dist/terminal/resume.js.map +1 -0
  553. package/dist/terminal/viewport.d.ts +93 -0
  554. package/dist/terminal/viewport.d.ts.map +1 -0
  555. package/dist/terminal/viewport.js +266 -0
  556. package/dist/terminal/viewport.js.map +1 -0
  557. package/dist/terminal/workbench.d.ts +32 -0
  558. package/dist/terminal/workbench.d.ts.map +1 -0
  559. package/dist/terminal/workbench.js +316 -0
  560. package/dist/terminal/workbench.js.map +1 -0
  561. package/dist/terminal/xterm-vte.d.ts +49 -0
  562. package/dist/terminal/xterm-vte.d.ts.map +1 -0
  563. package/dist/terminal/xterm-vte.js +602 -0
  564. package/dist/terminal/xterm-vte.js.map +1 -0
  565. package/dist/version.d.ts +3 -0
  566. package/dist/version.d.ts.map +1 -0
  567. package/dist/version.js +3 -0
  568. package/dist/version.js.map +1 -0
  569. package/dist/workspace/binding-path.d.ts +17 -0
  570. package/dist/workspace/binding-path.d.ts.map +1 -0
  571. package/dist/workspace/binding-path.js +91 -0
  572. package/dist/workspace/binding-path.js.map +1 -0
  573. package/dist/workspace/binding-store.d.ts +107 -0
  574. package/dist/workspace/binding-store.d.ts.map +1 -0
  575. package/dist/workspace/binding-store.js +783 -0
  576. package/dist/workspace/binding-store.js.map +1 -0
  577. package/dist/workspace/binding.d.ts +35 -0
  578. package/dist/workspace/binding.d.ts.map +1 -0
  579. package/dist/workspace/binding.js +70 -0
  580. package/dist/workspace/binding.js.map +1 -0
  581. package/dist/workspace/errors.d.ts +4 -0
  582. package/dist/workspace/errors.d.ts.map +1 -0
  583. package/dist/workspace/errors.js +19 -0
  584. package/dist/workspace/errors.js.map +1 -0
  585. package/dist/workspace/exclusion.d.ts +21 -0
  586. package/dist/workspace/exclusion.d.ts.map +1 -0
  587. package/dist/workspace/exclusion.js +243 -0
  588. package/dist/workspace/exclusion.js.map +1 -0
  589. package/dist/workspace/index.d.ts +8 -0
  590. package/dist/workspace/index.d.ts.map +1 -0
  591. package/dist/workspace/index.js +8 -0
  592. package/dist/workspace/index.js.map +1 -0
  593. package/dist/workspace/lifecycle.d.ts +56 -0
  594. package/dist/workspace/lifecycle.d.ts.map +1 -0
  595. package/dist/workspace/lifecycle.js +94 -0
  596. package/dist/workspace/lifecycle.js.map +1 -0
  597. package/dist/workspace/manifest.d.ts +47 -0
  598. package/dist/workspace/manifest.d.ts.map +1 -0
  599. package/dist/workspace/manifest.js +243 -0
  600. package/dist/workspace/manifest.js.map +1 -0
  601. package/dist/workspace/paths.d.ts +14 -0
  602. package/dist/workspace/paths.d.ts.map +1 -0
  603. package/dist/workspace/paths.js +67 -0
  604. package/dist/workspace/paths.js.map +1 -0
  605. package/dist/workspace/schema.d.ts +15 -0
  606. package/dist/workspace/schema.d.ts.map +1 -0
  607. package/dist/workspace/schema.js +33 -0
  608. package/dist/workspace/schema.js.map +1 -0
  609. package/dist/workspace/selection-screen.d.ts +4 -0
  610. package/dist/workspace/selection-screen.d.ts.map +1 -0
  611. package/dist/workspace/selection-screen.js +216 -0
  612. package/dist/workspace/selection-screen.js.map +1 -0
  613. package/dist/workspace/selection-service.d.ts +16 -0
  614. package/dist/workspace/selection-service.d.ts.map +1 -0
  615. package/dist/workspace/selection-service.js +65 -0
  616. package/dist/workspace/selection-service.js.map +1 -0
  617. package/node_modules/@xterm/headless/README.md +31 -0
  618. package/node_modules/@xterm/headless/lib-headless/xterm-headless.js +2 -0
  619. package/node_modules/@xterm/headless/lib-headless/xterm-headless.js.map +1 -0
  620. package/node_modules/@xterm/headless/lib-headless/xterm-headless.mjs +46 -0
  621. package/node_modules/@xterm/headless/lib-headless/xterm-headless.mjs.map +7 -0
  622. package/node_modules/@xterm/headless/package.json +29 -0
  623. package/node_modules/@xterm/headless/typings/xterm-headless.d.ts +1385 -0
  624. package/package.json +75 -0
@@ -0,0 +1,838 @@
1
+ import { EXIT_CODES, CunaError } from "../core/errors.js";
2
+ import { CredentialBoundaryError } from "../credentials/errors.js";
3
+ import { INTERNAL_DEFECT_HINT, OFF_CONTRACT_RESPONSE_HINT, SUPPORT_URL, automationCredentialHint, } from "../core/product-web.js";
4
+ import { containsCredentialValue, isAccessToken, isProblemType, isProblemTypeForCode, isTransportCredential, } from "../core/namespace.js";
5
+ import { isIdempotencyKey, isObject, safeReasonCode } from "../core/validation.js";
6
+ import { isOpenCodeSupervisorUpgradeReason, openCodeSupervisorUpgradeRequired, } from "../machines/opencode-supervisor.js";
7
+ import { DEFAULT_REQUEST_BUDGET_MS, observationBudgetElapsed, } from "../core/observation-budget.js";
8
+ import { CLI_VERSION } from "../version.js";
9
+ const MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
10
+ // A 16 MiB body is never a legitimate answer on this contract, so the remedy is
11
+ // to narrow the request rather than to retry it.
12
+ const OVERSIZED_RESPONSE_HINT = "Narrow the request with --limit or a cursor. Retrying unchanged returns the same oversized body.";
13
+ const PROBLEM_CODE = /^[a-z][a-z0-9_]{2,63}$/u;
14
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
15
+ const PROBLEM_ACTIONS = new Set(["retry", "sign_in", "open_web", "contact_support", "none"]);
16
+ // Server prose reaches a terminal, so it may not carry control or format
17
+ // characters, and it may never echo a credential back at the user. Same guard
18
+ // `safePublicString` applies in `api/contracts.ts`; it rejects here instead of
19
+ // throwing, because an unusable sentence must degrade to the generic message
20
+ // rather than turn a server refusal into a client crash.
21
+ const FORBIDDEN_PUBLIC_CHARACTER = /[\p{Cc}\p{Cf}]/u;
22
+ function publicProse(value) {
23
+ if (FORBIDDEN_PUBLIC_CHARACTER.test(value) || containsCredentialValue(value))
24
+ return undefined;
25
+ return value;
26
+ }
27
+ const AGENT_SESSION_CREATE_PATH = /^\/v1\/sessions\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/agent-sessions$/u;
28
+ const WORKSPACE_SYNC_CAPABILITIES = Object.freeze([
29
+ "atomic_generation_commit",
30
+ "bounded_manifest_pages",
31
+ "content_digest_verification",
32
+ "explicit_reconciliation",
33
+ "ordered_generation_changes",
34
+ "policy_bound_admission",
35
+ ]);
36
+ const NO_WORKSPACE_SYNC_CAPABILITIES = Object.freeze([]);
37
+ function isOpenCodeAgentSessionCreate(input) {
38
+ return input.method === "POST" &&
39
+ AGENT_SESSION_CREATE_PATH.test(input.path) &&
40
+ isObject(input.requestBody) &&
41
+ input.requestBody.agent === "opencode";
42
+ }
43
+ /**
44
+ * The subject a request path names, when it names one.
45
+ *
46
+ * A 404 was answered two different ways depending on how the command reached
47
+ * the server: the ones that pass a resource-scoped capability check named the
48
+ * Machine or AgentSession, and the rest got "The requested Cuna resource or
49
+ * operation was not found." The vaguer half is the half a reader meets straight
50
+ * after typing an id, which is the worst place for it. One 404, one sentence.
51
+ */
52
+ function notFoundSubject(path) {
53
+ // A resource-scoped capability query carries its subject in the query string
54
+ // rather than the path, and it is the one command whose entire job is a
55
+ // resource-scoped question -- so it is the last place that should answer with
56
+ // the general sentence.
57
+ const scoped = /^\/v\d+\/capabilities\?(?=.*\bscope=(machine|agent_session)\b)(?=.*\bresource_id=([^&]+))/u.exec(path);
58
+ if (scoped !== null && scoped[1] !== undefined && scoped[2] !== undefined) {
59
+ return {
60
+ subject: scoped[1] === "machine" ? "Machine" : "AgentSession",
61
+ id: decodeURIComponent(scoped[2]),
62
+ };
63
+ }
64
+ const match = /^\/v\d+\/(sessions|agent-sessions|api-keys|workspace-bindings)\/([^/?]+)/u.exec(path);
65
+ const id = match?.[2];
66
+ if (match === null || id === undefined)
67
+ return undefined;
68
+ const subject = match[1] === "sessions"
69
+ ? "Machine"
70
+ : match[1] === "agent-sessions"
71
+ ? "AgentSession"
72
+ : match[1] === "api-keys"
73
+ ? "API key"
74
+ : "workspace binding";
75
+ return { subject, id: decodeURIComponent(id) };
76
+ }
77
+ function machineIdFromAgentSessionCreatePath(path) {
78
+ return AGENT_SESSION_CREATE_PATH.exec(path)?.[1];
79
+ }
80
+ function problemMetadata(body, expectedStatus) {
81
+ if (!isObject(body))
82
+ return undefined;
83
+ if (Object.hasOwn(body, "selected_protocol") || Object.hasOwn(body, "capabilities")) {
84
+ return workspaceSyncProblemMetadata(body, expectedStatus);
85
+ }
86
+ const required = new Set(["type", "title", "status", "code", "request_id", "retryable"]);
87
+ const optional = new Set(["detail", "action"]);
88
+ const keys = Object.keys(body);
89
+ if ([...required].some((key) => !Object.hasOwn(body, key)) ||
90
+ keys.some((key) => !required.has(key) && !optional.has(key)) ||
91
+ typeof body.type !== "string" || !isProblemType(body.type) ||
92
+ typeof body.title !== "string" || body.title.length < 1 || body.title.length > 120 ||
93
+ !Number.isSafeInteger(body.status) || body.status !== expectedStatus ||
94
+ typeof body.code !== "string" || !PROBLEM_CODE.test(body.code) ||
95
+ typeof body.request_id !== "string" || !UUID.test(body.request_id) ||
96
+ typeof body.retryable !== "boolean" ||
97
+ (Object.hasOwn(body, "detail") &&
98
+ (typeof body.detail !== "string" || body.detail.length > 500)) ||
99
+ (Object.hasOwn(body, "action") &&
100
+ (typeof body.action !== "string" || !PROBLEM_ACTIONS.has(body.action)))) {
101
+ return undefined;
102
+ }
103
+ const title = publicProse(body.title);
104
+ const detail = typeof body.detail === "string" ? publicProse(body.detail) : undefined;
105
+ return Object.freeze({
106
+ code: body.code,
107
+ requestId: body.request_id,
108
+ retryable: body.retryable,
109
+ ...(title === undefined ? {} : { title }),
110
+ ...(detail === undefined ? {} : { detail }),
111
+ });
112
+ }
113
+ function workspaceSyncProblemMetadata(body, expectedStatus) {
114
+ const required = new Set([
115
+ "type", "title", "status", "code", "request_id", "retryable", "action",
116
+ "selected_protocol", "capabilities", "detail",
117
+ ]);
118
+ const keys = Object.keys(body);
119
+ const selectedProtocol = body.selected_protocol;
120
+ const capabilities = body.capabilities;
121
+ const hasSelectedProtocol = selectedProtocol === 1 || selectedProtocol === 2;
122
+ if (keys.length !== required.size ||
123
+ [...required].some((key) => !Object.hasOwn(body, key)) ||
124
+ typeof body.code !== "string" ||
125
+ !/^workspace_sync_[a-z0-9_]{2,48}$/u.test(body.code) ||
126
+ typeof body.type !== "string" || !isProblemTypeForCode(body.type, body.code) ||
127
+ typeof body.title !== "string" || body.title.length < 1 || body.title.length > 120 ||
128
+ !Number.isSafeInteger(body.status) || body.status !== expectedStatus ||
129
+ typeof body.request_id !== "string" || !UUID.test(body.request_id) ||
130
+ typeof body.retryable !== "boolean" ||
131
+ (body.action !== "retry" && body.action !== "none") ||
132
+ typeof body.detail !== "string" || body.detail.length < 1 || body.detail.length > 500 ||
133
+ (!hasSelectedProtocol && selectedProtocol !== null) ||
134
+ !Array.isArray(capabilities) ||
135
+ (selectedProtocol === null
136
+ ? capabilities.length !== 0
137
+ : capabilities.length !== WORKSPACE_SYNC_CAPABILITIES.length ||
138
+ capabilities.some((value, index) => value !== WORKSPACE_SYNC_CAPABILITIES[index]))) {
139
+ return undefined;
140
+ }
141
+ return Object.freeze({
142
+ code: body.code,
143
+ requestId: body.request_id,
144
+ retryable: body.retryable,
145
+ selectedProtocol: selectedProtocol,
146
+ capabilities: selectedProtocol === null
147
+ ? NO_WORKSPACE_SYNC_CAPABILITIES
148
+ : WORKSPACE_SYNC_CAPABILITIES,
149
+ });
150
+ }
151
+ /**
152
+ * Build the error for a non-2xx response.
153
+ *
154
+ * `body` is the decoded response body, or `undefined` when the body was not
155
+ * JSON at all. The distinction is load-bearing: a status this API produced
156
+ * always carries a JSON object (a Problem document, or at minimum
157
+ * `{"error":"…"}`), because the request asks for exactly
158
+ * `application/json, application/problem+json`. A non-JSON body at an error
159
+ * status therefore came from a layer in front of the API that has no route for
160
+ * this path — measured: `GET https://api.getcuna.com/v1/capabilities` answers
161
+ * `404` with `content-type: text/plain` and the body `404 Not Found`, while
162
+ * `GET /v1/me` answers `401` with `application/json`.
163
+ */
164
+ function apiError(input) {
165
+ const { status, requestId, body, credentialKind } = input;
166
+ const problem = problemMetadata(body, status);
167
+ const reason = problem?.code ??
168
+ (isObject(body) ? safeReasonCode(body.code) ?? safeReasonCode(body.error) : undefined);
169
+ // Not every route on this API answers with a Problem document. `sessions.start`
170
+ // is declared `"errorModel": "legacy"` in the contract and answers
171
+ // `{"error": "<sentence>"}` with no code, title or detail — so `problem` is
172
+ // undefined and the sentence is not a reason code either, because it has
173
+ // spaces. Measured: the web console renders exactly this string while the CLI
174
+ // showed only `http_status: 409`. The sentence is the whole actionable
175
+ // content, so read it as prose under the same terminal-safety guard.
176
+ const legacyReason = isObject(body) && typeof body.error === "string" &&
177
+ body.error.length >= 1 && body.error.length <= 500
178
+ ? publicProse(body.error)
179
+ : undefined;
180
+ const effectiveRequestId = problem?.requestId ?? requestId;
181
+ const details = {
182
+ http_status: status,
183
+ ...(effectiveRequestId === undefined ? {} : { request_id: effectiveRequestId }),
184
+ ...(reason === undefined ? {} : { reason }),
185
+ ...(problem?.selectedProtocol === undefined
186
+ ? {}
187
+ : { selected_protocol: problem.selectedProtocol }),
188
+ ...(problem?.capabilities === undefined
189
+ ? {}
190
+ : { capabilities: problem.capabilities }),
191
+ };
192
+ if (status === 401) {
193
+ return new CunaError({
194
+ code: "cuna.auth.rejected",
195
+ message: "Cuna rejected the current credential.",
196
+ exitCode: EXIT_CODES.auth,
197
+ // The api_key arm used to say "Replace CUNA_API_KEY with a valid
198
+ // automation credential" and name no source, which is the same dead end
199
+ // the sign-in path had. It now shares the one sentence that does.
200
+ hint: credentialKind === "interactive"
201
+ ? "The access token was refused. Retry the command so Cuna can obtain a fresh token from the encrypted local session."
202
+ : credentialKind === "api_key"
203
+ ? `The current automation credential was refused. ${automationCredentialHint()}`
204
+ : `Run \`cuna login\`, or provide an automation credential. ${automationCredentialHint()}`,
205
+ ...(problem === undefined ? {} : { retryable: problem.retryable }),
206
+ details,
207
+ });
208
+ }
209
+ if (status === 403) {
210
+ return new CunaError({
211
+ code: "cuna.policy.denied",
212
+ message: "Cuna denied this operation.",
213
+ exitCode: EXIT_CODES.policy,
214
+ hint: "The credential authenticated but is not permitted to do this. Retrying will not change the outcome.",
215
+ ...(problem === undefined ? {} : { retryable: problem.retryable }),
216
+ details,
217
+ });
218
+ }
219
+ // This is not a retryable state conflict: the durable create authority
220
+ // rejected an AgentSession because its provider is not installed on the
221
+ // selected Machine. Keep the server's reason in safe details, but turn it
222
+ // into the same actionable provider-selection result the CLI emits when its
223
+ // immediately preceding machine observation detects the mismatch.
224
+ if (status === 409 && reason === "agent_session_provider_unavailable") {
225
+ return new CunaError({
226
+ code: "cuna.agent.provider_not_installed",
227
+ message: "OpenCode is not installed on the selected Machine.",
228
+ exitCode: EXIT_CODES.unsupported,
229
+ hint: "Choose a running Machine configured for OpenCode, or create one with `cuna machines create --agent opencode --name NAME --yes`.",
230
+ ...(problem === undefined ? {} : { retryable: problem.retryable }),
231
+ details,
232
+ });
233
+ }
234
+ // This is an authoritative refusal from the durable AgentSession create
235
+ // authority, not an attach failure and not an ambiguous network outcome.
236
+ // Keep the route fence here: `supervisor_upgrade_required` also occurs on
237
+ // terminal connections, where saying that no AgentSession was created would
238
+ // be false.
239
+ if (status === 409 &&
240
+ problem !== undefined &&
241
+ isOpenCodeAgentSessionCreate(input) &&
242
+ isOpenCodeSupervisorUpgradeReason(problem.code)) {
243
+ const machineId = machineIdFromAgentSessionCreatePath(input.path);
244
+ return openCodeSupervisorUpgradeRequired({
245
+ details,
246
+ ...(machineId === undefined ? {} : { machineId }),
247
+ retryable: problem.retryable,
248
+ });
249
+ }
250
+ if (status === 409) {
251
+ // The server names which state conflicts; this used to answer every 409
252
+ // with one fixed sentence and throw that away, so the user was told a
253
+ // conflict exists but never which one. Prefer the server's own words and
254
+ // keep the generic sentence only as the fallback for a refusal that
255
+ // carried none.
256
+ return new CunaError({
257
+ code: "cuna.remote.conflict",
258
+ message: problem?.title ?? legacyReason ??
259
+ "Cuna could not apply the operation because current state conflicts with it.",
260
+ exitCode: EXIT_CODES.conflict,
261
+ hint: problem?.detail ??
262
+ "Re-read the resource and decide again from its current state. Repeating this request unchanged repeats this answer.",
263
+ ...(problem === undefined ? {} : { retryable: problem.retryable }),
264
+ details,
265
+ });
266
+ }
267
+ // A 5xx the server marked final. `retryable` is the server's own word, so it
268
+ // decides, not the status class: exit 5 tells a caller to wait, and a refusal
269
+ // is not something waiting can clear.
270
+ //
271
+ // `hint: problem.detail` is load-bearing. One `code` may be emitted from
272
+ // several sites and the catalogue fixes `title` per code, so `detail` is the
273
+ // only field that distinguishes them.
274
+ if (status >= 500 && problem !== undefined && !problem.retryable) {
275
+ return new CunaError({
276
+ code: "cuna.remote.rejected",
277
+ message: problem.title ?? "Cuna rejected the request.",
278
+ exitCode: EXIT_CODES.remote,
279
+ hint: problem.detail ?? OFF_CONTRACT_RESPONSE_HINT,
280
+ retryable: false,
281
+ details,
282
+ });
283
+ }
284
+ if (status === 429 || status >= 500) {
285
+ // A 5xx that carries the server's own sentence (a Problem title, or the
286
+ // legacy `{"error": "<sentence>"}` that `sessions.start` answers) must
287
+ // show it: nine identical "temporarily unavailable" answers in a row on
288
+ // 2026-09-02 hid a reason the server had named every time.
289
+ const serverSentence = status === 429 ? undefined : problem?.title ?? legacyReason;
290
+ return new CunaError({
291
+ code: status === 429 ? "cuna.network.rate_limited" : "cuna.network.service_unavailable",
292
+ message: status === 429
293
+ ? "Cuna is rate limiting this request."
294
+ : serverSentence ?? "The Cuna service is temporarily unavailable.",
295
+ exitCode: EXIT_CODES.network,
296
+ hint: status === 429
297
+ ? "Wait before retrying. No change was applied by this request."
298
+ : problem?.detail ??
299
+ "No authoritative answer was received. Retry a read; do not assume a write was applied.",
300
+ retryable: problem?.retryable ?? true,
301
+ details: {
302
+ ...details,
303
+ ...(legacyReason === undefined || problem !== undefined ? {} : { server_error: legacyReason }),
304
+ },
305
+ });
306
+ }
307
+ if (status === 404 && !input.apiEncodedBody) {
308
+ // Reporting this as `cuna.remote.malformed_response` — which is what
309
+ // happened while the body was parsed before the status was read — names the
310
+ // layer that noticed the failure instead of the layer that caused it. The
311
+ // response is not malformed; this deployment does not implement the
312
+ // operation. Production serves 26 of the 57 operations this build knows, so
313
+ // this is the majority answer today, not an edge case.
314
+ return new CunaError({
315
+ code: "cuna.remote.operation_not_served",
316
+ message: `The Cuna API at ${input.origin} does not serve ${input.method} ${input.path}.`,
317
+ exitCode: EXIT_CODES.unsupported,
318
+ hint: `The deployed Cuna API does not implement this operation. Run \`cuna version --json\` and report it with that record at ${SUPPORT_URL} if it should be available.`,
319
+ details: {
320
+ http_status: status,
321
+ ...(requestId === undefined ? {} : { request_id: requestId }),
322
+ method: input.method,
323
+ path: input.path,
324
+ api_origin: input.origin,
325
+ },
326
+ });
327
+ }
328
+ const subject = status === 404 ? notFoundSubject(input.path) : undefined;
329
+ return new CunaError({
330
+ code: status === 404 ? "cuna.remote.not_found" : "cuna.remote.rejected",
331
+ message: status !== 404
332
+ ? "Cuna rejected the request."
333
+ : subject === undefined
334
+ ? "The requested Cuna resource or operation was not found."
335
+ : `${subject.subject} ${subject.id} is not available to this account.`,
336
+ exitCode: EXIT_CODES.remote,
337
+ hint: status === 404
338
+ ? subject?.subject === "Machine"
339
+ ? "Run `cuna machines list` to see the Machines on this account."
340
+ : subject?.subject === "AgentSession"
341
+ ? "Run `cuna agent-sessions list --machine <id>` to see the AgentSessions on a Machine."
342
+ : "The identifier does not name a resource this account can see. Re-list to get a current one."
343
+ : OFF_CONTRACT_RESPONSE_HINT,
344
+ ...(problem === undefined ? {} : { retryable: problem.retryable }),
345
+ details,
346
+ });
347
+ }
348
+ async function readLimited(response) {
349
+ const declared = response.headers.get("content-length");
350
+ if (declared !== null && Number(declared) > MAX_RESPONSE_BYTES) {
351
+ throw new CunaError({
352
+ code: "cuna.remote.response_too_large",
353
+ message: "Cuna returned an oversized response.",
354
+ exitCode: EXIT_CODES.remote,
355
+ hint: OVERSIZED_RESPONSE_HINT,
356
+ details: { predicate: "response_within_size_limit", limit_bytes: MAX_RESPONSE_BYTES },
357
+ });
358
+ }
359
+ if (response.body === null)
360
+ return new Uint8Array();
361
+ const reader = response.body.getReader();
362
+ const chunks = [];
363
+ let total = 0;
364
+ for (;;) {
365
+ const { done, value } = await reader.read();
366
+ if (done)
367
+ break;
368
+ if (value !== undefined) {
369
+ total += value.byteLength;
370
+ if (total > MAX_RESPONSE_BYTES) {
371
+ await reader.cancel();
372
+ throw new CunaError({
373
+ code: "cuna.remote.response_too_large",
374
+ message: "Cuna returned an oversized response.",
375
+ exitCode: EXIT_CODES.remote,
376
+ hint: OVERSIZED_RESPONSE_HINT,
377
+ details: { predicate: "response_within_size_limit", limit_bytes: MAX_RESPONSE_BYTES },
378
+ });
379
+ }
380
+ chunks.push(value);
381
+ }
382
+ }
383
+ const result = new Uint8Array(total);
384
+ let offset = 0;
385
+ for (const chunk of chunks) {
386
+ result.set(chunk, offset);
387
+ offset += chunk.byteLength;
388
+ }
389
+ return result;
390
+ }
391
+ function decodeJson(bytes) {
392
+ if (bytes.byteLength === 0)
393
+ return { decoded: true, value: null };
394
+ try {
395
+ return {
396
+ decoded: true,
397
+ value: JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)),
398
+ };
399
+ }
400
+ catch (cause) {
401
+ return { decoded: false, cause };
402
+ }
403
+ }
404
+ /**
405
+ * Decode a 2xx body, or fail naming the operation whose body would not parse.
406
+ *
407
+ * This is the other half of `cuna.remote.malformed_response`: not "the shape is
408
+ * wrong" but "these bytes are not JSON at all". The two are worth telling apart
409
+ * — a `predicate` of `response_body_is_json` points at a proxy or a truncated
410
+ * transfer, while a field-level predicate points at the API itself — so the
411
+ * detail says which, using the same key names the decode path uses.
412
+ */
413
+ function parseJson(bytes, request) {
414
+ const result = decodeJson(bytes);
415
+ if (result.decoded)
416
+ return result.value;
417
+ throw new CunaError({
418
+ code: "cuna.remote.malformed_response",
419
+ message: "Cuna returned a response body that is not valid JSON.",
420
+ exitCode: EXIT_CODES.remote,
421
+ hint: OFF_CONTRACT_RESPONSE_HINT,
422
+ details: {
423
+ operation: `${request.method} ${request.path}`,
424
+ predicate: "response_body_is_json",
425
+ // A byte count is a property of the transfer, not of the payload's
426
+ // contents, so it discloses nothing a proxy log would not already show.
427
+ response_bytes: bytes.byteLength,
428
+ },
429
+ cause: result.cause,
430
+ });
431
+ }
432
+ const CONNECT_PHASE_CODES = new Set([
433
+ // undici gave up waiting for the socket to connect.
434
+ "UND_ERR_CONNECT_TIMEOUT",
435
+ // The kernel refused or could not route the connect.
436
+ "ECONNREFUSED",
437
+ "EHOSTUNREACH",
438
+ "ENETUNREACH",
439
+ "EADDRNOTAVAIL",
440
+ // Name resolution failed, permanently or transiently.
441
+ "ENOTFOUND",
442
+ "EAI_AGAIN",
443
+ "EAI_FAIL",
444
+ "EAI_NONAME",
445
+ // The TLS handshake was refused. Node reports certificate faults with the
446
+ // OpenSSL verify-result names, and handshake protocol faults as `EPROTO`
447
+ // (only trusted here when the syscall confirms it happened during connect)
448
+ // or `ERR_TLS_*`.
449
+ "CERT_HAS_EXPIRED",
450
+ "CERT_NOT_YET_VALID",
451
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
452
+ "SELF_SIGNED_CERT_IN_CHAIN",
453
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
454
+ "UNABLE_TO_GET_ISSUER_CERT",
455
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
456
+ "ERR_TLS_CERT_ALTNAME_INVALID",
457
+ "ERR_TLS_HANDSHAKE_TIMEOUT",
458
+ "ERR_SSL_WRONG_VERSION_NUMBER",
459
+ ]);
460
+ // A syscall name is stronger evidence than a code: `ETIMEDOUT` on `connect`
461
+ // never wrote a byte, while `ETIMEDOUT` on `write` may have.
462
+ const CONNECT_PHASE_SYSCALLS = new Set(["connect", "getaddrinfo"]);
463
+ /**
464
+ * Walk the error, its `cause` chain and any `AggregateError.errors` (Node's
465
+ * Happy Eyeballs connect reports one `ECONNREFUSED` per address family that
466
+ * way) looking for a `connect`-phase witness. Anything else — headers or body
467
+ * timeouts, a reset after the request was written, a bare `fetch failed` with
468
+ * no cause — is `response`: the fail-closed answer, because the CLI cannot
469
+ * prove the request was not sent.
470
+ */
471
+ function transportFailurePhase(error) {
472
+ const seen = new Set();
473
+ const pending = [error];
474
+ while (pending.length > 0) {
475
+ const current = pending.pop();
476
+ if (typeof current !== "object" || current === null || seen.has(current))
477
+ continue;
478
+ seen.add(current);
479
+ if (seen.size > 16)
480
+ break;
481
+ const record = current;
482
+ if (typeof record.syscall === "string" && CONNECT_PHASE_SYSCALLS.has(record.syscall))
483
+ return "connect";
484
+ if (typeof record.code === "string" && CONNECT_PHASE_CODES.has(record.code))
485
+ return "connect";
486
+ if (Array.isArray(record.errors))
487
+ pending.push(...record.errors);
488
+ pending.push(record.cause);
489
+ }
490
+ return "response";
491
+ }
492
+ function transportFailure(input) {
493
+ const { request, phase, attempts } = input;
494
+ if (phase === "connect") {
495
+ // Never sent, so nothing was applied, so every method may retry. The
496
+ // sentence says so: the old one ("failed before an authoritative result
497
+ // was received") left the user unable to tell a lost answer from a lost
498
+ // connection, and those call for different next steps.
499
+ return new CunaError({
500
+ code: "cuna.network.failed",
501
+ message: `Cuna could not be reached: the connection was not established after ${attempts} attempts, so the request was never sent.`,
502
+ exitCode: EXIT_CODES.network,
503
+ hint: "No change was applied by this request. Check connectivity to the API origin shown by `cuna config get`, then retry.",
504
+ retryable: true,
505
+ details: {
506
+ method: request.method,
507
+ path: request.path,
508
+ phase,
509
+ remote_outcome: "not_sent",
510
+ attempts,
511
+ },
512
+ cause: input.cause,
513
+ });
514
+ }
515
+ // A failure after the request may have been written cannot prove whether a
516
+ // mutating request reached the authority. An idempotency key alone is not
517
+ // reconciliation evidence, so mutations stay fail-closed until a producer
518
+ // contract exposes authoritative operation-status reconciliation.
519
+ //
520
+ // This does not govern the timeout arm, and that separation is deliberate.
521
+ // A budget elapsing is not a transport failure: nothing failed, the CLI
522
+ // stopped waiting. `core/observation-budget.ts` owns that answer and makes it
523
+ // retryable at a single site.
524
+ return new CunaError({
525
+ code: "cuna.network.failed",
526
+ message: "The Cuna request was sent, but the connection failed before an authoritative result was received.",
527
+ exitCode: EXIT_CODES.network,
528
+ hint: request.settleWith === undefined
529
+ ? "Check connectivity to the API origin shown by `cuna config get`. A mutating request may still have been applied; re-read the resource before re-issuing it."
530
+ : `The operation may still have been applied. Inspect its outcome with \`${request.settleWith}\` before re-issuing it.`,
531
+ retryable: request.method === "GET",
532
+ details: {
533
+ method: request.method,
534
+ path: request.path,
535
+ phase,
536
+ remote_outcome: "unobserved",
537
+ attempts,
538
+ },
539
+ cause: input.cause,
540
+ });
541
+ }
542
+ export function createHttpTransport(input) {
543
+ const credentialAuthorities = [
544
+ input.apiKey,
545
+ input.bearerToken,
546
+ input.bearerTokenProvider,
547
+ ].filter((value) => value !== undefined).length;
548
+ if (credentialAuthorities > 1) {
549
+ throw new TypeError("HTTP transport accepts exactly one credential authority.");
550
+ }
551
+ const credential = input.apiKey ?? input.bearerToken;
552
+ const credentialKind = input.apiKey !== undefined
553
+ ? "api_key"
554
+ : input.bearerToken !== undefined || input.bearerTokenProvider !== undefined
555
+ ? "interactive"
556
+ : "anonymous";
557
+ if (credential !== undefined && !isTransportCredential(credential)) {
558
+ throw new TypeError("HTTP transport credential is invalid.");
559
+ }
560
+ const fetcher = input.fetch ?? globalThis.fetch;
561
+ // Precedence, in one expression so it cannot be spelled differently twice:
562
+ // what the user typed, then what the operation declares it is worth, then the
563
+ // one default.
564
+ const budgetFor = (request) => input.timeoutMs ?? request.budgetMs ?? DEFAULT_REQUEST_BUDGET_MS;
565
+ return Object.freeze({
566
+ async request(request) {
567
+ if (request.signal?.aborted === true) {
568
+ throw new CunaError({
569
+ code: "cuna.network.cancelled",
570
+ message: "The Cuna request was cancelled.",
571
+ exitCode: EXIT_CODES.network,
572
+ hint: "The request was cancelled before dispatch, so nothing was sent.",
573
+ retryable: false,
574
+ cause: request.signal.reason,
575
+ });
576
+ }
577
+ if (!request.path.startsWith("/v1/") || request.path.includes("..") || request.path.includes("?")) {
578
+ throw new CunaError({
579
+ code: "cuna.internal.invalid_api_path",
580
+ message: "Cuna refused an invalid API operation.",
581
+ exitCode: EXIT_CODES.internal,
582
+ hint: INTERNAL_DEFECT_HINT,
583
+ });
584
+ }
585
+ if (request.machineCreateRequestId !== undefined &&
586
+ !UUID.test(request.machineCreateRequestId)) {
587
+ throw new CunaError({
588
+ code: "cuna.internal.invalid_machine_create_request_id",
589
+ message: "Cuna refused an invalid machine-create request identity.",
590
+ exitCode: EXIT_CODES.internal,
591
+ hint: INTERNAL_DEFECT_HINT,
592
+ });
593
+ }
594
+ const target = new URL(request.path, `${input.baseUrl}/`);
595
+ if (target.origin !== input.baseUrl || target.pathname !== request.path) {
596
+ throw new CunaError({
597
+ code: "cuna.internal.invalid_api_origin",
598
+ message: "Cuna refused an invalid API origin.",
599
+ exitCode: EXIT_CODES.internal,
600
+ hint: INTERNAL_DEFECT_HINT,
601
+ });
602
+ }
603
+ for (const [key, value] of Object.entries(request.query ?? {})) {
604
+ if (value !== undefined)
605
+ target.searchParams.set(key, value);
606
+ }
607
+ const budgetMs = budgetFor(request);
608
+ let body;
609
+ let contentType;
610
+ let contentLength;
611
+ if (request.body !== undefined) {
612
+ if (request.body instanceof Uint8Array) {
613
+ if (request.contentType !== "application/octet-stream") {
614
+ throw new CunaError({
615
+ code: "cuna.usage.invalid_body",
616
+ message: "Binary request bodies require application/octet-stream.",
617
+ exitCode: EXIT_CODES.usage,
618
+ hint: INTERNAL_DEFECT_HINT,
619
+ });
620
+ }
621
+ const binary = new Uint8Array(request.body.byteLength);
622
+ binary.set(request.body);
623
+ body = binary.buffer;
624
+ contentType = request.contentType;
625
+ contentLength = request.body.byteLength;
626
+ }
627
+ else {
628
+ if (request.contentType !== undefined &&
629
+ request.contentType !== "application/json; charset=utf-8") {
630
+ throw new CunaError({
631
+ code: "cuna.usage.invalid_body",
632
+ message: "Structured request bodies require JSON content type.",
633
+ exitCode: EXIT_CODES.usage,
634
+ hint: INTERNAL_DEFECT_HINT,
635
+ });
636
+ }
637
+ try {
638
+ body = JSON.stringify(request.body);
639
+ contentType = "application/json; charset=utf-8";
640
+ }
641
+ catch (cause) {
642
+ throw new CunaError({
643
+ code: "cuna.usage.invalid_body",
644
+ message: "The request body cannot be encoded.",
645
+ exitCode: EXIT_CODES.usage,
646
+ hint: INTERNAL_DEFECT_HINT,
647
+ cause,
648
+ });
649
+ }
650
+ }
651
+ }
652
+ else if (request.contentType !== undefined) {
653
+ throw new CunaError({
654
+ code: "cuna.usage.invalid_body",
655
+ message: "A request content type requires a request body.",
656
+ exitCode: EXIT_CODES.usage,
657
+ hint: INTERNAL_DEFECT_HINT,
658
+ });
659
+ }
660
+ const controller = new AbortController();
661
+ let timeout;
662
+ // Dispatches actually started, reported in `details.attempts` so a
663
+ // transport failure says how many connections were tried.
664
+ let attempts = 0;
665
+ const onAbort = () => controller.abort(request.signal?.reason);
666
+ request.signal?.addEventListener("abort", onAbort, { once: true });
667
+ try {
668
+ const requestCredential = input.bearerTokenProvider === undefined
669
+ ? credential
670
+ : await input.bearerTokenProvider(controller.signal);
671
+ if (requestCredential !== undefined &&
672
+ (input.bearerTokenProvider === undefined
673
+ ? !isTransportCredential(requestCredential)
674
+ : !isAccessToken(requestCredential))) {
675
+ throw new CunaError({
676
+ code: "cuna.internal.invalid_transport_credential",
677
+ message: "Cuna refused an invalid HTTP credential authority.",
678
+ exitCode: EXIT_CODES.internal,
679
+ hint: INTERNAL_DEFECT_HINT,
680
+ });
681
+ }
682
+ // The response-observation budget starts at dispatch. Credential
683
+ // acquisition is a distinct local security boundary and may wait for
684
+ // another healthy CLI process to finish a revision-fenced refresh.
685
+ // The caller's AbortSignal remains live throughout both phases.
686
+ timeout = setTimeout(() => controller.abort(new DOMException("Timed out", "TimeoutError")), budgetMs);
687
+ const dispatch = async (bearer) => {
688
+ const response = await fetcher(target, {
689
+ method: request.method,
690
+ headers: {
691
+ Accept: "application/json, application/problem+json",
692
+ ...(bearer === undefined ? {} : { Authorization: `Bearer ${bearer}` }),
693
+ "User-Agent": `cuna-cli/${CLI_VERSION}`,
694
+ ...(contentType === undefined ? {} : { "Content-Type": contentType }),
695
+ ...(contentLength === undefined ? {} : { "Content-Length": String(contentLength) }),
696
+ ...(request.idempotencyKey === undefined ? {} : { "Idempotency-Key": request.idempotencyKey }),
697
+ ...(request.machineCreateRequestId === undefined
698
+ ? {}
699
+ : { "X-Cuna-Machine-Create-Request-Id": request.machineCreateRequestId }),
700
+ },
701
+ ...(body === undefined ? {} : { body }),
702
+ signal: controller.signal,
703
+ redirect: "error",
704
+ });
705
+ const bytes = await readLimited(response);
706
+ if (!response.ok) {
707
+ const decoded = decodeJson(bytes);
708
+ throw apiError({
709
+ status: response.status,
710
+ requestId: response.headers.get("x-request-id") ?? undefined,
711
+ body: decoded.decoded ? decoded.value : undefined,
712
+ apiEncodedBody: decoded.decoded && isObject(decoded.value),
713
+ credentialKind,
714
+ method: request.method,
715
+ path: request.path,
716
+ requestBody: request.body,
717
+ origin: input.baseUrl,
718
+ });
719
+ }
720
+ return parseJson(bytes, request);
721
+ };
722
+ // One immediate retry when the connection was never established. The
723
+ // request was not sent, so this is safe for every method, and the
724
+ // budget is respected without splitting it: both attempts share
725
+ // `controller`, so the one `setTimeout` above bounds their sum, and an
726
+ // attempt that fails after the budget fired is reported as the budget,
727
+ // never retried. Counted so the final error can say how many times.
728
+ const dispatchWithConnectRetry = async (bearer) => {
729
+ attempts += 1;
730
+ try {
731
+ return await dispatch(bearer);
732
+ }
733
+ catch (error) {
734
+ if (error instanceof CunaError || error instanceof CredentialBoundaryError)
735
+ throw error;
736
+ if (controller.signal.aborted)
737
+ throw error;
738
+ // Checked BEFORE the phase classification, deliberately. For an
739
+ // operation that opted out there is no error shape that licenses a
740
+ // second send, so the walk over `cause`/`errors` never runs and
741
+ // cannot decide anything.
742
+ if (request.automaticRedispatch === false)
743
+ throw error;
744
+ if (transportFailurePhase(error) !== "connect")
745
+ throw error;
746
+ attempts += 1;
747
+ return await dispatch(bearer);
748
+ }
749
+ };
750
+ try {
751
+ return await dispatchWithConnectRetry(requestCredential);
752
+ }
753
+ catch (error) {
754
+ const canRetryUnauthorized = error instanceof CunaError &&
755
+ error.code === "cuna.auth.rejected" &&
756
+ input.bearerTokenProvider !== undefined &&
757
+ requestCredential !== undefined &&
758
+ (request.method === "GET" ||
759
+ (request.idempotencyKey !== undefined && isIdempotencyKey(request.idempotencyKey)));
760
+ if (!canRetryUnauthorized)
761
+ throw error;
762
+ const refreshedCredential = await input.bearerTokenProvider(controller.signal, {
763
+ reason: "unauthorized",
764
+ rejectedToken: requestCredential,
765
+ });
766
+ if (!isAccessToken(refreshedCredential)) {
767
+ throw new CunaError({
768
+ code: "cuna.internal.invalid_transport_credential",
769
+ message: "Cuna refused an invalid refreshed HTTP credential authority.",
770
+ exitCode: EXIT_CODES.internal,
771
+ hint: INTERNAL_DEFECT_HINT,
772
+ });
773
+ }
774
+ // Deliberately outside a retry loop: a second 401 is authoritative.
775
+ // The same serialized body and Idempotency-Key are reused verbatim.
776
+ // The connect retry still applies: the first exchange proved the
777
+ // origin reachable, and a fresh connection can still stall.
778
+ return await dispatchWithConnectRetry(refreshedCredential);
779
+ }
780
+ }
781
+ catch (error) {
782
+ if (error instanceof CunaError)
783
+ throw error;
784
+ // Token acquisition is a local credential boundary, not a network
785
+ // dispatch. Preserve its typed failure so the CLI can name the exact
786
+ // authentication repair instead of misreporting connectivity.
787
+ if (error instanceof CredentialBoundaryError)
788
+ throw error;
789
+ if (controller.signal.aborted) {
790
+ // TWO DIFFERENT DETECTORS ARRIVE AT THIS ONE BRANCH, and collapsing
791
+ // them is the defect. The caller pressing Ctrl-C is a decision by a
792
+ // person; this process's own `setTimeout` firing is a decision by
793
+ // this process's configuration. Only the first is `cancelled`.
794
+ //
795
+ // Read through a binding rather than compared inline: the pre-dispatch
796
+ // guard above narrowed `request.signal?.aborted` to `false | undefined`
797
+ // for the rest of the function, and the whole point here is that it may
798
+ // have become `true` in the meantime.
799
+ const cancelledByCaller = request.signal?.aborted ?? false;
800
+ if (cancelledByCaller) {
801
+ throw new CunaError({
802
+ code: "cuna.network.cancelled",
803
+ message: "The Cuna request was cancelled.",
804
+ exitCode: EXIT_CODES.network,
805
+ hint: "No authoritative answer was received, so a mutating request may still have been applied.",
806
+ retryable: false,
807
+ cause: error,
808
+ });
809
+ }
810
+ // Named `cuna.network.timeout` until 2026-08-19, which named the
811
+ // network. The network was fine: `cuna machines create` reported it
812
+ // for a machine that reached `running` five seconds later. What
813
+ // elapsed was this budget.
814
+ throw observationBudgetElapsed({
815
+ kind: "response",
816
+ operation: `${request.method} ${request.path}`,
817
+ budgetMs,
818
+ ...(request.settleWith === undefined ? {} : { settleWith: request.settleWith }),
819
+ details: { method: request.method, path: request.path },
820
+ cause: error,
821
+ });
822
+ }
823
+ throw transportFailure({
824
+ request,
825
+ phase: transportFailurePhase(error),
826
+ attempts,
827
+ cause: error,
828
+ });
829
+ }
830
+ finally {
831
+ if (timeout !== undefined)
832
+ clearTimeout(timeout);
833
+ request.signal?.removeEventListener("abort", onAbort);
834
+ }
835
+ },
836
+ });
837
+ }
838
+ //# sourceMappingURL=http.js.map