@kortix/sdk 0.12.8 → 0.13.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 (261) hide show
  1. package/README.md +3 -6
  2. package/dist/browser/session-sync/session-sync-registry.d.ts +7 -2
  3. package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
  4. package/dist/browser/session-sync/session-sync-registry.js +33 -44
  5. package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
  6. package/dist/browser/stores/opencode-compaction-store.d.ts +9 -3
  7. package/dist/browser/stores/opencode-compaction-store.d.ts.map +1 -1
  8. package/dist/browser/stores/opencode-compaction-store.js +5 -12
  9. package/dist/browser/stores/opencode-compaction-store.js.map +1 -1
  10. package/dist/browser/stores/sandbox-connection-store.d.ts +28 -17
  11. package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
  12. package/dist/browser/stores/sandbox-connection-store.js +32 -84
  13. package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
  14. package/dist/browser/stores/session-working-store.d.ts +73 -0
  15. package/dist/browser/stores/session-working-store.d.ts.map +1 -0
  16. package/dist/browser/stores/session-working-store.js +86 -0
  17. package/dist/browser/stores/session-working-store.js.map +1 -0
  18. package/dist/browser/stores/sync-store/types.d.ts +14 -4
  19. package/dist/browser/stores/sync-store/types.d.ts.map +1 -1
  20. package/dist/browser/stores/sync-store.d.ts +140 -3
  21. package/dist/browser/stores/sync-store.d.ts.map +1 -1
  22. package/dist/browser/stores/sync-store.js +425 -36
  23. package/dist/browser/stores/sync-store.js.map +1 -1
  24. package/dist/core/client/kortix.d.ts +102 -1
  25. package/dist/core/client/kortix.d.ts.map +1 -1
  26. package/dist/core/client/kortix.js +78 -0
  27. package/dist/core/client/kortix.js.map +1 -1
  28. package/dist/core/files/client.d.ts +50 -2
  29. package/dist/core/files/client.d.ts.map +1 -1
  30. package/dist/core/files/client.js +253 -44
  31. package/dist/core/files/client.js.map +1 -1
  32. package/dist/core/files/types.d.ts +11 -0
  33. package/dist/core/files/types.d.ts.map +1 -1
  34. package/dist/core/http/abort-error.d.ts +89 -0
  35. package/dist/core/http/abort-error.d.ts.map +1 -0
  36. package/dist/core/http/abort-error.js +190 -0
  37. package/dist/core/http/abort-error.js.map +1 -0
  38. package/dist/core/http/api-client.d.ts.map +1 -1
  39. package/dist/core/http/api-client.js +18 -4
  40. package/dist/core/http/api-client.js.map +1 -1
  41. package/dist/core/rest/platform-client/github-app.d.ts +13 -0
  42. package/dist/core/rest/platform-client/github-app.d.ts.map +1 -1
  43. package/dist/core/rest/platform-client/github-app.js +2 -0
  44. package/dist/core/rest/platform-client/github-app.js.map +1 -1
  45. package/dist/core/rest/platform-client/members.d.ts +10 -64
  46. package/dist/core/rest/platform-client/members.d.ts.map +1 -1
  47. package/dist/core/rest/platform-client/members.js +10 -28
  48. package/dist/core/rest/platform-client/members.js.map +1 -1
  49. package/dist/core/rest/projects-client/accounts.d.ts +30 -1
  50. package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
  51. package/dist/core/rest/projects-client/accounts.js +1 -1
  52. package/dist/core/rest/projects-client/accounts.js.map +1 -1
  53. package/dist/core/rest/projects-client/apps.d.ts +13 -0
  54. package/dist/core/rest/projects-client/apps.d.ts.map +1 -1
  55. package/dist/core/rest/projects-client/apps.js.map +1 -1
  56. package/dist/core/rest/projects-client/assignments.d.ts +114 -0
  57. package/dist/core/rest/projects-client/assignments.d.ts.map +1 -0
  58. package/dist/core/rest/projects-client/assignments.js +91 -0
  59. package/dist/core/rest/projects-client/assignments.js.map +1 -0
  60. package/dist/core/rest/projects-client/billing.d.ts +10 -1
  61. package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
  62. package/dist/core/rest/projects-client/billing.js +11 -2
  63. package/dist/core/rest/projects-client/billing.js.map +1 -1
  64. package/dist/core/rest/projects-client/connectors.d.ts +2 -0
  65. package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
  66. package/dist/core/rest/projects-client/connectors.js.map +1 -1
  67. package/dist/core/rest/projects-client/files.js +2 -2
  68. package/dist/core/rest/projects-client/files.js.map +1 -1
  69. package/dist/core/rest/projects-client/gateway.d.ts +51 -0
  70. package/dist/core/rest/projects-client/gateway.d.ts.map +1 -1
  71. package/dist/core/rest/projects-client/gateway.js.map +1 -1
  72. package/dist/core/rest/projects-client/iam.d.ts +51 -3
  73. package/dist/core/rest/projects-client/iam.d.ts.map +1 -1
  74. package/dist/core/rest/projects-client/iam.js +18 -1
  75. package/dist/core/rest/projects-client/iam.js.map +1 -1
  76. package/dist/core/rest/projects-client/index.d.ts +1 -0
  77. package/dist/core/rest/projects-client/index.d.ts.map +1 -1
  78. package/dist/core/rest/projects-client/index.js +1 -0
  79. package/dist/core/rest/projects-client/index.js.map +1 -1
  80. package/dist/core/rest/projects-client/projects.d.ts +1 -1
  81. package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
  82. package/dist/core/rest/projects-client/projects.js +3 -0
  83. package/dist/core/rest/projects-client/projects.js.map +1 -1
  84. package/dist/core/rest/projects-client/secrets.d.ts +11 -0
  85. package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
  86. package/dist/core/rest/projects-client/secrets.js +1 -1
  87. package/dist/core/rest/projects-client/secrets.js.map +1 -1
  88. package/dist/core/rest/projects-client/session-costs.d.ts +33 -0
  89. package/dist/core/rest/projects-client/session-costs.d.ts.map +1 -1
  90. package/dist/core/rest/projects-client/session-costs.js.map +1 -1
  91. package/dist/core/rest/projects-client/sessions.d.ts +226 -2
  92. package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
  93. package/dist/core/rest/projects-client/sessions.js +101 -4
  94. package/dist/core/rest/projects-client/sessions.js.map +1 -1
  95. package/dist/core/rest/projects-client/shared.d.ts +10 -1
  96. package/dist/core/rest/projects-client/shared.d.ts.map +1 -1
  97. package/dist/core/rest/projects-client/shared.js.map +1 -1
  98. package/dist/core/rest/projects-client/tokens.d.ts +13 -1
  99. package/dist/core/rest/projects-client/tokens.d.ts.map +1 -1
  100. package/dist/core/rest/projects-client/tokens.js +7 -2
  101. package/dist/core/rest/projects-client/tokens.js.map +1 -1
  102. package/dist/core/rest/projects-client/triggers.d.ts +69 -2
  103. package/dist/core/rest/projects-client/triggers.d.ts.map +1 -1
  104. package/dist/core/rest/projects-client/triggers.js +1 -1
  105. package/dist/core/rest/projects-client/triggers.js.map +1 -1
  106. package/dist/core/session/compaction.d.ts +98 -0
  107. package/dist/core/session/compaction.d.ts.map +1 -0
  108. package/dist/core/session/compaction.js +108 -0
  109. package/dist/core/session/compaction.js.map +1 -0
  110. package/dist/core/session/health.d.ts +22 -0
  111. package/dist/core/session/health.d.ts.map +1 -1
  112. package/dist/core/session/health.js +31 -5
  113. package/dist/core/session/health.js.map +1 -1
  114. package/dist/core/session/index.d.ts +2 -0
  115. package/dist/core/session/index.d.ts.map +1 -1
  116. package/dist/core/session/index.js +2 -0
  117. package/dist/core/session/index.js.map +1 -1
  118. package/dist/core/session/message-queue.d.ts +79 -15
  119. package/dist/core/session/message-queue.d.ts.map +1 -1
  120. package/dist/core/session/message-queue.js +73 -27
  121. package/dist/core/session/message-queue.js.map +1 -1
  122. package/dist/core/session/rewind.d.ts +76 -10
  123. package/dist/core/session/rewind.d.ts.map +1 -1
  124. package/dist/core/session/rewind.js +68 -11
  125. package/dist/core/session/rewind.js.map +1 -1
  126. package/dist/core/session/working.d.ts +241 -0
  127. package/dist/core/session/working.d.ts.map +1 -0
  128. package/dist/core/session/working.js +261 -0
  129. package/dist/core/session/working.js.map +1 -0
  130. package/dist/core/session-sync/session-sync-controller.d.ts +35 -20
  131. package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
  132. package/dist/core/session-sync/session-sync-controller.js +48 -115
  133. package/dist/core/session-sync/session-sync-controller.js.map +1 -1
  134. package/dist/core/stream/event-stream.d.ts +22 -0
  135. package/dist/core/stream/event-stream.d.ts.map +1 -1
  136. package/dist/core/stream/event-stream.js +132 -36
  137. package/dist/core/stream/event-stream.js.map +1 -1
  138. package/dist/core/turns/grouping.d.ts +32 -2
  139. package/dist/core/turns/grouping.d.ts.map +1 -1
  140. package/dist/core/turns/grouping.js +31 -2
  141. package/dist/core/turns/grouping.js.map +1 -1
  142. package/dist/core/turns/index.d.ts +1 -0
  143. package/dist/core/turns/index.d.ts.map +1 -1
  144. package/dist/core/turns/index.js +1 -0
  145. package/dist/core/turns/index.js.map +1 -1
  146. package/dist/core/turns/open-turn.d.ts +81 -0
  147. package/dist/core/turns/open-turn.d.ts.map +1 -0
  148. package/dist/core/turns/open-turn.js +77 -0
  149. package/dist/core/turns/open-turn.js.map +1 -0
  150. package/dist/core/turns/state.js +26 -26
  151. package/dist/core/turns/state.js.map +1 -1
  152. package/dist/core/turns/types.d.ts +5 -0
  153. package/dist/core/turns/types.d.ts.map +1 -1
  154. package/dist/index.d.ts +2 -1
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js +2 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/kortix.esm.min.js +25 -25
  159. package/dist/kortix.global.js +25 -25
  160. package/dist/node/server.d.ts.map +1 -1
  161. package/dist/node/server.js +14 -2
  162. package/dist/node/server.js.map +1 -1
  163. package/dist/react/index.d.ts +2 -1
  164. package/dist/react/index.d.ts.map +1 -1
  165. package/dist/react/index.js +7 -1
  166. package/dist/react/index.js.map +1 -1
  167. package/dist/react/initial-session-pin.d.ts +17 -0
  168. package/dist/react/initial-session-pin.d.ts.map +1 -1
  169. package/dist/react/initial-session-pin.js +58 -0
  170. package/dist/react/initial-session-pin.js.map +1 -1
  171. package/dist/react/opencode.d.ts +6 -2
  172. package/dist/react/opencode.d.ts.map +1 -1
  173. package/dist/react/opencode.js +5 -1
  174. package/dist/react/opencode.js.map +1 -1
  175. package/dist/react/prefetch-session-start.d.ts +10 -4
  176. package/dist/react/prefetch-session-start.d.ts.map +1 -1
  177. package/dist/react/prefetch-session-start.js +10 -4
  178. package/dist/react/prefetch-session-start.js.map +1 -1
  179. package/dist/react/query-keys.d.ts +8 -2
  180. package/dist/react/query-keys.d.ts.map +1 -1
  181. package/dist/react/query-keys.js +8 -2
  182. package/dist/react/query-keys.js.map +1 -1
  183. package/dist/react/session-start-stash.d.ts +25 -0
  184. package/dist/react/session-start-stash.d.ts.map +1 -1
  185. package/dist/react/session-start-stash.js +34 -3
  186. package/dist/react/session-start-stash.js.map +1 -1
  187. package/dist/react/session-title-sync.d.ts +5 -1
  188. package/dist/react/session-title-sync.d.ts.map +1 -1
  189. package/dist/react/session-title-sync.js +16 -4
  190. package/dist/react/session-title-sync.js.map +1 -1
  191. package/dist/react/use-can.d.ts +105 -0
  192. package/dist/react/use-can.d.ts.map +1 -0
  193. package/dist/react/use-can.js +190 -0
  194. package/dist/react/use-can.js.map +1 -0
  195. package/dist/react/use-canonical-opencode-session.d.ts +6 -1
  196. package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
  197. package/dist/react/use-canonical-opencode-session.js +46 -3
  198. package/dist/react/use-canonical-opencode-session.js.map +1 -1
  199. package/dist/react/use-opencode-events/handle-event.d.ts +10 -0
  200. package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
  201. package/dist/react/use-opencode-events/handle-event.js +76 -7
  202. package/dist/react/use-opencode-events/handle-event.js.map +1 -1
  203. package/dist/react/use-opencode-events/helpers.d.ts +21 -8
  204. package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
  205. package/dist/react/use-opencode-events/helpers.js +25 -26
  206. package/dist/react/use-opencode-events/helpers.js.map +1 -1
  207. package/dist/react/use-opencode-events/index.d.ts.map +1 -1
  208. package/dist/react/use-opencode-events/index.js +43 -26
  209. package/dist/react/use-opencode-events/index.js.map +1 -1
  210. package/dist/react/use-opencode-events/use-event-stream-refs.d.ts.map +1 -1
  211. package/dist/react/use-opencode-events/use-event-stream-refs.js +66 -3
  212. package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
  213. package/dist/react/use-opencode-local.d.ts +17 -0
  214. package/dist/react/use-opencode-local.d.ts.map +1 -1
  215. package/dist/react/use-opencode-local.js +41 -7
  216. package/dist/react/use-opencode-local.js.map +1 -1
  217. package/dist/react/use-opencode-sessions/messages.d.ts +101 -1
  218. package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
  219. package/dist/react/use-opencode-sessions/messages.js +481 -63
  220. package/dist/react/use-opencode-sessions/messages.js.map +1 -1
  221. package/dist/react/use-project-apps.d.ts +24 -1
  222. package/dist/react/use-project-apps.d.ts.map +1 -1
  223. package/dist/react/use-project-apps.js +5 -3
  224. package/dist/react/use-project-apps.js.map +1 -1
  225. package/dist/react/use-runtime-boot-stalled.d.ts +32 -0
  226. package/dist/react/use-runtime-boot-stalled.d.ts.map +1 -0
  227. package/dist/react/use-runtime-boot-stalled.js +48 -0
  228. package/dist/react/use-runtime-boot-stalled.js.map +1 -0
  229. package/dist/react/use-runtime-reconnect.d.ts +67 -1
  230. package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
  231. package/dist/react/use-runtime-reconnect.js +116 -18
  232. package/dist/react/use-runtime-reconnect.js.map +1 -1
  233. package/dist/react/use-session-prompts.d.ts +113 -0
  234. package/dist/react/use-session-prompts.d.ts.map +1 -0
  235. package/dist/react/use-session-prompts.js +242 -0
  236. package/dist/react/use-session-prompts.js.map +1 -0
  237. package/dist/react/use-session-send.d.ts +169 -20
  238. package/dist/react/use-session-send.d.ts.map +1 -1
  239. package/dist/react/use-session-send.js +178 -29
  240. package/dist/react/use-session-send.js.map +1 -1
  241. package/dist/react/use-session-sync.d.ts +35 -2
  242. package/dist/react/use-session-sync.d.ts.map +1 -1
  243. package/dist/react/use-session-sync.js +46 -9
  244. package/dist/react/use-session-sync.js.map +1 -1
  245. package/dist/react/use-session-working.d.ts +57 -0
  246. package/dist/react/use-session-working.d.ts.map +1 -0
  247. package/dist/react/use-session-working.js +178 -0
  248. package/dist/react/use-session-working.js.map +1 -0
  249. package/dist/react/use-session.d.ts +122 -5
  250. package/dist/react/use-session.d.ts.map +1 -1
  251. package/dist/react/use-session.js +343 -69
  252. package/dist/react/use-session.js.map +1 -1
  253. package/package.json +2 -2
  254. package/dist/browser/stores/tab-store.d.ts +0 -91
  255. package/dist/browser/stores/tab-store.d.ts.map +0 -1
  256. package/dist/browser/stores/tab-store.js +0 -369
  257. package/dist/browser/stores/tab-store.js.map +0 -1
  258. package/dist/core/session/send-queue.d.ts +0 -70
  259. package/dist/core/session/send-queue.d.ts.map +0 -1
  260. package/dist/core/session/send-queue.js +0 -116
  261. package/dist/core/session/send-queue.js.map +0 -1
@@ -401,8 +401,31 @@ export declare function useAppDeployments(projectId: string | null | undefined,
401
401
  fetchStatus: import("@tanstack/react-query").FetchStatus;
402
402
  promise: Promise<NoInfer<import("../index.js").AppDeployment[]>>;
403
403
  };
404
+ export interface UseAppAccessOptions {
405
+ /**
406
+ * Fetch the access POLICY as well as the session. Defaults to true.
407
+ *
408
+ * `GET .../apps/{id}/access` is an administrative read — a caller without
409
+ * `project.customize.write` gets a 403. A list of Apps only needs the SESSION
410
+ * (the short-lived URL its preview tile loads), so a grid of N Apps was firing
411
+ * N policy reads it never displayed, every one of them a 403 for an ordinary
412
+ * member. Pass `false` there and let the surface that actually edits access
413
+ * (the access modal) be the one that asks for it.
414
+ */
415
+ policy?: boolean;
416
+ /**
417
+ * Mint the access SESSION. Defaults to true.
418
+ *
419
+ * Same failure as `policy`, one endpoint over: `POST .../access-session` is
420
+ * 403 for any App the caller may see but not open, and a card that renders a
421
+ * live thumbnail asks for one on mount. A grid of N such Apps produced N
422
+ * console errors and a broken tile, for a state that is not an error — the
423
+ * App is simply not yours to open. Pass `App.viewer_can_access` here.
424
+ */
425
+ session?: boolean;
426
+ }
404
427
  /** App access policy plus a short-lived URL that exchanges into a host-only cookie. */
405
- export declare function useAppAccess(projectId: string | null | undefined, appId: string | null | undefined): {
428
+ export declare function useAppAccess(projectId: string | null | undefined, appId: string | null | undefined, options?: UseAppAccessOptions): {
406
429
  policy: import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").AppAccessConfig>, Error>;
407
430
  session: import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").AppAccessSession>, Error>;
408
431
  update: import("@tanstack/react-query").UseMutationResult<import("../index.js").AppAccessConfig, Error, import("../index.js").UpdateAppAccessInput, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"use-project-apps.d.ts","sourceRoot":"","sources":["../../src/react/use-project-apps.ts"],"names":[],"mappings":"AAGA,OAAO,EAWL,SAAS,EAEV,MAAM,8BAA8B,CAAC;AAItC,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,+CACjC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,sEAC0B,CAAC;AAE7D,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;eAgBnC,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB7E;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BjC;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;;EA+BjC"}
1
+ {"version":3,"file":"use-project-apps.d.ts","sourceRoot":"","sources":["../../src/react/use-project-apps.ts"],"names":[],"mappings":"AAGA,OAAO,EAWL,SAAS,EAEV,MAAM,8BAA8B,CAAC;AAItC,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,+CACjC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,sEAC0B,CAAC;AAE7D,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;eAgBnC,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA9C,MAAM;eAAS,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB7E;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BjC;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,GAAE,mBAAwB;;;;EAiClC"}
@@ -65,20 +65,22 @@ export function useAppDeployments(projectId, appId) {
65
65
  return { ...query, deploy, rollback };
66
66
  }
67
67
  /** App access policy plus a short-lived URL that exchanges into a host-only cookie. */
68
- export function useAppAccess(projectId, appId) {
68
+ export function useAppAccess(projectId, appId, options = {}) {
69
69
  const queryClient = useQueryClient();
70
+ const wantsPolicy = options.policy ?? true;
71
+ const wantsSession = options.session ?? true;
70
72
  const queryKey = qk.project.appAccess(projectId ?? '', appId ?? '');
71
73
  const sessionQueryKey = qk.project.appAccessSession(projectId ?? '', appId ?? '');
72
74
  const policy = useQuery({
73
75
  queryKey,
74
76
  queryFn: () => getAppAccess(projectId, appId),
75
- enabled: !!projectId && !!appId,
77
+ enabled: !!projectId && !!appId && wantsPolicy,
76
78
  ...contract('config'),
77
79
  });
78
80
  const session = useQuery({
79
81
  queryKey: sessionQueryKey,
80
82
  queryFn: () => createAppAccessSession(projectId, appId),
81
- enabled: !!projectId && !!appId,
83
+ enabled: !!projectId && !!appId && wantsSession,
82
84
  staleTime: 4 * 60_000,
83
85
  gcTime: 5 * 60_000,
84
86
  retry: false,
@@ -1 +1 @@
1
- {"version":3,"file":"use-project-apps.js","sourceRoot":"","sources":["../../src/react/use-project-apps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-project-apps.js","sourceRoot":"","sources":["../../src/react/use-project-apps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The same ceiling the `/start` poll uses to decide a boot attempt is no longer
3
+ * "in progress", now DERIVED from it rather than hand-copied and kept in sync
4
+ * by a comment. The two give-up clocks — server-side `/start` staying
5
+ * inconclusive, client-side runtime never turning healthy — cannot disagree
6
+ * about how long "still starting" gets to mean.
7
+ *
8
+ * It claims no turn and no health truth: `ready` is false either way
9
+ * (`session-composer-readiness.ts`). It is only the bound on the documented
10
+ * wedged-503 shape, where `classifyProbeResult` maps every 503 to `booting` and
11
+ * resets the probe failure count, so `status` never becomes `'unreachable'` no
12
+ * matter how long the box stays wedged.
13
+ */
14
+ export declare const RUNTIME_BOOT_STALL_MS = 45000;
15
+ /**
16
+ * True once the runtime has been reachable-but-not-healthy for at least
17
+ * `thresholdMs` with no ready flip — independent of
18
+ * `useRuntimePhase() === 'unreachable'`.
19
+ *
20
+ * That distinction matters: a sandbox proxy that answers every probe with a
21
+ * 503 (OpenCode wedged mid-boot) is classified `'booting'` on every tick,
22
+ * which resets the failure counter each time (see `classifyProbeResult` /
23
+ * `resetSandboxFail` in `use-runtime-reconnect`). `failCount` can never cross
24
+ * `FAIL_THRESHOLD_*` through that path, so `status` never becomes
25
+ * `'unreachable'` no matter how long the box stays wedged — the composer's
26
+ * "Waking this session up…" notice had no time bound and no escape hatch in
27
+ * that case. This hook gives it one, keyed off `bootingSinceAt` (cleared only
28
+ * when `healthy` actually flips true), so `sessionComposerReadiness` can
29
+ * offer a manual retry even when the probe layer itself never gives up.
30
+ */
31
+ export declare function useRuntimeBootStalled(thresholdMs?: number): boolean;
32
+ //# sourceMappingURL=use-runtime-boot-stalled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-runtime-boot-stalled.d.ts","sourceRoot":"","sources":["../../src/react/use-runtime-boot-stalled.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,QAAgC,CAAC;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,MAA8B,GAAG,OAAO,CAY1F"}
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ import { useEffect, useState } from 'react';
3
+ import { useSandboxConnectionStore } from '../browser/stores/sandbox-connection-store.js';
4
+ import { START_INCONCLUSIVE_GIVE_UP_MS } from './use-session.js';
5
+ /**
6
+ * The same ceiling the `/start` poll uses to decide a boot attempt is no longer
7
+ * "in progress", now DERIVED from it rather than hand-copied and kept in sync
8
+ * by a comment. The two give-up clocks — server-side `/start` staying
9
+ * inconclusive, client-side runtime never turning healthy — cannot disagree
10
+ * about how long "still starting" gets to mean.
11
+ *
12
+ * It claims no turn and no health truth: `ready` is false either way
13
+ * (`session-composer-readiness.ts`). It is only the bound on the documented
14
+ * wedged-503 shape, where `classifyProbeResult` maps every 503 to `booting` and
15
+ * resets the probe failure count, so `status` never becomes `'unreachable'` no
16
+ * matter how long the box stays wedged.
17
+ */
18
+ export const RUNTIME_BOOT_STALL_MS = START_INCONCLUSIVE_GIVE_UP_MS;
19
+ /**
20
+ * True once the runtime has been reachable-but-not-healthy for at least
21
+ * `thresholdMs` with no ready flip — independent of
22
+ * `useRuntimePhase() === 'unreachable'`.
23
+ *
24
+ * That distinction matters: a sandbox proxy that answers every probe with a
25
+ * 503 (OpenCode wedged mid-boot) is classified `'booting'` on every tick,
26
+ * which resets the failure counter each time (see `classifyProbeResult` /
27
+ * `resetSandboxFail` in `use-runtime-reconnect`). `failCount` can never cross
28
+ * `FAIL_THRESHOLD_*` through that path, so `status` never becomes
29
+ * `'unreachable'` no matter how long the box stays wedged — the composer's
30
+ * "Waking this session up…" notice had no time bound and no escape hatch in
31
+ * that case. This hook gives it one, keyed off `bootingSinceAt` (cleared only
32
+ * when `healthy` actually flips true), so `sessionComposerReadiness` can
33
+ * offer a manual retry even when the probe layer itself never gives up.
34
+ */
35
+ export function useRuntimeBootStalled(thresholdMs = RUNTIME_BOOT_STALL_MS) {
36
+ const bootingSinceAt = useSandboxConnectionStore((s) => s.bootingSinceAt);
37
+ const [now, setNow] = useState(() => Date.now());
38
+ useEffect(() => {
39
+ if (bootingSinceAt === null)
40
+ return;
41
+ const interval = setInterval(() => setNow(Date.now()), 1_000);
42
+ return () => clearInterval(interval);
43
+ }, [bootingSinceAt]);
44
+ if (bootingSinceAt === null)
45
+ return false;
46
+ return now - bootingSinceAt >= thresholdMs;
47
+ }
48
+ //# sourceMappingURL=use-runtime-boot-stalled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-runtime-boot-stalled.js","sourceRoot":"","sources":["../../src/react/use-runtime-boot-stalled.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,6BAA6B,CAAC;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB,CAAC,cAAsB,qBAAqB;IAC/E,MAAM,cAAc,GAAG,yBAAyB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC1E,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,cAAc,KAAK,IAAI;YAAE,OAAO;QACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,IAAI,cAAc,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,GAAG,GAAG,cAAc,IAAI,WAAW,CAAC;AAC7C,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type SessionHealthResponse } from '../core/session/index.js';
1
+ import { type ProxyHop, type SessionHealthResponse } from '../core/session/index.js';
2
2
  import { type SandboxConnectionStatus } from '../browser/stores/sandbox-connection-store.js';
3
3
  /**
4
4
  * Number of consecutive failures before marking as unreachable
@@ -18,6 +18,60 @@ export declare const POLL_CONNECTED = 30000;
18
18
  export declare const POLL_FAILING = 150;
19
19
  export declare const POLL_UNREACHABLE = 5000;
20
20
  export declare const CHECK_TIMEOUT = 20000;
21
+ /**
22
+ * How recently a live SSE event must have arrived to veto a failed probe.
23
+ * An event that just came over the wire is stronger evidence of reachability
24
+ * than a probe timeout: a box saturated by a heavy turn (PDF rendering, asset
25
+ * builds) can miss the probe deadline while streaming that same turn's events.
26
+ * Without the veto, two such misses flipped the UI to "Waking this session
27
+ * up…", tore down the SSE stream (gated on status === 'connected'), and queued
28
+ * every send — against a runtime that was demonstrably up and mid-turn.
29
+ */
30
+ export declare const RUNTIME_EVIDENCE_FRESH_MS = 15000;
31
+ /**
32
+ * Whether a failed health probe should be discarded because live runtime
33
+ * events prove reachability. Pure — see RUNTIME_EVIDENCE_FRESH_MS.
34
+ */
35
+ export declare function shouldIgnoreProbeFailure(lastRuntimeEvidenceAt: number | null, now: number): boolean;
36
+ /**
37
+ * Whether a failed probe is evidence that the RUNTIME is unreachable, and may
38
+ * therefore move this session toward "unreachable".
39
+ *
40
+ * TWO independent facts can clear a failure, and they cover disjoint failures.
41
+ *
42
+ * 1. WHICH HOP the proxy blamed (`X-Kortix-Proxy-Hop`). Two of the four say
43
+ * nothing about the runtime:
44
+ *
45
+ * - `control_plane` — the platform answered from the session row without
46
+ * ever dialling the box (`503 sandbox not ready (status: stopped)`). An
47
+ * answer is not silence; counting it drove a session to "unreachable"
48
+ * while `/start` was still resuming it.
49
+ * - `upstream_port` — the user's own dev server on an app port is down.
50
+ * That is their process, not our runtime, and it must never render
51
+ * "Waking".
52
+ *
53
+ * 2. WHETHER SSE FRAMES ARE STILL ARRIVING. The hop cannot answer this and
54
+ * never will: the health probe addresses the daemon port, so every failure
55
+ * it can observe is `daemon` (the proxy reached the box, the runtime did
56
+ * not answer), `provider_ingress`, or — for a `CHECK_TIMEOUT` abort — no hop
57
+ * at all. All three count. On a box saturated by a heavy turn that is the
58
+ * 2026-08-17 incident verbatim: two missed probes flip `sandboxStatus` to
59
+ * `unreachable`, `useOpenCodeEventStream` (gated on `=== 'connected'`) tears
60
+ * the live stream down, and the transcript freezes mid-turn on a runtime
61
+ * that is provably up — it is delivering the frames. A frame is a fact from
62
+ * the runtime itself, not an inference, and it outranks a probe that timed
63
+ * out behind it.
64
+ *
65
+ * An UNATTRIBUTED failure with no fresh frames still counts. A network error,
66
+ * a `CHECK_TIMEOUT` abort, or a response from something that is not our proxy
67
+ * carries no hop, and refusing to count those would leave a browser that lost
68
+ * its connection reading "connected" forever — the poller's only job.
69
+ */
70
+ export declare function shouldCountProbeFailure(input: {
71
+ hop: ProxyHop | null;
72
+ lastRuntimeEvidenceAt: number | null;
73
+ nowMs: number;
74
+ }): boolean;
21
75
  /** Statuses whose HTTP response itself signals "nothing is home" — no threshold needed. */
22
76
  export declare function isImmediateOfflineStatus(status: number): boolean;
23
77
  /**
@@ -43,6 +97,9 @@ export type ProbeOutcome = {
43
97
  } | {
44
98
  kind: 'failure';
45
99
  immediateOffline: boolean;
100
+ /** Which proxy hop produced it — see `shouldCountProbeFailure`. */
101
+ hop: ProxyHop | null;
102
+ upstreamStatus: number | null;
46
103
  } | {
47
104
  kind: 'healthy';
48
105
  health: SessionHealthResponse | null;
@@ -52,6 +109,15 @@ export interface ProbeResultLike {
52
109
  ok: boolean;
53
110
  health: SessionHealthResponse | null;
54
111
  body: string;
112
+ /**
113
+ * OPTIONAL, and it has to stay that way. This interface is published on
114
+ * `@kortix/sdk/react` and appears only in INPUT position — constructing one
115
+ * is the only way an external caller reaches `classifyProbeResult`. The two
116
+ * fields below landed after 0.12.8, so requiring them would break every such
117
+ * caller at compile time for a value the SDK's own probe always supplies.
118
+ */
119
+ hop?: ProxyHop | null;
120
+ upstreamStatus?: number | null;
55
121
  }
56
122
  export declare function classifyProbeResult(result: ProbeResultLike): ProbeOutcome;
57
123
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"use-runtime-reconnect.d.ts","sourceRoot":"","sources":["../../src/react/use-runtime-reconnect.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoC,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EASL,KAAK,uBAAuB,EAC7B,MAAM,4CAA4C,CAAC;AAGpD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,0CAA0C;AAC1C,eAAO,MAAM,cAAc,QAAS,CAAC;AAMrC,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AAEtC,eAAO,MAAM,aAAa,QAAS,CAAC;AAEpC,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAAE,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY,CAqBzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,OAAO,EACrB,gBAAgB,EAAE,OAAO,GACxB,uBAAuB,GAAG,IAAI,CAOhC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAQ9F;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,SAwIlC"}
1
+ {"version":3,"file":"use-runtime-reconnect.d.ts","sourceRoot":"","sources":["../../src/react/use-runtime-reconnect.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAQL,KAAK,uBAAuB,EAC7B,MAAM,4CAA4C,CAAC;AAGpD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,0CAA0C;AAC1C,eAAO,MAAM,cAAc,QAAS,CAAC;AAMrC,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AAEtC,eAAO,MAAM,aAAa,QAAS,CAAC;AAEpC;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,qBAAqB,EAAE,MAAM,GAAG,IAAI,EACpC,GAAG,EAAE,MAAM,GACV,OAAO,CAGT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAIV;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAAE,GACzD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mEAAmE;IACnE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAAE,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY,CA0BzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,OAAO,EACrB,gBAAgB,EAAE,OAAO,GACxB,uBAAuB,GAAG,IAAI,CAOhC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAQ9F;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,SAyKlC"}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { useEffect, useRef } from 'react';
3
3
  import { getSupabaseAccessToken } from '../core/http/auth.js';
4
- import { getSessionHealth, isRuntimeReady } from '../core/session/index.js';
5
- import { incrementSandboxFail, markInitialCheckDone, resetForServerSwitch, resetSandboxFail, setOpenCodeHealth, setSandboxStatus, setSandboxVersion, useSandboxConnectionStore, } from '../browser/stores/sandbox-connection-store.js';
4
+ import { getSessionHealth, isRuntimeReady, } from '../core/session/index.js';
5
+ import { incrementSandboxFail, markInitialCheckDone, resetForServerSwitch, resetSandboxFail, setOpenCodeHealth, setSandboxStatus, useSandboxConnectionStore, } from '../browser/stores/sandbox-connection-store.js';
6
6
  import { useServerStore } from '../browser/stores/server-store.js';
7
7
  /**
8
8
  * Number of consecutive failures before marking as unreachable
@@ -27,6 +27,66 @@ export const POLL_CONNECTED = 30_000; // 30s when healthy
27
27
  export const POLL_FAILING = 150;
28
28
  export const POLL_UNREACHABLE = 5_000; // 5s when confirmed unreachable
29
29
  export const CHECK_TIMEOUT = 20_000;
30
+ /**
31
+ * How recently a live SSE event must have arrived to veto a failed probe.
32
+ * An event that just came over the wire is stronger evidence of reachability
33
+ * than a probe timeout: a box saturated by a heavy turn (PDF rendering, asset
34
+ * builds) can miss the probe deadline while streaming that same turn's events.
35
+ * Without the veto, two such misses flipped the UI to "Waking this session
36
+ * up…", tore down the SSE stream (gated on status === 'connected'), and queued
37
+ * every send — against a runtime that was demonstrably up and mid-turn.
38
+ */
39
+ export const RUNTIME_EVIDENCE_FRESH_MS = 15_000;
40
+ /**
41
+ * Whether a failed health probe should be discarded because live runtime
42
+ * events prove reachability. Pure — see RUNTIME_EVIDENCE_FRESH_MS.
43
+ */
44
+ export function shouldIgnoreProbeFailure(lastRuntimeEvidenceAt, now) {
45
+ if (lastRuntimeEvidenceAt === null)
46
+ return false;
47
+ return now - lastRuntimeEvidenceAt < RUNTIME_EVIDENCE_FRESH_MS;
48
+ }
49
+ /**
50
+ * Whether a failed probe is evidence that the RUNTIME is unreachable, and may
51
+ * therefore move this session toward "unreachable".
52
+ *
53
+ * TWO independent facts can clear a failure, and they cover disjoint failures.
54
+ *
55
+ * 1. WHICH HOP the proxy blamed (`X-Kortix-Proxy-Hop`). Two of the four say
56
+ * nothing about the runtime:
57
+ *
58
+ * - `control_plane` — the platform answered from the session row without
59
+ * ever dialling the box (`503 sandbox not ready (status: stopped)`). An
60
+ * answer is not silence; counting it drove a session to "unreachable"
61
+ * while `/start` was still resuming it.
62
+ * - `upstream_port` — the user's own dev server on an app port is down.
63
+ * That is their process, not our runtime, and it must never render
64
+ * "Waking".
65
+ *
66
+ * 2. WHETHER SSE FRAMES ARE STILL ARRIVING. The hop cannot answer this and
67
+ * never will: the health probe addresses the daemon port, so every failure
68
+ * it can observe is `daemon` (the proxy reached the box, the runtime did
69
+ * not answer), `provider_ingress`, or — for a `CHECK_TIMEOUT` abort — no hop
70
+ * at all. All three count. On a box saturated by a heavy turn that is the
71
+ * 2026-08-17 incident verbatim: two missed probes flip `sandboxStatus` to
72
+ * `unreachable`, `useOpenCodeEventStream` (gated on `=== 'connected'`) tears
73
+ * the live stream down, and the transcript freezes mid-turn on a runtime
74
+ * that is provably up — it is delivering the frames. A frame is a fact from
75
+ * the runtime itself, not an inference, and it outranks a probe that timed
76
+ * out behind it.
77
+ *
78
+ * An UNATTRIBUTED failure with no fresh frames still counts. A network error,
79
+ * a `CHECK_TIMEOUT` abort, or a response from something that is not our proxy
80
+ * carries no hop, and refusing to count those would leave a browser that lost
81
+ * its connection reading "connected" forever — the poller's only job.
82
+ */
83
+ export function shouldCountProbeFailure(input) {
84
+ if (input.hop === 'control_plane' || input.hop === 'upstream_port')
85
+ return false;
86
+ if (shouldIgnoreProbeFailure(input.lastRuntimeEvidenceAt, input.nowMs))
87
+ return false;
88
+ return true;
89
+ }
30
90
  /** Statuses whose HTTP response itself signals "nothing is home" — no threshold needed. */
31
91
  export function isImmediateOfflineStatus(status) {
32
92
  return status === 502 || status === 503 || status === 504;
@@ -55,7 +115,12 @@ export function classifyProbeResult(result) {
55
115
  return { kind: 'booting', health: result.health };
56
116
  }
57
117
  if (!result.ok) {
58
- return { kind: 'failure', immediateOffline: isImmediateOfflineSignal(result.status, result.body) };
118
+ return {
119
+ kind: 'failure',
120
+ immediateOffline: isImmediateOfflineSignal(result.status, result.body),
121
+ hop: result.hop ?? null,
122
+ upstreamStatus: result.upstreamStatus ?? null,
123
+ };
59
124
  }
60
125
  return { kind: 'healthy', health: result.health };
61
126
  }
@@ -130,16 +195,37 @@ export function useRuntimeReconnect() {
130
195
  async function check() {
131
196
  if (!alive)
132
197
  return;
133
- const url = useServerStore.getState().getActiveServerUrl();
134
- if (!url) {
135
- scheduleNext();
136
- return;
198
+ let url;
199
+ let token;
200
+ try {
201
+ url = useServerStore.getState().getActiveServerUrl();
202
+ if (!url) {
203
+ scheduleNext();
204
+ return;
205
+ }
206
+ // Don't fire health checks until auth is ready — avoids naked requests
207
+ // that return synthetic 401s and cause false "unreachable" status.
208
+ token = await getSupabaseAccessToken();
209
+ if (!token) {
210
+ scheduleNext();
211
+ return;
212
+ }
137
213
  }
138
- // Don't fire health checks until auth is ready — avoids naked requests
139
- // that return synthetic 401s and cause false "unreachable" status.
140
- const token = await getSupabaseAccessToken();
141
- if (!token) {
142
- scheduleNext();
214
+ catch {
215
+ // `getActiveServerUrl()` and `getSupabaseAccessToken()` are host
216
+ // config/auth lookups, not network calls guarded by the `try` below
217
+ // — a throw here (e.g. `createClient()`'s "Missing Supabase browser
218
+ // environment variables" during an env hydration race) used to
219
+ // escape `check()` uncaught. `check()` runs detached (fire-and-forget
220
+ // from the effect, and from this same `setTimeout` callback), so an
221
+ // uncaught rejection silently ended the poll loop: `scheduleNext()`
222
+ // never ran again, `healthy` stayed whatever it last was, and
223
+ // "Waking this session up…" (gated on `runtimeReady`, which reads
224
+ // this store) stayed up forever — recoverable only by a hard reload
225
+ // remounting this effect. Retry next tick exactly like the `!token`
226
+ // early-return above, instead of dying.
227
+ if (alive)
228
+ scheduleNext();
143
229
  return;
144
230
  }
145
231
  abortRef.current?.abort();
@@ -147,6 +233,9 @@ export function useRuntimeReconnect() {
147
233
  abortRef.current = controller;
148
234
  let immediateOffline = false;
149
235
  let failed = false;
236
+ // Which hop the proxy blamed, when it blamed one. Stays null for a thrown
237
+ // probe — there is no response to read it from.
238
+ let hop = null;
150
239
  try {
151
240
  const timer = setTimeout(() => controller.abort(), CHECK_TIMEOUT);
152
241
  const result = await getSessionHealth(url, { signal: controller.signal });
@@ -164,23 +253,18 @@ export function useRuntimeReconnect() {
164
253
  resetSandboxFail();
165
254
  setSandboxStatus('connected');
166
255
  setOpenCodeHealth(false, outcome.health?.version, outcome.health?.boot_error ?? outcome.health?.message ?? outcome.health?.reason ?? null);
167
- if (outcome.health?.version) {
168
- setSandboxVersion(outcome.health.version);
169
- }
170
256
  break;
171
257
  }
172
258
  case 'failure': {
173
259
  failed = true;
174
260
  immediateOffline = outcome.immediateOffline;
261
+ hop = outcome.hop;
175
262
  break;
176
263
  }
177
264
  case 'healthy': {
178
265
  resetSandboxFail();
179
266
  setSandboxStatus('connected');
180
267
  setOpenCodeHealth(isRuntimeReady(outcome.health), outcome.health?.version, outcome.health?.boot_error ?? outcome.health?.message ?? outcome.health?.reason ?? null);
181
- if (outcome.health?.version) {
182
- setSandboxVersion(outcome.health.version);
183
- }
184
268
  break;
185
269
  }
186
270
  }
@@ -193,8 +277,22 @@ export function useRuntimeReconnect() {
193
277
  return;
194
278
  failed = true;
195
279
  immediateOffline = false;
280
+ hop = null;
196
281
  }
197
282
  finally {
283
+ // A failure the proxy attributed to a hop that is not the runtime (our
284
+ // own control-plane answer, or the user's app port), or one raised
285
+ // while live SSE frames are still arriving, is discarded here rather
286
+ // than in `computeFailureStatus` — so it moves neither the counter nor
287
+ // the status, an "immediate offline" 502/503 included.
288
+ if (failed &&
289
+ !shouldCountProbeFailure({
290
+ hop,
291
+ lastRuntimeEvidenceAt: useSandboxConnectionStore.getState().lastRuntimeEvidenceAt,
292
+ nowMs: Date.now(),
293
+ })) {
294
+ failed = false;
295
+ }
198
296
  if (failed) {
199
297
  incrementSandboxFail();
200
298
  if (immediateOffline) {
@@ -1 +1 @@
1
- {"version":3,"file":"use-runtime-reconnect.js","sourceRoot":"","sources":["../../src/react/use-runtime-reconnect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-runtime-reconnect.js","sourceRoot":"","sources":["../../src/react/use-runtime-reconnect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ import { type CreateSessionPromptInput, type CreateSessionPromptResult, type RemovedSessionPrompt, type SessionPrompt, type SessionPromptOverrides, type SessionPromptPart, createSessionPrompt } from '../core/rest/projects-client/sessions.js';
2
+ /**
3
+ * The session's SERVER-SIDE prompt inbox.
4
+ *
5
+ * The queue used to be a browser store: closing the tab, switching device, or
6
+ * a crash lost every pending message silently, and two tabs on one session each
7
+ * believed their own list. This hook reads the durable rows instead, so what
8
+ * the composer renders is what the server will actually deliver.
9
+ *
10
+ * Polling has TWO cadences, and the slow one is not an optimization.
11
+ *
12
+ * While prompts exist the list is the only thing that can report a state change
13
+ * (`waiting` → `queued` → `delivering`), so it polls fast. An empty list is the
14
+ * common state and does not need that — but it cannot stop either, because a
15
+ * prompt can ENTER the inbox with this tab doing nothing at all: the reaper
16
+ * redelivers one whose turn never ran, and parking a box requeues its in-flight
17
+ * prompt as `held`. A held row is deliberately not due; the user releases it by
18
+ * sending something or pressing "send now" on it, which they can only do if
19
+ * they can SEE it. Not polling an empty list meant only a full page load ever
20
+ * showed those rows — and the same gap hid a prompt queued from a second tab.
21
+ */
22
+ export declare const SESSION_PROMPTS_POLL_MS = 1000;
23
+ /** The floor for an EMPTY list. Slow enough to be free, fast enough that a
24
+ * prompt handed back by the server appears while the user is still looking. */
25
+ export declare const SESSION_PROMPTS_IDLE_POLL_MS = 15000;
26
+ /** The cadence for a list of `count` prompts. Pure, so the floor is testable. */
27
+ export declare function sessionPromptsPollMs(count: number, pollMs?: number): number;
28
+ /**
29
+ * Feed one reading of the list into the working projection.
30
+ *
31
+ * The inbox is not only something to render. A prompt is DURABLE long before it
32
+ * is a turn: the lifecycle row has to be drained, and the box may have to resume
33
+ * first (18.9s Daytona / 24.5s Platinum, measured). `GET .../turn` truthfully
34
+ * answers "no turns" for that whole window, and the composer used to believe it
35
+ * — swapping Stop back to Send while the user's prompt was still queued. The
36
+ * stamp is the instant the read was ISSUED, for the same reason `/turn`'s is.
37
+ */
38
+ export declare function noteInboxObservation(sessionId: string, prompts: readonly SessionPrompt[], atMs: number): void;
39
+ export declare const OPTIMISTIC_PROMPT_PREFIX = "optimistic:";
40
+ /** Is this row the tab's own echo, not yet confirmed by the server? */
41
+ export declare function isOptimisticSessionPrompt(prompt: Pick<SessionPrompt, 'prompt_id'>): boolean;
42
+ /**
43
+ * The strip-shaped row for a submission that has left this tab but not yet
44
+ * come back from `POST .../prompts`. The queue is server-side; this is the
45
+ * one client-side thing a server queue cannot do — paint on the keypress.
46
+ * Replaced by the server's row on the response (`settleOptimisticPrompt`),
47
+ * or by the poll landing first (`reconcileOptimisticPrompts`), and removed
48
+ * on failure so a refused send never lingers.
49
+ */
50
+ export declare function optimisticSessionPrompt(input: CreateSessionPromptInput, nowMs: number): SessionPrompt;
51
+ export declare function applyOptimisticPrompt(prompts: readonly SessionPrompt[], input: CreateSessionPromptInput, nowMs: number): SessionPrompt[];
52
+ export declare function settleOptimisticPrompt(prompts: readonly SessionPrompt[], clientMessageId: string, result: CreateSessionPromptResult): SessionPrompt[];
53
+ export declare function removeOptimisticPrompt(prompts: readonly SessionPrompt[], clientMessageId: string): SessionPrompt[];
54
+ /**
55
+ * Merge a fresh server list over the cached one: the server's rows are the
56
+ * truth, and an optimistic row survives only while the server has not listed
57
+ * its submission yet (the POST is still in flight).
58
+ */
59
+ export declare function reconcileOptimisticPrompts(cached: readonly SessionPrompt[] | undefined, server: readonly SessionPrompt[]): SessionPrompt[];
60
+ export interface UseSessionPromptsResult {
61
+ prompts: SessionPrompt[];
62
+ isLoading: boolean;
63
+ /** Put one prompt in the inbox. Resolving means DURABLE, not delivered. */
64
+ enqueue: (input: CreateSessionPromptInput) => Promise<CreateSessionPromptResult>;
65
+ /** Drop a prompt that has not gone out. Throws 409 for one already on the
66
+ * wire. Resolves with the removed prompt, which is what an undo re-POSTs:
67
+ * the row is hard-deleted, so nothing else still holds its full body. */
68
+ remove: (promptId: string) => Promise<RemovedSessionPrompt>;
69
+ /** Run THIS prompt next — the primitive behind both retry and "send now". */
70
+ retry: (promptId: string) => Promise<SessionPrompt>;
71
+ /** Hold, or release, the whole queue. The Stop button holds; any new send,
72
+ * and `retry`, release. */
73
+ hold: (held: boolean) => Promise<{
74
+ prompts: SessionPrompt[];
75
+ }>;
76
+ refetch: () => Promise<unknown>;
77
+ }
78
+ export declare function useSessionPrompts(projectId: string | undefined, sessionId: string | undefined, options?: {
79
+ pollMs?: number;
80
+ enabled?: boolean;
81
+ }): UseSessionPromptsResult;
82
+ /** Injectable seams for {@link startSessionWithPrompt}'s tests. */
83
+ export interface StartSessionWithPromptAdapters {
84
+ create?: typeof createSessionPrompt;
85
+ nowMs?: () => number;
86
+ }
87
+ /**
88
+ * POST the first prompt of a session straight to the durable inbox.
89
+ *
90
+ * A plain async function, not a hook — two of its producers are plain click
91
+ * handlers on pages that never mount a session. The admission gate holds the
92
+ * row until the box answers; `session-composer-readiness.ts` states the
93
+ * contract: "A submit against a sleeping box is POSTed to `.../prompts` and
94
+ * becomes a durable row."
95
+ *
96
+ * This replaces the sessionStorage start-stash as the delivery channel (the
97
+ * stash still hands off the model/agent PICKS): the stash needed a mounted
98
+ * workbench to replay it 19-25s later (measured boot), and a closed tab in
99
+ * that window lost the message silently. The wire id is minted here but
100
+ * flagged `remintOnDelivery` — this producer runs before any transcript
101
+ * exists to place an id against, which is the exact criterion that flag
102
+ * documents.
103
+ *
104
+ * Files the same receipts `handleSend` does, so the composer's working
105
+ * projection covers the send from the click, and drops them on every path
106
+ * where nothing is coming — including a `failed` verdict, which arrives as a
107
+ * 200 (a dead-lettered dedupe) and is thrown here as the refusal it is.
108
+ */
109
+ export declare function startSessionWithPrompt(projectId: string, sessionId: string, input: {
110
+ parts: SessionPromptPart[];
111
+ overrides?: SessionPromptOverrides;
112
+ }, adapters?: StartSessionWithPromptAdapters): Promise<CreateSessionPromptResult>;
113
+ //# sourceMappingURL=use-session-prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-prompts.d.ts","sourceRoot":"","sources":["../../src/react/use-session-prompts.ts"],"names":[],"mappings":"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"}