@superblocksteam/gateway 2.0.161 → 2.0.162-next.1

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 (235) hide show
  1. package/README.md +135 -39
  2. package/dist/agents/resolve-orchestrator-url.d.ts +18 -0
  3. package/dist/agents/resolve-orchestrator-url.js +64 -1
  4. package/dist/agents/resolve-orchestrator-url.js.map +1 -1
  5. package/dist/capabilities/lifecycle.d.ts +46 -29
  6. package/dist/capabilities/lifecycle.js +1731 -843
  7. package/dist/capabilities/lifecycle.js.map +1 -1
  8. package/dist/capabilities/query-integration.d.ts +14 -0
  9. package/dist/capabilities/query-integration.js +172 -0
  10. package/dist/capabilities/query-integration.js.map +1 -0
  11. package/dist/capabilities/source-files-archive.d.ts +11 -0
  12. package/dist/capabilities/source-files-archive.js +54 -0
  13. package/dist/capabilities/source-files-archive.js.map +1 -0
  14. package/dist/capabilities/types.d.ts +197 -119
  15. package/dist/capabilities/types.js +45 -6
  16. package/dist/capabilities/types.js.map +1 -1
  17. package/dist/capture/browser-contract.d.ts +15 -5
  18. package/dist/capture/browser-contract.js +13 -3
  19. package/dist/capture/browser-contract.js.map +1 -1
  20. package/dist/capture/browser-instructions.d.ts +3 -2
  21. package/dist/capture/browser-instructions.js +3 -2
  22. package/dist/capture/browser-instructions.js.map +1 -1
  23. package/dist/capture/mode.d.ts +8 -1
  24. package/dist/capture/mode.js +22 -2
  25. package/dist/capture/mode.js.map +1 -1
  26. package/dist/config.d.ts +22 -23
  27. package/dist/config.js +13 -12
  28. package/dist/config.js.map +1 -1
  29. package/dist/deps.d.ts +7 -7
  30. package/dist/index.d.ts +2 -4
  31. package/dist/index.js +2 -4
  32. package/dist/index.js.map +1 -1
  33. package/dist/integrations/read-only-postgres-query.d.ts +2 -0
  34. package/dist/integrations/read-only-postgres-query.js +164 -0
  35. package/dist/integrations/read-only-postgres-query.js.map +1 -0
  36. package/dist/main.js +1 -1
  37. package/dist/main.js.map +1 -1
  38. package/dist/playwright/ensure-chromium.d.ts +5 -7
  39. package/dist/playwright/ensure-chromium.js +13 -13
  40. package/dist/playwright/ensure-chromium.js.map +1 -1
  41. package/dist/preview/capture-screenshot.d.ts +30 -4
  42. package/dist/preview/capture-screenshot.js +67 -17
  43. package/dist/preview/capture-screenshot.js.map +1 -1
  44. package/dist/preview/viewer-url.js +3 -1
  45. package/dist/preview/viewer-url.js.map +1 -1
  46. package/dist/process/fault-barrier.js +1 -1
  47. package/dist/process/fault-barrier.js.map +1 -1
  48. package/dist/sabs/agent-facing-text.d.ts +2 -0
  49. package/dist/sabs/agent-facing-text.js +56 -2
  50. package/dist/sabs/agent-facing-text.js.map +1 -1
  51. package/dist/sabs/app-state.d.ts +126 -0
  52. package/dist/sabs/app-state.js +332 -0
  53. package/dist/sabs/app-state.js.map +1 -0
  54. package/dist/sabs/awaited-decision.d.ts +49 -0
  55. package/dist/sabs/awaited-decision.js +129 -0
  56. package/dist/sabs/awaited-decision.js.map +1 -0
  57. package/dist/sabs/editor-client-methods.d.ts +23 -5
  58. package/dist/sabs/editor-client-methods.js +45 -4
  59. package/dist/sabs/editor-client-methods.js.map +1 -1
  60. package/dist/sabs/editor-socket.d.ts +85 -0
  61. package/dist/sabs/editor-socket.js +67 -0
  62. package/dist/sabs/editor-socket.js.map +1 -0
  63. package/dist/sabs/session-peer.d.ts +119 -82
  64. package/dist/sabs/session-peer.js +10 -1
  65. package/dist/sabs/session-peer.js.map +1 -1
  66. package/dist/sabs/streamed-reply.d.ts +45 -0
  67. package/dist/sabs/streamed-reply.js +125 -0
  68. package/dist/sabs/streamed-reply.js.map +1 -0
  69. package/dist/sabs/turn-collector.d.ts +50 -35
  70. package/dist/sabs/turn-collector.js +110 -176
  71. package/dist/sabs/turn-collector.js.map +1 -1
  72. package/dist/sabs/websocket-session-peer.d.ts +104 -69
  73. package/dist/sabs/websocket-session-peer.js +1333 -477
  74. package/dist/sabs/websocket-session-peer.js.map +1 -1
  75. package/dist/server/client.d.ts +41 -9
  76. package/dist/server/client.js +126 -21
  77. package/dist/server/client.js.map +1 -1
  78. package/dist/start.d.ts +1 -1
  79. package/dist/start.js +30 -8
  80. package/dist/start.js.map +1 -1
  81. package/dist/stores/memory.d.ts +46 -0
  82. package/dist/stores/memory.js +163 -0
  83. package/dist/stores/memory.js.map +1 -0
  84. package/dist/stores/types.d.ts +92 -0
  85. package/dist/stores/types.js +11 -0
  86. package/dist/stores/types.js.map +1 -0
  87. package/dist/telemetry/mcp-client.d.ts +6 -1
  88. package/dist/telemetry/mcp-client.js +100 -4
  89. package/dist/telemetry/mcp-client.js.map +1 -1
  90. package/dist/telemetry/metrics.d.ts +12 -3
  91. package/dist/telemetry/metrics.js +60 -14
  92. package/dist/telemetry/metrics.js.map +1 -1
  93. package/dist/telemetry/runtime.js +4 -6
  94. package/dist/telemetry/runtime.js.map +1 -1
  95. package/dist/transports/mcp/admin-tools.d.ts +8 -0
  96. package/dist/transports/mcp/admin-tools.js +115 -4
  97. package/dist/transports/mcp/admin-tools.js.map +1 -1
  98. package/dist/transports/mcp/app-status-html.d.ts +4 -8
  99. package/dist/transports/mcp/app-status-html.js +336 -128
  100. package/dist/transports/mcp/app-status-html.js.map +1 -1
  101. package/dist/transports/mcp/client-presentation.d.ts +16 -0
  102. package/dist/transports/mcp/client-presentation.js +13 -0
  103. package/dist/transports/mcp/client-presentation.js.map +1 -0
  104. package/dist/transports/mcp/cowork-editor-url.d.ts +6 -0
  105. package/dist/transports/mcp/cowork-editor-url.js +10 -0
  106. package/dist/transports/mcp/cowork-editor-url.js.map +1 -0
  107. package/dist/transports/mcp/decision-card-html.d.ts +26 -0
  108. package/dist/transports/mcp/decision-card-html.js +876 -0
  109. package/dist/transports/mcp/decision-card-html.js.map +1 -0
  110. package/dist/transports/mcp/decision-elicitation.d.ts +42 -0
  111. package/dist/transports/mcp/decision-elicitation.js +59 -0
  112. package/dist/transports/mcp/decision-elicitation.js.map +1 -1
  113. package/dist/transports/mcp/editor-document-probe.d.ts +4 -0
  114. package/dist/transports/mcp/editor-document-probe.js +35 -0
  115. package/dist/transports/mcp/editor-document-probe.js.map +1 -0
  116. package/dist/transports/mcp/editor-integration-setup-url.d.ts +14 -0
  117. package/dist/transports/mcp/editor-integration-setup-url.js +29 -0
  118. package/dist/transports/mcp/editor-integration-setup-url.js.map +1 -0
  119. package/dist/transports/mcp/format-tool-content.d.ts +13 -18
  120. package/dist/transports/mcp/format-tool-content.js +172 -13
  121. package/dist/transports/mcp/format-tool-content.js.map +1 -1
  122. package/dist/transports/mcp/instructions/index.d.ts +23 -0
  123. package/dist/transports/mcp/instructions/index.js +81 -0
  124. package/dist/transports/mcp/instructions/index.js.map +1 -0
  125. package/dist/transports/mcp/instructions/result.d.ts +18 -0
  126. package/dist/transports/mcp/instructions/result.js +58 -0
  127. package/dist/transports/mcp/instructions/result.js.map +1 -0
  128. package/dist/transports/mcp/instructions/tools/ask-user.d.ts +2 -0
  129. package/dist/transports/mcp/instructions/tools/ask-user.js +20 -0
  130. package/dist/transports/mcp/instructions/tools/ask-user.js.map +1 -0
  131. package/dist/transports/mcp/instructions/tools/build-app.d.ts +4 -0
  132. package/dist/transports/mcp/instructions/tools/build-app.js +54 -0
  133. package/dist/transports/mcp/instructions/tools/build-app.js.map +1 -0
  134. package/dist/transports/mcp/instructions/tools/check-app-progress.d.ts +3 -0
  135. package/dist/transports/mcp/instructions/tools/check-app-progress.js +79 -0
  136. package/dist/transports/mcp/instructions/tools/check-app-progress.js.map +1 -0
  137. package/dist/transports/mcp/instructions/tools/check-publish-progress.d.ts +3 -0
  138. package/dist/transports/mcp/instructions/tools/check-publish-progress.js +23 -0
  139. package/dist/transports/mcp/instructions/tools/check-publish-progress.js.map +1 -0
  140. package/dist/transports/mcp/instructions/tools/copy.d.ts +18 -0
  141. package/dist/transports/mcp/instructions/tools/copy.js +49 -0
  142. package/dist/transports/mcp/instructions/tools/copy.js.map +1 -0
  143. package/dist/transports/mcp/instructions/tools/create-integration.d.ts +4 -0
  144. package/dist/transports/mcp/instructions/tools/create-integration.js +41 -0
  145. package/dist/transports/mcp/instructions/tools/create-integration.js.map +1 -0
  146. package/dist/transports/mcp/instructions/tools/edit-app.d.ts +3 -0
  147. package/dist/transports/mcp/instructions/tools/edit-app.js +18 -0
  148. package/dist/transports/mcp/instructions/tools/edit-app.js.map +1 -0
  149. package/dist/transports/mcp/instructions/tools/get-app.d.ts +3 -0
  150. package/dist/transports/mcp/instructions/tools/get-app.js +49 -0
  151. package/dist/transports/mcp/instructions/tools/get-app.js.map +1 -0
  152. package/dist/transports/mcp/instructions/tools/get-integration-metadata.d.ts +2 -0
  153. package/dist/transports/mcp/instructions/tools/get-integration-metadata.js +13 -0
  154. package/dist/transports/mcp/instructions/tools/get-integration-metadata.js.map +1 -0
  155. package/dist/transports/mcp/instructions/tools/index.d.ts +7 -0
  156. package/dist/transports/mcp/instructions/tools/index.js +31 -0
  157. package/dist/transports/mcp/instructions/tools/index.js.map +1 -0
  158. package/dist/transports/mcp/instructions/tools/publish-app.d.ts +3 -0
  159. package/dist/transports/mcp/instructions/tools/publish-app.js +23 -0
  160. package/dist/transports/mcp/instructions/tools/publish-app.js.map +1 -0
  161. package/dist/transports/mcp/instructions/tools/start-app.d.ts +3 -0
  162. package/dist/transports/mcp/instructions/tools/start-app.js +22 -0
  163. package/dist/transports/mcp/instructions/tools/start-app.js.map +1 -0
  164. package/dist/transports/mcp/instructions/tools/upload-artifact.d.ts +2 -0
  165. package/dist/transports/mcp/instructions/tools/upload-artifact.js +13 -0
  166. package/dist/transports/mcp/instructions/tools/upload-artifact.js.map +1 -0
  167. package/dist/transports/mcp/mcp-app-brand-css.d.ts +1 -0
  168. package/dist/transports/mcp/mcp-app-brand-css.js +180 -0
  169. package/dist/transports/mcp/mcp-app-brand-css.js.map +1 -0
  170. package/dist/transports/mcp/mount.d.ts +14 -1
  171. package/dist/transports/mcp/mount.js +729 -172
  172. package/dist/transports/mcp/mount.js.map +1 -1
  173. package/dist/transports/mcp/native-browser-presence.d.ts +45 -0
  174. package/dist/transports/mcp/native-browser-presence.js +158 -0
  175. package/dist/transports/mcp/native-browser-presence.js.map +1 -0
  176. package/dist/transports/mcp/plan-approval.d.ts +44 -0
  177. package/dist/transports/mcp/plan-approval.js +179 -0
  178. package/dist/transports/mcp/plan-approval.js.map +1 -0
  179. package/dist/transports/mcp/session-directory.d.ts +7 -0
  180. package/dist/transports/mcp/session-directory.js +18 -0
  181. package/dist/transports/mcp/session-directory.js.map +1 -0
  182. package/dist/transports/mcp/tool-names.d.ts +2 -0
  183. package/dist/transports/mcp/tool-names.js +2 -0
  184. package/dist/transports/mcp/tool-names.js.map +1 -0
  185. package/package.json +16 -7
  186. package/skills/superblocks-build/SKILL.md +59 -0
  187. package/skills/superblocks-import/SKILL.md +125 -0
  188. package/dist/capabilities/import-prompt.d.ts +0 -11
  189. package/dist/capabilities/import-prompt.js +0 -96
  190. package/dist/capabilities/import-prompt.js.map +0 -1
  191. package/dist/capabilities/persisted-progress.d.ts +0 -46
  192. package/dist/capabilities/persisted-progress.js +0 -246
  193. package/dist/capabilities/persisted-progress.js.map +0 -1
  194. package/dist/events/cursor.d.ts +0 -43
  195. package/dist/events/cursor.js +0 -78
  196. package/dist/events/cursor.js.map +0 -1
  197. package/dist/events/memory-event-store.d.ts +0 -34
  198. package/dist/events/memory-event-store.js +0 -110
  199. package/dist/events/memory-event-store.js.map +0 -1
  200. package/dist/events/merge.d.ts +0 -23
  201. package/dist/events/merge.js +0 -97
  202. package/dist/events/merge.js.map +0 -1
  203. package/dist/events/normalized-collector.d.ts +0 -62
  204. package/dist/events/normalized-collector.js +0 -156
  205. package/dist/events/normalized-collector.js.map +0 -1
  206. package/dist/events/schema.d.ts +0 -9
  207. package/dist/events/schema.js +0 -93
  208. package/dist/events/schema.js.map +0 -1
  209. package/dist/events/snapshot.d.ts +0 -32
  210. package/dist/events/snapshot.js +0 -57
  211. package/dist/events/snapshot.js.map +0 -1
  212. package/dist/events/stream-key.d.ts +0 -2
  213. package/dist/events/stream-key.js +0 -31
  214. package/dist/events/stream-key.js.map +0 -1
  215. package/dist/events/types.d.ts +0 -179
  216. package/dist/events/types.js +0 -66
  217. package/dist/events/types.js.map +0 -1
  218. package/dist/resume/memory-progress-store.d.ts +0 -39
  219. package/dist/resume/memory-progress-store.js +0 -82
  220. package/dist/resume/memory-progress-store.js.map +0 -1
  221. package/dist/resume/memory-recent-app-store.d.ts +0 -14
  222. package/dist/resume/memory-recent-app-store.js +0 -27
  223. package/dist/resume/memory-recent-app-store.js.map +0 -1
  224. package/dist/resume/memory-turn-store.d.ts +0 -18
  225. package/dist/resume/memory-turn-store.js +0 -73
  226. package/dist/resume/memory-turn-store.js.map +0 -1
  227. package/dist/resume/progress-key.d.ts +0 -21
  228. package/dist/resume/progress-key.js +0 -58
  229. package/dist/resume/progress-key.js.map +0 -1
  230. package/dist/resume/stores.d.ts +0 -14
  231. package/dist/resume/stores.js +0 -18
  232. package/dist/resume/stores.js.map +0 -1
  233. package/dist/resume/types.d.ts +0 -124
  234. package/dist/resume/types.js +0 -13
  235. package/dist/resume/types.js.map +0 -1
@@ -1,7 +1,9 @@
1
+ import type { LLMProviderConfig } from "@superblocksteam/library-shared/types";
1
2
  import type { RecentToolRun } from "../capabilities/types.js";
2
3
  import { type OrchestratorClient } from "../orchestrator/client.js";
3
4
  import type { SuperblocksServerClient } from "../server/client.js";
4
- import type { HoldLiveEditInput, TurnState, ForwardPromptResult, PromptInput, RetryAction, SessionPeer, StartPromptResult, TurnDecision, TurnUpdate } from "./session-peer.js";
5
+ import { AppState } from "./app-state.js";
6
+ import { type ForwardPromptResult, type HoldLiveEditInput, type PromptInput, type RecoveryAction, type RetryAction, type SessionPeer, type StartPromptResult, type TurnDecision, type TurnState, type TurnUpdate } from "./session-peer.js";
5
7
  /**
6
8
  * Consecutive upgrade rejections from one host before asking where the live
7
9
  * edit went. More than one, so an ingress route that briefly answers for a pod
@@ -34,20 +36,37 @@ export declare const MAX_RERESOLVES_PER_OPEN = 3;
34
36
  */
35
37
  export declare const DEFAULT_RELEASE_AFTER_TURN_MS = 30000;
36
38
  export type WebSocketSessionPeerOptions = {
39
+ /** Shared with the capability layer; created here when omitted. */
40
+ appState?: AppState;
37
41
  /**
38
42
  * How long a lost liveness beat must stay lost before the turn on that socket
39
43
  * is given up on. See {@link DEFAULT_BEAT_LOST_GRACE_MS}.
40
44
  */
41
45
  beatLostGraceMs?: number;
46
+ captureCheckpointScreenshot?: (input: {
47
+ applicationId: string;
48
+ commitId: string;
49
+ sessionToken: string;
50
+ }) => Promise<string | undefined>;
51
+ /**
52
+ * Hard cap on the detached capture-and-upload task. Capture can spend 45s
53
+ * plus settle, then the upload RPC can spend the held-socket budget. Without
54
+ * this, a hung Playwright launch never drains pendingCheckpointScreenshots.
55
+ */
56
+ checkpointScreenshotTimeoutMs?: number;
42
57
  connectAttemptTimeoutMs?: number;
43
- coreModel?: string;
58
+ coreModel?: LLMProviderConfig["coreModel"];
44
59
  /**
45
60
  * How long a turn that died before Superblocks saw it stays worth reporting.
46
- * See {@link FailedStarts}; injectable so its bounds are testable without
47
- * waiting them out.
61
+ * See {@link AppState}; injectable so its bounds are testable without waiting
62
+ * them out.
48
63
  */
49
64
  failedStartTtlMs?: number;
50
- /** Distinct apps holding a dead start at once. See {@link FailedStarts}. */
65
+ /** Maximum age of acknowledged work before it is treated as abandoned. */
66
+ pendingStartTtlMs?: number;
67
+ /**
68
+ * Distinct apps holding a dead start at once. See {@link AppState}.
69
+ */
51
70
  maxFailedStarts?: number;
52
71
  /** Consecutive genuine misses before the beat is declared lost. */
53
72
  heartbeatMaxMisses?: number;
@@ -77,7 +96,7 @@ export type WebSocketSessionPeerOptions = {
77
96
  * executing APIs. Defaults to `default`.
78
97
  */
79
98
  profileKey?: string;
80
- provider?: string;
99
+ provider?: LLMProviderConfig["provider"];
81
100
  pushWaitMs?: number;
82
101
  readyWaitMs?: number;
83
102
  /** Grace period between a turn settling and the gateway socket being dropped. */
@@ -99,7 +118,6 @@ export type WebSocketSessionPeerOptions = {
99
118
  */
100
119
  testingEnabled?: boolean;
101
120
  timeoutMs?: number;
102
- turnTimeoutMs?: number;
103
121
  /** Origin the sandbox app shell should report as its parent window. */
104
122
  uiBaseUrl?: string;
105
123
  };
@@ -112,6 +130,7 @@ export declare function buildSessionUrl(input: {
112
130
  export declare class WebSocketSessionPeer implements SessionPeer {
113
131
  private readonly options;
114
132
  private readonly held;
133
+ private readonly promptStarts;
115
134
  /**
116
135
  * Every server -> editor method the dev server has called on this peer.
117
136
  * Diagnostic only: it answers "did that push ever arrive" without guessing
@@ -129,36 +148,36 @@ export declare class WebSocketSessionPeer implements SessionPeer {
129
148
  * prompt for the same app replaces it.
130
149
  */
131
150
  private readonly turns;
132
- /**
133
- * Last plan Clark proposed per application, so approve/refine can re-send
134
- * planContext without the MCP client echoing the full markdown.
135
- */
136
- private readonly pendingPlans;
137
- /**
138
- * Last needs_decision payload (plan or multi_choice) per application, so
139
- * approve/refine via edit_app can reuse the pending plan after
140
- * check_app_progress drained the finished turn.
141
- */
142
- private readonly pendingDecisions;
143
- /**
144
- * Applications that have dispatched at least one BUILD turn. Survives
145
- * clearing the pending plan, which happens as soon as an approved build
146
- * starts — the point of the latch is the turns that come after it.
147
- */
148
- private readonly buildModeApplications;
149
- /**
150
- * Turns that died before Superblocks ever saw them, so no {@link ActiveTurn}
151
- * was ever created to hold the outcome. Read by
152
- * {@link WebSocketSessionPeer.turnState} and
153
- * {@link WebSocketSessionPeer.awaitTurn} after the live map, and cleared when
154
- * a prompt for the app is accepted.
155
- */
156
- private readonly failedStarts;
151
+ /** Browser-owned turns observed over an authenticated held session. */
152
+ private readonly observedTurns;
153
+ private readonly editorStructureByScope;
154
+ /** Facts about an application that outlive any one turn. */
155
+ private readonly appState;
157
156
  constructor(options?: WebSocketSessionPeerOptions);
157
+ /** The per-application facts this peer writes, for the capability layer. */
158
+ state(): AppState;
159
+ recordPendingStart(input: {
160
+ applicationId: string;
161
+ branch?: string;
162
+ idempotencyKey?: string;
163
+ organizationId: string;
164
+ retryAction?: RetryAction;
165
+ userId: string;
166
+ }): number;
167
+ clearPendingStart(input: {
168
+ applicationId: string;
169
+ branch?: string;
170
+ idempotencyKey?: string;
171
+ organizationId: string;
172
+ pendingStartToken?: number;
173
+ userId: string;
174
+ }): void;
175
+ private waitForPendingTurn;
158
176
  /**
159
177
  * Plan waiting on human approve/refine for this application, if any.
160
178
  */
161
- pendingPlan(applicationId: string): {
179
+ pendingPlan(applicationId: string, requestedBranch?: string): {
180
+ branch?: string;
162
181
  messageId?: string;
163
182
  plan: string;
164
183
  title?: string;
@@ -166,7 +185,8 @@ export declare class WebSocketSessionPeer implements SessionPeer {
166
185
  /**
167
186
  * Full needs_decision payload waiting on a human for this application.
168
187
  */
169
- pendingDecision(applicationId: string): {
188
+ pendingDecision(applicationId: string, requestedBranch?: string): {
189
+ branch?: string;
170
190
  decision: TurnDecision;
171
191
  recentRuns?: RecentToolRun[];
172
192
  reply: string;
@@ -177,42 +197,41 @@ export declare class WebSocketSessionPeer implements SessionPeer {
177
197
  */
178
198
  recordFailedStart(input: {
179
199
  applicationId: string;
200
+ branch?: string;
201
+ decision?: TurnDecision;
202
+ generationStatus?: "detached" | "live_edit_terminated" | "needs_decision";
203
+ idempotencyKey?: string;
180
204
  organizationId: string;
205
+ pendingStartRequired?: boolean;
206
+ pendingStartToken?: number;
181
207
  reason: string;
208
+ recoveryAction?: RecoveryAction;
209
+ revision?: number;
182
210
  retryAction?: RetryAction;
211
+ retryable?: false;
183
212
  userId: string;
184
213
  }): void;
185
214
  /**
186
215
  * Where this application's turn stands for this caller, read without draining
187
216
  * the activity an {@link WebSocketSessionPeer.awaitTurn} poll is owed.
188
217
  *
189
- * Order matters, and it is recency. A turn still *running* is live work and
190
- * outranks everything - a second prompt failing to open its own session does
191
- * not end it. Failing that, this caller's own dead start outranks a turn that
192
- * already finished: `turns` keeps finished turns, so without this a follow-up
193
- * whose connect failed would be answered by the previous turn's outcome and
194
- * its reply, reporting an edit as landed that never ran. And it is read rather
195
- * than superseded by deleting from `turns`, because that map is keyed by
196
- * application while a dead start belongs to one caller - deleting would erase
197
- * a colleague's outcome to answer this caller's question.
198
- *
199
- * Reading recency out of the order rather than out of a clock holds because
200
- * of the two rules either side of this one: accepting a prompt clears every
201
- * caller's record for the app, and no record is made while a turn is running.
202
- * Together they leave every stored record newer than any finished turn it can
203
- * be read beside, so "the record wins" is not a guess about which came first.
218
+ * A running turn is current. Once it finishes, the newer of that turn and an
219
+ * unscoped failed start wins; explicit branch reads filter before comparing.
220
+ * Revisions preserve that ordering even when both events share a clock tick.
204
221
  */
205
222
  turnState(input: {
206
223
  applicationId: string;
224
+ branch?: string;
207
225
  organizationId: string;
208
226
  userId: string;
209
227
  }): TurnState | undefined;
210
228
  clearPendingPlan(applicationId: string): void;
211
229
  clearPendingDecision(applicationId: string): void;
212
- markBuildMode(applicationId: string): void;
213
- buildMode(applicationId: string): boolean;
214
230
  isHeld(applicationId: string): boolean;
215
- libraryBrowserContext(applicationId: string): import("@superblocksteam/library-shared/types").BrowserContext | undefined;
231
+ heldContext(applicationId: string): {
232
+ branch?: string;
233
+ } | undefined;
234
+ libraryBrowserContext(applicationId: string, requestedBranch?: string): import("@superblocksteam/library-shared/types").BrowserContext | undefined;
216
235
  holdLiveEdit(input: HoldLiveEditInput): Promise<void>;
217
236
  release(applicationId: string): void;
218
237
  closeAll(): void;
@@ -224,17 +243,27 @@ export declare class WebSocketSessionPeer implements SessionPeer {
224
243
  * {@link startPrompt} so there is one turn lifecycle, not two.
225
244
  */
226
245
  forwardPrompt(input: PromptInput): Promise<ForwardPromptResult>;
246
+ private claimPromptLane;
227
247
  startPrompt(input: PromptInput): Promise<StartPromptResult>;
228
248
  /**
229
249
  * Sends the prompt on a session already holding a subscribed turn, and hands
230
250
  * the turn to {@link runTurn} once the session confirms it took it on.
231
251
  */
232
252
  private sendPrompt;
253
+ private latestTurn;
254
+ private observeEditorEvent;
255
+ private forgetObservedTurn;
256
+ private finishObservedTurn;
257
+ private settleObservedTurn;
258
+ private armObservedTurnRelease;
259
+ private armObservedPostTurnRelease;
233
260
  awaitTurn(input: {
234
261
  applicationId: string;
262
+ branch?: string;
235
263
  organizationId?: string;
236
264
  signal?: AbortSignal;
237
265
  userId?: string;
266
+ floorMs?: number;
238
267
  waitMs: number;
239
268
  }): Promise<TurnUpdate>;
240
269
  /**
@@ -245,15 +274,6 @@ export declare class WebSocketSessionPeer implements SessionPeer {
245
274
  */
246
275
  private runTurn;
247
276
  private pushWaitMs;
248
- /**
249
- * Attaches a turn to the events SABS relays for its live edit, returning the
250
- * idempotent detach the turn calls when it ends.
251
- *
252
- * A turn with no live edit id, or a deployment with no push channel, gets a
253
- * detach that does nothing: the socket remains its only source, which is the
254
- * behavior from before the channel existed.
255
- */
256
- private subscribeToPushes;
257
277
  /**
258
278
  * Checks that the session took this prompt on as a turn belonging to this
259
279
  * peer, and gives up on it now if it did not.
@@ -261,8 +281,8 @@ export declare class WebSocketSessionPeer implements SessionPeer {
261
281
  * A dev server that predates the gateway role accepts the socket, echoes the
262
282
  * role it was offered, and then treats the connection as a library socket: the
263
283
  * prompt is acknowledged and Clark's pushes go to the browser binding
264
- * instead. The turn would spend its whole budget looking detached, and a
265
- * rollout with one stale sandbox in it would look like Clark hanging. Only a
284
+ * instead. The turn would stay detached, and a rollout with one stale
285
+ * sandbox in it would look like Clark hanging. Only a
266
286
  * server that bound the turn can name it back, so the missing handle is the
267
287
  * mismatch, reported where it is still cheap to act on.
268
288
  */
@@ -341,6 +361,10 @@ export declare class WebSocketSessionPeer implements SessionPeer {
341
361
  */
342
362
  private proveIdentity;
343
363
  private reconnect;
364
+ private setHeld;
365
+ private recordEditorStructure;
366
+ private publishEditorStructure;
367
+ private currentViewStatus;
344
368
  /** Lines this caller has not been handed yet. */
345
369
  private drain;
346
370
  private wake;
@@ -348,7 +372,7 @@ export declare class WebSocketSessionPeer implements SessionPeer {
348
372
  private note;
349
373
  /**
350
374
  * Records the outcome of a turn from outside runTurn, and ends the collector
351
- * waits so runTurn cannot overwrite it with a later timeout of its own. The
375
+ * waits so runTurn cannot overwrite it with a later terminal status. The
352
376
  * first outcome written wins: it is the one callers have already been shown.
353
377
  */
354
378
  private settleTurn;
@@ -360,6 +384,7 @@ export declare class WebSocketSessionPeer implements SessionPeer {
360
384
  private checkpoint;
361
385
  private ensureHeld;
362
386
  private connect;
387
+ private assertReadOnlyHoldCurrent;
363
388
  /**
364
389
  * The liveness beat for one held socket.
365
390
  *
@@ -369,13 +394,16 @@ export declare class WebSocketSessionPeer implements SessionPeer {
369
394
  * who to tell.
370
395
  */
371
396
  private buildHeartbeat;
397
+ private livenessTurnSnapshot;
398
+ private sameLivenessTurnSnapshot;
399
+ private confirmBeatLostSession;
372
400
  private armIdle;
373
401
  /**
374
402
  * Ends a turn whose live edit is gone.
375
403
  *
376
404
  * The dev server exits on its own when its lock is lost, and it says nothing
377
- * on the way out. A turn left waiting on that socket burns its entire budget
378
- * — ten minutes — before the caller is told anything.
405
+ * on the way out. A turn left waiting on that socket would otherwise never
406
+ * report an outcome to the caller.
379
407
  *
380
408
  * Reached only once the live edit being gone is established, which a close on
381
409
  * its own never does: either it named its own end in the application range,
@@ -414,17 +442,20 @@ export declare class WebSocketSessionPeer implements SessionPeer {
414
442
  /**
415
443
  * Ends a turn whose socket has stopped answering.
416
444
  *
417
- * Two gates, because they answer different questions. `SocketHeartbeat`
445
+ * Three gates answer different questions. `SocketHeartbeat`
418
446
  * declares the beat lost after consecutive genuine misses, having already
419
447
  * excused a run of unanswered beats and every silence that inbound traffic
420
448
  * explained - the right threshold for a diagnostic, and too eager for this: a
421
449
  * sandbox that misses two beats and answers the next was recovering, and its
422
450
  * turn has to survive that. So the loss also has to outlast
423
451
  * {@link DEFAULT_BEAT_LOST_GRACE_MS}, and any beat that succeeds clears it.
452
+ * Finally, the exact live edit must either be terminal in the control plane,
453
+ * or its direct HTTP health check must fail again after another grace
454
+ * window. One timeout, 5xx, or inconclusive control-plane result is still
455
+ * recoverable.
424
456
  *
425
457
  * What is left is a request channel that has been silent for minutes on a
426
- * socket that never closed, with a turn waiting on it - which without this
427
- * waits out the whole turn budget.
458
+ * socket that never closed, with a turn waiting on it indefinitely.
428
459
  *
429
460
  * This is the only trigger that reaches a half-open socket. An unsolicited
430
461
  * close is the ordinary one and never arrives for a connection that stays up
@@ -477,13 +508,17 @@ export declare class WebSocketSessionPeer implements SessionPeer {
477
508
  * session.
478
509
  */
479
510
  private supersedeTurn;
511
+ private cancelTurn;
512
+ private discardUnstartedTurn;
480
513
  private armPostTurnRelease;
514
+ private releasePostTurnIfReady;
481
515
  private armKeepalive;
482
516
  /**
483
517
  * Clears the turn timers only. The beat is stopped separately on purpose: it
484
518
  * belongs to the socket and outlives these, which the post-turn grace period
485
519
  * resets.
486
520
  */
521
+ private clearIdleTimer;
487
522
  private clearTimers;
488
523
  private drop;
489
524
  private editorContextFor;