@opengeni/sdk 3.1.0 → 3.1.2

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 (295) hide show
  1. package/README.md +1037 -71
  2. package/dist/accounts.d.ts +5 -1
  3. package/dist/accounts.js +13 -1
  4. package/dist/accounts.js.map +1 -1
  5. package/dist/adapters/express.d.ts +31 -0
  6. package/dist/adapters/express.js +87 -0
  7. package/dist/adapters/express.js.map +1 -0
  8. package/dist/adapters/hono.d.ts +16 -0
  9. package/dist/adapters/hono.js +8 -0
  10. package/dist/adapters/hono.js.map +1 -0
  11. package/dist/adapters/next.d.ts +29 -0
  12. package/dist/adapters/next.js +22 -0
  13. package/dist/adapters/next.js.map +1 -0
  14. package/dist/allowance-refusal.d.ts +2 -0
  15. package/dist/allowance-refusal.js +50 -0
  16. package/dist/allowance-refusal.js.map +1 -0
  17. package/dist/app-links.d.ts +42 -0
  18. package/dist/app-links.js +66 -0
  19. package/dist/app-links.js.map +1 -0
  20. package/dist/artifact-catalog.d.ts +40 -0
  21. package/dist/artifact-client.d.ts +20 -8
  22. package/dist/artifacts.d.ts +1 -1
  23. package/dist/artifacts.js +8 -6
  24. package/dist/automations.js +8 -2
  25. package/dist/automations.js.map +1 -1
  26. package/dist/azure-live-transport.d.ts +32 -0
  27. package/dist/browser.d.ts +7 -2
  28. package/dist/browser.js +27 -5
  29. package/dist/chat/fold.d.ts +75 -0
  30. package/dist/chat/handler.d.ts +41 -0
  31. package/dist/chat/http.d.ts +67 -0
  32. package/dist/chat/ids.d.ts +34 -0
  33. package/dist/chat/index.d.ts +9 -0
  34. package/dist/chat/index.js +1703 -0
  35. package/dist/chat/index.js.map +1 -0
  36. package/dist/chat/openai.d.ts +30 -0
  37. package/dist/chat/opengeni.d.ts +129 -0
  38. package/dist/chat/types.d.ts +207 -0
  39. package/dist/chat/vercel.d.ts +49 -0
  40. package/dist/chats.d.ts +8 -0
  41. package/dist/chunk-4AHR4KGA.js +301 -0
  42. package/dist/chunk-4AHR4KGA.js.map +1 -0
  43. package/dist/chunk-6HZGAIUE.js +1665 -0
  44. package/dist/chunk-6HZGAIUE.js.map +1 -0
  45. package/dist/chunk-7EWT3PV6.js +368 -0
  46. package/dist/chunk-7EWT3PV6.js.map +1 -0
  47. package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
  48. package/dist/chunk-GZQSWAKD.js.map +1 -0
  49. package/dist/chunk-JXXCTW5W.js +1392 -0
  50. package/dist/chunk-JXXCTW5W.js.map +1 -0
  51. package/dist/{chunk-YTAWBDO2.js → chunk-KADZ5PGG.js} +28 -2
  52. package/dist/chunk-KADZ5PGG.js.map +1 -0
  53. package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
  54. package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
  55. package/dist/{chunk-7ZXBPJZP.js → chunk-NEM5N6C6.js} +3902 -1457
  56. package/dist/chunk-NEM5N6C6.js.map +1 -0
  57. package/dist/{chunk-GW3EJ2GP.js → chunk-O7KANXC3.js} +86 -13
  58. package/dist/chunk-O7KANXC3.js.map +1 -0
  59. package/dist/{chunk-VUQZAB3O.js → chunk-OAKHWFSV.js} +28 -32
  60. package/dist/chunk-OAKHWFSV.js.map +1 -0
  61. package/dist/chunk-P7UWKORG.js +561 -0
  62. package/dist/chunk-P7UWKORG.js.map +1 -0
  63. package/dist/chunk-QGEIL4TR.js +195 -0
  64. package/dist/chunk-QGEIL4TR.js.map +1 -0
  65. package/dist/chunk-RJHCBZF7.js +270 -0
  66. package/dist/chunk-RJHCBZF7.js.map +1 -0
  67. package/dist/chunk-S3D75WSQ.js +340 -0
  68. package/dist/chunk-S3D75WSQ.js.map +1 -0
  69. package/dist/chunk-UM4ZXXJR.js +9 -0
  70. package/dist/chunk-UM4ZXXJR.js.map +1 -0
  71. package/dist/chunk-VPVMLM7Q.js +15 -0
  72. package/dist/chunk-VPVMLM7Q.js.map +1 -0
  73. package/dist/{chunk-C2H7HBNP.js → chunk-WVCJRSGJ.js} +119 -14
  74. package/dist/chunk-WVCJRSGJ.js.map +1 -0
  75. package/dist/chunk-XA7HVIHI.js +126 -0
  76. package/dist/chunk-XA7HVIHI.js.map +1 -0
  77. package/dist/{chunk-TX3EIENU.js → chunk-YDVPI7WT.js} +73 -2
  78. package/dist/chunk-YDVPI7WT.js.map +1 -0
  79. package/dist/chunk-YKIHNLWD.js +153 -0
  80. package/dist/chunk-YKIHNLWD.js.map +1 -0
  81. package/dist/chunk-ZDUBPV33.js +277 -0
  82. package/dist/chunk-ZDUBPV33.js.map +1 -0
  83. package/dist/client.d.ts +1065 -124
  84. package/dist/codex-realtime-controller.d.ts +13 -0
  85. package/dist/codex-realtime-controller.js +4 -2
  86. package/dist/codex-realtime-v3-wire.d.ts +3 -2
  87. package/dist/codex-realtime.d.ts +5 -1
  88. package/dist/company-brain.d.ts +1 -11
  89. package/dist/company-profile.d.ts +13 -0
  90. package/dist/core.d.ts +7 -2
  91. package/dist/core.js +25 -6
  92. package/dist/deprecation.d.ts +47 -0
  93. package/dist/document-authority-client.d.ts +24 -2
  94. package/dist/document-authority.js +7 -5
  95. package/dist/editable-artifacts/index.d.ts +1 -1
  96. package/dist/editable-artifacts/types.d.ts +12 -2
  97. package/dist/editable-artifacts.js +19 -3
  98. package/dist/editable-artifacts.js.map +1 -1
  99. package/dist/embedding-client.d.ts +129 -0
  100. package/dist/errors.d.ts +76 -1
  101. package/dist/feedback.d.ts +23 -0
  102. package/dist/gateway-realtime-transport.js +1 -1
  103. package/dist/github-repositories.d.ts +10 -0
  104. package/dist/github-repositories.js +36 -0
  105. package/dist/github-repositories.js.map +1 -0
  106. package/dist/index.d.ts +64 -11
  107. package/dist/index.js +566 -141
  108. package/dist/index.js.map +1 -1
  109. package/dist/insights-usage.d.ts +33 -0
  110. package/dist/insights-usage.js +7 -0
  111. package/dist/insights-usage.js.map +1 -0
  112. package/dist/interaction.d.ts +103 -71
  113. package/dist/interaction.js +4 -2
  114. package/dist/knowledge.d.ts +7 -0
  115. package/dist/knowledge.js +20 -0
  116. package/dist/knowledge.js.map +1 -0
  117. package/dist/known-tools.d.ts +4 -0
  118. package/dist/message-links.d.ts +68 -0
  119. package/dist/model-context.d.ts +68 -0
  120. package/dist/model-display.d.ts +2 -0
  121. package/dist/model-display.js +17 -0
  122. package/dist/model-display.js.map +1 -0
  123. package/dist/model-picker-order.d.ts +1 -0
  124. package/dist/model-picker-order.js +10 -0
  125. package/dist/model-picker-order.js.map +1 -0
  126. package/dist/organization-integration-policy.d.ts +26 -0
  127. package/dist/organization-integration-policy.js +26 -0
  128. package/dist/organization-integration-policy.js.map +1 -0
  129. package/dist/pr-review-client.d.ts +1 -1
  130. package/dist/pr-review.d.ts +1 -1
  131. package/dist/pr-review.js.map +1 -1
  132. package/dist/preference-registry.d.ts +1 -1
  133. package/dist/prepared-mcp-setup.d.ts +5 -0
  134. package/dist/proxy.d.ts +13 -11
  135. package/dist/realtime.d.ts +4 -2
  136. package/dist/realtime.js +253 -7
  137. package/dist/realtime.js.map +1 -1
  138. package/dist/session-history-import.d.ts +22 -0
  139. package/dist/session-history-import.js +36 -0
  140. package/dist/session-history-import.js.map +1 -0
  141. package/dist/session-list-entries.d.ts +1 -0
  142. package/dist/session-list-entries.js +7 -0
  143. package/dist/session-list-entries.js.map +1 -0
  144. package/dist/session-message-search.d.ts +53 -0
  145. package/dist/session-proxy-client.d.ts +28 -0
  146. package/dist/session-proxy.d.ts +334 -0
  147. package/dist/session-proxy.js +24 -0
  148. package/dist/session-proxy.js.map +1 -0
  149. package/dist/session-titles.d.ts +2 -0
  150. package/dist/session-usage-limits.d.ts +10 -0
  151. package/dist/session-usage-limits.js +43 -0
  152. package/dist/session-usage-limits.js.map +1 -0
  153. package/dist/shared-catalog-loader.d.ts +34 -0
  154. package/dist/site-bridge-host.d.ts +112 -0
  155. package/dist/site-bridge-host.js +285 -0
  156. package/dist/site-bridge-host.js.map +1 -0
  157. package/dist/site-browser-entry.d.ts +1 -0
  158. package/dist/site-browser-runtime.gen.d.ts +1 -0
  159. package/dist/site-data.d.ts +178 -0
  160. package/dist/site-document.d.ts +5 -0
  161. package/dist/site-document.js +20 -0
  162. package/dist/site-document.js.map +1 -0
  163. package/dist/site-document.test.d.ts +1 -0
  164. package/dist/site-http.d.ts +17 -0
  165. package/dist/site-sql.d.ts +31 -0
  166. package/dist/site-tool-bridge.d.ts +57 -0
  167. package/dist/site.d.ts +182 -0
  168. package/dist/site.js +62 -0
  169. package/dist/site.js.map +1 -0
  170. package/dist/skills.d.ts +75 -0
  171. package/dist/sse.d.ts +1 -1
  172. package/dist/stream.d.ts +2 -0
  173. package/dist/tenant-workspaces.d.ts +47 -0
  174. package/dist/tenant-workspaces.js +8 -0
  175. package/dist/tenant-workspaces.js.map +1 -0
  176. package/dist/tool-auth.d.ts +87 -0
  177. package/dist/tool-auth.js +23 -0
  178. package/dist/tool-auth.js.map +1 -0
  179. package/dist/tool-display-metadata.d.ts +3 -0
  180. package/dist/tools-37DCTCNZ.js +12 -0
  181. package/dist/tools-37DCTCNZ.js.map +1 -0
  182. package/dist/tools.d.ts +81 -0
  183. package/dist/transcription.d.ts +1 -1
  184. package/dist/types.d.ts +2848 -573
  185. package/dist/usage-allowances.d.ts +36 -0
  186. package/dist/usage-allowances.js +80 -0
  187. package/dist/usage-allowances.js.map +1 -0
  188. package/dist/vault-types.d.ts +236 -0
  189. package/dist/vaults-api.d.ts +57 -0
  190. package/dist/workspace-artifacts.d.ts +47 -5
  191. package/dist/workspace-instruction-policies.d.ts +2 -2
  192. package/dist/workspace-integrations.d.ts +74 -0
  193. package/dist/workspace-integrations.js +65 -0
  194. package/dist/workspace-integrations.js.map +1 -0
  195. package/dist/workspace-state.d.ts +8 -71
  196. package/package.json +99 -5
  197. package/src/accounts.ts +18 -0
  198. package/src/adapters/express.ts +136 -0
  199. package/src/adapters/hono.ts +18 -0
  200. package/src/adapters/next.ts +42 -0
  201. package/src/allowance-refusal.ts +5 -0
  202. package/src/app-links.ts +117 -0
  203. package/src/artifact-catalog.ts +51 -0
  204. package/src/artifact-client.ts +40 -49
  205. package/src/artifacts.ts +1 -0
  206. package/src/automations-client.ts +8 -2
  207. package/src/azure-live-transport.ts +286 -0
  208. package/src/browser.ts +37 -0
  209. package/src/chat/fold.ts +431 -0
  210. package/src/chat/handler.ts +240 -0
  211. package/src/chat/http.ts +257 -0
  212. package/src/chat/ids.ts +85 -0
  213. package/src/chat/index.ts +88 -0
  214. package/src/chat/openai.ts +439 -0
  215. package/src/chat/opengeni.ts +737 -0
  216. package/src/chat/types.ts +219 -0
  217. package/src/chat/vercel.ts +204 -0
  218. package/src/chats.ts +16 -0
  219. package/src/client.ts +5822 -1847
  220. package/src/codex-realtime-controller.ts +163 -8
  221. package/src/codex-realtime-v3-wire.ts +4 -3
  222. package/src/codex-realtime-v3.ts +12 -3
  223. package/src/codex-realtime.ts +11 -3
  224. package/src/company-brain.ts +0 -40
  225. package/src/company-profile.ts +13 -0
  226. package/src/core.ts +20 -0
  227. package/src/deprecation.ts +149 -0
  228. package/src/document-authority-client.ts +104 -1
  229. package/src/editable-artifacts/controller.ts +36 -2
  230. package/src/editable-artifacts/index.ts +1 -0
  231. package/src/editable-artifacts/types.ts +29 -16
  232. package/src/embedding-client.ts +519 -0
  233. package/src/errors.ts +303 -4
  234. package/src/feedback.ts +20 -0
  235. package/src/gateway-realtime-transport.ts +3 -3
  236. package/src/github-repositories.ts +60 -0
  237. package/src/index.ts +611 -64
  238. package/src/insights-usage.ts +61 -0
  239. package/src/interaction.ts +274 -93
  240. package/src/knowledge.ts +72 -0
  241. package/src/known-tools.ts +279 -0
  242. package/src/message-links.ts +178 -0
  243. package/src/model-context.ts +113 -0
  244. package/src/model-display.ts +11 -0
  245. package/src/model-picker-order.ts +6 -0
  246. package/src/organization-integration-policy.ts +54 -0
  247. package/src/pr-review-client.ts +1 -1
  248. package/src/pr-review.ts +1 -1
  249. package/src/preference-registry.ts +2 -0
  250. package/src/prepared-mcp-setup.ts +123 -0
  251. package/src/proxy.ts +23 -12
  252. package/src/realtime.ts +16 -6
  253. package/src/session-history-import.ts +84 -0
  254. package/src/session-list-entries.ts +1 -0
  255. package/src/session-message-search.ts +47 -0
  256. package/src/session-proxy-client.ts +68 -0
  257. package/src/session-proxy.ts +2098 -0
  258. package/src/session-titles.ts +10 -0
  259. package/src/session-usage-limits.ts +71 -0
  260. package/src/shared-catalog-loader.ts +169 -0
  261. package/src/site-bridge-host.ts +422 -0
  262. package/src/site-browser-entry.ts +6 -0
  263. package/src/site-browser-runtime.gen.ts +2 -0
  264. package/src/site-data.ts +372 -0
  265. package/src/site-document.test.ts +64 -0
  266. package/src/site-document.ts +18 -0
  267. package/src/site-http.ts +171 -0
  268. package/src/site-sql.ts +153 -0
  269. package/src/site-tool-bridge.ts +401 -0
  270. package/src/site.ts +867 -0
  271. package/src/skills.ts +69 -0
  272. package/src/sse.ts +9 -3
  273. package/src/stream.ts +33 -10
  274. package/src/tenant-workspaces.ts +148 -0
  275. package/src/tool-auth.ts +301 -0
  276. package/src/tool-display-metadata.ts +27 -0
  277. package/src/tools.ts +452 -0
  278. package/src/transcription.ts +3 -0
  279. package/src/types.ts +3216 -581
  280. package/src/usage-allowances.ts +189 -0
  281. package/src/vault-types.ts +293 -0
  282. package/src/vaults-api.ts +288 -0
  283. package/src/workspace-artifacts.ts +55 -6
  284. package/src/workspace-instruction-policies.ts +2 -1
  285. package/src/workspace-integrations.ts +402 -0
  286. package/src/workspace-state.ts +8 -82
  287. package/dist/chunk-7ZXBPJZP.js.map +0 -1
  288. package/dist/chunk-C2H7HBNP.js.map +0 -1
  289. package/dist/chunk-C4DJPZRU.js +0 -119
  290. package/dist/chunk-C4DJPZRU.js.map +0 -1
  291. package/dist/chunk-GW3EJ2GP.js.map +0 -1
  292. package/dist/chunk-TX3EIENU.js.map +0 -1
  293. package/dist/chunk-VUQZAB3O.js.map +0 -1
  294. package/dist/chunk-VYCTL62C.js.map +0 -1
  295. package/dist/chunk-YTAWBDO2.js.map +0 -1
@@ -0,0 +1,1392 @@
1
+ import {
2
+ OpenGeniToolsClient,
3
+ createSharedCatalogLoader
4
+ } from "./chunk-P7UWKORG.js";
5
+ import {
6
+ OpenGeniClient
7
+ } from "./chunk-NEM5N6C6.js";
8
+ import {
9
+ OpenGeniApiError
10
+ } from "./chunk-7EWT3PV6.js";
11
+
12
+ // ../contracts/src/site-operations.ts
13
+ var ID = "[A-Za-z0-9_-]{1,128}";
14
+ var DATA = "/published-artifacts/current/(?:data|files)(?:/[A-Za-z0-9._~:@!$&'()*+,;=-]+)*";
15
+ var SITE_OPERATIONS = Object.freeze([
16
+ { id: "config.client", method: "GET", pattern: /^\/v1\/config\/client$/u },
17
+ { id: "workspace.get", method: "GET", pattern: /^$/u },
18
+ { id: "site.config", method: "GET", pattern: /^\/site\/config$/u },
19
+ { id: "models.list", method: "GET", pattern: /^\/model-catalog$/u },
20
+ { id: "sessions.list", method: "GET", pattern: /^\/sessions$/u },
21
+ { id: "sessions.create", method: "POST", pattern: /^\/sessions$/u, agent: true },
22
+ { id: "sessions.get", method: "GET", pattern: new RegExp(`^/sessions/${ID}$`, "u") },
23
+ { id: "sessions.events", method: "GET", pattern: new RegExp(`^/sessions/${ID}/events$`, "u") },
24
+ {
25
+ id: "sessions.stream",
26
+ method: "GET",
27
+ pattern: new RegExp(`^/sessions/${ID}/events/stream$`, "u"),
28
+ stream: true
29
+ },
30
+ {
31
+ id: "sessions.send",
32
+ method: "POST",
33
+ pattern: new RegExp(`^/sessions/${ID}/events$`, "u"),
34
+ agent: true
35
+ },
36
+ {
37
+ id: "sessions.steer",
38
+ method: "POST",
39
+ pattern: new RegExp(`^/sessions/${ID}/steer$`, "u"),
40
+ agent: true
41
+ },
42
+ {
43
+ id: "sessions.control",
44
+ method: "POST",
45
+ pattern: new RegExp(`^/sessions/${ID}/control$`, "u"),
46
+ agent: true
47
+ },
48
+ { id: "sessions.queue", method: "GET", pattern: new RegExp(`^/sessions/${ID}/queue$`, "u") },
49
+ // SessionConversation's documented queue edit/delete/steer/move.
50
+ {
51
+ id: "sessions.queue.item",
52
+ method: "POST",
53
+ pattern: new RegExp(`^/sessions/${ID}/queue/${ID}/(?:move|edit|steer|delete)$`, "u"),
54
+ agent: true
55
+ },
56
+ // SessionConversation's durable composer draft and its Send.
57
+ {
58
+ id: "sessions.composerDraft.get",
59
+ method: "GET",
60
+ pattern: new RegExp(`^/sessions/${ID}/composer-draft$`, "u")
61
+ },
62
+ {
63
+ id: "sessions.composerDraft.put",
64
+ method: "PUT",
65
+ pattern: new RegExp(`^/sessions/${ID}/composer-draft$`, "u")
66
+ },
67
+ {
68
+ id: "sessions.composerDraft.submit",
69
+ method: "POST",
70
+ pattern: new RegExp(`^/sessions/${ID}/composer-draft/submit$`, "u"),
71
+ agent: true
72
+ },
73
+ {
74
+ id: "sessions.humanInput",
75
+ method: "GET",
76
+ pattern: new RegExp(`^/sessions/${ID}/human-input-requests$`, "u")
77
+ },
78
+ // SessionConversation's human-input form reads the one open request.
79
+ {
80
+ id: "sessions.humanInput.get",
81
+ method: "GET",
82
+ pattern: new RegExp(`^/sessions/${ID}/human-input-requests/${ID}$`, "u")
83
+ },
84
+ { id: "data.read", method: "GET", pattern: new RegExp(`^${DATA}$`, "u") },
85
+ { id: "data.write", method: "POST", pattern: new RegExp(`^${DATA}$`, "u") },
86
+ { id: "data.put", method: "PUT", pattern: new RegExp(`^${DATA}$`, "u") },
87
+ { id: "data.patch", method: "PATCH", pattern: new RegExp(`^${DATA}$`, "u") },
88
+ { id: "data.delete", method: "DELETE", pattern: new RegExp(`^${DATA}$`, "u") },
89
+ // Site SQL (PR B): run one named query the owner defined; never raw SQL.
90
+ {
91
+ id: "sql.run",
92
+ method: "POST",
93
+ pattern: /^\/published-artifacts\/current\/sql\/queries\/[A-Za-z][A-Za-z0-9_-]{0,63}$/u
94
+ },
95
+ { id: "site.report", method: "POST", pattern: /^\/site\/reports$/u }
96
+ ]);
97
+ var SITE_TOOL_METHODS = Object.freeze([
98
+ "catalog",
99
+ "declarations",
100
+ "call",
101
+ "resolve",
102
+ "invoke"
103
+ ]);
104
+ var SITE_HOST_PREFIX = "/v1/workspaces/site-host";
105
+ function matchSiteOperation(method, path) {
106
+ if (/[%\\#\u0000-\u0020\u007f]/u.test(path)) return null;
107
+ if (path.split("/").some((part) => part === "." || part === "..")) return null;
108
+ const upper = method.toUpperCase();
109
+ let suffix;
110
+ if (path === "/v1/config/client") suffix = path;
111
+ else if (path === SITE_HOST_PREFIX) suffix = "";
112
+ else if (path.startsWith(`${SITE_HOST_PREFIX}/`)) suffix = path.slice(SITE_HOST_PREFIX.length);
113
+ else return null;
114
+ const operation = SITE_OPERATIONS.find(
115
+ (candidate) => candidate.method === upper && candidate.pattern.test(suffix)
116
+ );
117
+ return operation ? { operation, suffix } : null;
118
+ }
119
+
120
+ // ../contracts/src/site-session-http.ts
121
+ var SITE_WORKSPACE_PREFIX = "/v1/workspaces/site-host";
122
+ var SITE_DATA_PATH = /^\/v1\/workspaces\/site-host\/published-artifacts\/([^/]+)\/(?:data|files|sql)(?:\/|$)/u;
123
+ var SITE_NO_ORIGIN_ID = "00000000-0000-0000-0000-000000000000";
124
+ var SITE_FRAME_HEADER = "x-opengeni-site-frame";
125
+ var SITE_FRAME_ID_HEADER = "x-opengeni-site-frame-id";
126
+ var SITE_ID_HEADER = "x-opengeni-site-id";
127
+ var SITE_VERSION_HEADER = "x-opengeni-site-version";
128
+ var SiteSessionPathError = class extends Error {
129
+ code = "site_session_path_unsupported";
130
+ constructor() {
131
+ super("Unsupported Site session API path");
132
+ this.name = "SiteSessionPathError";
133
+ }
134
+ };
135
+ var SiteDataUnsupportedError = class extends Error {
136
+ code = "site_data_unsupported";
137
+ constructor() {
138
+ super("This Site host does not provide Site Data");
139
+ this.name = "SiteDataUnsupportedError";
140
+ }
141
+ };
142
+ function unsafePathname(pathname) {
143
+ return /[%\\#\u0000-\u0020\u007f]/u.test(pathname) || pathname.split("/").some((part) => part === "." || part === "..");
144
+ }
145
+ function hostWorkspacePath(path, workspaceId) {
146
+ return path.replace("/workspaces/site-host", `/workspaces/${encodeURIComponent(workspaceId)}`);
147
+ }
148
+ function siteDataPath(path, rewritten, workspaceId, siteId) {
149
+ if (workspaceId === "site-host") return path;
150
+ if (!siteId) throw new SiteDataUnsupportedError();
151
+ return rewritten.replace(
152
+ "/published-artifacts/current/",
153
+ `/published-artifacts/${encodeURIComponent(siteId)}/`
154
+ );
155
+ }
156
+ function siteSessionPath(path, workspaceId, method = "GET", siteId) {
157
+ const pathname = path.split("?")[0];
158
+ const match = matchSiteOperation(method, pathname);
159
+ if (!match) throw new SiteSessionPathError();
160
+ const rewritten = hostWorkspacePath(path, workspaceId);
161
+ if (SITE_DATA_PATH.test(pathname)) return siteDataPath(path, rewritten, workspaceId, siteId);
162
+ if (match.operation.id !== "sessions.list") return rewritten;
163
+ const url = new URL(rewritten, "http://site.invalid");
164
+ const origins = url.searchParams.getAll("originSiteId");
165
+ if (origins.length !== 1 || origins[0] !== "current") throw new SiteSessionPathError();
166
+ if (workspaceId === "site-host") return path;
167
+ url.searchParams.set("originSiteId", siteId ?? SITE_NO_ORIGIN_ID);
168
+ return url.pathname + url.search;
169
+ }
170
+ function siteFrameOperation(method, pathname, workspaceId, frameSiteId) {
171
+ if (unsafePathname(pathname)) return null;
172
+ let sitePath = pathname;
173
+ if (pathname !== "/v1/config/client") {
174
+ const prefix = `/v1/workspaces/${workspaceId}`;
175
+ if (pathname !== prefix && !pathname.startsWith(`${prefix}/`)) return null;
176
+ sitePath = `${SITE_WORKSPACE_PREFIX}${pathname.slice(prefix.length)}`;
177
+ const data = /^\/v1\/workspaces\/site-host\/published-artifacts\/([^/]+)\//u.exec(sitePath);
178
+ if (data) {
179
+ if (!frameSiteId || data[1] !== frameSiteId) return null;
180
+ sitePath = sitePath.replace(
181
+ `/published-artifacts/${frameSiteId}/`,
182
+ "/published-artifacts/current/"
183
+ );
184
+ }
185
+ }
186
+ const match = matchSiteOperation(method, sitePath);
187
+ if (!match) return null;
188
+ const session = /^\/sessions\/([^/]+)(?:\/|$)/u.exec(match.suffix);
189
+ return { ...match, sessionId: session ? session[1] : null };
190
+ }
191
+ function siteRequestHeaders(input) {
192
+ const headers = new Headers(input);
193
+ const connectionHeaders = (headers.get("connection") ?? "").split(",").map((value) => value.trim().toLowerCase());
194
+ for (const name of [...headers.keys()]) {
195
+ if (connectionHeaders.includes(name) || /^(authorization|proxy-authorization|cookie|cookie2|host|origin|referer|connection|keep-alive|proxy-connection|te|trailer|transfer-encoding|upgrade|content-length|accept-encoding|forwarded|x-api-key)$/i.test(
196
+ name
197
+ ) || /^(sec-|x-forwarded-|x-opengeni-(access-key|external-actor|site-|managed-actor))/i.test(name))
198
+ headers.delete(name);
199
+ }
200
+ return headers;
201
+ }
202
+ var SITE_FRAME_MESSAGE_FIELDS = [
203
+ "text",
204
+ "annotations",
205
+ "model",
206
+ "reasoningEffort",
207
+ "latencyMode",
208
+ "controlEtag",
209
+ "expectedDraftRevision"
210
+ ];
211
+ var SITE_FRAME_BODY_FIELDS = Object.freeze({
212
+ "sessions.send": ["type", "payload", "clientEventId"],
213
+ "sessions.steer": [...SITE_FRAME_MESSAGE_FIELDS, "clientEventId"],
214
+ "sessions.control": ["action", "reason", "clientEventId", "expectedControlEtag"],
215
+ "sessions.composerDraft.put": [
216
+ "text",
217
+ "annotations",
218
+ "resources",
219
+ "model",
220
+ "reasoningEffort",
221
+ "latencyMode",
222
+ "expectedRevision"
223
+ ],
224
+ "sessions.composerDraft.submit": [
225
+ ...SITE_FRAME_MESSAGE_FIELDS,
226
+ "resources",
227
+ "connectionAccounts",
228
+ "clientEventId",
229
+ "delivery"
230
+ ],
231
+ "sessions.queue.move": ["clientEventId", "expectedQueueVersion", "beforeTurnId"],
232
+ "sessions.queue.edit": [
233
+ "clientEventId",
234
+ "expectedTurnVersion",
235
+ "expectedDraftRevision",
236
+ "replaceDraft"
237
+ ],
238
+ "sessions.queue.steer": ["clientEventId", "expectedTurnVersion", "controlEtag"],
239
+ "sessions.queue.delete": ["clientEventId", "expectedTurnVersion", "reason"]
240
+ });
241
+ var SITE_FRAME_EMPTY_ONLY_FIELDS = /* @__PURE__ */ new Set(["resources", "connectionAccounts"]);
242
+ var SITE_FRAME_SESSION_CREATE_FIELDS = Object.freeze([
243
+ "initialMessage",
244
+ "requestedSessionId",
245
+ "idempotencyKey",
246
+ "clientEventId",
247
+ "model",
248
+ "reasoningEffort",
249
+ "latencyMode",
250
+ "startMode",
251
+ "metadata"
252
+ ]);
253
+ function bodyRecord(value) {
254
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
255
+ }
256
+ function emptyBodyValue(value) {
257
+ if (value === void 0 || value === null) return true;
258
+ if (Array.isArray(value)) return value.length === 0;
259
+ if (typeof value === "object") return Object.keys(value).length === 0;
260
+ return false;
261
+ }
262
+ function refusedField(body, allowed, prefix = "") {
263
+ for (const [name, value] of Object.entries(body)) {
264
+ if (emptyBodyValue(value)) continue;
265
+ if (!allowed.includes(name) || SITE_FRAME_EMPTY_ONLY_FIELDS.has(name))
266
+ return `${prefix}${name}`;
267
+ }
268
+ return null;
269
+ }
270
+ function siteFrameBodyRefusal(operationId, suffix, body) {
271
+ const record = bodyRecord(body);
272
+ if (!record) return null;
273
+ if (operationId === "sessions.create")
274
+ return refusedField(record, SITE_FRAME_SESSION_CREATE_FIELDS);
275
+ const action = operationId === "sessions.queue.item" ? /\/queue\/[^/]+\/(move|edit|steer|delete)$/u.exec(suffix)?.[1] : void 0;
276
+ const key = action ? `sessions.queue.${action}` : operationId;
277
+ const allowed = SITE_FRAME_BODY_FIELDS[key];
278
+ if (!allowed) return null;
279
+ const refused = refusedField(record, allowed);
280
+ if (refused) return refused;
281
+ if (operationId !== "sessions.send") return null;
282
+ if (record.type !== "user.message") return "type";
283
+ const payload = bodyRecord(record.payload);
284
+ return payload ? refusedField(payload, SITE_FRAME_MESSAGE_FIELDS, "payload.") : null;
285
+ }
286
+
287
+ // src/site-http.ts
288
+ var SITE_HTTP = "opengeni.site.http";
289
+ var SITE_WORKSPACE = "site-host";
290
+ function isSiteHttpRequest(value) {
291
+ if (!value || typeof value !== "object") return false;
292
+ const v = value;
293
+ return v.type === SITE_HTTP && typeof v.requestId === "string" && typeof v.path === "string" && typeof v.method === "string" && /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(v.method) && (v.body === void 0 || typeof v.body === "string" || v.body instanceof ArrayBuffer) && Array.isArray(v.headers) && v.headers.every(
294
+ (h) => Array.isArray(h) && h.length === 2 && h.every((x) => typeof x === "string")
295
+ );
296
+ }
297
+ async function serveSiteHttp(message, port, fetchResponse, signal) {
298
+ let reader;
299
+ let wake;
300
+ let pulling = false;
301
+ const onMessage = (event) => {
302
+ if (event.data === "pull") {
303
+ pulling = true;
304
+ wake?.();
305
+ }
306
+ };
307
+ const abort = () => {
308
+ void reader?.cancel(signal.reason).catch(() => {
309
+ });
310
+ wake?.();
311
+ };
312
+ port.addEventListener("message", onMessage);
313
+ signal.addEventListener("abort", abort, { once: true });
314
+ port.start();
315
+ try {
316
+ if (signal.aborted) throw signal.reason;
317
+ const response = await fetchResponse(message, signal);
318
+ reader = response.body?.getReader();
319
+ port.postMessage({ status: response.status, headers: [...response.headers], body: !!reader });
320
+ if (reader)
321
+ while (!signal.aborted) {
322
+ if (!pulling)
323
+ await new Promise((resolve) => {
324
+ wake = resolve;
325
+ });
326
+ wake = void 0;
327
+ if (signal.aborted) break;
328
+ pulling = false;
329
+ const part = await reader.read();
330
+ if (part.done) {
331
+ port.postMessage({ done: true });
332
+ break;
333
+ }
334
+ port.postMessage({ chunk: part.value });
335
+ }
336
+ if (signal.aborted) throw signal.reason;
337
+ } catch (error) {
338
+ port.postMessage({ error: error instanceof Error ? error.message : "Site request failed" });
339
+ } finally {
340
+ signal.removeEventListener("abort", abort);
341
+ port.removeEventListener("message", onMessage);
342
+ await reader?.cancel().catch(() => {
343
+ });
344
+ port.close();
345
+ }
346
+ }
347
+ async function sitePortFetch(port, input, init) {
348
+ const request = new Request(input, init);
349
+ const url = new URL(request.url);
350
+ const path = `${url.pathname}${url.search}`;
351
+ siteSessionPath(path, SITE_WORKSPACE, request.method);
352
+ const channel = new MessageChannel();
353
+ const requestId = crypto.randomUUID();
354
+ const binary = init?.body instanceof ArrayBuffer || ArrayBuffer.isView(init?.body) || typeof Blob !== "undefined" && init?.body instanceof Blob;
355
+ const body = request.body ? binary ? await request.arrayBuffer() : await request.text() : void 0;
356
+ return await new Promise((resolve, reject) => {
357
+ let controller;
358
+ let finished = false;
359
+ const cleanup = () => {
360
+ finished = true;
361
+ request.signal.removeEventListener("abort", abort);
362
+ channel.port1.close();
363
+ };
364
+ const abort = () => {
365
+ if (finished) return;
366
+ port.postMessage({ type: "opengeni.site.cancel", version: 2, requestId });
367
+ const error = request.signal.reason ?? new DOMException("Cancelled", "AbortError");
368
+ controller?.error(error);
369
+ reject(error);
370
+ cleanup();
371
+ };
372
+ channel.port1.onmessage = (event) => {
373
+ const data = event.data;
374
+ if (data.error) {
375
+ const error = new Error(data.error);
376
+ controller?.error(error);
377
+ reject(error);
378
+ cleanup();
379
+ } else if (data.status) {
380
+ const stream = data.body ? new ReadableStream({
381
+ start(c) {
382
+ controller = c;
383
+ },
384
+ pull() {
385
+ channel.port1.postMessage("pull");
386
+ },
387
+ cancel() {
388
+ controller = void 0;
389
+ abort();
390
+ }
391
+ }) : null;
392
+ resolve(new Response(stream, { status: data.status, headers: data.headers }));
393
+ if (!data.body) cleanup();
394
+ } else if (data.done) {
395
+ controller?.close();
396
+ cleanup();
397
+ } else if (data.chunk) controller?.enqueue(data.chunk);
398
+ };
399
+ if (request.signal.aborted) {
400
+ abort();
401
+ return;
402
+ }
403
+ request.signal.addEventListener("abort", abort, { once: true });
404
+ port.postMessage(
405
+ {
406
+ type: SITE_HTTP,
407
+ requestId,
408
+ path,
409
+ method: request.method,
410
+ headers: [...request.headers],
411
+ ...body === void 0 ? {} : { body }
412
+ },
413
+ [channel.port2]
414
+ );
415
+ });
416
+ }
417
+
418
+ // src/site-tool-bridge.ts
419
+ function createSiteToolBridge(input) {
420
+ const allowed = input.requestedTools ? new Set(input.requestedTools.map(identityKey)) : null;
421
+ const frameId = crypto.randomUUID();
422
+ const targeted = input.workspaceTools.$targetProtocol === 1 && input.workspaceTools.$resolve && input.workspaceTools.$invoke && input.workspaceTools.$manifest;
423
+ const context = input.artifactId ? { siteArtifactId: input.artifactId, siteVersionId: input.siteVersionId } : {};
424
+ const manifests = /* @__PURE__ */ new Map();
425
+ const resolve = async (request, { signal }) => {
426
+ if (allowed && "identity" in request.target && !allowed.has(identityKey(request.target.identity)))
427
+ throw new Error("This tool is not available to the Site");
428
+ const tool = await input.workspaceTools.$resolve(request.target, { signal, ...context });
429
+ if (allowed && !allowed.has(identityKey(tool.entry.identity)))
430
+ throw new Error("This tool is not available to the Site");
431
+ return tool;
432
+ };
433
+ const invoke = async (request, { signal }) => {
434
+ if (allowed && "identity" in request.target && !allowed.has(identityKey(request.target.identity)))
435
+ throw new Error("This tool is not available to the Site");
436
+ return await input.workspaceTools.$invoke(
437
+ {
438
+ target: request.target,
439
+ operationId: request.operationId,
440
+ arguments: request.arguments,
441
+ ...request.expectedDefinitionDigest === void 0 ? {} : { expectedDefinitionDigest: request.expectedDefinitionDigest },
442
+ ...context
443
+ },
444
+ { signal }
445
+ );
446
+ };
447
+ const projectedCatalog = createSharedCatalogLoader(
448
+ async (refresh, signal) => {
449
+ if (targeted && input.requestedTools) {
450
+ const manifest = await input.workspaceTools.$manifest(
451
+ { identities: [...input.requestedTools], ...context },
452
+ { signal }
453
+ );
454
+ signal.throwIfAborted();
455
+ if (manifests.size >= 4) manifests.delete(manifests.keys().next().value);
456
+ manifests.set(manifest.digest, manifest.tools);
457
+ return {
458
+ version: 1,
459
+ generation: 1,
460
+ digest: manifest.digest,
461
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
462
+ entries: manifest.tools.map((tool) => tool.entry)
463
+ };
464
+ }
465
+ const current = await input.workspaceTools.$catalog({
466
+ signal,
467
+ ...refresh ? { refresh } : {}
468
+ });
469
+ if (current.workspaceId !== input.workspaceId)
470
+ throw new Error("Site catalog workspace mismatch");
471
+ return {
472
+ version: current.version,
473
+ generation: current.generation,
474
+ digest: current.digest,
475
+ createdAt: current.createdAt,
476
+ entries: current.entries.filter(
477
+ (entry) => !allowed || allowed.has(identityKey(entry.identity))
478
+ )
479
+ };
480
+ }
481
+ );
482
+ const loadCatalog = async ({
483
+ signal,
484
+ staleDigest
485
+ }) => {
486
+ signal.throwIfAborted();
487
+ const catalog = staleDigest === void 0 ? await projectedCatalog.load({ signal }) : await projectedCatalog.reloadAfterStale(staleDigest, signal);
488
+ signal.throwIfAborted();
489
+ return catalog;
490
+ };
491
+ return {
492
+ ...targeted ? { resolve, invoke } : {},
493
+ ...input.fetchResponse && input.artifactId ? { siteData: true } : {},
494
+ ...input.fetchResponse ? {
495
+ fetch: async (message, signal) => {
496
+ const path = siteSessionPath(
497
+ message.path,
498
+ input.workspaceId,
499
+ message.method,
500
+ input.artifactId
501
+ );
502
+ const refused = siteFrameBodyFieldRefusal(path, message, input);
503
+ if (refused) return refused;
504
+ const headers = siteRequestHeaders(message.headers);
505
+ headers.set(SITE_FRAME_HEADER, "1");
506
+ headers.set(SITE_FRAME_ID_HEADER, frameId);
507
+ if (input.artifactId) {
508
+ headers.set(SITE_ID_HEADER, input.artifactId);
509
+ headers.set(SITE_VERSION_HEADER, input.siteVersionId);
510
+ }
511
+ return input.fetchResponse(path, {
512
+ method: message.method,
513
+ signal,
514
+ headers: Object.fromEntries(headers),
515
+ ...message.body === void 0 ? {} : { body: message.body }
516
+ });
517
+ }
518
+ } : {},
519
+ catalog: async ({ signal }) => await loadCatalog({ signal }),
520
+ call: async (request, { signal }) => {
521
+ if (allowed && !allowed.has(identityKey(request.identity)))
522
+ throw new Error("This tool is not available to the Site");
523
+ if (targeted && input.requestedTools) {
524
+ const tool = manifests.get(request.catalogDigest)?.find(
525
+ (candidate) => identityKey(candidate.entry.identity) === identityKey(request.identity)
526
+ );
527
+ if (!tool)
528
+ throw new OpenGeniApiError(
529
+ 409,
530
+ JSON.stringify({
531
+ error: { code: "conflict", details: { code: "catalog_stale" }, retryable: true }
532
+ })
533
+ );
534
+ try {
535
+ const response = await invoke(
536
+ {
537
+ operationId: request.operationId ?? crypto.randomUUID(),
538
+ target: { identity: request.identity },
539
+ arguments: request.arguments,
540
+ expectedDefinitionDigest: tool.definitionDigest
541
+ },
542
+ { signal }
543
+ );
544
+ return {
545
+ operationId: response.operationId,
546
+ catalogDigest: request.catalogDigest,
547
+ result: legacySiteToolResult(response.result)
548
+ };
549
+ } catch (error) {
550
+ if (error instanceof OpenGeniApiError && error.retryable !== false && !error.outcomeUnknown && error.details?.code === "tool_definition_stale") {
551
+ projectedCatalog.invalidate(request.catalogDigest);
552
+ manifests.delete(request.catalogDigest);
553
+ throw new OpenGeniApiError(
554
+ 409,
555
+ JSON.stringify({
556
+ error: {
557
+ code: "catalog_stale",
558
+ details: { code: "catalog_stale" },
559
+ retryable: true
560
+ }
561
+ })
562
+ );
563
+ }
564
+ throw error;
565
+ }
566
+ }
567
+ let usedDigest;
568
+ const call = async (staleDigest) => {
569
+ const catalog = await loadCatalog({
570
+ signal,
571
+ ...staleDigest === void 0 ? {} : { staleDigest }
572
+ });
573
+ usedDigest = catalog.digest;
574
+ if (!catalog.entries.some(
575
+ (entry) => identityKey(entry.identity) === identityKey(request.identity)
576
+ ))
577
+ throw new Error("This requested tool is not enabled in the workspace");
578
+ const response = await input.callTool({
579
+ workspaceId: input.workspaceId,
580
+ signal,
581
+ request: {
582
+ ...request.operationId ? { operationId: request.operationId } : {},
583
+ catalogDigest: catalog.digest,
584
+ identity: request.identity,
585
+ arguments: request.arguments,
586
+ ...input.artifactId ? { siteArtifactId: input.artifactId, siteVersionId: input.siteVersionId } : {}
587
+ }
588
+ });
589
+ return { ...response, result: legacySiteToolResult(response.result) };
590
+ };
591
+ try {
592
+ return await call();
593
+ } catch (error) {
594
+ if (staleRetryVetoed(error) || !(input.isCatalogStale ?? isSiteCatalogStaleError)(error) || usedDigest === void 0)
595
+ throw error;
596
+ return await call(usedDigest);
597
+ }
598
+ }
599
+ };
600
+ }
601
+ function legacySiteToolResult(result) {
602
+ if (!result?.isError) return result;
603
+ const structured = result.structuredContent;
604
+ const error = structured?.error;
605
+ if (typeof error !== "object" || error === null || !("code" in error) || error.code !== "catalog_stale" && error.code !== "tool_definition_stale")
606
+ return result;
607
+ return {
608
+ ...result,
609
+ structuredContent: {
610
+ ...structured,
611
+ error: {
612
+ code: "site_tool_execution_failed",
613
+ message: "message" in error && typeof error.message === "string" ? error.message : "Site tool execution failed",
614
+ retryable: false,
615
+ outcomeUnknown: "outcomeUnknown" in error && error.outcomeUnknown === true,
616
+ providerError: error
617
+ }
618
+ }
619
+ };
620
+ }
621
+ function isSiteCatalogStaleError(error) {
622
+ return !staleRetryVetoed(error) && error instanceof OpenGeniApiError && error.status === 409 && error.details?.code === "catalog_stale";
623
+ }
624
+ function staleRetryVetoed(error) {
625
+ return typeof error === "object" && error !== null && ("outcomeUnknown" in error && error.outcomeUnknown === true || "retryable" in error && error.retryable === false);
626
+ }
627
+ function identityKey(identity) {
628
+ return `${identity.serverId}\0${identity.toolName}`;
629
+ }
630
+ function siteFrameBodyFieldRefusal(path, message, input) {
631
+ if (typeof message.body !== "string" || message.method === "GET") return null;
632
+ const operation = siteFrameOperation(
633
+ message.method,
634
+ path.split("?")[0],
635
+ input.workspaceId,
636
+ input.artifactId ?? null
637
+ );
638
+ if (!operation) return null;
639
+ let body;
640
+ try {
641
+ body = JSON.parse(message.body);
642
+ } catch {
643
+ return null;
644
+ }
645
+ const field = siteFrameBodyRefusal(operation.operation.id, operation.suffix, body);
646
+ if (!field) return null;
647
+ return Response.json(
648
+ {
649
+ error: {
650
+ status: 403,
651
+ code: "forbidden",
652
+ message: "A Site page can send message text only. Approvals, answers, resources, credentials and connection choices happen in the console.",
653
+ retryable: false,
654
+ details: { code: "site_frame_field_forbidden", field }
655
+ }
656
+ },
657
+ { status: 403 }
658
+ );
659
+ }
660
+
661
+ // src/site-data.ts
662
+ var OpenGeniSiteDataError = class extends Error {
663
+ constructor(code, message, status, details = {}) {
664
+ super(message);
665
+ this.code = code;
666
+ this.status = status;
667
+ this.details = details;
668
+ this.name = "OpenGeniSiteDataError";
669
+ }
670
+ };
671
+ var SITE_DATA_PATH_PREFIX = "/v1/workspaces/site-host/published-artifacts/current";
672
+ function createOpenGeniSiteData(fetchSite, ready) {
673
+ const send = async (path, init = {}) => {
674
+ if (!await ready())
675
+ throw new OpenGeniSiteDataError(
676
+ "site_data_unsupported",
677
+ "This Site host does not provide Site Data",
678
+ 0
679
+ );
680
+ const response = await fetchSite(`${SITE_DATA_PATH_PREFIX}${path}`, init);
681
+ const text = await response.text();
682
+ let value = null;
683
+ try {
684
+ value = text ? JSON.parse(text) : null;
685
+ } catch {
686
+ value = null;
687
+ }
688
+ if (response.ok) return value;
689
+ throw siteDataErrorFromResponse(response.status, value);
690
+ };
691
+ const json = (body) => ({
692
+ method: "POST",
693
+ headers: { "content-type": "application/json" },
694
+ body: JSON.stringify(body)
695
+ });
696
+ const write = async (operations) => (await send("/data/write", json({ operations }))).results;
697
+ const one = async (operation) => {
698
+ const [result] = await write([operation]);
699
+ if (!result || !("record" in result))
700
+ throw new OpenGeniSiteDataError("request_failed", "Unexpected Site Data response", 200);
701
+ return result.record;
702
+ };
703
+ const count = async (collection, where, scope) => (await send(
704
+ "/data/query",
705
+ json({
706
+ collection,
707
+ limit: 1,
708
+ count: true,
709
+ ...where ? { where } : {},
710
+ ...scope ? { scope } : {}
711
+ })
712
+ )).count ?? 0;
713
+ const data = {
714
+ collection(name) {
715
+ const collection = {
716
+ name,
717
+ list: async (options = {}) => await send(
718
+ "/data/query",
719
+ json({ collection: name, ...options })
720
+ ),
721
+ get: async (ref) => {
722
+ try {
723
+ return (await send(
724
+ "/data/get",
725
+ json({ collection: name, ...refFields(ref) })
726
+ )).record;
727
+ } catch (error) {
728
+ if (error instanceof OpenGeniSiteDataError && error.code === "not_found") return null;
729
+ throw error;
730
+ }
731
+ },
732
+ insert: async (value, options = {}) => await one({
733
+ op: "insert",
734
+ collection: name,
735
+ data: value,
736
+ ...options.key === void 0 ? {} : { key: options.key }
737
+ }),
738
+ put: async (key, value, options = {}) => await one({
739
+ op: "put",
740
+ collection: name,
741
+ key,
742
+ data: value,
743
+ ...options
744
+ }),
745
+ patch: async (ref, value, options = {}) => await one({
746
+ op: "patch",
747
+ collection: name,
748
+ ...refFields(ref),
749
+ data: value,
750
+ ...options
751
+ }),
752
+ delete: async (ref, options = {}) => {
753
+ await write([{ op: "delete", collection: name, ...refFields(ref), ...options }]);
754
+ },
755
+ increment: async (ref, field, by) => await one({
756
+ op: "increment",
757
+ collection: name,
758
+ ...refFields(ref),
759
+ field,
760
+ ...by === void 0 ? {} : { by }
761
+ }),
762
+ count: async (where, options = {}) => await count(name, where, options.scope)
763
+ };
764
+ return collection;
765
+ },
766
+ batch: write,
767
+ count: async (collection, where) => await count(collection, where)
768
+ };
769
+ const files = {
770
+ upload: async (file, options = {}) => {
771
+ const blob = file instanceof Blob ? file : new Blob([file instanceof Uint8Array ? file.slice() : file], {
772
+ type: options.contentType ?? "application/octet-stream"
773
+ });
774
+ const name = options.name ?? (typeof File !== "undefined" && file instanceof File ? file.name : "file");
775
+ const query = new URLSearchParams({ name, scope: options.scope ?? "shared" });
776
+ return await send(`/files?${query}`, {
777
+ method: "POST",
778
+ headers: {
779
+ "content-type": options.contentType ?? (blob.type || "application/octet-stream")
780
+ },
781
+ body: await blob.arrayBuffer()
782
+ });
783
+ },
784
+ list: async (options = {}) => {
785
+ const query = new URLSearchParams();
786
+ if (options.limit !== void 0) query.set("limit", String(options.limit));
787
+ if (options.cursor) query.set("cursor", options.cursor);
788
+ const suffix = query.size ? `?${query}` : "";
789
+ return await send(`/files${suffix}`, { method: "GET" });
790
+ },
791
+ url: async (fileId) => await send(`/files/${encodeURIComponent(fileId)}`, { method: "GET" }),
792
+ delete: async (fileId) => {
793
+ await send(`/files/${encodeURIComponent(fileId)}`, { method: "DELETE" });
794
+ }
795
+ };
796
+ return { data, files };
797
+ }
798
+ function refFields(ref) {
799
+ if (typeof ref === "string") return { key: ref };
800
+ if ("id" in ref) return { id: ref.id };
801
+ return { key: ref.key };
802
+ }
803
+ var KNOWN_CODES = /* @__PURE__ */ new Set([
804
+ "validation",
805
+ "conflict",
806
+ "not_found",
807
+ "forbidden",
808
+ "not_available_for_viewer",
809
+ "quota_exceeded",
810
+ "rate_limited"
811
+ ]);
812
+ function siteDataErrorFromResponse(status, value) {
813
+ const error = typeof value === "object" && value !== null && "error" in value ? value.error : null;
814
+ const record = typeof error === "object" && error !== null ? error : {};
815
+ const details = typeof record.details === "object" && record.details !== null ? record.details : {};
816
+ const detailCode = details.code;
817
+ const code = detailCode && KNOWN_CODES.has(detailCode) ? detailCode : status === 404 ? "not_found" : status === 403 ? "forbidden" : status === 413 ? "quota_exceeded" : status === 429 ? "rate_limited" : "request_failed";
818
+ const message = typeof record.message === "string" && record.message ? record.message : `Site Data request failed with HTTP ${status}`;
819
+ return new OpenGeniSiteDataError(code, message, status, details);
820
+ }
821
+
822
+ // src/site-sql.ts
823
+ var OpenGeniSiteSqlError = class extends Error {
824
+ constructor(code, message, status, details = {}) {
825
+ super(message);
826
+ this.code = code;
827
+ this.status = status;
828
+ this.details = details;
829
+ this.name = "OpenGeniSiteSqlError";
830
+ }
831
+ };
832
+ var QUERY_NAME = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/u;
833
+ var KNOWN_CODES2 = /* @__PURE__ */ new Set([
834
+ "validation",
835
+ "not_found",
836
+ "forbidden",
837
+ "not_available_for_viewer",
838
+ "conflict",
839
+ "quota_exceeded",
840
+ "rate_limited",
841
+ "sql_error",
842
+ "unavailable",
843
+ "disabled"
844
+ ]);
845
+ function createOpenGeniSiteSql(fetchSite, ready) {
846
+ return {
847
+ async run(name, params = {}) {
848
+ if (!QUERY_NAME.test(name))
849
+ throw new OpenGeniSiteSqlError("validation", "Invalid query name", 0);
850
+ if (Object.keys(params).some((key) => key === "viewer" || key.startsWith("viewer_")))
851
+ throw new OpenGeniSiteSqlError(
852
+ "validation",
853
+ "viewer parameters are bound by the host, not the Site",
854
+ 0
855
+ );
856
+ if (!await ready())
857
+ throw new OpenGeniSiteSqlError(
858
+ "site_sql_unsupported",
859
+ "This Site host does not provide Site SQL",
860
+ 0
861
+ );
862
+ const response = await fetchSite(
863
+ `${SITE_DATA_PATH_PREFIX}/sql/queries/${encodeURIComponent(name)}`,
864
+ {
865
+ method: "POST",
866
+ headers: { "content-type": "application/json" },
867
+ body: JSON.stringify({ params })
868
+ }
869
+ );
870
+ const text = await response.text();
871
+ let value = null;
872
+ try {
873
+ value = text ? JSON.parse(text) : null;
874
+ } catch {
875
+ value = null;
876
+ }
877
+ if (response.ok) return value;
878
+ throw siteSqlErrorFromResponse(response.status, value);
879
+ }
880
+ };
881
+ }
882
+ function siteSqlErrorFromResponse(status, value) {
883
+ const error = typeof value === "object" && value !== null && "error" in value ? value.error : null;
884
+ const record = typeof error === "object" && error !== null ? error : {};
885
+ const details = typeof record.details === "object" && record.details !== null ? record.details : {};
886
+ const detailCode = typeof details.code === "string" ? details.code : void 0;
887
+ const code = detailCode && KNOWN_CODES2.has(detailCode) ? detailCode : status === 404 ? "not_found" : status === 403 ? "forbidden" : status === 413 ? "quota_exceeded" : status === 429 ? "rate_limited" : "request_failed";
888
+ const message = typeof record.message === "string" && record.message ? record.message : `Site SQL request failed with HTTP ${status}`;
889
+ return new OpenGeniSiteSqlError(code, message, status, details);
890
+ }
891
+
892
+ // src/site.ts
893
+ var OPENGENI_SITE_BRIDGE_VERSION = 2;
894
+ var OPENGENI_SITE_BRIDGE_CONNECT = "opengeni.site.connect";
895
+ var OPENGENI_SITE_BRIDGE_READY = "opengeni.site.ready";
896
+ var OPENGENI_SITE_BRIDGE_REQUEST = "opengeni.site.request";
897
+ var OPENGENI_SITE_BRIDGE_RESPONSE = "opengeni.site.response";
898
+ var OPENGENI_SITE_BRIDGE_CANCEL = "opengeni.site.cancel";
899
+ var OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL = "__opengeniSiteBridgeBootstrapV2";
900
+ var OPENGENI_SITE_LOCAL_CODEMODE_PATH = "/__opengeni/site-tools";
901
+ var OPENGENI_SITE_BRIDGE_VIEWER_METHOD = "viewer";
902
+ var OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD = "auth.signIn";
903
+ var OpenGeniSiteBridgeError = class extends Error {
904
+ constructor(code, message, retryable = false, outcomeUnknown = false) {
905
+ super(message);
906
+ this.code = code;
907
+ this.retryable = retryable;
908
+ this.outcomeUnknown = outcomeUnknown;
909
+ this.name = "OpenGeniSiteBridgeError";
910
+ }
911
+ };
912
+ function createOpenGeniSiteClient(options = {}) {
913
+ const transport = shouldUseLocalCodemode(options) ? new OpenGeniSiteLocalCodemodeTransport(options) : new OpenGeniSiteBridgeTransport(options);
914
+ const siteData = createOpenGeniSiteData(
915
+ (path, init) => transport.fetch(`https://site.opengeni.invalid${path}`, init),
916
+ () => transport.siteDataSupported()
917
+ );
918
+ const siteSql = createOpenGeniSiteSql(
919
+ (path, init) => transport.fetch(`https://site.opengeni.invalid${path}`, init),
920
+ () => transport.siteDataSupported()
921
+ );
922
+ let viewer = null;
923
+ let capabilities = null;
924
+ return {
925
+ client: new OpenGeniClient({
926
+ baseUrl: "https://site.opengeni.invalid",
927
+ toolGatewayMode: options.toolGatewayMode ?? "target",
928
+ fetch: (input, init) => transport.fetch(input, init)
929
+ }),
930
+ workspaceId: SITE_WORKSPACE,
931
+ tools: new OpenGeniToolsClient(transport).forWorkspace("site-host"),
932
+ data: siteData.data,
933
+ files: siteData.files,
934
+ sql: siteSql,
935
+ get viewer() {
936
+ if (!viewer) {
937
+ const pending = transport.viewer();
938
+ viewer = pending;
939
+ pending.catch(() => {
940
+ if (viewer === pending) viewer = null;
941
+ });
942
+ }
943
+ return viewer;
944
+ },
945
+ get capabilities() {
946
+ capabilities ??= readSiteCapabilities(transport);
947
+ return capabilities;
948
+ },
949
+ auth: { signIn: () => transport.signIn() },
950
+ close: () => transport.close()
951
+ };
952
+ }
953
+ var OpenGeniSiteLocalCodemodeTransport = class {
954
+ toolGatewayMode;
955
+ fetchImpl;
956
+ basePath;
957
+ constructor(options) {
958
+ this.toolGatewayMode = options.toolGatewayMode ?? "target";
959
+ this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
960
+ const configured = options.localCodemodePath;
961
+ this.basePath = (typeof configured === "string" ? configured : OPENGENI_SITE_LOCAL_CODEMODE_PATH).replace(/\/+$/u, "");
962
+ }
963
+ close() {
964
+ }
965
+ /** Local previews have no published Site, so no Site Data. */
966
+ async siteDataSupported() {
967
+ return false;
968
+ }
969
+ /** Local previews run outside any host that knows the viewer. */
970
+ async viewer() {
971
+ return null;
972
+ }
973
+ async signIn() {
974
+ return { started: false };
975
+ }
976
+ async fetch(input, init) {
977
+ const request = new Request(input, init);
978
+ const url = new URL(request.url);
979
+ const path = `${url.pathname}${url.search}`;
980
+ siteSessionPath(path, SITE_WORKSPACE, request.method);
981
+ return this.fetchImpl(`${this.basePath}/sdk${path}`, {
982
+ method: request.method,
983
+ headers: request.headers,
984
+ signal: request.signal,
985
+ ...request.body ? { body: await request.text() } : {}
986
+ });
987
+ }
988
+ async requestJson(method, path, body, _query, options = {}) {
989
+ const suffix = localCodemodeSuffix(method, path);
990
+ const response = await this.fetchImpl(`${this.basePath}${suffix}`, {
991
+ method,
992
+ ...options.signal ? { signal: options.signal } : {},
993
+ ...body === void 0 ? {} : {
994
+ headers: { "content-type": "application/json" },
995
+ body: JSON.stringify(body)
996
+ }
997
+ });
998
+ const value = await response.json();
999
+ if (response.ok) return value;
1000
+ const envelope = isRecord(value) && isRecord(value.error) ? value.error : {};
1001
+ throw new OpenGeniSiteBridgeError(
1002
+ typeof envelope.code === "string" ? envelope.code : "local_codemode_error",
1003
+ typeof envelope.message === "string" ? envelope.message : `Local Site tool request failed with HTTP ${response.status}`,
1004
+ envelope.retryable === true,
1005
+ envelope.outcomeUnknown === true
1006
+ );
1007
+ }
1008
+ };
1009
+ function shouldUseLocalCodemode(options) {
1010
+ if (options.localCodemodePath === false || options.bootstrapPort) return false;
1011
+ if (typeof options.localCodemodePath === "string") return true;
1012
+ const siteWindow = options.siteWindow ?? globalThis.window;
1013
+ return Boolean(siteWindow && siteWindow.parent === siteWindow);
1014
+ }
1015
+ function localCodemodeSuffix(method, path) {
1016
+ if (method === "GET" && path.endsWith("/tools/catalog")) return "/catalog";
1017
+ if (method === "GET" && path.endsWith("/tools/declarations")) return "/declarations";
1018
+ if (method === "POST" && path.endsWith("/tools/calls")) return "/calls";
1019
+ if (method === "POST" && path.endsWith("/tools/resolve")) return "/resolve";
1020
+ if (method === "POST" && path.endsWith("/tools/invoke")) return "/invoke";
1021
+ throw new OpenGeniSiteBridgeError("unsupported_request", "Unsupported Site tool request");
1022
+ }
1023
+ function isOpenGeniSiteBridgeConnectMessage(value) {
1024
+ return isRecord(value) && value.type === OPENGENI_SITE_BRIDGE_CONNECT && value.version === OPENGENI_SITE_BRIDGE_VERSION;
1025
+ }
1026
+ function isOpenGeniSiteBridgeRequestMessage(value) {
1027
+ if (!isRecord(value) || value.type !== OPENGENI_SITE_BRIDGE_REQUEST || value.version !== OPENGENI_SITE_BRIDGE_VERSION || typeof value.requestId !== "string" || !value.requestId) {
1028
+ return false;
1029
+ }
1030
+ if (value.method === "catalog" || value.method === "declarations" || value.method === OPENGENI_SITE_BRIDGE_VIEWER_METHOD || value.method === OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD)
1031
+ return true;
1032
+ return ["call", "resolve", "invoke"].includes(String(value.method)) && isRecord(value.payload);
1033
+ }
1034
+ function isOpenGeniSiteBridgeCancelMessage(value) {
1035
+ return isRecord(value) && value.type === OPENGENI_SITE_BRIDGE_CANCEL && value.version === OPENGENI_SITE_BRIDGE_VERSION && typeof value.requestId === "string" && Boolean(value.requestId);
1036
+ }
1037
+ function sanitizeOpenGeniSiteToolCallRequest(value) {
1038
+ return {
1039
+ ...value.operationId === void 0 ? {} : { operationId: value.operationId },
1040
+ catalogDigest: value.catalogDigest,
1041
+ identity: value.identity,
1042
+ arguments: value.arguments
1043
+ };
1044
+ }
1045
+ function sanitizeOpenGeniSiteToolInvokeRequest(value) {
1046
+ return {
1047
+ target: value.target,
1048
+ operationId: value.operationId,
1049
+ arguments: value.arguments,
1050
+ ...value.expectedDefinitionDigest === void 0 ? {} : { expectedDefinitionDigest: value.expectedDefinitionDigest }
1051
+ };
1052
+ }
1053
+ var OpenGeniSiteBridgeTransport = class {
1054
+ toolGatewayMode;
1055
+ targetTools = false;
1056
+ siteData = false;
1057
+ viewerSupported = false;
1058
+ options;
1059
+ bootstrap;
1060
+ port = null;
1061
+ connecting = null;
1062
+ closed = false;
1063
+ constructor(options) {
1064
+ this.toolGatewayMode = options.toolGatewayMode ?? "target";
1065
+ this.options = options;
1066
+ this.bootstrap = createSiteBridgeBootstrap(options);
1067
+ }
1068
+ async fetch(input, init) {
1069
+ return sitePortFetch(await this.connect(), input, init);
1070
+ }
1071
+ async siteDataSupported() {
1072
+ await this.connect();
1073
+ return this.siteData;
1074
+ }
1075
+ async viewer() {
1076
+ await this.connect();
1077
+ if (!this.viewerSupported) return null;
1078
+ const value = await this.request({ method: OPENGENI_SITE_BRIDGE_VIEWER_METHOD }, {});
1079
+ if (!isOpenGeniSiteViewer(value))
1080
+ throw new OpenGeniSiteBridgeError(
1081
+ "invalid_viewer",
1082
+ "The Site host returned an invalid viewer"
1083
+ );
1084
+ return value;
1085
+ }
1086
+ async signIn() {
1087
+ await this.connect();
1088
+ if (!this.viewerSupported) return { started: false };
1089
+ const value = await this.request({ method: OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD }, {});
1090
+ return { started: isRecord(value) && value.started === true };
1091
+ }
1092
+ async requestJson(method, path, body, _query, requestOptions = {}) {
1093
+ if (method === "POST" && (path.endsWith("/tools/resolve") || path.endsWith("/tools/invoke"))) {
1094
+ await this.connect();
1095
+ if (!this.targetTools)
1096
+ throw new OpenGeniSiteBridgeError(
1097
+ "target_tools_unsupported",
1098
+ "Upgrade the Site host to use targeted tools"
1099
+ );
1100
+ if (!isRecord(body)) throw new TypeError("Site target payload is required");
1101
+ const request = body;
1102
+ return await this.request(
1103
+ path.endsWith("/tools/resolve") ? { method: "resolve", payload: { target: request.target } } : { method: "invoke", payload: sanitizeOpenGeniSiteToolInvokeRequest(request) },
1104
+ requestOptions
1105
+ );
1106
+ }
1107
+ if (method === "GET" && path.endsWith("/tools/catalog")) {
1108
+ return await this.request({ method: "catalog" }, requestOptions);
1109
+ }
1110
+ if (method === "GET" && path.endsWith("/tools/declarations")) {
1111
+ return await this.request({ method: "declarations" }, requestOptions);
1112
+ }
1113
+ if (method === "POST" && path.endsWith("/tools/calls")) {
1114
+ if (!isRecord(body)) throw new TypeError("Site tool call payload is required");
1115
+ return await this.request(
1116
+ {
1117
+ method: "call",
1118
+ payload: sanitizeOpenGeniSiteToolCallRequest(body)
1119
+ },
1120
+ requestOptions
1121
+ );
1122
+ }
1123
+ throw new OpenGeniSiteBridgeError("unsupported_request", "Unsupported Site bridge request");
1124
+ }
1125
+ close() {
1126
+ if (this.closed) return;
1127
+ this.closed = true;
1128
+ this.bootstrap.close();
1129
+ this.port?.close();
1130
+ this.port = null;
1131
+ }
1132
+ async request(request, options) {
1133
+ const port = await this.connect();
1134
+ const requestId = crypto.randomUUID();
1135
+ const timeoutMs = positiveTimeout(
1136
+ options.timeoutMs ?? this.options.requestTimeoutMs ?? 12e4,
1137
+ "requestTimeoutMs"
1138
+ );
1139
+ return await new Promise((resolve, reject) => {
1140
+ const timeout = setTimeout(() => {
1141
+ cleanup();
1142
+ cancel(port, requestId);
1143
+ reject(
1144
+ request.method === "call" || request.method === "invoke" ? new OpenGeniSiteBridgeError(
1145
+ "timeout",
1146
+ "Site tool request timed out after execution may have started",
1147
+ false,
1148
+ true
1149
+ ) : new OpenGeniSiteBridgeError("timeout", "Site tool request timed out", true)
1150
+ );
1151
+ }, timeoutMs);
1152
+ const abort = () => {
1153
+ cleanup();
1154
+ cancel(port, requestId);
1155
+ reject(options.signal?.reason ?? new DOMException("Request aborted", "AbortError"));
1156
+ };
1157
+ const onMessage = (event) => {
1158
+ const response = event.data;
1159
+ if (!isRecord(response) || response.type !== OPENGENI_SITE_BRIDGE_RESPONSE || response.version !== OPENGENI_SITE_BRIDGE_VERSION || response.requestId !== requestId || typeof response.ok !== "boolean") {
1160
+ return;
1161
+ }
1162
+ cleanup();
1163
+ if (response.ok) {
1164
+ resolve(response.value);
1165
+ return;
1166
+ }
1167
+ const error = isRecord(response.error) ? response.error : {};
1168
+ reject(
1169
+ new OpenGeniSiteBridgeError(
1170
+ typeof error.code === "string" ? error.code : "bridge_error",
1171
+ typeof error.message === "string" ? error.message : "Site tool request failed",
1172
+ error.retryable === true,
1173
+ error.outcomeUnknown === true
1174
+ )
1175
+ );
1176
+ };
1177
+ const cleanup = () => {
1178
+ clearTimeout(timeout);
1179
+ options.signal?.removeEventListener("abort", abort);
1180
+ port.removeEventListener("message", onMessage);
1181
+ };
1182
+ if (options.signal?.aborted) {
1183
+ abort();
1184
+ return;
1185
+ }
1186
+ options.signal?.addEventListener("abort", abort, { once: true });
1187
+ port.addEventListener("message", onMessage);
1188
+ port.postMessage({
1189
+ type: OPENGENI_SITE_BRIDGE_REQUEST,
1190
+ version: OPENGENI_SITE_BRIDGE_VERSION,
1191
+ requestId,
1192
+ ...request
1193
+ });
1194
+ });
1195
+ }
1196
+ async connect() {
1197
+ if (this.closed) throw new OpenGeniSiteBridgeError("closed", "Site bridge is closed");
1198
+ if (this.port) return this.port;
1199
+ if (this.connecting) return await this.connecting;
1200
+ const channel = (this.options.createMessageChannel ?? (() => new MessageChannel()))();
1201
+ const timeoutMs = positiveTimeout(this.options.connectTimeoutMs ?? 1e4, "connectTimeoutMs");
1202
+ this.connecting = new Promise((resolve, reject) => {
1203
+ let active = true;
1204
+ const timeout = setTimeout(() => {
1205
+ cleanup();
1206
+ channel.port1.close();
1207
+ reject(new OpenGeniSiteBridgeError("host_timeout", "Opengeni Site host did not respond"));
1208
+ }, timeoutMs);
1209
+ const onMessage = (event) => {
1210
+ const message = event.data;
1211
+ if (!isRecord(message) || message.type !== OPENGENI_SITE_BRIDGE_READY || message.version !== OPENGENI_SITE_BRIDGE_VERSION) {
1212
+ return;
1213
+ }
1214
+ cleanup();
1215
+ this.targetTools = message.targetTools === 1;
1216
+ this.siteData = message.siteData === 1;
1217
+ this.viewerSupported = message.viewer === 1;
1218
+ this.port = channel.port1;
1219
+ resolve(channel.port1);
1220
+ };
1221
+ const cleanup = () => {
1222
+ active = false;
1223
+ clearTimeout(timeout);
1224
+ channel.port1.removeEventListener("message", onMessage);
1225
+ };
1226
+ channel.port1.addEventListener("message", onMessage);
1227
+ channel.port1.start();
1228
+ void this.bootstrap.port().then((bootstrapPort) => {
1229
+ if (!active) return;
1230
+ if (this.closed) throw new OpenGeniSiteBridgeError("closed", "Site bridge is closed");
1231
+ bootstrapPort.postMessage(
1232
+ {
1233
+ type: OPENGENI_SITE_BRIDGE_CONNECT,
1234
+ version: OPENGENI_SITE_BRIDGE_VERSION
1235
+ },
1236
+ [channel.port2]
1237
+ );
1238
+ }).catch((error) => {
1239
+ cleanup();
1240
+ channel.port1.close();
1241
+ reject(error);
1242
+ });
1243
+ }).finally(() => {
1244
+ this.connecting = null;
1245
+ });
1246
+ return await this.connecting;
1247
+ }
1248
+ };
1249
+ function createSiteBridgeBootstrap(options) {
1250
+ if (options.bootstrapPort) {
1251
+ return {
1252
+ port: async () => options.bootstrapPort,
1253
+ close: () => options.bootstrapPort?.close()
1254
+ };
1255
+ }
1256
+ const siteWindow = options.siteWindow ?? globalThis.window;
1257
+ const parentWindow = options.parentWindow ?? siteWindow?.parent;
1258
+ if (!siteWindow || !parentWindow || parentWindow === siteWindow) {
1259
+ return {
1260
+ port: async () => {
1261
+ throw new OpenGeniSiteBridgeError(
1262
+ "host_unavailable",
1263
+ "Opengeni Site client must run inside a hosted iframe"
1264
+ );
1265
+ },
1266
+ close: () => void 0
1267
+ };
1268
+ }
1269
+ const retainedPort = retainedSiteBridgeBootstrapPort(siteWindow);
1270
+ if (retainedPort) {
1271
+ return {
1272
+ port: async () => retainedPort,
1273
+ close: () => void 0
1274
+ };
1275
+ }
1276
+ let settledPort = null;
1277
+ let rejectBootstrap = null;
1278
+ const onMessage = (event) => {
1279
+ if (event.source !== parentWindow || !isOpenGeniSiteBridgeReadyMessage(event.data) || event.ports.length !== 1) {
1280
+ return;
1281
+ }
1282
+ cleanup();
1283
+ settledPort = event.ports[0];
1284
+ settledPort.start();
1285
+ retainSiteBridgeBootstrapPort(siteWindow, settledPort);
1286
+ resolveBootstrap?.(settledPort);
1287
+ };
1288
+ let resolveBootstrap = null;
1289
+ const cleanup = () => siteWindow.removeEventListener("message", onMessage);
1290
+ const port = new Promise((resolve, reject) => {
1291
+ resolveBootstrap = resolve;
1292
+ rejectBootstrap = reject;
1293
+ siteWindow.addEventListener("message", onMessage);
1294
+ });
1295
+ void port.catch(() => void 0);
1296
+ return {
1297
+ port: async () => await port,
1298
+ close: () => {
1299
+ cleanup();
1300
+ rejectBootstrap?.(new OpenGeniSiteBridgeError("closed", "Site bridge is closed"));
1301
+ resolveBootstrap = null;
1302
+ rejectBootstrap = null;
1303
+ }
1304
+ };
1305
+ }
1306
+ function retainedSiteBridgeBootstrapPort(siteWindow) {
1307
+ const state = siteWindow[OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL];
1308
+ if (!isRecord(state)) return null;
1309
+ const candidate = state.port;
1310
+ return candidate && typeof candidate.postMessage === "function" && typeof candidate.addEventListener === "function" && typeof candidate.start === "function" ? candidate : null;
1311
+ }
1312
+ function retainSiteBridgeBootstrapPort(siteWindow, port) {
1313
+ try {
1314
+ Object.defineProperty(siteWindow, OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL, {
1315
+ configurable: true,
1316
+ value: { port }
1317
+ });
1318
+ } catch {
1319
+ }
1320
+ }
1321
+ function isOpenGeniSiteBridgeReadyMessage(value) {
1322
+ return isRecord(value) && value.type === OPENGENI_SITE_BRIDGE_READY && value.version === OPENGENI_SITE_BRIDGE_VERSION;
1323
+ }
1324
+ var SITE_VIEWER_KINDS = ["member", "invited", "user", "guest"];
1325
+ async function readSiteCapabilities(transport) {
1326
+ try {
1327
+ if (!await transport.siteDataSupported()) return null;
1328
+ const response = await transport.fetch(
1329
+ "https://site.opengeni.invalid/v1/workspaces/site-host/site/config",
1330
+ { method: "GET", headers: { accept: "application/json" } }
1331
+ );
1332
+ if (!response.ok) {
1333
+ await response.body?.cancel();
1334
+ return null;
1335
+ }
1336
+ const value = (await response.json())?.capabilities;
1337
+ return isOpenGeniSiteCapabilities(value) ? value : null;
1338
+ } catch {
1339
+ return null;
1340
+ }
1341
+ }
1342
+ function isOpenGeniSiteCapabilities(value) {
1343
+ return isRecord(value) && typeof value.agent === "boolean" && typeof value.workspaceTools === "boolean" && (value.siteData === "viewer" || value.siteData === "guest") && Array.isArray(value.sqlQueryAudiences) && value.sqlQueryAudiences.every(
1344
+ (audience) => audience === "everyone" || audience === "signed_in"
1345
+ ) && (value.viewAs === null || value.viewAs === "invited" || value.viewAs === "public");
1346
+ }
1347
+ function isOpenGeniSiteViewer(value) {
1348
+ return isRecord(value) && SITE_VIEWER_KINDS.includes(String(value.kind)) && typeof value.id === "string" && value.id.length > 0 && (value.name === null || typeof value.name === "string") && (value.email === null || typeof value.email === "string") && typeof value.signedIn === "boolean";
1349
+ }
1350
+ function cancel(port, requestId) {
1351
+ port.postMessage({
1352
+ type: OPENGENI_SITE_BRIDGE_CANCEL,
1353
+ version: OPENGENI_SITE_BRIDGE_VERSION,
1354
+ requestId
1355
+ });
1356
+ }
1357
+ function positiveTimeout(value, label) {
1358
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${label} must be positive`);
1359
+ return value;
1360
+ }
1361
+ function isRecord(value) {
1362
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1363
+ }
1364
+
1365
+ export {
1366
+ siteSessionPath,
1367
+ isSiteHttpRequest,
1368
+ serveSiteHttp,
1369
+ createSiteToolBridge,
1370
+ isSiteCatalogStaleError,
1371
+ OpenGeniSiteDataError,
1372
+ SITE_DATA_PATH_PREFIX,
1373
+ OpenGeniSiteSqlError,
1374
+ OPENGENI_SITE_BRIDGE_VERSION,
1375
+ OPENGENI_SITE_BRIDGE_CONNECT,
1376
+ OPENGENI_SITE_BRIDGE_READY,
1377
+ OPENGENI_SITE_BRIDGE_REQUEST,
1378
+ OPENGENI_SITE_BRIDGE_RESPONSE,
1379
+ OPENGENI_SITE_BRIDGE_CANCEL,
1380
+ OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,
1381
+ OPENGENI_SITE_LOCAL_CODEMODE_PATH,
1382
+ OPENGENI_SITE_BRIDGE_VIEWER_METHOD,
1383
+ OPENGENI_SITE_BRIDGE_SIGN_IN_METHOD,
1384
+ OpenGeniSiteBridgeError,
1385
+ createOpenGeniSiteClient,
1386
+ isOpenGeniSiteBridgeConnectMessage,
1387
+ isOpenGeniSiteBridgeRequestMessage,
1388
+ isOpenGeniSiteBridgeCancelMessage,
1389
+ sanitizeOpenGeniSiteToolCallRequest,
1390
+ sanitizeOpenGeniSiteToolInvokeRequest
1391
+ };
1392
+ //# sourceMappingURL=chunk-JXXCTW5W.js.map