@the-open-engine/zeroshot 6.29.0 → 6.30.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 (347) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/cli/index.js +2 -4
  3. package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
  4. package/lib/agent-cli-provider/adapters/codex.js +0 -1
  5. package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
  6. package/lib/agent-cli-provider/contract-actions.d.ts +1 -1
  7. package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
  8. package/lib/agent-cli-provider/contract-actions.js +5 -5
  9. package/lib/agent-cli-provider/contract-actions.js.map +1 -1
  10. package/lib/agent-cli-provider/contract-invoke.d.ts +1 -1
  11. package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -1
  12. package/lib/agent-cli-provider/contract-invoke.js +2 -2
  13. package/lib/agent-cli-provider/contract-invoke.js.map +1 -1
  14. package/lib/agent-cli-provider/contract-support.d.ts +1 -1
  15. package/lib/agent-cli-provider/contract-support.d.ts.map +1 -1
  16. package/lib/agent-cli-provider/contract-support.js +2 -2
  17. package/lib/agent-cli-provider/contract-support.js.map +1 -1
  18. package/lib/agent-cli-provider/contract.d.ts +1 -0
  19. package/lib/agent-cli-provider/contract.d.ts.map +1 -1
  20. package/lib/agent-cli-provider/contract.js +1 -1
  21. package/lib/agent-cli-provider/contract.js.map +1 -1
  22. package/lib/agent-cli-provider/index.d.ts +1 -1
  23. package/lib/agent-cli-provider/index.d.ts.map +1 -1
  24. package/lib/agent-cli-provider/index.js +2 -1
  25. package/lib/agent-cli-provider/index.js.map +1 -1
  26. package/lib/agent-cli-provider/provider-registry.d.ts +1 -0
  27. package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
  28. package/lib/agent-cli-provider/provider-registry.js +4 -0
  29. package/lib/agent-cli-provider/provider-registry.js.map +1 -1
  30. package/lib/agent-cli-provider/single-agent-runtime.d.ts +3 -3
  31. package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
  32. package/lib/agent-cli-provider/single-agent-runtime.js +22 -48
  33. package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
  34. package/lib/cluster/client.cjs +30 -7
  35. package/lib/cluster/client.d.cts +52 -0
  36. package/lib/cluster/client.d.mts +52 -0
  37. package/lib/cluster/client.d.ts +4 -6
  38. package/lib/cluster/client.mjs +32 -9
  39. package/lib/cluster/connection-state.cjs +25 -0
  40. package/lib/cluster/connection-state.d.cts +13 -0
  41. package/lib/cluster/connection-state.d.mts +13 -0
  42. package/lib/cluster/connection-state.d.ts +13 -0
  43. package/lib/cluster/connection-state.mjs +21 -0
  44. package/lib/{target/hosted-run/contracts.js → cluster/connection-types.cjs} +0 -1
  45. package/lib/cluster/connection-types.d.cts +33 -0
  46. package/lib/cluster/connection-types.d.mts +33 -0
  47. package/lib/cluster/connection-types.d.ts +33 -0
  48. package/lib/cluster/connection-types.mjs +1 -0
  49. package/lib/cluster/connection.cjs +18 -46
  50. package/lib/cluster/connection.d.cts +26 -0
  51. package/lib/cluster/connection.d.mts +26 -0
  52. package/lib/cluster/connection.d.ts +7 -25
  53. package/lib/cluster/connection.mjs +12 -42
  54. package/lib/cluster/errors.cjs +9 -1
  55. package/lib/cluster/errors.d.cts +29 -0
  56. package/lib/cluster/errors.d.mts +29 -0
  57. package/lib/cluster/errors.d.ts +4 -0
  58. package/lib/cluster/errors.mjs +7 -0
  59. package/lib/cluster/frames.d.cts +12 -0
  60. package/lib/cluster/frames.d.mts +12 -0
  61. package/lib/cluster/generated/protocol-schema.d.cts +1 -0
  62. package/lib/cluster/generated/protocol-schema.d.mts +1 -0
  63. package/lib/cluster/generated/protocol.d.cts +781 -0
  64. package/lib/cluster/generated/protocol.d.mts +781 -0
  65. package/lib/cluster/index.cjs +2 -2
  66. package/lib/cluster/index.d.cts +13 -0
  67. package/lib/cluster/index.d.mts +13 -0
  68. package/lib/cluster/index.d.ts +3 -3
  69. package/lib/cluster/index.mjs +2 -2
  70. package/lib/cluster/json-source.cjs +1 -0
  71. package/lib/cluster/json-source.d.cts +5 -0
  72. package/lib/cluster/json-source.d.mts +5 -0
  73. package/lib/cluster/json-source.d.ts +1 -0
  74. package/lib/cluster/json-source.mjs +1 -0
  75. package/lib/cluster/payload-value.cjs +1 -0
  76. package/lib/cluster/payload-value.d.cts +8 -0
  77. package/lib/cluster/payload-value.d.mts +8 -0
  78. package/lib/cluster/payload-value.d.ts +1 -0
  79. package/lib/cluster/payload-value.mjs +1 -0
  80. package/lib/cluster/queue.d.cts +15 -0
  81. package/lib/cluster/queue.d.mts +15 -0
  82. package/lib/cluster/socket.cjs +8 -0
  83. package/lib/cluster/socket.d.cts +13 -0
  84. package/lib/cluster/socket.d.mts +13 -0
  85. package/lib/cluster/socket.d.ts +2 -0
  86. package/lib/cluster/socket.mjs +7 -0
  87. package/lib/cluster/subscriptions.d.cts +73 -0
  88. package/lib/cluster/subscriptions.d.mts +73 -0
  89. package/lib/cluster/subscriptions.d.ts +5 -1
  90. package/lib/cluster/validators.cjs +1 -0
  91. package/lib/cluster/validators.d.cts +7 -0
  92. package/lib/cluster/validators.d.mts +7 -0
  93. package/lib/cluster/validators.d.ts +1 -0
  94. package/lib/cluster/validators.mjs +1 -0
  95. package/lib/cluster-worker/engine-adapter-common.js +37 -0
  96. package/lib/cluster-worker/engine-adapter.js +24 -30
  97. package/lib/cluster-worker/engine-start.js +59 -0
  98. package/lib/cluster-worker/index.js +49 -67
  99. package/lib/cluster-worker/profiles.js +1 -42
  100. package/lib/cluster-worker/runtime-dependencies.js +49 -0
  101. package/lib/cluster-worker/runtime-support.js +2 -34
  102. package/lib/cluster-worker/terminal-normalizer.js +9 -10
  103. package/lib/hosted-session/authority.cjs +61 -0
  104. package/lib/hosted-session/authority.d.cts +3 -0
  105. package/lib/hosted-session/authority.d.mts +3 -0
  106. package/lib/hosted-session/authority.d.ts +3 -0
  107. package/lib/hosted-session/authority.mjs +57 -0
  108. package/lib/hosted-session/coordinator.cjs +78 -51
  109. package/lib/hosted-session/coordinator.d.cts +11 -0
  110. package/lib/hosted-session/coordinator.d.mts +11 -0
  111. package/lib/hosted-session/coordinator.d.ts +4 -2
  112. package/lib/hosted-session/coordinator.mjs +75 -51
  113. package/lib/hosted-session/errors.cjs +25 -0
  114. package/lib/hosted-session/errors.d.cts +10 -0
  115. package/lib/hosted-session/errors.d.mts +10 -0
  116. package/lib/hosted-session/errors.d.ts +10 -0
  117. package/lib/hosted-session/errors.mjs +19 -0
  118. package/lib/hosted-session/index.cjs +4 -1
  119. package/lib/hosted-session/index.d.cts +2 -0
  120. package/lib/hosted-session/index.d.mts +2 -0
  121. package/lib/hosted-session/index.d.ts +2 -2
  122. package/lib/hosted-session/index.mjs +1 -1
  123. package/lib/hosted-session/reconnecting-watch.cjs +131 -0
  124. package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
  125. package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
  126. package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
  127. package/lib/hosted-session/reconnecting-watch.mjs +127 -0
  128. package/lib/hosted-session/types.d.cts +32 -0
  129. package/lib/hosted-session/types.d.mts +32 -0
  130. package/lib/hosted-session/types.d.ts +19 -7
  131. package/lib/hosted-target/access-url.cjs +44 -0
  132. package/lib/hosted-target/access-url.d.cts +2 -0
  133. package/lib/hosted-target/access-url.d.mts +2 -0
  134. package/lib/hosted-target/access-url.d.ts +2 -0
  135. package/lib/hosted-target/access-url.mjs +41 -0
  136. package/lib/hosted-target/adapter-request.cjs +12 -0
  137. package/lib/hosted-target/adapter-request.d.cts +17 -0
  138. package/lib/hosted-target/adapter-request.d.mts +17 -0
  139. package/lib/hosted-target/adapter-request.d.ts +17 -0
  140. package/lib/hosted-target/adapter-request.mjs +9 -0
  141. package/lib/hosted-target/adapter-types.cjs +2 -0
  142. package/lib/hosted-target/adapter-types.d.cts +27 -0
  143. package/lib/hosted-target/adapter-types.d.mts +27 -0
  144. package/lib/hosted-target/adapter-types.d.ts +27 -0
  145. package/lib/hosted-target/adapter-types.mjs +1 -0
  146. package/lib/hosted-target/bounds.cjs +10 -0
  147. package/lib/hosted-target/bounds.d.cts +7 -0
  148. package/lib/hosted-target/bounds.d.mts +7 -0
  149. package/lib/hosted-target/bounds.d.ts +7 -0
  150. package/lib/hosted-target/bounds.mjs +7 -0
  151. package/lib/hosted-target/capsule-error-response.cjs +76 -0
  152. package/lib/hosted-target/capsule-error-response.d.cts +2 -0
  153. package/lib/hosted-target/capsule-error-response.d.mts +2 -0
  154. package/lib/hosted-target/capsule-error-response.d.ts +2 -0
  155. package/lib/hosted-target/capsule-error-response.mjs +73 -0
  156. package/lib/hosted-target/errors.cjs +88 -0
  157. package/lib/hosted-target/errors.d.cts +36 -0
  158. package/lib/hosted-target/errors.d.mts +36 -0
  159. package/lib/hosted-target/errors.d.ts +36 -0
  160. package/lib/hosted-target/errors.mjs +75 -0
  161. package/lib/hosted-target/index.cjs +16 -0
  162. package/lib/hosted-target/index.d.cts +3 -0
  163. package/lib/hosted-target/index.d.mts +3 -0
  164. package/lib/hosted-target/index.d.ts +3 -0
  165. package/lib/hosted-target/index.mjs +2 -0
  166. package/lib/hosted-target/response-validation.cjs +169 -0
  167. package/lib/hosted-target/response-validation.d.cts +5 -0
  168. package/lib/hosted-target/response-validation.d.mts +5 -0
  169. package/lib/hosted-target/response-validation.d.ts +5 -0
  170. package/lib/hosted-target/response-validation.mjs +163 -0
  171. package/lib/hosted-target/retry-executor.cjs +51 -0
  172. package/lib/hosted-target/retry-executor.d.cts +8 -0
  173. package/lib/hosted-target/retry-executor.d.mts +8 -0
  174. package/lib/hosted-target/retry-executor.d.ts +8 -0
  175. package/lib/hosted-target/retry-executor.mjs +48 -0
  176. package/lib/hosted-target/retry.cjs +78 -0
  177. package/lib/hosted-target/retry.d.cts +9 -0
  178. package/lib/hosted-target/retry.d.mts +9 -0
  179. package/lib/hosted-target/retry.d.ts +9 -0
  180. package/lib/hosted-target/retry.mjs +73 -0
  181. package/lib/hosted-target/target-adapter.cjs +10 -0
  182. package/lib/hosted-target/target-adapter.d.cts +3 -0
  183. package/lib/hosted-target/target-adapter.d.mts +3 -0
  184. package/lib/hosted-target/target-adapter.d.ts +3 -0
  185. package/lib/hosted-target/target-adapter.mjs +7 -0
  186. package/lib/hosted-target/types.cjs +4 -0
  187. package/lib/hosted-target/types.d.cts +50 -0
  188. package/lib/hosted-target/types.d.mts +50 -0
  189. package/lib/hosted-target/types.d.ts +50 -0
  190. package/lib/hosted-target/types.mjs +1 -0
  191. package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
  192. package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
  193. package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
  194. package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
  195. package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
  196. package/lib/start-cluster.js +3 -3
  197. package/lib/target/bounded-response.cjs +51 -0
  198. package/lib/target/bounded-response.d.cts +1 -0
  199. package/lib/target/bounded-response.d.mts +1 -0
  200. package/lib/target/bounded-response.d.ts +1 -0
  201. package/lib/target/bounded-response.js +51 -0
  202. package/lib/target/bounded-response.mjs +48 -0
  203. package/lib/target/credential-lock.js +1 -3
  204. package/lib/target/credential-store.js +9 -4
  205. package/lib/target/device-flow.cjs +213 -0
  206. package/lib/target/device-flow.d.cts +54 -0
  207. package/lib/target/device-flow.d.mts +54 -0
  208. package/lib/target/device-flow.d.ts +26 -14
  209. package/lib/target/device-flow.js +162 -58
  210. package/lib/target/device-flow.mjs +203 -0
  211. package/lib/target/discovery-errors.cjs +10 -0
  212. package/lib/target/discovery-errors.d.cts +3 -0
  213. package/lib/target/discovery-errors.d.mts +3 -0
  214. package/lib/target/discovery-errors.d.ts +3 -0
  215. package/lib/target/discovery-errors.js +10 -0
  216. package/lib/target/discovery-errors.mjs +6 -0
  217. package/lib/target/discovery-sections.cjs +191 -0
  218. package/lib/target/discovery-sections.d.cts +52 -0
  219. package/lib/target/discovery-sections.d.mts +52 -0
  220. package/lib/target/discovery-sections.d.ts +52 -0
  221. package/lib/target/discovery-sections.js +191 -0
  222. package/lib/target/discovery-sections.mjs +179 -0
  223. package/lib/target/discovery-validation.cjs +109 -0
  224. package/lib/target/discovery-validation.d.cts +28 -0
  225. package/lib/target/discovery-validation.d.mts +28 -0
  226. package/lib/target/discovery-validation.d.ts +28 -0
  227. package/lib/target/discovery-validation.js +109 -0
  228. package/lib/target/discovery-validation.mjs +99 -0
  229. package/lib/target/discovery.cjs +112 -0
  230. package/lib/target/discovery.d.cts +74 -0
  231. package/lib/target/discovery.d.mts +74 -0
  232. package/lib/target/discovery.d.ts +67 -5
  233. package/lib/target/discovery.js +94 -79
  234. package/lib/target/discovery.mjs +105 -0
  235. package/lib/target/index.d.ts +6 -6
  236. package/lib/target/index.js +36 -36
  237. package/lib/target/oauth-http.d.ts +2 -0
  238. package/lib/target/oauth-http.js +25 -0
  239. package/lib/target/refresh-exchange.d.ts +11 -0
  240. package/lib/target/refresh-exchange.js +24 -0
  241. package/lib/target/refresh-revocation.d.ts +8 -0
  242. package/lib/target/refresh-revocation.js +19 -0
  243. package/lib/target/route-template.cjs +85 -0
  244. package/lib/target/route-template.d.cts +7 -0
  245. package/lib/target/route-template.d.mts +7 -0
  246. package/lib/target/route-template.d.ts +7 -0
  247. package/lib/target/route-template.js +85 -0
  248. package/lib/target/route-template.mjs +81 -0
  249. package/lib/target/session-errors.d.ts +4 -0
  250. package/lib/target/session-errors.js +12 -0
  251. package/lib/target/session-verification.d.ts +10 -0
  252. package/lib/target/session-verification.js +42 -0
  253. package/lib/target/target-registry.d.ts +7 -3
  254. package/lib/target/target-registry.js +41 -10
  255. package/lib/target/target-session-manager.d.ts +48 -0
  256. package/lib/target/target-session-manager.js +226 -0
  257. package/lib/target/target-session.d.ts +39 -32
  258. package/lib/target/target-session.js +63 -151
  259. package/lib/target/token-response.cjs +51 -0
  260. package/lib/target/token-response.d.cts +7 -0
  261. package/lib/target/token-response.d.mts +7 -0
  262. package/lib/target/token-response.d.ts +7 -0
  263. package/lib/target/token-response.js +51 -0
  264. package/lib/target/token-response.mjs +48 -0
  265. package/package.json +14 -7
  266. package/protocol/openengine-cluster/v1/worker.schema.json +171 -9
  267. package/scripts/build-cluster.js +23 -3
  268. package/scripts/opcore-introduced-check.js +0 -2
  269. package/src/agent-cli-provider/adapters/codex.ts +0 -1
  270. package/src/agent-cli-provider/contract-actions.ts +9 -5
  271. package/src/agent-cli-provider/contract-invoke.ts +3 -2
  272. package/src/agent-cli-provider/contract-support.ts +12 -6
  273. package/src/agent-cli-provider/contract.ts +6 -1
  274. package/src/agent-cli-provider/index.ts +1 -0
  275. package/src/agent-cli-provider/provider-registry.ts +4 -0
  276. package/src/agent-cli-provider/single-agent-runtime.ts +32 -45
  277. package/src/cluster/client.ts +42 -15
  278. package/src/cluster/connection-state.ts +33 -0
  279. package/src/cluster/connection-types.ts +28 -0
  280. package/src/cluster/connection.ts +37 -68
  281. package/src/cluster/errors.ts +5 -0
  282. package/src/cluster/index.ts +3 -1
  283. package/src/cluster/json-source.ts +1 -0
  284. package/src/cluster/payload-value.ts +1 -0
  285. package/src/cluster/socket.ts +13 -0
  286. package/src/cluster/subscriptions.ts +7 -2
  287. package/src/cluster/validators.ts +1 -0
  288. package/src/cluster/ws.d.ts +1 -1
  289. package/src/hosted-session/authority.ts +77 -0
  290. package/src/hosted-session/coordinator.ts +113 -56
  291. package/src/hosted-session/errors.ts +21 -0
  292. package/src/hosted-session/index.ts +14 -2
  293. package/src/hosted-session/reconnecting-watch.ts +148 -0
  294. package/src/hosted-session/types.ts +22 -8
  295. package/src/hosted-target/access-url.ts +46 -0
  296. package/src/hosted-target/adapter-request.ts +28 -0
  297. package/src/hosted-target/adapter-types.ts +39 -0
  298. package/src/hosted-target/bounds.ts +1 -0
  299. package/src/hosted-target/capsule-error-response.ts +107 -0
  300. package/src/hosted-target/errors.ts +36 -35
  301. package/src/hosted-target/index.ts +10 -23
  302. package/src/hosted-target/response-validation.ts +170 -62
  303. package/src/hosted-target/retry-executor.ts +62 -0
  304. package/src/hosted-target/retry.ts +47 -11
  305. package/src/hosted-target/target-adapter.ts +12 -8
  306. package/src/hosted-target/types.ts +19 -18
  307. package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
  308. package/src/isolation-manager.js +1 -16
  309. package/src/target/bounded-response.ts +68 -0
  310. package/src/target/credential-lock.ts +1 -3
  311. package/src/target/credential-store.ts +14 -10
  312. package/src/target/device-flow.ts +209 -85
  313. package/src/target/discovery-errors.ts +6 -0
  314. package/src/target/discovery-sections.ts +251 -0
  315. package/src/target/discovery-validation.ts +144 -0
  316. package/src/target/discovery.ts +163 -97
  317. package/src/target/index.ts +15 -11
  318. package/src/target/oauth-http.ts +27 -0
  319. package/src/target/refresh-exchange.ts +36 -0
  320. package/src/target/refresh-revocation.ts +29 -0
  321. package/src/target/route-template.ts +105 -0
  322. package/src/target/session-errors.ts +9 -0
  323. package/src/target/session-verification.ts +51 -0
  324. package/src/target/target-registry.ts +60 -27
  325. package/src/target/target-session-manager.ts +285 -0
  326. package/src/target/target-session.ts +105 -226
  327. package/src/target/token-response.ts +62 -0
  328. package/docker/zeroshot-oecp/Cargo.toml +0 -12
  329. package/docker/zeroshot-oecp/Dockerfile +0 -65
  330. package/docker/zeroshot-oecp/src/main.rs +0 -32
  331. package/lib/target/bounded-json.d.ts +0 -6
  332. package/lib/target/bounded-json.js +0 -43
  333. package/lib/target/hosted-run/client.d.ts +0 -26
  334. package/lib/target/hosted-run/client.js +0 -158
  335. package/lib/target/hosted-run/commands.d.ts +0 -4
  336. package/lib/target/hosted-run/commands.js +0 -113
  337. package/lib/target/hosted-run/contracts.d.ts +0 -49
  338. package/lib/target/hosted-run/input.d.ts +0 -5
  339. package/lib/target/hosted-run/input.js +0 -200
  340. package/lib/target/hosted-run.d.ts +0 -4
  341. package/lib/target/hosted-run.js +0 -12
  342. package/src/target/bounded-json.ts +0 -48
  343. package/src/target/hosted-run/client.ts +0 -198
  344. package/src/target/hosted-run/commands.ts +0 -140
  345. package/src/target/hosted-run/contracts.ts +0 -53
  346. package/src/target/hosted-run/input.ts +0 -199
  347. package/src/target/hosted-run.ts +0 -8
@@ -1,253 +1,132 @@
1
- import type { TargetCredentialStore } from './credential-store.ts';
2
- import type { TargetRecord, SettingsPort } from './target-registry.ts';
1
+ import type { TargetCredentialStore } from './credential-store.js';
2
+ import type { Clock } from './device-flow.js';
3
3
  import {
4
- requestDeviceCode,
5
- pollForToken,
6
- UnboundSessionError,
7
- type HttpTransport,
8
- type Clock,
9
- type TokenResponse,
10
- } from './device-flow.ts';
11
- import { targetServiceKey, TARGET_ACCOUNT } from './credential-store.ts';
12
- import { updateTargetOrganization } from './target-registry.ts';
4
+ TargetSessionManager,
5
+ type TargetSessionDeps,
6
+ } from './target-session-manager.js';
7
+ import type { SettingsPort, TargetRecord } from './target-registry.js';
8
+
9
+ export {
10
+ LoginRequiredError,
11
+ TargetSessionManager,
12
+ type BrowserOpener,
13
+ type TargetSessionDeps,
14
+ type TargetSessionManagerInit,
15
+ } from './target-session-manager.js';
13
16
 
14
- export class LoginRequiredError extends Error {
15
- readonly targetName: string;
16
- constructor(targetName: string) {
17
- super(`Login required. Run: zeroshot target login ${targetName}`);
18
- this.name = 'LoginRequiredError';
19
- this.targetName = targetName;
20
- }
21
- }
22
-
23
- export interface BrowserOpener {
24
- open(url: string): Promise<void>;
17
+ export interface TargetAccessTokenProvider {
18
+ getAccessToken(signal?: AbortSignal): Promise<string>;
25
19
  }
26
20
 
27
- export interface TargetSessionDeps {
28
- readonly http: HttpTransport;
29
- readonly clock: Clock;
30
- readonly browserOpener: BrowserOpener;
31
- readonly stderr: { write(s: string): void };
32
- readonly discoveryEndpoints: {
33
- readonly deviceAuthorizationEndpoint: string;
34
- readonly tokenEndpoint: string;
35
- readonly revocationEndpoint?: string;
36
- readonly clientId: string;
37
- readonly capsuleApiBaseUrl: string;
38
- };
39
- }
21
+ type LegacySessionDeps = Pick<TargetSessionDeps, 'http' | 'discoveryEndpoints'> & {
22
+ readonly settings?: SettingsPort;
23
+ readonly targetName?: string;
24
+ readonly clock?: Clock;
25
+ };
40
26
 
41
- export async function targetLogin(
27
+ type TargetLoginArgs = readonly [
42
28
  targetName: string,
43
29
  target: TargetRecord,
44
30
  credentialStore: TargetCredentialStore,
45
31
  acquireLock: () => Promise<() => Promise<void>>,
46
32
  settings: SettingsPort,
47
- deps: TargetSessionDeps
48
- ): Promise<{ organization: { id: string; name: string } }> {
49
- const { http, clock, browserOpener, stderr, discoveryEndpoints } = deps;
50
- const { deviceAuthorizationEndpoint, tokenEndpoint, clientId } = discoveryEndpoints;
51
-
52
- const codeResponse = await requestDeviceCode(deviceAuthorizationEndpoint, clientId, http);
53
-
54
- stderr.write(
55
- `\nOpen this URL to authorize:\n ${codeResponse.verification_uri}\n\nEnter code: ${codeResponse.user_code}\n\n`
56
- );
57
-
58
- if (codeResponse.verification_uri_complete) {
59
- try {
60
- await browserOpener.open(codeResponse.verification_uri_complete);
61
- } catch {
62
- // Browser open is best-effort
63
- }
64
- }
65
-
66
- const tokenResponse = await pollForToken(
67
- tokenEndpoint,
68
- clientId,
69
- codeResponse.device_code,
70
- codeResponse.interval,
71
- codeResponse.expires_in,
72
- http,
73
- clock,
74
- undefined,
75
- { token: target.deviceToken, label: 'Zeroshot CLI' }
76
- );
77
-
78
- if (!tokenResponse.organization) {
79
- throw new UnboundSessionError(codeResponse.verification_uri);
80
- }
33
+ deps: TargetSessionDeps,
34
+ ];
81
35
 
82
- const serviceKey = targetServiceKey(target.id);
83
- const release = await acquireLock();
84
- try {
85
- await credentialStore.set(serviceKey, TARGET_ACCOUNT, tokenResponse.refresh_token);
86
- } finally {
87
- await release();
88
- }
89
-
90
- updateTargetOrganization(targetName, tokenResponse.organization, settings);
91
-
92
- return { organization: tokenResponse.organization };
93
- }
94
-
95
- export async function refreshAccessToken(
36
+ type RefreshAccessArgs = readonly [
96
37
  targetName: string,
97
38
  target: TargetRecord,
98
39
  credentialStore: TargetCredentialStore,
99
40
  acquireLock: () => Promise<() => Promise<void>>,
100
- deps: Pick<TargetSessionDeps, 'http' | 'discoveryEndpoints'>
101
- ): Promise<{ accessToken: string; expiresIn: number }> {
102
- const { http, discoveryEndpoints } = deps;
103
- const { tokenEndpoint, revocationEndpoint, clientId } = discoveryEndpoints;
104
- const serviceKey = targetServiceKey(target.id);
41
+ deps: LegacySessionDeps,
42
+ clock?: Clock,
43
+ ];
105
44
 
106
- const release = await acquireLock();
107
- try {
108
- const currentRefreshToken = await credentialStore.get(serviceKey, TARGET_ACCOUNT);
109
- if (!currentRefreshToken) {
110
- throw new LoginRequiredError(targetName);
111
- }
112
-
113
- const body = new URLSearchParams({
114
- grant_type: 'refresh_token',
115
- refresh_token: currentRefreshToken,
116
- client_id: clientId,
117
- audience: 'capsule',
118
- });
119
-
120
- let tokenResponse: TokenResponse;
121
- const response = await http.fetch(tokenEndpoint, {
122
- method: 'POST',
123
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
124
- body: body.toString(),
125
- redirect: 'error',
126
- });
127
-
128
- if (!response.ok) {
129
- const errorBody = (await response.json().catch(() => ({ error: 'unknown' }))) as {
130
- error: string;
131
- };
132
- if (errorBody.error === 'invalid_grant') {
133
- await credentialStore.delete(serviceKey, TARGET_ACCOUNT);
134
- throw new LoginRequiredError(targetName);
135
- }
136
- throw new Error(`Token refresh failed (${response.status}): ${errorBody.error}`);
137
- }
138
-
139
- tokenResponse = (await response.json()) as TokenResponse;
140
-
141
- try {
142
- await credentialStore.set(serviceKey, TARGET_ACCOUNT, tokenResponse.refresh_token);
143
- } catch {
144
- await bestEffortRevoke(tokenResponse.refresh_token, revocationEndpoint, clientId, http);
145
- await credentialStore.delete(serviceKey, TARGET_ACCOUNT);
146
- throw new LoginRequiredError(targetName);
147
- }
45
+ type RevokeArgs = readonly [
46
+ target: TargetRecord,
47
+ credentialStore: TargetCredentialStore,
48
+ acquireLock: () => Promise<() => Promise<void>>,
49
+ deps: LegacySessionDeps,
50
+ force: boolean,
51
+ ];
148
52
 
149
- return { accessToken: tokenResponse.access_token, expiresIn: tokenResponse.expires_in };
150
- } finally {
151
- await release();
152
- }
53
+ type LegacyManagerInit = {
54
+ readonly targetName: string;
55
+ readonly target: TargetRecord;
56
+ readonly credentialStore: TargetCredentialStore;
57
+ readonly acquireLock: () => Promise<() => Promise<void>>;
58
+ readonly deps: LegacySessionDeps;
59
+ readonly clock?: Clock;
60
+ };
61
+
62
+ function transientSettings(targetName: string, target: TargetRecord): SettingsPort {
63
+ const state: { _targets: Record<string, TargetRecord> } = {
64
+ _targets: { [targetName]: target },
65
+ };
66
+ return {
67
+ load: () => state,
68
+ mutate: (mutator) => mutator(state),
69
+ };
153
70
  }
154
71
 
155
- async function bestEffortRevoke(
156
- token: string,
157
- revocationEndpoint: string | undefined,
158
- clientId: string,
159
- http: HttpTransport
160
- ): Promise<void> {
161
- if (!revocationEndpoint) return;
162
- try {
163
- const body = new URLSearchParams({
164
- token,
165
- client_id: clientId,
166
- token_type_hint: 'refresh_token',
167
- });
168
- await http.fetch(revocationEndpoint, {
169
- method: 'POST',
170
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
171
- body: body.toString(),
172
- redirect: 'error',
173
- });
174
- } catch {
175
- // Best-effort
176
- }
72
+ function legacyManager(init: LegacyManagerInit): TargetSessionManager {
73
+ const clock = init.clock ?? init.deps.clock ?? { now: () => Date.now() };
74
+ return new TargetSessionManager({
75
+ targetName: init.targetName,
76
+ target: init.target,
77
+ credentialStore: init.credentialStore,
78
+ acquireLock: init.acquireLock,
79
+ settings: init.deps.settings ?? transientSettings(init.targetName, init.target),
80
+ deps: {
81
+ http: init.deps.http,
82
+ clock,
83
+ browserOpener: { open: () => Promise.resolve() },
84
+ stderr: { write: () => undefined },
85
+ discoveryEndpoints: init.deps.discoveryEndpoints,
86
+ },
87
+ });
177
88
  }
178
89
 
179
- export interface TargetAccessTokenProvider {
180
- getAccessToken(signal?: AbortSignal): Promise<string>;
90
+ export function targetLogin(...args: TargetLoginArgs): Promise<{ organization: { id: string } }> {
91
+ const [targetName, target, credentialStore, acquireLock, settings, deps] = args;
92
+ return new TargetSessionManager({
93
+ targetName,
94
+ target,
95
+ credentialStore,
96
+ acquireLock,
97
+ settings,
98
+ deps,
99
+ }).login();
181
100
  }
182
101
 
183
- export function getAccessTokenProvider(
184
- targetName: string,
185
- target: TargetRecord,
186
- credentialStore: TargetCredentialStore,
187
- acquireLock: () => Promise<() => Promise<void>>,
188
- deps: Pick<TargetSessionDeps, 'http' | 'discoveryEndpoints'>,
189
- clock: Clock = { now: () => Date.now() }
190
- ): TargetAccessTokenProvider {
191
- let cachedToken: string | null = null;
192
- let expiresAt = 0;
193
-
194
- return {
195
- async getAccessToken(_signal?: AbortSignal): Promise<string> {
196
- if (cachedToken && clock.now() < expiresAt - 30_000) {
197
- return cachedToken;
198
- }
199
- const result = await refreshAccessToken(
200
- targetName,
201
- target,
202
- credentialStore,
203
- acquireLock,
204
- deps
205
- );
206
- cachedToken = result.accessToken;
207
- expiresAt = clock.now() + result.expiresIn * 1000;
208
- return result.accessToken;
209
- },
210
- };
102
+ export async function refreshAccessToken(
103
+ ...args: RefreshAccessArgs
104
+ ): Promise<{ accessToken: string; expiresIn: number }> {
105
+ const [targetName, target, credentialStore, acquireLock, deps, clock] = args;
106
+ return legacyManager({
107
+ targetName,
108
+ target,
109
+ credentialStore,
110
+ acquireLock,
111
+ deps,
112
+ ...(clock === undefined ? {} : { clock }),
113
+ }).getAccessTokenWithLifetime('capsule');
211
114
  }
212
115
 
213
- export async function revokeAndCleanup(
214
- target: TargetRecord,
215
- credentialStore: TargetCredentialStore,
216
- acquireLock: () => Promise<() => Promise<void>>,
217
- deps: Pick<TargetSessionDeps, 'http' | 'discoveryEndpoints'>,
218
- force: boolean
219
- ): Promise<void> {
220
- const { http, discoveryEndpoints } = deps;
221
- const { revocationEndpoint, clientId } = discoveryEndpoints;
222
- const serviceKey = targetServiceKey(target.id);
116
+ export function getAccessTokenProvider(...args: RefreshAccessArgs): TargetAccessTokenProvider {
117
+ const [targetName, target, credentialStore, acquireLock, deps, clock] = args;
118
+ return legacyManager({
119
+ targetName,
120
+ target,
121
+ credentialStore,
122
+ acquireLock,
123
+ deps,
124
+ ...(clock === undefined ? {} : { clock }),
125
+ }).tokenProvider('capsule');
126
+ }
223
127
 
224
- const release = await acquireLock();
225
- try {
226
- const refreshToken = await credentialStore.get(serviceKey, TARGET_ACCOUNT);
227
- if (refreshToken && revocationEndpoint) {
228
- const body = new URLSearchParams({
229
- token: refreshToken,
230
- client_id: clientId,
231
- token_type_hint: 'refresh_token',
232
- });
233
- try {
234
- const response = await http.fetch(revocationEndpoint, {
235
- method: 'POST',
236
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
237
- body: body.toString(),
238
- redirect: 'error',
239
- });
240
- if (!response.ok && !force) {
241
- throw new Error(
242
- `Remote revocation failed (${response.status}). Use --force to remove anyway.`
243
- );
244
- }
245
- } catch (err) {
246
- if (!force) throw err;
247
- }
248
- }
249
- await credentialStore.delete(serviceKey, TARGET_ACCOUNT);
250
- } finally {
251
- await release();
252
- }
128
+ export function revokeAndCleanup(...args: RevokeArgs): Promise<void> {
129
+ const [target, credentialStore, acquireLock, deps, force] = args;
130
+ const targetName = deps.targetName ?? target.id;
131
+ return legacyManager({ targetName, target, credentialStore, acquireLock, deps }).revoke(force);
253
132
  }
@@ -0,0 +1,62 @@
1
+ const MAX_TOKEN_BYTES = 16 * 1024;
2
+ const TOKEN_RESPONSE_FIELDS = [
3
+ 'access_token',
4
+ 'refresh_token',
5
+ 'token_type',
6
+ 'expires_in',
7
+ 'refresh_expires_in',
8
+ 'scope',
9
+ ] as const;
10
+
11
+ export interface TokenResponse {
12
+ readonly access_token: string;
13
+ readonly refresh_token: string;
14
+ readonly token_type: 'Bearer';
15
+ readonly expires_in: number;
16
+ }
17
+
18
+ function boundedString(value: unknown, maxBytes: number): value is string {
19
+ return typeof value === 'string' && value.length > 0 &&
20
+ new TextEncoder().encode(value).byteLength <= maxBytes;
21
+ }
22
+
23
+ function tokenFieldsValid(token: Record<string, unknown>): boolean {
24
+ const fields = Object.keys(token);
25
+ return fields.length === TOKEN_RESPONSE_FIELDS.length &&
26
+ fields.every((key) => TOKEN_RESPONSE_FIELDS.includes(
27
+ key as (typeof TOKEN_RESPONSE_FIELDS)[number],
28
+ ));
29
+ }
30
+
31
+ function tokenLifetimesValid(token: Record<string, unknown>): boolean {
32
+ return Number.isSafeInteger(token.expires_in) &&
33
+ (token.expires_in as number) > 0 &&
34
+ (token.expires_in as number) <= 86_400 &&
35
+ Number.isSafeInteger(token.refresh_expires_in) &&
36
+ (token.refresh_expires_in as number) > 0 &&
37
+ (token.refresh_expires_in as number) <= 31_536_000;
38
+ }
39
+
40
+ function tokenStringsValid(token: Record<string, unknown>): boolean {
41
+ return boundedString(token.access_token, MAX_TOKEN_BYTES) &&
42
+ boundedString(token.refresh_token, MAX_TOKEN_BYTES) &&
43
+ token.token_type === 'Bearer' &&
44
+ boundedString(token.scope, 512) &&
45
+ !/[\u0000-\u001f\u007f]/.test(token.scope);
46
+ }
47
+
48
+ export function parseTokenResponse(value: unknown): TokenResponse {
49
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
50
+ throw new Error('Token response is malformed');
51
+ }
52
+ const token = value as Record<string, unknown>;
53
+ if (!tokenFieldsValid(token) || !tokenLifetimesValid(token) || !tokenStringsValid(token)) {
54
+ throw new Error('Token response is malformed');
55
+ }
56
+ return Object.freeze({
57
+ access_token: token.access_token,
58
+ refresh_token: token.refresh_token,
59
+ token_type: 'Bearer',
60
+ expires_in: token.expires_in,
61
+ }) as TokenResponse;
62
+ }
@@ -1,12 +0,0 @@
1
- [package]
2
- name = "zeroshot-oecp-server"
3
- version = "0.1.0"
4
- edition.workspace = true
5
- rust-version.workspace = true
6
- license.workspace = true
7
- repository.workspace = true
8
- publish = false
9
-
10
- [dependencies]
11
- tokio.workspace = true
12
- zeroshot-engine = { package = "zeroshot-rust", path = "../../zeroshot-rust" }
@@ -1,65 +0,0 @@
1
- # syntax=docker/dockerfile:1
2
-
3
- # The server and the existing Node worker ship together because OECP is the
4
- # in-capsule process boundary. Capsule allocation and termination remain owned
5
- # by Zero Cloud's control plane and capsule agent.
6
- FROM rust@sha256:14b9b5f47dcc6644d0f0c1b35a2c2c5d0124f67159aaee28a348627523459b55 AS rust-builder
7
- # Security package revisions intentionally follow the pinned Alpine release repositories.
8
- # hadolint ignore=DL3018
9
- RUN apk add --no-cache musl-dev
10
- WORKDIR /build
11
- COPY Cargo.toml Cargo.lock rust-toolchain.toml ./
12
- COPY crates ./crates
13
- COPY zeroshot-rust ./zeroshot-rust
14
- COPY docker/zeroshot-oecp ./docker/zeroshot-oecp
15
- # musl does not expose renameat2 through libc, although the Linux syscall is
16
- # available. Keep the portable source API on glibc and use the syscall binding
17
- # only for this musl image build.
18
- RUN sed -i 's/libc::renameat2(/libc::syscall(libc::SYS_renameat2,/' \
19
- zeroshot-rust/src/workspace_lease/types.rs \
20
- && grep -Fq 'libc::syscall(libc::SYS_renameat2,' \
21
- zeroshot-rust/src/workspace_lease/types.rs
22
- RUN rustup component add --toolchain 1.97.0 rustfmt clippy \
23
- && cargo +1.97.0 build --locked --release -p zeroshot-oecp-server \
24
- && rustup default 1.97.0 \
25
- && rustup toolchain uninstall 1.96.0 1.96.1
26
-
27
- FROM node@sha256:c2cc26d8f991c2db236ad51a61efee843c482372d6d22570787309d511694110 AS node-builder
28
- ARG CODEX_VERSION=0.146.0
29
- # Security package revisions intentionally follow the pinned Alpine release repositories.
30
- # hadolint ignore=DL3018
31
- RUN apk add --no-cache build-base python3
32
- WORKDIR /opt/zeroshot
33
- COPY package.json package-lock.json ./
34
- RUN npm ci --omit=dev --ignore-scripts --no-audit --no-fund \
35
- && npm rebuild better-sqlite3 node-pty \
36
- && npm install --global --no-audit --no-fund "@openai/codex@${CODEX_VERSION}"
37
- COPY . .
38
-
39
- FROM node@sha256:c2cc26d8f991c2db236ad51a61efee843c482372d6d22570787309d511694110 AS runtime
40
- ARG ZEROSHOT_MIN_DISK_GB=10
41
- ENV ZEROSHOT_MIN_DISK_GB=${ZEROSHOT_MIN_DISK_GB}
42
- # Security package revisions intentionally follow the pinned Alpine release repositories.
43
- # hadolint ignore=DL3018
44
- RUN apk add --no-cache bash build-base ca-certificates git github-cli openssl python3 tini \
45
- && install -d -m 1777 /tmp \
46
- && install -d -m 0750 -o node -g node /workspace
47
- COPY --from=node-builder --chown=node:node /opt/zeroshot /opt/zeroshot
48
- COPY --from=node-builder /usr/local/lib/node_modules/@openai /usr/local/lib/node_modules/@openai
49
- COPY --from=rust-builder --chown=node:node /usr/local/cargo/bin /usr/local/cargo/bin
50
- COPY --from=rust-builder --chown=node:node /usr/local/rustup /usr/local/rustup
51
- COPY --from=rust-builder /build/target/release/zeroshot-oecp-server /usr/local/bin/zeroshot-oecp-server
52
- RUN ln -s /opt/zeroshot/bin/zeroshot-cluster-worker.js /usr/local/bin/zeroshot-cluster-worker \
53
- && ln -s /opt/zeroshot/cli/index.js /usr/local/bin/zeroshot \
54
- && ln -s /usr/local/lib/node_modules/@openai/codex/bin/codex.js /usr/local/bin/codex \
55
- && for command in cargo cargo-clippy cargo-fmt clippy-driver rustc rustdoc rustfmt rustup; do \
56
- ln -s "/usr/local/cargo/bin/${command}" "/usr/local/bin/${command}"; \
57
- done
58
- ENV RUSTUP_HOME=/usr/local/rustup
59
- ENV PATH=/usr/local/cargo/bin:${PATH}
60
- # The official Node image defines this stable application user.
61
- # hadolint ignore=DL3066
62
- USER node
63
- WORKDIR /workspace
64
- EXPOSE 8083 8084
65
- ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/zeroshot-oecp-server"]
@@ -1,32 +0,0 @@
1
- use std::{error::Error, net::SocketAddr, sync::Arc};
2
-
3
- use tokio::net::TcpListener;
4
- use zeroshot_engine::hosted_oecp::{serve, HostedBackend, OECP_PORT};
5
-
6
- #[tokio::main]
7
- async fn main() -> Result<(), Box<dyn Error>> {
8
- if std::env::args().nth(1).as_deref() == Some("--healthcheck") {
9
- println!("zeroshot OECP server ready");
10
- return Ok(());
11
- }
12
- let backend = Arc::new(HostedBackend::new());
13
- let listener = TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], OECP_PORT))).await?;
14
- serve(listener, backend, shutdown_signal()).await?;
15
- Ok(())
16
- }
17
-
18
- #[cfg(unix)]
19
- async fn shutdown_signal() {
20
- use tokio::signal::unix::{signal, SignalKind};
21
-
22
- let mut terminate = signal(SignalKind::terminate()).expect("SIGTERM handler must install");
23
- tokio::select! {
24
- _ = tokio::signal::ctrl_c() => {}
25
- _ = terminate.recv() => {}
26
- }
27
- }
28
-
29
- #[cfg(not(unix))]
30
- async fn shutdown_signal() {
31
- let _result = tokio::signal::ctrl_c().await;
32
- }
@@ -1,6 +0,0 @@
1
- interface BoundedJsonErrors {
2
- readonly tooLarge: () => Error;
3
- readonly invalid: () => Error;
4
- }
5
- export declare function readBoundedJson(response: Response, maxBytes: number, errors: BoundedJsonErrors): Promise<unknown>;
6
- export {};
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readBoundedJson = readBoundedJson;
4
- async function readBoundedJson(response, maxBytes, errors) {
5
- const declared = response.headers.get('content-length');
6
- if (declared !== null && Number(declared) > maxBytes)
7
- throw errors.tooLarge();
8
- const reader = response.body?.getReader();
9
- if (!reader) {
10
- const bytes = new Uint8Array(await response.arrayBuffer());
11
- if (bytes.byteLength > maxBytes)
12
- throw errors.tooLarge();
13
- return parseJson(bytes, errors);
14
- }
15
- const chunks = [];
16
- let total = 0;
17
- for (;;) {
18
- const { done, value } = await reader.read();
19
- if (done)
20
- break;
21
- total += value.byteLength;
22
- if (total > maxBytes) {
23
- await reader.cancel();
24
- throw errors.tooLarge();
25
- }
26
- chunks.push(value);
27
- }
28
- const bytes = new Uint8Array(total);
29
- let offset = 0;
30
- for (const chunk of chunks) {
31
- bytes.set(chunk, offset);
32
- offset += chunk.byteLength;
33
- }
34
- return parseJson(bytes, errors);
35
- }
36
- function parseJson(bytes, errors) {
37
- try {
38
- return JSON.parse(new TextDecoder().decode(bytes));
39
- }
40
- catch {
41
- throw errors.invalid();
42
- }
43
- }
@@ -1,26 +0,0 @@
1
- import { type TargetAccessTokenProvider } from '../target-session.ts';
2
- import type { HostedRunDependencies, HostedRunIntent } from './contracts.ts';
3
- export declare const UUID: RegExp;
4
- export declare const TERMINAL_STATES: Set<string>;
5
- export interface HostedContext {
6
- readonly targetName: string;
7
- readonly organization: string;
8
- readonly client: RunIntentClient;
9
- }
10
- export declare class HostedRunHttpError extends Error {
11
- readonly status: number;
12
- readonly code: string | null;
13
- constructor(status: number, message: string, code?: string | null);
14
- }
15
- export declare class RunIntentClient {
16
- private readonly baseUrl;
17
- private readonly organization;
18
- private readonly tokenProvider;
19
- private readonly fetch;
20
- constructor(baseUrl: string, organization: string, tokenProvider: TargetAccessTokenProvider, fetchImplementation: typeof globalThis.fetch);
21
- submit(body: Record<string, unknown>, submissionKey: string): Promise<HostedRunIntent>;
22
- get(intentId: string): Promise<HostedRunIntent>;
23
- cancel(intentId: string): Promise<HostedRunIntent>;
24
- private request;
25
- }
26
- export declare function context(targetName: string, deps: HostedRunDependencies): Promise<HostedContext>;