@kortix/sdk 0.13.5 → 0.13.9

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 (253) hide show
  1. package/README.md +69 -6
  2. package/dist/browser/session-sync/server-transcript-mirror.d.ts +82 -0
  3. package/dist/browser/session-sync/server-transcript-mirror.d.ts.map +1 -0
  4. package/dist/browser/session-sync/server-transcript-mirror.js +143 -0
  5. package/dist/browser/session-sync/server-transcript-mirror.js.map +1 -0
  6. package/dist/browser/session-sync/session-sync-registry.d.ts +11 -21
  7. package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
  8. package/dist/browser/session-sync/session-sync-registry.js +48 -3
  9. package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
  10. package/dist/browser/stores/sandbox-connection-store.d.ts +13 -1
  11. package/dist/browser/stores/sandbox-connection-store.d.ts.map +1 -1
  12. package/dist/browser/stores/sandbox-connection-store.js +5 -2
  13. package/dist/browser/stores/sandbox-connection-store.js.map +1 -1
  14. package/dist/browser/stores/session-working-store.d.ts +10 -5
  15. package/dist/browser/stores/session-working-store.d.ts.map +1 -1
  16. package/dist/browser/stores/session-working-store.js +32 -8
  17. package/dist/browser/stores/session-working-store.js.map +1 -1
  18. package/dist/browser/stores/sync-store.d.ts +29 -1
  19. package/dist/browser/stores/sync-store.d.ts.map +1 -1
  20. package/dist/browser/stores/sync-store.js +516 -393
  21. package/dist/browser/stores/sync-store.js.map +1 -1
  22. package/dist/core/auth/app-viewer.d.ts +57 -0
  23. package/dist/core/auth/app-viewer.d.ts.map +1 -0
  24. package/dist/core/auth/app-viewer.js +82 -0
  25. package/dist/core/auth/app-viewer.js.map +1 -0
  26. package/dist/core/auth/session.d.ts +45 -0
  27. package/dist/core/auth/session.d.ts.map +1 -0
  28. package/dist/core/auth/session.js +113 -0
  29. package/dist/core/auth/session.js.map +1 -0
  30. package/dist/core/client/kortix.d.ts +37 -18
  31. package/dist/core/client/kortix.d.ts.map +1 -1
  32. package/dist/core/client/kortix.js +47 -0
  33. package/dist/core/client/kortix.js.map +1 -1
  34. package/dist/core/http/config.d.ts +4 -2
  35. package/dist/core/http/config.d.ts.map +1 -1
  36. package/dist/core/http/config.js.map +1 -1
  37. package/dist/core/http/opencode-errors.d.ts +17 -0
  38. package/dist/core/http/opencode-errors.d.ts.map +1 -1
  39. package/dist/core/http/opencode-errors.js +25 -0
  40. package/dist/core/http/opencode-errors.js.map +1 -1
  41. package/dist/core/rest/platform-client/auth.d.ts +120 -0
  42. package/dist/core/rest/platform-client/auth.d.ts.map +1 -0
  43. package/dist/core/rest/platform-client/auth.js +98 -0
  44. package/dist/core/rest/platform-client/auth.js.map +1 -0
  45. package/dist/core/rest/platform-client/host-boundary.d.ts +5 -0
  46. package/dist/core/rest/platform-client/host-boundary.d.ts.map +1 -1
  47. package/dist/core/rest/platform-client/host-boundary.js.map +1 -1
  48. package/dist/core/rest/projects-client/accounts.d.ts +57 -0
  49. package/dist/core/rest/projects-client/accounts.d.ts.map +1 -1
  50. package/dist/core/rest/projects-client/accounts.js +31 -0
  51. package/dist/core/rest/projects-client/accounts.js.map +1 -1
  52. package/dist/core/rest/projects-client/apps.d.ts +9 -0
  53. package/dist/core/rest/projects-client/apps.d.ts.map +1 -1
  54. package/dist/core/rest/projects-client/apps.js.map +1 -1
  55. package/dist/core/rest/projects-client/billing.d.ts +2 -0
  56. package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
  57. package/dist/core/rest/projects-client/billing.js.map +1 -1
  58. package/dist/core/rest/projects-client/connectors.d.ts +104 -19
  59. package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
  60. package/dist/core/rest/projects-client/connectors.js +56 -2
  61. package/dist/core/rest/projects-client/connectors.js.map +1 -1
  62. package/dist/core/rest/projects-client/index.d.ts +1 -0
  63. package/dist/core/rest/projects-client/index.d.ts.map +1 -1
  64. package/dist/core/rest/projects-client/index.js +1 -0
  65. package/dist/core/rest/projects-client/index.js.map +1 -1
  66. package/dist/core/rest/projects-client/oauth-clients.d.ts +47 -0
  67. package/dist/core/rest/projects-client/oauth-clients.d.ts.map +1 -0
  68. package/dist/core/rest/projects-client/oauth-clients.js +33 -0
  69. package/dist/core/rest/projects-client/oauth-clients.js.map +1 -0
  70. package/dist/core/rest/projects-client/projects.d.ts +23 -6
  71. package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
  72. package/dist/core/rest/projects-client/projects.js +1 -0
  73. package/dist/core/rest/projects-client/projects.js.map +1 -1
  74. package/dist/core/rest/projects-client/session-sandbox.d.ts +52 -0
  75. package/dist/core/rest/projects-client/session-sandbox.d.ts.map +1 -1
  76. package/dist/core/rest/projects-client/session-sandbox.js.map +1 -1
  77. package/dist/core/rest/projects-client/sessions.d.ts +134 -1
  78. package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
  79. package/dist/core/rest/projects-client/sessions.js +47 -1
  80. package/dist/core/rest/projects-client/sessions.js.map +1 -1
  81. package/dist/core/session/index.d.ts +1 -0
  82. package/dist/core/session/index.d.ts.map +1 -1
  83. package/dist/core/session/index.js +1 -0
  84. package/dist/core/session/index.js.map +1 -1
  85. package/dist/core/session/open-bundle.d.ts +110 -0
  86. package/dist/core/session/open-bundle.d.ts.map +1 -0
  87. package/dist/core/session/open-bundle.js +183 -0
  88. package/dist/core/session/open-bundle.js.map +1 -0
  89. package/dist/core/session/poll-owner.d.ts +35 -0
  90. package/dist/core/session/poll-owner.d.ts.map +1 -0
  91. package/dist/core/session/poll-owner.js +90 -0
  92. package/dist/core/session/poll-owner.js.map +1 -0
  93. package/dist/core/session/static-file-preview.d.ts +50 -0
  94. package/dist/core/session/static-file-preview.d.ts.map +1 -0
  95. package/dist/core/session/static-file-preview.js +91 -0
  96. package/dist/core/session/static-file-preview.js.map +1 -0
  97. package/dist/core/session/wake-escalation.d.ts +188 -0
  98. package/dist/core/session/wake-escalation.d.ts.map +1 -0
  99. package/dist/core/session/wake-escalation.js +241 -0
  100. package/dist/core/session/wake-escalation.js.map +1 -0
  101. package/dist/core/session/working.d.ts +63 -2
  102. package/dist/core/session/working.d.ts.map +1 -1
  103. package/dist/core/session/working.js +66 -9
  104. package/dist/core/session/working.js.map +1 -1
  105. package/dist/core/session-sync/session-sync-controller.d.ts +34 -2
  106. package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
  107. package/dist/core/session-sync/session-sync-controller.js +97 -11
  108. package/dist/core/session-sync/session-sync-controller.js.map +1 -1
  109. package/dist/core/stream/keepalive.d.ts +17 -0
  110. package/dist/core/stream/keepalive.d.ts.map +1 -0
  111. package/dist/core/stream/keepalive.js +19 -0
  112. package/dist/core/stream/keepalive.js.map +1 -0
  113. package/dist/core/turns/grouping.d.ts.map +1 -1
  114. package/dist/core/turns/grouping.js +13 -0
  115. package/dist/core/turns/grouping.js.map +1 -1
  116. package/dist/core/turns/types.d.ts +5 -0
  117. package/dist/core/turns/types.d.ts.map +1 -1
  118. package/dist/index.d.ts +15 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +18 -0
  121. package/dist/index.js.map +1 -1
  122. package/dist/kortix.esm.min.js +25 -25
  123. package/dist/kortix.global.js +25 -25
  124. package/dist/node/app-viewer.d.ts +41 -0
  125. package/dist/node/app-viewer.d.ts.map +1 -0
  126. package/dist/node/app-viewer.js +150 -0
  127. package/dist/node/app-viewer.js.map +1 -0
  128. package/dist/node/auth.d.ts +84 -0
  129. package/dist/node/auth.d.ts.map +1 -0
  130. package/dist/node/auth.js +414 -0
  131. package/dist/node/auth.js.map +1 -0
  132. package/dist/node/server.d.ts +19 -0
  133. package/dist/node/server.d.ts.map +1 -1
  134. package/dist/node/server.js +13 -1
  135. package/dist/node/server.js.map +1 -1
  136. package/dist/react/bedrock-invokable.d.ts +58 -0
  137. package/dist/react/bedrock-invokable.d.ts.map +1 -0
  138. package/dist/react/bedrock-invokable.js +83 -0
  139. package/dist/react/bedrock-invokable.js.map +1 -0
  140. package/dist/react/index.d.ts +3 -0
  141. package/dist/react/index.d.ts.map +1 -1
  142. package/dist/react/index.js +7 -0
  143. package/dist/react/index.js.map +1 -1
  144. package/dist/react/model-flatten.d.ts +14 -1
  145. package/dist/react/model-flatten.d.ts.map +1 -1
  146. package/dist/react/model-flatten.js +3 -4
  147. package/dist/react/model-flatten.js.map +1 -1
  148. package/dist/react/opencode.d.ts +2 -1
  149. package/dist/react/opencode.d.ts.map +1 -1
  150. package/dist/react/opencode.js +2 -1
  151. package/dist/react/opencode.js.map +1 -1
  152. package/dist/react/provider-selection.d.ts +58 -0
  153. package/dist/react/provider-selection.d.ts.map +1 -1
  154. package/dist/react/provider-selection.js +253 -2
  155. package/dist/react/provider-selection.js.map +1 -1
  156. package/dist/react/session-start-giveup.d.ts +12 -0
  157. package/dist/react/session-start-giveup.d.ts.map +1 -0
  158. package/dist/react/session-start-giveup.js +13 -0
  159. package/dist/react/session-start-giveup.js.map +1 -0
  160. package/dist/react/session-title-sync.d.ts.map +1 -1
  161. package/dist/react/session-title-sync.js +15 -5
  162. package/dist/react/session-title-sync.js.map +1 -1
  163. package/dist/react/sign-in-with-kortix.d.ts +346 -0
  164. package/dist/react/sign-in-with-kortix.d.ts.map +1 -0
  165. package/dist/react/sign-in-with-kortix.js +65 -0
  166. package/dist/react/sign-in-with-kortix.js.map +1 -0
  167. package/dist/react/use-admin-accounts.d.ts +1 -1
  168. package/dist/react/use-admin-accounts.d.ts.map +1 -1
  169. package/dist/react/use-admin-accounts.js +1 -0
  170. package/dist/react/use-admin-accounts.js.map +1 -1
  171. package/dist/react/use-gateway-routing-policy.d.ts +1 -0
  172. package/dist/react/use-gateway-routing-policy.d.ts.map +1 -1
  173. package/dist/react/use-gateway-routing-policy.js +12 -1
  174. package/dist/react/use-gateway-routing-policy.js.map +1 -1
  175. package/dist/react/use-kortix-app-viewer.d.ts +13 -0
  176. package/dist/react/use-kortix-app-viewer.d.ts.map +1 -0
  177. package/dist/react/use-kortix-app-viewer.js +29 -0
  178. package/dist/react/use-kortix-app-viewer.js.map +1 -0
  179. package/dist/react/use-model-defaults.d.ts +7 -0
  180. package/dist/react/use-model-defaults.d.ts.map +1 -1
  181. package/dist/react/use-model-defaults.js +7 -1
  182. package/dist/react/use-model-defaults.js.map +1 -1
  183. package/dist/react/use-model-enablement.d.ts.map +1 -1
  184. package/dist/react/use-model-enablement.js +5 -1
  185. package/dist/react/use-model-enablement.js.map +1 -1
  186. package/dist/react/use-model-store.d.ts +31 -0
  187. package/dist/react/use-model-store.d.ts.map +1 -1
  188. package/dist/react/use-model-store.js +31 -2
  189. package/dist/react/use-model-store.js.map +1 -1
  190. package/dist/react/use-opencode-events/helpers.d.ts +49 -5
  191. package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
  192. package/dist/react/use-opencode-events/helpers.js +54 -6
  193. package/dist/react/use-opencode-events/helpers.js.map +1 -1
  194. package/dist/react/use-opencode-events/index.d.ts.map +1 -1
  195. package/dist/react/use-opencode-events/index.js +22 -3
  196. package/dist/react/use-opencode-events/index.js.map +1 -1
  197. package/dist/react/use-opencode-events/use-event-stream-refs.d.ts.map +1 -1
  198. package/dist/react/use-opencode-events/use-event-stream-refs.js +14 -2
  199. package/dist/react/use-opencode-events/use-event-stream-refs.js.map +1 -1
  200. package/dist/react/use-opencode-local.d.ts.map +1 -1
  201. package/dist/react/use-opencode-local.js +27 -8
  202. package/dist/react/use-opencode-local.js.map +1 -1
  203. package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
  204. package/dist/react/use-opencode-sessions/providers.js +44 -3
  205. package/dist/react/use-opencode-sessions/providers.js.map +1 -1
  206. package/dist/react/use-poll-owner.d.ts +14 -0
  207. package/dist/react/use-poll-owner.d.ts.map +1 -0
  208. package/dist/react/use-poll-owner.js +32 -0
  209. package/dist/react/use-poll-owner.js.map +1 -0
  210. package/dist/react/use-project-llm-gateway.d.ts +27 -0
  211. package/dist/react/use-project-llm-gateway.d.ts.map +1 -0
  212. package/dist/react/use-project-llm-gateway.js +41 -0
  213. package/dist/react/use-project-llm-gateway.js.map +1 -0
  214. package/dist/react/use-project-models.d.ts +9 -0
  215. package/dist/react/use-project-models.d.ts.map +1 -1
  216. package/dist/react/use-project-models.js +24 -1
  217. package/dist/react/use-project-models.js.map +1 -1
  218. package/dist/react/use-runtime-reconnect.d.ts +11 -0
  219. package/dist/react/use-runtime-reconnect.d.ts.map +1 -1
  220. package/dist/react/use-runtime-reconnect.js +34 -3
  221. package/dist/react/use-runtime-reconnect.js.map +1 -1
  222. package/dist/react/use-session-prompts.d.ts +16 -1
  223. package/dist/react/use-session-prompts.d.ts.map +1 -1
  224. package/dist/react/use-session-prompts.js +76 -11
  225. package/dist/react/use-session-prompts.js.map +1 -1
  226. package/dist/react/use-session-send.d.ts.map +1 -1
  227. package/dist/react/use-session-send.js +14 -1
  228. package/dist/react/use-session-send.js.map +1 -1
  229. package/dist/react/use-session-start-give-up.d.ts +20 -0
  230. package/dist/react/use-session-start-give-up.d.ts.map +1 -0
  231. package/dist/react/use-session-start-give-up.js +60 -0
  232. package/dist/react/use-session-start-give-up.js.map +1 -0
  233. package/dist/react/use-session-sync.d.ts +22 -0
  234. package/dist/react/use-session-sync.d.ts.map +1 -1
  235. package/dist/react/use-session-sync.js +61 -5
  236. package/dist/react/use-session-sync.js.map +1 -1
  237. package/dist/react/use-session-working.d.ts +38 -0
  238. package/dist/react/use-session-working.d.ts.map +1 -1
  239. package/dist/react/use-session-working.js +81 -10
  240. package/dist/react/use-session-working.js.map +1 -1
  241. package/dist/react/use-session.d.ts +13 -13
  242. package/dist/react/use-session.d.ts.map +1 -1
  243. package/dist/react/use-session.js +74 -53
  244. package/dist/react/use-session.js.map +1 -1
  245. package/dist/react/use-static-file-preview.d.ts +12 -0
  246. package/dist/react/use-static-file-preview.d.ts.map +1 -0
  247. package/dist/react/use-static-file-preview.js +119 -0
  248. package/dist/react/use-static-file-preview.js.map +1 -0
  249. package/dist/react/use-wake-escalation.d.ts +51 -0
  250. package/dist/react/use-wake-escalation.d.ts.map +1 -0
  251. package/dist/react/use-wake-escalation.js +62 -0
  252. package/dist/react/use-wake-escalation.js.map +1 -0
  253. package/package.json +6 -4
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Framing a file from the sandbox's static file server.
3
+ *
4
+ * A host that wants to SHOW an HTML file has exactly one correct move: load it
5
+ * from the server that ships inside the sandbox (port 3211, `/open?path=…`) and
6
+ * frame that URL. The tempting shortcut — hand the file's text to an iframe as
7
+ * `srcDoc` — cannot work, and not for a reason a flag can fix: `srcDoc` gives
8
+ * the document no URL at all, so `./style.css`, `img/logo.png` and `app.js`
9
+ * have no base to resolve against. A page written as a page arrives unstyled.
10
+ *
11
+ * Two rules live here rather than in the hook, because both are decisions and
12
+ * neither needs a network to be reasoned about.
13
+ */
14
+ import { buildStaticFileHealthPreviewUrl, buildStaticFilePreviewUrl, hasPreviewTarget, } from './url.js';
15
+ /**
16
+ * Resolve both URLs for one file, or `null` when there is nothing to address.
17
+ *
18
+ * The `null` is the whole point. `buildStaticFilePreviewUrl` answers with the
19
+ * INTERNAL form — `http://localhost:3211/open?path=…` — when no sandbox is
20
+ * bound, which is honest for a link that will be re-resolved on click and
21
+ * actively wrong for anything that loads or probes it now: that port is on the
22
+ * viewer's own machine. Framing it shows whatever the user happens to be
23
+ * running; probing it can answer `200` and mark a preview "ready" that can
24
+ * never load. A sandbox binds asynchronously, so every caller passes through
25
+ * this state on the way to a working preview — it is the common case, not an
26
+ * edge one.
27
+ */
28
+ export function staticFilePreviewTargets(path, options) {
29
+ if (!path)
30
+ return null;
31
+ if (!hasPreviewTarget(options))
32
+ return null;
33
+ const previewUrl = buildStaticFilePreviewUrl(path, options);
34
+ if (!previewUrl)
35
+ return null;
36
+ return { previewUrl, healthUrl: buildStaticFileHealthPreviewUrl(options) };
37
+ }
38
+ /** Gap between liveness probes, ms. */
39
+ export const STATIC_FILE_HEALTH_RETRY_MS = 1_500;
40
+ /**
41
+ * How many probes before the wait becomes a reported failure.
42
+ *
43
+ * 20 × 1.5s ≈ 30s. The bound is not a guess about how long a sandbox takes to
44
+ * boot — it is the line past which silence stops being informative. Without it
45
+ * a surface spins "Starting preview server…" for the life of the tab; with it
46
+ * the user gets a sentence and a Retry.
47
+ */
48
+ export const STATIC_FILE_HEALTH_MAX_ATTEMPTS = 20;
49
+ /** Whether a caller that has made `attempts` probes should make another. */
50
+ export function shouldRetryStaticFileHealth(attempts) {
51
+ return attempts < STATIC_FILE_HEALTH_MAX_ATTEMPTS;
52
+ }
53
+ /**
54
+ * Does an authenticated preview URL address the file we are asking for?
55
+ *
56
+ * `useAuthenticatedPreviewUrl` resolves in an effect, so on the render where a
57
+ * viewer switches to a different file it still holds the PREVIOUS file's URL.
58
+ * Framing that shows the page the user just navigated away from.
59
+ *
60
+ * Compare NORMALIZED, never by prefix. The subdomain form authenticates with a
61
+ * one-shot `token` that `appendPreviewToken` adds through `URLSearchParams`,
62
+ * which re-serializes the WHOLE query — and the static file URL is the one
63
+ * preview URL that has a query, so `?path=/workspace/a.html` comes back as
64
+ * `?path=%2Fworkspace%2Fa.html`. No prefix of the original survives that, and a
65
+ * prefix test shipped a preview stuck on "Starting preview server…" forever:
66
+ * the server was up, the URL was authenticated, and the check said it belonged
67
+ * to a different file. A prefix is wrong in the other direction too —
68
+ * `a.html.bak` starts with the URL for `a.html`.
69
+ *
70
+ * Both sides go through the same `URL` round-trip, so both carry the same
71
+ * encoding; `token` is dropped because it is the credential, not the address.
72
+ */
73
+ function normalizeAddress(candidate) {
74
+ try {
75
+ const url = new URL(candidate);
76
+ url.searchParams.delete('token');
77
+ url.searchParams.sort();
78
+ return url.toString();
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ export function authenticatedUrlAddresses(authenticatedUrl, previewUrl) {
85
+ if (!authenticatedUrl || !previewUrl)
86
+ return false;
87
+ const authenticated = normalizeAddress(authenticatedUrl);
88
+ const wanted = normalizeAddress(previewUrl);
89
+ return authenticated !== null && authenticated === wanted;
90
+ }
91
+ //# sourceMappingURL=static-file-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-file-preview.js","sourceRoot":"","sources":["../../../src/core/session/static-file-preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,+BAA+B,EAC/B,yBAAyB,EACzB,gBAAgB,GAEjB,MAAM,OAAO,CAAC;AAUf;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAwB,EACxB,OAA4B;IAE5B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,+BAA+B,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,uCAAuC;AACvC,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAElD,4EAA4E;AAC5E,MAAM,UAAU,2BAA2B,CAAC,QAAgB;IAC1D,OAAO,QAAQ,GAAG,+BAA+B,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,gBAAgB,CAAC,SAAiB;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,gBAA2C,EAC3C,UAA8B;IAE9B,IAAI,CAAC,gBAAgB,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,aAAa,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC5C,OAAO,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,MAAM,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * The wake escalation ladder — what a session view does when bringing a
3
+ * runtime up takes longer than it should.
4
+ *
5
+ * ## The failure this replaces
6
+ *
7
+ * Opening a stopped session starts a wake. The old model gave that wake a FIXED
8
+ * budget: the server's own `RUNTIME_WAKE_LEASE_MS` (240s,
9
+ * `apps/api/src/projects/session-lifecycle/runtime-wake-fence.ts:10`), after
10
+ * which maintenance stamps `stopReason: 'runtime_wake_failed'` and every
11
+ * subsequent `/start` short-circuits to a terminal payload
12
+ * (`apps/api/src/projects/routes/shared.ts:672-694`)
13
+ *
14
+ * "Couldn't start session <id> — The session runtime did not become
15
+ * reachable. Restart the session to try again."
16
+ *
17
+ * Measured on Essentia (2026-08-26, box `inqwpv4a1cc1kynlg46k8`): that card
18
+ * painted while the box was SECONDS from ready — its daemon logged
19
+ * `opencode ready` at 06:10:02, right after the budget expired. The card is a
20
+ * dead end with no auto-recovery, and the human's fix is always the same one
21
+ * click: "clicking restart made it work instantly". Two more recurrences
22
+ * followed, both during a post-deploy image rebuild — i.e. this class recurs on
23
+ * every ops event that slows a provider resume.
24
+ *
25
+ * ## The two rules that fix it
26
+ *
27
+ * 1. **A budget measures SILENCE, not elapsed time.** A wake that is visibly
28
+ * advancing — provider state moving, daemon boot phases changing, health
29
+ * improving — has not failed, however long it takes. Only a bounded window
30
+ * with ZERO observable change is evidence of a wedge. So the clock here is
31
+ * reset by any change to {@link WakeObservation.progress} and the elapsed
32
+ * total is never consulted.
33
+ *
34
+ * 2. **Escalate through the ladder the human uses, and only then give up.**
35
+ * A quiet `/start` retry first (free, and it heals a row that recovered on
36
+ * its own), then the RESTART the user would have clicked — bounded to
37
+ * {@link WAKE_MAX_RESTARTS}. The terminal card is what remains after the
38
+ * ladder is exhausted, and it then has to name what was tried
39
+ * ({@link wakeEscalationAttemptSummary}).
40
+ *
41
+ * A blanket "just restart it by default" was considered and REJECTED: it
42
+ * destroys fast warm resumes (a Platinum CoW resume reaches `running` in ~1.9s)
43
+ * by throwing away a box that was about to answer.
44
+ *
45
+ * ## Why `runtimeReachable` is a separate input from `waking`
46
+ *
47
+ * The session row is NOT proof the runtime is up. Observed on Essentia the same
48
+ * day: `POST …/start` answered 202 and the row stayed `running` for 5+ minutes
49
+ * while the E2B resume had silently failed — the provider reported the sandbox
50
+ * `stopped` and the daemon proxy answered `503 sandbox_not_ready`. A ladder that
51
+ * treated `stage: 'ready'` as the end of the wake would sit there forever. So
52
+ * the wake ends when the RUNTIME ANSWERS (`/kortix/health`), not when the
53
+ * control plane says it should have.
54
+ *
55
+ * That reachability is also a LATCH: once a runtime has answered, this machine
56
+ * is done for the life of the session view. A box that drops mid-session is
57
+ * `useRuntimeReconnect`'s problem, and auto-restarting it would destroy the
58
+ * turn the user is watching.
59
+ *
60
+ * Pure and clock-free: every decision is a function of the passed state plus one
61
+ * observation. The React glue lives in `react/use-wake-escalation.ts`.
62
+ */
63
+ /**
64
+ * How long a wake may show ZERO observable change before the ladder escalates.
65
+ *
66
+ * Sized against the measured wake profile rather than a guess: a cold resume is
67
+ * 18.9s (Daytona) / 24.5s (Platinum) end to end, and each phase of it produces
68
+ * an observable change, so a healthy wake never accumulates more than a few
69
+ * seconds of silence. 75s is comfortably past the slowest legitimate single
70
+ * phase (the server's own provider-confirmation grace is 90s but it emits
71
+ * `runtime_waking` throughout) while still being three times faster to react
72
+ * than the 240s lease that produced the incident.
73
+ */
74
+ export declare const WAKE_NO_PROGRESS_MS = 75000;
75
+ /**
76
+ * Automatic restarts the ladder may perform. Two, because the human fix that
77
+ * always works is one restart, and a second covers the case where the first
78
+ * landed during the same ops event (an image rebuild) that wedged the wake.
79
+ * Unbounded retries would be a restart loop against a genuinely dead provider.
80
+ */
81
+ export declare const WAKE_MAX_RESTARTS = 2;
82
+ /**
83
+ * Minimum gap between two ladder actions.
84
+ *
85
+ * A server-declared wake failure short-circuits the no-progress window (there is
86
+ * nothing left to wait for), so without a floor the ladder would spend its whole
87
+ * budget inside one second. `POST /restart` plus its first `/start` take ~2.6s
88
+ * measured; 20s leaves the new attempt room to produce its first signal.
89
+ */
90
+ export declare const WAKE_ESCALATION_COOLDOWN_MS = 20000;
91
+ /** One rung of the ladder. */
92
+ export type WakeEscalationStep = 'retry-start' | 'restart';
93
+ /** The action to dispatch on THIS tick — `none` on almost every tick. */
94
+ export type WakeEscalationDispatch = 'none' | WakeEscalationStep;
95
+ export type WakeEscalationStatus =
96
+ /** No wake in progress, or the runtime already answered. */
97
+ 'idle'
98
+ /** A wake is running and has not needed help. */
99
+ | 'waking'
100
+ /** The ladder has intervened at least once and the wake continues. */
101
+ | 'escalating'
102
+ /** Every rung has been used; the host may now show a terminal card. */
103
+ | 'exhausted';
104
+ export interface WakeAttempt {
105
+ step: WakeEscalationStep;
106
+ atMs: number;
107
+ }
108
+ export interface WakeEscalationState {
109
+ status: WakeEscalationStatus;
110
+ /** What the host must do NOW. Read once per transition, never replayed. */
111
+ dispatch: WakeEscalationDispatch;
112
+ /** The last progress fingerprint seen, or null before the first observation. */
113
+ fingerprint: string | null;
114
+ /** When the fingerprint last changed. */
115
+ lastProgressAtMs: number | null;
116
+ /** When the ladder last dispatched an action. */
117
+ lastDispatchAtMs: number | null;
118
+ /** Everything the ladder has tried, oldest first. */
119
+ attempts: readonly WakeAttempt[];
120
+ /**
121
+ * How long the wake has shown no observable change. This is the
122
+ * PROGRESS-AWARE budget a host should render against — never wall-clock time
123
+ * since the wake began, which is what produced the premature terminal card.
124
+ */
125
+ msSinceProgress: number;
126
+ /** The runtime has answered at least once in this session view. */
127
+ settled: boolean;
128
+ }
129
+ export interface WakeObservation {
130
+ nowMs: number;
131
+ /**
132
+ * The host is trying to bring this session's runtime up. False switches the
133
+ * ladder off entirely (no session, gated, unmounted) and resets it.
134
+ */
135
+ waking: boolean;
136
+ /**
137
+ * The RUNTIME answered — daemon health, not the session row. True ends the
138
+ * wake and latches: see the module comment.
139
+ */
140
+ runtimeReachable: boolean;
141
+ /**
142
+ * Everything observable about this wake, joined into one value. Any change is
143
+ * progress. Build it with {@link wakeProgressFingerprint}.
144
+ */
145
+ progress: string;
146
+ /**
147
+ * The server has declared this wake failed — the state that used to paint the
148
+ * terminal card. Escalates immediately: there is no further progress to wait
149
+ * for, only a rung of the ladder left to try.
150
+ */
151
+ serverGaveUp: boolean;
152
+ }
153
+ export interface WakeEscalationLimits {
154
+ noProgressMs?: number;
155
+ maxRestarts?: number;
156
+ cooldownMs?: number;
157
+ }
158
+ export declare function initialWakeEscalationState(): WakeEscalationState;
159
+ /**
160
+ * Join the observable wake signals into one comparable value, dropping the ones
161
+ * that are not known yet.
162
+ *
163
+ * `null`/`undefined` are DROPPED rather than stringified so that a signal
164
+ * arriving for the first time (a sandbox row appearing, a health body parsing)
165
+ * reads as the progress it is, while a signal that is simply absent contributes
166
+ * nothing and cannot manufacture a change on its own.
167
+ */
168
+ export declare function wakeProgressFingerprint(parts: readonly (string | number | boolean | null | undefined)[]): string;
169
+ /**
170
+ * Fold one observation into the ladder's state. Pure — same inputs, same output,
171
+ * no clock and no I/O.
172
+ */
173
+ export declare function advanceWakeEscalation(state: WakeEscalationState, observation: WakeObservation, limits?: WakeEscalationLimits): WakeEscalationState;
174
+ /**
175
+ * The honest one-line status while the ladder is working, in the same voice as
176
+ * the boot-phase pill ("Waking the agent", "Connecting").
177
+ *
178
+ * Null while the first, ordinary wake is running — that wake already has honest
179
+ * copy and does not need a second component talking over it — and null once
180
+ * exhausted, where the terminal card takes over.
181
+ */
182
+ export declare function wakeEscalationNote(state: WakeEscalationState): string | null;
183
+ /**
184
+ * What the ladder tried, for the terminal card. A dead end that cannot say what
185
+ * was already attempted invites the user to repeat it by hand.
186
+ */
187
+ export declare function wakeEscalationAttemptSummary(state: WakeEscalationState): string | null;
188
+ //# sourceMappingURL=wake-escalation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wake-escalation.d.ts","sourceRoot":"","sources":["../../../src/core/session/wake-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,8BAA8B;AAC9B,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE3D,yEAAyE;AACzE,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAEjE,MAAM,MAAM,oBAAoB;AAC9B,4DAA4D;AAC1D,MAAM;AACR,iDAAiD;GAC/C,QAAQ;AACV,sEAAsE;GACpE,YAAY;AACd,uEAAuE;GACrE,WAAW,CAAC;AAEhB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,EAAE,sBAAsB,CAAC;IACjC,gFAAgF;IAChF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,qDAAqD;IACrD,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,0BAA0B,IAAI,mBAAmB,CAWhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,GAC/D,MAAM,CAER;AAYD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,mBAAmB,EAC1B,WAAW,EAAE,eAAe,EAC5B,MAAM,GAAE,oBAAyB,GAChC,mBAAmB,CA0ErB;AAOD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAM5E;AAQD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAStF"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * The wake escalation ladder — what a session view does when bringing a
3
+ * runtime up takes longer than it should.
4
+ *
5
+ * ## The failure this replaces
6
+ *
7
+ * Opening a stopped session starts a wake. The old model gave that wake a FIXED
8
+ * budget: the server's own `RUNTIME_WAKE_LEASE_MS` (240s,
9
+ * `apps/api/src/projects/session-lifecycle/runtime-wake-fence.ts:10`), after
10
+ * which maintenance stamps `stopReason: 'runtime_wake_failed'` and every
11
+ * subsequent `/start` short-circuits to a terminal payload
12
+ * (`apps/api/src/projects/routes/shared.ts:672-694`)
13
+ *
14
+ * "Couldn't start session <id> — The session runtime did not become
15
+ * reachable. Restart the session to try again."
16
+ *
17
+ * Measured on Essentia (2026-08-26, box `inqwpv4a1cc1kynlg46k8`): that card
18
+ * painted while the box was SECONDS from ready — its daemon logged
19
+ * `opencode ready` at 06:10:02, right after the budget expired. The card is a
20
+ * dead end with no auto-recovery, and the human's fix is always the same one
21
+ * click: "clicking restart made it work instantly". Two more recurrences
22
+ * followed, both during a post-deploy image rebuild — i.e. this class recurs on
23
+ * every ops event that slows a provider resume.
24
+ *
25
+ * ## The two rules that fix it
26
+ *
27
+ * 1. **A budget measures SILENCE, not elapsed time.** A wake that is visibly
28
+ * advancing — provider state moving, daemon boot phases changing, health
29
+ * improving — has not failed, however long it takes. Only a bounded window
30
+ * with ZERO observable change is evidence of a wedge. So the clock here is
31
+ * reset by any change to {@link WakeObservation.progress} and the elapsed
32
+ * total is never consulted.
33
+ *
34
+ * 2. **Escalate through the ladder the human uses, and only then give up.**
35
+ * A quiet `/start` retry first (free, and it heals a row that recovered on
36
+ * its own), then the RESTART the user would have clicked — bounded to
37
+ * {@link WAKE_MAX_RESTARTS}. The terminal card is what remains after the
38
+ * ladder is exhausted, and it then has to name what was tried
39
+ * ({@link wakeEscalationAttemptSummary}).
40
+ *
41
+ * A blanket "just restart it by default" was considered and REJECTED: it
42
+ * destroys fast warm resumes (a Platinum CoW resume reaches `running` in ~1.9s)
43
+ * by throwing away a box that was about to answer.
44
+ *
45
+ * ## Why `runtimeReachable` is a separate input from `waking`
46
+ *
47
+ * The session row is NOT proof the runtime is up. Observed on Essentia the same
48
+ * day: `POST …/start` answered 202 and the row stayed `running` for 5+ minutes
49
+ * while the E2B resume had silently failed — the provider reported the sandbox
50
+ * `stopped` and the daemon proxy answered `503 sandbox_not_ready`. A ladder that
51
+ * treated `stage: 'ready'` as the end of the wake would sit there forever. So
52
+ * the wake ends when the RUNTIME ANSWERS (`/kortix/health`), not when the
53
+ * control plane says it should have.
54
+ *
55
+ * That reachability is also a LATCH: once a runtime has answered, this machine
56
+ * is done for the life of the session view. A box that drops mid-session is
57
+ * `useRuntimeReconnect`'s problem, and auto-restarting it would destroy the
58
+ * turn the user is watching.
59
+ *
60
+ * Pure and clock-free: every decision is a function of the passed state plus one
61
+ * observation. The React glue lives in `react/use-wake-escalation.ts`.
62
+ */
63
+ /**
64
+ * How long a wake may show ZERO observable change before the ladder escalates.
65
+ *
66
+ * Sized against the measured wake profile rather than a guess: a cold resume is
67
+ * 18.9s (Daytona) / 24.5s (Platinum) end to end, and each phase of it produces
68
+ * an observable change, so a healthy wake never accumulates more than a few
69
+ * seconds of silence. 75s is comfortably past the slowest legitimate single
70
+ * phase (the server's own provider-confirmation grace is 90s but it emits
71
+ * `runtime_waking` throughout) while still being three times faster to react
72
+ * than the 240s lease that produced the incident.
73
+ */
74
+ export const WAKE_NO_PROGRESS_MS = 75_000;
75
+ /**
76
+ * Automatic restarts the ladder may perform. Two, because the human fix that
77
+ * always works is one restart, and a second covers the case where the first
78
+ * landed during the same ops event (an image rebuild) that wedged the wake.
79
+ * Unbounded retries would be a restart loop against a genuinely dead provider.
80
+ */
81
+ export const WAKE_MAX_RESTARTS = 2;
82
+ /**
83
+ * Minimum gap between two ladder actions.
84
+ *
85
+ * A server-declared wake failure short-circuits the no-progress window (there is
86
+ * nothing left to wait for), so without a floor the ladder would spend its whole
87
+ * budget inside one second. `POST /restart` plus its first `/start` take ~2.6s
88
+ * measured; 20s leaves the new attempt room to produce its first signal.
89
+ */
90
+ export const WAKE_ESCALATION_COOLDOWN_MS = 20_000;
91
+ export function initialWakeEscalationState() {
92
+ return {
93
+ status: 'idle',
94
+ dispatch: 'none',
95
+ fingerprint: null,
96
+ lastProgressAtMs: null,
97
+ lastDispatchAtMs: null,
98
+ attempts: [],
99
+ msSinceProgress: 0,
100
+ settled: false,
101
+ };
102
+ }
103
+ /**
104
+ * Join the observable wake signals into one comparable value, dropping the ones
105
+ * that are not known yet.
106
+ *
107
+ * `null`/`undefined` are DROPPED rather than stringified so that a signal
108
+ * arriving for the first time (a sandbox row appearing, a health body parsing)
109
+ * reads as the progress it is, while a signal that is simply absent contributes
110
+ * nothing and cannot manufacture a change on its own.
111
+ */
112
+ export function wakeProgressFingerprint(parts) {
113
+ return parts.filter((part) => part !== null && part !== undefined).join('|');
114
+ }
115
+ /** The next rung, or null when the ladder is spent. */
116
+ function nextStep(attempts, maxRestarts) {
117
+ if (attempts.length === 0)
118
+ return 'retry-start';
119
+ const restarts = attempts.filter((attempt) => attempt.step === 'restart').length;
120
+ return restarts < maxRestarts ? 'restart' : null;
121
+ }
122
+ /**
123
+ * Fold one observation into the ladder's state. Pure — same inputs, same output,
124
+ * no clock and no I/O.
125
+ */
126
+ export function advanceWakeEscalation(state, observation, limits = {}) {
127
+ const noProgressMs = limits.noProgressMs ?? WAKE_NO_PROGRESS_MS;
128
+ const maxRestarts = limits.maxRestarts ?? WAKE_MAX_RESTARTS;
129
+ const cooldownMs = limits.cooldownMs ?? WAKE_ESCALATION_COOLDOWN_MS;
130
+ // The runtime answered. The wake is over, and nothing about it may leak into
131
+ // the next one. `settled` survives the reset: within one session view, a
132
+ // runtime that has answered is never woken again by this machine.
133
+ if (observation.runtimeReachable) {
134
+ return { ...initialWakeEscalationState(), settled: true };
135
+ }
136
+ // The host cannot classify the wake right now — PAUSE, do not forget.
137
+ //
138
+ // This is not hypothetical tidiness. `useRestartProjectSession` seeds the
139
+ // `/start` cache with `{stage: 'provisioning', sandbox: null}` the instant a
140
+ // restart is dispatched, and a null sandbox is exactly "cannot classify". If
141
+ // that cleared `attempts`, every rung the ladder fired would reset its own
142
+ // budget and `WAKE_MAX_RESTARTS` would bound nothing — a restart loop, which
143
+ // is strictly worse than the dead-end card this replaces.
144
+ //
145
+ // The silence clock IS cleared, so resuming re-baselines rather than
146
+ // escalating on the strength of a window the ladder never actually watched.
147
+ // The dispatch cooldown is deliberately kept: a pause must not become a way
148
+ // to fire two rungs back to back.
149
+ if (!observation.waking) {
150
+ return { ...state, dispatch: 'none', fingerprint: null, lastProgressAtMs: null, msSinceProgress: 0 };
151
+ }
152
+ // A runtime that already answered and later dropped is a mid-session
153
+ // reconnect, not a wake. Restarting it would destroy the live turn.
154
+ if (state.settled)
155
+ return { ...initialWakeEscalationState(), settled: true };
156
+ const previousProgressAtMs = state.lastProgressAtMs;
157
+ const first = previousProgressAtMs === null;
158
+ const changed = observation.progress !== state.fingerprint;
159
+ const lastProgressAtMs = previousProgressAtMs === null || changed ? observation.nowMs : previousProgressAtMs;
160
+ const msSinceProgress = Math.max(0, observation.nowMs - lastProgressAtMs);
161
+ const base = {
162
+ ...state,
163
+ dispatch: 'none',
164
+ fingerprint: observation.progress,
165
+ lastProgressAtMs,
166
+ msSinceProgress,
167
+ status: state.attempts.length > 0 ? 'escalating' : 'waking',
168
+ };
169
+ if (state.status === 'exhausted')
170
+ return { ...base, status: 'exhausted' };
171
+ // A server-declared failure needs no window: the wake is over, only the
172
+ // ladder is left. Everything else waits out the silence.
173
+ const stalled = !first && !changed && msSinceProgress >= noProgressMs;
174
+ if (!observation.serverGaveUp && !stalled)
175
+ return base;
176
+ // One action per cooldown, whatever triggered it.
177
+ if (state.lastDispatchAtMs !== null &&
178
+ observation.nowMs - state.lastDispatchAtMs < cooldownMs) {
179
+ return base;
180
+ }
181
+ const step = nextStep(state.attempts, maxRestarts);
182
+ if (!step)
183
+ return { ...base, status: 'exhausted' };
184
+ return {
185
+ ...base,
186
+ status: 'escalating',
187
+ dispatch: step,
188
+ attempts: [...state.attempts, { step, atMs: observation.nowMs }],
189
+ lastDispatchAtMs: observation.nowMs,
190
+ // The new attempt gets its own window: it has not been silent yet.
191
+ lastProgressAtMs: observation.nowMs,
192
+ msSinceProgress: 0,
193
+ };
194
+ }
195
+ const STEP_VERB = {
196
+ 'retry-start': 'retrying',
197
+ restart: 'restarting',
198
+ };
199
+ /**
200
+ * The honest one-line status while the ladder is working, in the same voice as
201
+ * the boot-phase pill ("Waking the agent", "Connecting").
202
+ *
203
+ * Null while the first, ordinary wake is running — that wake already has honest
204
+ * copy and does not need a second component talking over it — and null once
205
+ * exhausted, where the terminal card takes over.
206
+ */
207
+ export function wakeEscalationNote(state) {
208
+ if (state.status !== 'escalating')
209
+ return null;
210
+ const last = state.attempts[state.attempts.length - 1];
211
+ if (!last)
212
+ return null;
213
+ // The original wake is attempt 1, so the Nth ladder action is attempt N+1.
214
+ return `Still waking — ${STEP_VERB[last.step]} the runtime (attempt ${state.attempts.length + 1})`;
215
+ }
216
+ function countWord(count) {
217
+ if (count === 1)
218
+ return 'once';
219
+ if (count === 2)
220
+ return 'twice';
221
+ return `${count} times`;
222
+ }
223
+ /**
224
+ * What the ladder tried, for the terminal card. A dead end that cannot say what
225
+ * was already attempted invites the user to repeat it by hand.
226
+ */
227
+ export function wakeEscalationAttemptSummary(state) {
228
+ if (state.status !== 'exhausted')
229
+ return null;
230
+ const restarts = state.attempts.filter((attempt) => attempt.step === 'restart').length;
231
+ const retried = state.attempts.some((attempt) => attempt.step === 'retry-start');
232
+ if (!retried && restarts === 0)
233
+ return null;
234
+ const parts = [];
235
+ if (retried)
236
+ parts.push('re-issuing the wake');
237
+ if (restarts > 0)
238
+ parts.push(`restarting the session ${countWord(restarts)}`);
239
+ return `Tried: ${parts.join(', then ')}.`;
240
+ }
241
+ //# sourceMappingURL=wake-escalation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wake-escalation.js","sourceRoot":"","sources":["../../../src/core/session/wake-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC;AA4ElD,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE,IAAI;QACtB,gBAAgB,EAAE,IAAI;QACtB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK;KACf,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAgE;IAEhE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,uDAAuD;AACvD,SAAS,QAAQ,CACf,QAAgC,EAChC,WAAmB;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACjF,OAAO,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,WAA4B,EAC5B,SAA+B,EAAE;IAEjC,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAChE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,iBAAiB,CAAC;IAC5D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,2BAA2B,CAAC;IAEpE,6EAA6E;IAC7E,yEAAyE;IACzE,kEAAkE;IAClE,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO,EAAE,GAAG,0BAA0B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IACD,sEAAsE;IACtE,EAAE;IACF,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,0DAA0D;IAC1D,EAAE;IACF,qEAAqE;IACrE,4EAA4E;IAC5E,4EAA4E;IAC5E,kCAAkC;IAClC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IACvG,CAAC;IACD,qEAAqE;IACrE,oEAAoE;IACpE,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,GAAG,0BAA0B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAE7E,MAAM,oBAAoB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACpD,MAAM,KAAK,GAAG,oBAAoB,KAAK,IAAI,CAAC;IAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,KAAK,KAAK,CAAC,WAAW,CAAC;IAC3D,MAAM,gBAAgB,GACpB,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACtF,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAwB;QAChC,GAAG,KAAK;QACR,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE,WAAW,CAAC,QAAQ;QACjC,gBAAgB;QAChB,eAAe;QACf,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;KAC5D,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAE1E,wEAAwE;IACxE,yDAAyD;IACzD,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,eAAe,IAAI,YAAY,CAAC;IACtE,IAAI,CAAC,WAAW,CAAC,YAAY,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAEvD,kDAAkD;IAClD,IACE,KAAK,CAAC,gBAAgB,KAAK,IAAI;QAC/B,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,gBAAgB,GAAG,UAAU,EACvD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAEnD,OAAO;QACL,GAAG,IAAI;QACP,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC;QAChE,gBAAgB,EAAE,WAAW,CAAC,KAAK;QACnC,mEAAmE;QACnE,gBAAgB,EAAE,WAAW,CAAC,KAAK;QACnC,eAAe,EAAE,CAAC;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAuC;IACpD,aAAa,EAAE,UAAU;IACzB,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,2EAA2E;IAC3E,OAAO,kBAAkB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC;AACrG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAChC,OAAO,GAAG,KAAK,QAAQ,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAA0B;IACrE,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IACvF,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACjF,IAAI,CAAC,OAAO,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,IAAI,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,0BAA0B,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9E,OAAO,UAAU,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;AAC5C,CAAC"}
@@ -129,9 +129,17 @@ export declare const TURN_END_LEDGER_LAG_MS = 3000;
129
129
  export declare const OPTIMISTIC_ABORT_MAX_MS = 15000;
130
130
  /** This tab's own record that a prompt went out. */
131
131
  export interface SendReceipt {
132
- /** The submission's tab-local name — never sent anywhere. It exists so a
133
- * `working` state can say WHICH send it is standing on. */
132
+ /** The submission's tab-local name — never sent anywhere. */
134
133
  messageId: string;
134
+ /**
135
+ * The user-message turn that owns the working indicator while this receipt
136
+ * is live. A direct idle send names itself. A send made during an existing
137
+ * response names that existing turn, so its new bubble remains pending.
138
+ *
139
+ * `undefined` preserves the original contract and falls back to
140
+ * `messageId`. `null` explicitly means the caller cannot identify the turn.
141
+ */
142
+ turnId?: string | null;
135
143
  /** ms epoch at which the send left this tab. */
136
144
  atMs: number;
137
145
  /**
@@ -181,6 +189,25 @@ export interface WorkingServerInput {
181
189
  /** One observed runtime status frame, stamped when this tab observed it. */
182
190
  export interface WorkingStreamInput {
183
191
  type: 'busy' | 'retry' | 'idle';
192
+ /**
193
+ * WHO minted the frame. `'wire'` (or absent — the field is additive) means
194
+ * the runtime's own SSE frame reached this tab. `'local'` means the tab
195
+ * synthesized it: `reconcileMissingBusySessions` reading absence out of a
196
+ * status snapshot, `markSessionAbortedLocally` on `server.instance.disposed`,
197
+ * `clearSession` on a cache-ownership handoff.
198
+ *
199
+ * The distinction exists for exactly one rule: only the runtime's own idle
200
+ * frame may CONTRADICT the lifecycle authority (`endedByRuntime`, and the
201
+ * "fresher frame knows more" ordering over an open row). A local frame is an
202
+ * inference, and the veto it inherited is unbounded on purpose — so one
203
+ * fabricated idle discarded every fresh `/turn` read for the rest of a quiet
204
+ * turn: the busy indicator left, the composer swapped Stop for Send, and
205
+ * both came back only when the reply finally streamed (dev, 2026-08-24). A
206
+ * local frame may still ANSWER when nothing fresher exists — the repair for
207
+ * a missed terminal frame stays a repair — it just cannot overrule a source
208
+ * that can actually know.
209
+ */
210
+ origin?: 'wire' | 'local';
184
211
  atMs: number;
185
212
  }
186
213
  /**
@@ -197,6 +224,13 @@ export interface WorkingStreamInput {
197
224
  * live spinner and text growing on screen, and a composer showing its send
198
225
  * arrow. Every observer had gone quiet; the only thing still speaking was the
199
226
  * content, and nothing was listening to it.
227
+ *
228
+ * Content reaches the tab two ways, and both stamp this: pushed (a streamed
229
+ * part off the SSE wire) and PULLED (a liveness-poll tail read whose hydrate
230
+ * shows the transcript moved with its tail still open — `sync-store.hydrate`).
231
+ * The pull path is what answers when the wire itself is the thing that died
232
+ * (essentia, 2026-08-26: stream black-holed mid-turn, stale idle frame vetoing
233
+ * the open turn row, transcript minutes behind).
200
234
  */
201
235
  export interface WorkingActivityInput {
202
236
  atMs: number;
@@ -205,8 +239,35 @@ export interface WorkingActivityInput {
205
239
  * still going to run, and when that list was read. */
206
240
  export interface WorkingInboxInput {
207
241
  pending: number;
242
+ /** This tab's clock at ISSUE or RECEIVE time. The AGE stamp: it only ever
243
+ * meets `nowMs` — the same clock — in `INBOX_OBSERVATION_MAX_MS`. */
208
244
  atMs: number;
245
+ /**
246
+ * The SERVER's clock at the observation — `observed_at` captured before the
247
+ * read (GET, bundle, stream frame) or after the write (`POST .../prompts`).
248
+ * The ORDERING stamp: it only ever meets another `serverAtMs`. Absent when
249
+ * the server did not supply one.
250
+ *
251
+ * Two stamps because one field served both jobs and the jobs need different
252
+ * clocks. Ranked against a browser stamp, an API clock ±10 minutes off
253
+ * either rejected every later direct read (skew ahead) or aged the
254
+ * observation out on arrival (skew behind) — both reproduced in PR #6957's
255
+ * review as a stale empty snapshot hiding a backend-confirmed queue row.
256
+ */
257
+ serverAtMs?: number;
209
258
  }
259
+ /**
260
+ * May `candidate` replace `current` as the session's inbox observation?
261
+ *
262
+ * ONE clock per comparison. When both observations carry the server's stamp,
263
+ * the server clock decides — it is the only pair drawn from one clock, and it
264
+ * orders a read against a write exactly (a read issued before a POST carries an
265
+ * older `observed_at` than the POST's response, so it can never erase it).
266
+ * Otherwise the browser stamps decide, as before. Ties stand aside for the
267
+ * candidate: two reads of the same instant agree, and the newer arrival may
268
+ * carry a corrected list.
269
+ */
270
+ export declare function inboxObservationSupersedes(candidate: WorkingInboxInput, current: WorkingInboxInput | null | undefined): boolean;
210
271
  export interface WorkingInputs {
211
272
  optimistic: SendReceipt | null;
212
273
  /** This tab's pending stop. `null`/absent means it is not stopping. */
@@ -1 +1 @@
1
- {"version":3,"file":"working.d.ts","sourceRoot":"","sources":["../../../src/core/session/working.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"working.d.ts","sourceRoot":"","sources":["../../../src/core/session/working.ts"],"names":[],"mappings":"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"}