@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,57 +1,115 @@
1
- import type { HttpTransport } from './device-flow.ts';
2
- import { readBoundedJson } from './bounded-json.ts';
1
+ import type { HttpTransport } from './device-flow.js';
2
+ import { readBoundedResponseJson } from './bounded-response.js';
3
+ import { TargetDiscoveryError } from './discovery-errors.js';
4
+ import type { RouteTemplate } from './route-template.js';
5
+ import {
6
+ exact,
7
+ exactStringSet,
8
+ record,
9
+ type CredentialInstallDescriptor,
10
+ } from './discovery-validation.js';
11
+ import {
12
+ parseAdapter,
13
+ parseCapsule,
14
+ parseEndpoint,
15
+ parseExtensions,
16
+ parseOAuth,
17
+ parseSession,
18
+ parseSizes,
19
+ parseTransport,
20
+ validateOAuthMetadata,
21
+ } from './discovery-sections.js';
22
+ export type { CredentialInstallDescriptor } from './discovery-validation.js';
23
+ export { TargetDiscoveryError } from './discovery-errors.js';
24
+ export { expandRoute, type RouteTemplate } from './route-template.js';
3
25
 
4
26
  const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
5
27
  const MAX_DISCOVERY_BYTES = 64 * 1024;
28
+ const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
29
+ const CAPSULE_AUDIENCE = 'capsule';
6
30
 
31
+ const ROOT_FIELDS = [
32
+ 'kind',
33
+ 'adapter',
34
+ 'protocol',
35
+ 'binding',
36
+ 'endpoint',
37
+ 'pagination',
38
+ 'cache_policy',
39
+ 'schema_links',
40
+ 'capsule_protocol',
41
+ 'oauth',
42
+ 'organization_binding',
43
+ 'capability_flags',
44
+ 'sizes',
45
+ 'session',
46
+ 'transport',
47
+ 'extensions',
48
+ ] as const;
49
+ export interface TargetDiscoveryDescriptor {
50
+ readonly origin: string;
51
+ readonly adapter: { readonly name: 'fargate' | 'docker' | 'local'; readonly majorVersion: 1 };
52
+ readonly endpoint: string;
53
+ readonly endpointCapabilities: readonly ['exec', 'log_stream'];
54
+ readonly pagination: { readonly defaultPageSize: number; readonly maxPageSize: number };
55
+ readonly sizes: {
56
+ readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
57
+ readonly default: 'tiny' | 'small' | 'standard' | 'large';
58
+ };
59
+ readonly oauth: {
60
+ readonly metadataUrl: string;
61
+ readonly deviceAuthorizationEndpoint: string;
62
+ readonly tokenEndpoint: string;
63
+ readonly revocationEndpoint: string;
64
+ readonly clientId: string;
65
+ readonly deviceGrantType: typeof DEVICE_GRANT;
66
+ readonly audience: typeof CAPSULE_AUDIENCE;
67
+ };
68
+ readonly session: { readonly routeTemplate: RouteTemplate; readonly method: 'GET' };
69
+ readonly capsule: {
70
+ readonly baseUrl: string;
71
+ readonly routes: {
72
+ readonly allocate: RouteTemplate;
73
+ readonly list: RouteTemplate;
74
+ readonly inspect: RouteTemplate;
75
+ readonly terminate: RouteTemplate;
76
+ readonly limits: RouteTemplate;
77
+ readonly access: RouteTemplate;
78
+ };
79
+ };
80
+ readonly transport: {
81
+ readonly websocketRouteTemplate: RouteTemplate;
82
+ readonly unauthorizedStatus: 401;
83
+ readonly closeCodes: { readonly expired: 4401; readonly revoked: 4403 };
84
+ };
85
+ readonly capabilityFlags: readonly string[];
86
+ readonly credentialInstall: CredentialInstallDescriptor | null;
87
+ readonly additional: Readonly<Record<string, unknown>>;
88
+ }
89
+
90
+ /** Compatibility projection. New callers should retain the complete descriptor. */
7
91
  export interface TargetSessionEndpoints {
8
92
  readonly deviceAuthorizationEndpoint: string;
9
93
  readonly tokenEndpoint: string;
10
- readonly revocationEndpoint?: string;
94
+ readonly revocationEndpoint: string;
11
95
  readonly clientId: string;
12
96
  readonly capsuleApiBaseUrl: string;
97
+ readonly deviceGrantType: typeof DEVICE_GRANT;
98
+ readonly audience: typeof CAPSULE_AUDIENCE;
99
+ readonly sessionEndpoint: string;
100
+ readonly descriptor: TargetDiscoveryDescriptor;
13
101
  }
14
102
 
15
- export class TargetDiscoveryError extends Error {
16
- constructor(message: string) {
17
- super(`Target discovery failed: ${message}`);
18
- this.name = 'TargetDiscoveryError';
19
- }
20
- }
21
103
 
22
- function record(value: unknown, field: string): Record<string, unknown> {
23
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
24
- throw new TargetDiscoveryError(`${field} must be an object`);
25
- }
26
- return value as Record<string, unknown>;
27
- }
28
104
 
29
- function stringField(source: Record<string, unknown>, field: string): string {
30
- const value = source[field];
31
- if (typeof value !== 'string' || value.length === 0) {
32
- throw new TargetDiscoveryError(`${field} must be a non-empty string`);
33
- }
34
- return value;
105
+ async function readBoundedJson(response: Response): Promise<unknown> {
106
+ return readBoundedResponseJson(response, MAX_DISCOVERY_BYTES, (kind) =>
107
+ new TargetDiscoveryError(
108
+ kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON',
109
+ ),
110
+ );
35
111
  }
36
112
 
37
- function safeEndpoint(value: unknown, field: string, serviceOrigin: string): string {
38
- if (typeof value !== 'string') {
39
- throw new TargetDiscoveryError(`${field} must be an absolute URL`);
40
- }
41
- let endpoint: URL;
42
- try {
43
- endpoint = new URL(value);
44
- } catch {
45
- throw new TargetDiscoveryError(`${field} must be an absolute URL`);
46
- }
47
- if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
48
- throw new TargetDiscoveryError(`${field} contains forbidden URL components`);
49
- }
50
- if (endpoint.origin !== serviceOrigin) {
51
- throw new TargetDiscoveryError(`${field} must remain on the target origin`);
52
- }
53
- return endpoint.href;
54
- }
55
113
 
56
114
  async function fetchDocument(http: HttpTransport, url: string): Promise<Record<string, unknown>> {
57
115
  const response = await http.fetch(url, {
@@ -59,73 +117,81 @@ async function fetchDocument(http: HttpTransport, url: string): Promise<Record<s
59
117
  headers: { Accept: 'application/json' },
60
118
  redirect: 'error',
61
119
  });
120
+ if (response.url && new URL(response.url).href !== url) {
121
+ await response.body?.cancel().catch(() => undefined);
122
+ throw new TargetDiscoveryError('request changed target route or authority');
123
+ }
62
124
  if (!response.ok) {
125
+ await response.body?.cancel().catch(() => undefined);
63
126
  throw new TargetDiscoveryError(`request failed with status ${response.status}`);
64
127
  }
65
- const body = await readBoundedJson(response, MAX_DISCOVERY_BYTES, {
66
- tooLarge: () => new TargetDiscoveryError('response exceeds the size limit'),
67
- invalid: () => new TargetDiscoveryError('response is not valid JSON'),
68
- });
69
- return record(body, 'response');
128
+ return record(await readBoundedJson(response), 'response');
70
129
  }
71
130
 
72
- export async function discoverTargetSessionEndpoints(
73
- targetUrl: string,
74
- http: HttpTransport
75
- ): Promise<TargetSessionEndpoints> {
131
+
132
+ export async function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor> {
76
133
  const target = new URL(targetUrl);
134
+ const origin = target.origin;
77
135
  const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
78
- if (discovery.kind !== 'openengine.hosted-target/v1') {
79
- throw new TargetDiscoveryError('unsupported hosted-target version');
80
- }
81
- if (discovery.organization_binding !== 'device_approval') {
82
- throw new TargetDiscoveryError('unsupported organization binding');
83
- }
136
+ exact(discovery.kind, 'openengine.hosted-target/v1', 'kind');
84
137
 
85
- const oauth = record(discovery.oauth, 'oauth');
86
- const capsuleProtocol = record(discovery.capsule_protocol, 'capsule_protocol');
87
- if (capsuleProtocol.name !== 'openengine.capsules/v1' || capsuleProtocol.major_version !== 1) {
88
- throw new TargetDiscoveryError('unsupported capsule protocol');
89
- }
90
- const capsuleApiBaseUrl = safeEndpoint(
91
- capsuleProtocol.base_url,
92
- 'capsule_protocol.base_url',
93
- target.origin
94
- ).replace(/\/$/, '');
95
- const metadataUrl = safeEndpoint(oauth.metadata_url, 'oauth.metadata_url', target.origin);
96
- const deviceEndpoint = safeEndpoint(
97
- oauth.device_authorization_endpoint,
98
- 'oauth.device_authorization_endpoint',
99
- target.origin
100
- );
101
- const tokenEndpoint = safeEndpoint(oauth.token_endpoint, 'oauth.token_endpoint', target.origin);
102
- const clientId = stringField(oauth, 'client_id');
138
+ const adapter = parseAdapter(discovery);
139
+ const endpoint = parseEndpoint(discovery, origin);
140
+ const capsule = parseCapsule(discovery, origin);
141
+ const oauth = parseOAuth(discovery, origin);
142
+ exact(discovery.organization_binding, 'device_approval', 'organization_binding');
143
+ const capabilityFlags = exactStringSet(discovery.capability_flags, 'capability_flags', [
144
+ 'capsule_allocate',
145
+ 'capsule_read',
146
+ 'capsule_terminate',
147
+ 'capsule_access',
148
+ 'connections_onboarding',
149
+ ]);
150
+ const sizes = parseSizes(discovery);
151
+ const session = parseSession(discovery);
152
+ const transport = parseTransport(discovery);
153
+ const credentialInstall = parseExtensions(discovery, origin);
103
154
 
104
- const metadata = await fetchDocument(http, metadataUrl);
105
- const metadataDeviceEndpoint = safeEndpoint(
106
- metadata.device_authorization_endpoint,
107
- 'device_authorization_endpoint',
108
- target.origin
109
- );
110
- const metadataTokenEndpoint = safeEndpoint(
111
- metadata.token_endpoint,
112
- 'token_endpoint',
113
- target.origin
114
- );
115
- if (metadataDeviceEndpoint !== deviceEndpoint || metadataTokenEndpoint !== tokenEndpoint) {
116
- throw new TargetDiscoveryError('OAuth metadata does not match hosted-target discovery');
117
- }
155
+ const metadata = await fetchDocument(http, oauth.metadataUrl);
156
+ validateOAuthMetadata(metadata, origin, [
157
+ oauth.deviceAuthorizationEndpoint,
158
+ oauth.tokenEndpoint,
159
+ oauth.revocationEndpoint,
160
+ ]);
118
161
 
119
- const revocationEndpoint =
120
- metadata.revocation_endpoint === undefined
121
- ? undefined
122
- : safeEndpoint(metadata.revocation_endpoint, 'revocation_endpoint', target.origin);
162
+ const additional = Object.freeze(
163
+ Object.fromEntries(Object.entries(discovery).filter(([key]) =>
164
+ !ROOT_FIELDS.includes(key as (typeof ROOT_FIELDS)[number]),
165
+ )),
166
+ );
167
+ return Object.freeze({
168
+ origin,
169
+ adapter,
170
+ endpoint: endpoint.url,
171
+ endpointCapabilities: endpoint.capabilities,
172
+ pagination: endpoint.pagination,
173
+ sizes,
174
+ oauth,
175
+ session,
176
+ capsule,
177
+ transport,
178
+ capabilityFlags,
179
+ credentialInstall,
180
+ additional,
181
+ });
182
+ }
123
183
 
124
- return {
125
- deviceAuthorizationEndpoint: deviceEndpoint,
126
- tokenEndpoint,
127
- ...(revocationEndpoint === undefined ? {} : { revocationEndpoint }),
128
- clientId,
129
- capsuleApiBaseUrl,
130
- };
184
+ export async function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints> {
185
+ const descriptor = await discoverTarget(targetUrl, http);
186
+ return Object.freeze({
187
+ deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
188
+ tokenEndpoint: descriptor.oauth.tokenEndpoint,
189
+ revocationEndpoint: descriptor.oauth.revocationEndpoint,
190
+ clientId: descriptor.oauth.clientId,
191
+ capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
192
+ deviceGrantType: descriptor.oauth.deviceGrantType,
193
+ audience: descriptor.oauth.audience,
194
+ sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
195
+ descriptor,
196
+ });
131
197
  }
@@ -5,21 +5,23 @@ export {
5
5
  targetServiceKey,
6
6
  TARGET_ACCOUNT,
7
7
  type TargetCredentialStore,
8
- } from './credential-store.ts';
8
+ } from './credential-store.js';
9
9
 
10
- export { acquireTargetLock } from './credential-lock.ts';
10
+ export { acquireTargetLock } from './credential-lock.js';
11
11
 
12
12
  export {
13
13
  requestDeviceCode,
14
14
  pollForToken,
15
+ parseTokenResponse,
15
16
  DeviceFlowDeniedError,
16
17
  DeviceFlowExpiredError,
17
18
  UnboundSessionError,
18
19
  type DeviceCodeResponse,
20
+ type DeviceExchangeContext,
19
21
  type TokenResponse,
20
22
  type HttpTransport,
21
23
  type Clock,
22
- } from './device-flow.ts';
24
+ } from './device-flow.js';
23
25
 
24
26
  export {
25
27
  addTarget,
@@ -35,21 +37,23 @@ export {
35
37
  TargetUrlInvalidError,
36
38
  type TargetRecord,
37
39
  type SettingsPort,
38
- } from './target-registry.ts';
40
+ } from './target-registry.js';
39
41
 
40
42
  export {
41
- targetLogin,
42
- refreshAccessToken,
43
- getAccessTokenProvider,
44
- revokeAndCleanup,
43
+ TargetSessionManager,
45
44
  LoginRequiredError,
46
45
  type BrowserOpener,
47
46
  type TargetSessionDeps,
48
- type TargetAccessTokenProvider,
49
- } from './target-session.ts';
47
+ type TargetSessionManagerInit,
48
+ } from './target-session.js';
50
49
 
51
50
  export {
51
+ discoverTarget,
52
52
  discoverTargetSessionEndpoints,
53
+ expandRoute,
53
54
  TargetDiscoveryError,
55
+ type CredentialInstallDescriptor,
56
+ type RouteTemplate,
57
+ type TargetDiscoveryDescriptor,
54
58
  type TargetSessionEndpoints,
55
- } from './discovery.ts';
59
+ } from './discovery.js';
@@ -0,0 +1,27 @@
1
+ import { readBoundedResponseJson } from './bounded-response.js';
2
+
3
+ const MAX_SESSION_RESPONSE_BYTES = 64 * 1024;
4
+
5
+
6
+ export async function readTargetSessionJson(response: Response): Promise<unknown> {
7
+ return readBoundedResponseJson(response, MAX_SESSION_RESPONSE_BYTES, (kind) =>
8
+ new Error(
9
+ kind === 'size'
10
+ ? 'Target session response exceeds the size limit'
11
+ : 'Target session response is malformed',
12
+ ),
13
+ );
14
+ }
15
+
16
+ export async function readOAuthError(response: Response): Promise<string | null> {
17
+ try {
18
+ const value = await readTargetSessionJson(response);
19
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) return null;
20
+ const record = value as Record<string, unknown>;
21
+ return Object.keys(record).length === 1 && typeof record.error === 'string'
22
+ ? record.error
23
+ : null;
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
@@ -0,0 +1,36 @@
1
+ import { oauthFormRequest, type HttpTransport } from './device-flow.js';
2
+ import { readOAuthError, readTargetSessionJson } from './oauth-http.js';
3
+ import { parseTokenResponse, type TokenResponse } from './token-response.js';
4
+
5
+ export interface RefreshExchangeRequest {
6
+ readonly tokenEndpoint: string;
7
+ readonly clientId: string;
8
+ readonly refreshToken: string;
9
+ readonly audience: string;
10
+ readonly http: HttpTransport;
11
+ readonly signal?: AbortSignal;
12
+ }
13
+
14
+ export async function exchangeRefreshToken(
15
+ request: RefreshExchangeRequest,
16
+ ): Promise<TokenResponse> {
17
+ const body = new URLSearchParams({
18
+ grant_type: 'refresh_token',
19
+ client_id: request.clientId,
20
+ refresh_token: request.refreshToken,
21
+ audience: request.audience,
22
+ });
23
+ const response = await request.http.fetch(
24
+ request.tokenEndpoint,
25
+ oauthFormRequest(body, request.signal),
26
+ );
27
+ if (response.url && new URL(response.url).href !== request.tokenEndpoint) {
28
+ await response.body?.cancel().catch(() => undefined);
29
+ throw new Error('Target token response changed route or authority');
30
+ }
31
+ if (!response.ok) {
32
+ await readOAuthError(response);
33
+ throw new Error('Target token exchange failed');
34
+ }
35
+ return parseTokenResponse(await readTargetSessionJson(response));
36
+ }
@@ -0,0 +1,29 @@
1
+ import { oauthFormRequest, type HttpTransport } from './device-flow.js';
2
+ import type { TargetSessionEndpoints } from './discovery.js';
3
+
4
+ interface RevocationDeps {
5
+ readonly http: HttpTransport;
6
+ readonly discoveryEndpoints: TargetSessionEndpoints;
7
+ }
8
+
9
+ export async function revokeRefreshToken(
10
+ token: string,
11
+ deps: RevocationDeps,
12
+ ): Promise<Response> {
13
+ const body = new URLSearchParams({
14
+ token,
15
+ client_id: deps.discoveryEndpoints.clientId,
16
+ token_type_hint: 'refresh_token',
17
+ });
18
+ const response = await deps.http.fetch(
19
+ deps.discoveryEndpoints.revocationEndpoint,
20
+ oauthFormRequest(body),
21
+ );
22
+ if (response.url &&
23
+ new URL(response.url).href !== deps.discoveryEndpoints.revocationEndpoint) {
24
+ await response.body?.cancel().catch(() => undefined);
25
+ throw new Error('Target revocation response changed route or authority');
26
+ }
27
+ await response.body?.cancel().catch(() => undefined);
28
+ return response;
29
+ }
@@ -0,0 +1,105 @@
1
+ import { TargetDiscoveryError } from './discovery-errors.js';
2
+
3
+ export interface RouteTemplate {
4
+ readonly template: string;
5
+ readonly variables: readonly string[];
6
+ expand(values: Readonly<Record<string, string | number | undefined>>): string;
7
+ }
8
+
9
+ function expandCompiled(
10
+ template: string,
11
+ variables: readonly string[],
12
+ values: Readonly<Record<string, string | number | undefined>>,
13
+ ): string {
14
+ const supplied = Object.keys(values).filter((key) => values[key] !== undefined);
15
+ if (supplied.some((key) => !variables.includes(key))) {
16
+ throw new TargetDiscoveryError('route expansion supplied an undeclared variable');
17
+ }
18
+ let expanded = template.replace(/\{\?([^}]+)\}/g, (_match, names: string) => {
19
+ const params = names.split(',').flatMap((name) => {
20
+ const value = values[name];
21
+ return value === undefined
22
+ ? []
23
+ : [`${encodeURIComponent(name)}=${encodeURIComponent(String(value))}`];
24
+ });
25
+ return params.length === 0 ? '' : `?${params.join('&')}`;
26
+ });
27
+ expanded = expanded.replace(/\{([^}?][^}]*)\}/g, (_match, name: string) => {
28
+ const value = values[name];
29
+ if (value === undefined) throw new TargetDiscoveryError(`route expansion is missing ${name}`);
30
+ const opaque = String(value);
31
+ if (opaque === '.' || opaque === '..') {
32
+ throw new TargetDiscoveryError('route expansion contains a structural dot segment');
33
+ }
34
+ return encodeURIComponent(opaque);
35
+ });
36
+ if (/[{}]/.test(expanded)) {
37
+ throw new TargetDiscoveryError('route expansion left an unexpanded variable');
38
+ }
39
+ const canonical = new URL(expanded, 'https://route-validation.invalid');
40
+ if (canonical.origin !== 'https://route-validation.invalid' ||
41
+ `${canonical.pathname}${canonical.search}` !== expanded) {
42
+ throw new TargetDiscoveryError('route expansion changed during URL canonicalization');
43
+ }
44
+ return expanded;
45
+ }
46
+
47
+ function isUnsafeTemplate(value: unknown): boolean {
48
+ return typeof value !== 'string' || !value.startsWith('/') || value.startsWith('//') ||
49
+ value.includes('\\') || value.includes('#') || /[\u0000-\u0020\u007f]/.test(value) ||
50
+ value.replace(/\{\?[^}]+\}/g, '').includes('?');
51
+ }
52
+
53
+ function expressionNames(
54
+ expressions: RegExpMatchArray[],
55
+ field: string,
56
+ ): string[] {
57
+ const found: string[] = [];
58
+ for (const expression of expressions) {
59
+ const body = expression[1];
60
+ if (body === undefined) throw new TargetDiscoveryError(`${field} contains an invalid expression`);
61
+ const query = body.startsWith('?');
62
+ const names = body.replace(/^\?/, '').split(',');
63
+ if (query && field !== 'capsule_protocol.route_templates.list') {
64
+ throw new TargetDiscoveryError(`${field} contains an unsupported query expansion`);
65
+ }
66
+ found.push(...names);
67
+ }
68
+ return found;
69
+ }
70
+
71
+ export function routeTemplate(
72
+ value: unknown,
73
+ field: string,
74
+ variables: readonly string[],
75
+ ): RouteTemplate {
76
+ if (isUnsafeTemplate(value)) {
77
+ throw new TargetDiscoveryError(`${field} must be a safe relative route template`);
78
+ }
79
+ const template = value as string;
80
+ const expressions = [...template.matchAll(/\{([^{}]+)\}/g)];
81
+ const stripped = template.replace(/\{[^{}]+\}/g, '');
82
+ if (stripped.includes('{') || stripped.includes('}') ||
83
+ /(^|\/)(?:\.|%2e){1,2}(?:\/|$)/i.test(stripped)) {
84
+ throw new TargetDiscoveryError(`${field} contains an unsafe template expression`);
85
+ }
86
+ const found = expressionNames(expressions, field);
87
+ if (found.length !== variables.length || new Set(found).size !== found.length ||
88
+ variables.some((name) => !found.includes(name))) {
89
+ throw new TargetDiscoveryError(`${field} declares unsupported variables`);
90
+ }
91
+ const compiledVariables = Object.freeze([...variables]);
92
+ return Object.freeze({
93
+ template,
94
+ variables: compiledVariables,
95
+ expand: (values: Readonly<Record<string, string | number | undefined>>) =>
96
+ expandCompiled(template, compiledVariables, values),
97
+ });
98
+ }
99
+
100
+ export function expandRoute(
101
+ template: RouteTemplate,
102
+ values: Readonly<Record<string, string | number | undefined>>,
103
+ ): string {
104
+ return template.expand(values);
105
+ }
@@ -0,0 +1,9 @@
1
+ export class LoginRequiredError extends Error {
2
+ readonly targetName: string;
3
+
4
+ constructor(targetName: string) {
5
+ super(`Login required. Run: zeroshot target login ${targetName}`);
6
+ this.name = 'LoginRequiredError';
7
+ this.targetName = targetName;
8
+ }
9
+ }
@@ -0,0 +1,51 @@
1
+ import type { HttpTransport } from './device-flow.js';
2
+ import type { TargetSessionEndpoints } from './discovery.js';
3
+ import { readTargetSessionJson } from './oauth-http.js';
4
+
5
+ interface SessionVerificationDeps {
6
+ readonly http: HttpTransport;
7
+ readonly discoveryEndpoints: TargetSessionEndpoints;
8
+ }
9
+
10
+ function parseOrganization(value: unknown): { readonly id: string } {
11
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
12
+ throw new Error('Target session response is malformed');
13
+ }
14
+ const body = value as Record<string, unknown>;
15
+ const fields = Object.keys(body);
16
+ if (fields.length !== 2 || !fields.includes('kind') ||
17
+ !fields.includes('organization_id') ||
18
+ body.kind !== 'openengine.target-session/v1' ||
19
+ typeof body.organization_id !== 'string' ||
20
+ body.organization_id.length === 0 || body.organization_id.length > 256) {
21
+ throw new Error('Target session response is malformed');
22
+ }
23
+ return Object.freeze({ id: body.organization_id });
24
+ }
25
+
26
+ export async function readVerifiedOrganization(
27
+ accessToken: string,
28
+ signal: AbortSignal | undefined,
29
+ deps: SessionVerificationDeps,
30
+ ): Promise<{ readonly id: string }> {
31
+ const init: RequestInit & { redirect: 'error' } = {
32
+ method: deps.discoveryEndpoints.descriptor.session.method,
33
+ headers: {
34
+ Accept: 'application/json',
35
+ Authorization: `Bearer ${accessToken}`,
36
+ 'Cache-Control': 'no-store',
37
+ },
38
+ redirect: 'error',
39
+ };
40
+ if (signal !== undefined) init.signal = signal;
41
+ const response = await deps.http.fetch(deps.discoveryEndpoints.sessionEndpoint, init);
42
+ if (response.url && new URL(response.url).href !== deps.discoveryEndpoints.sessionEndpoint) {
43
+ await response.body?.cancel().catch(() => undefined);
44
+ throw new Error('Target session response changed route or authority');
45
+ }
46
+ if (!response.ok) {
47
+ await response.body?.cancel().catch(() => undefined);
48
+ throw new Error('Target session verification failed');
49
+ }
50
+ return parseOrganization(await readTargetSessionJson(response));
51
+ }