@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
@@ -0,0 +1,332 @@
1
+ /**
2
+ * How long a dead start stays the answer for an application.
3
+ *
4
+ * Long enough to outlive the poll that follows a failed prompt, short enough
5
+ * that an app abandoned after a failure is not still reporting it later.
6
+ */
7
+ export const DEFAULT_FAILED_START_TTL_MS = 30 * 60 * 1000;
8
+ /**
9
+ * Cap on remembered dead starts, because nothing else evicts: an app whose
10
+ * start failed and that is never retried would otherwise hold its entry for
11
+ * the life of the process.
12
+ */
13
+ export const MAX_FAILED_STARTS = 256;
14
+ const DEFAULT_BRANCH_KEY = "default";
15
+ /**
16
+ * How long an acknowledged start may go without its live owner renewing it.
17
+ * Long enough for a cold sandbox boot, short enough that a background start
18
+ * killed without recording anything stops pinning the app at "building".
19
+ */
20
+ export const DEFAULT_PENDING_START_TTL_MS = 5 * 60 * 1000;
21
+ /**
22
+ * What Gateway remembers about an application between turns.
23
+ *
24
+ * None of this is transport state, and none of it can be pushed onto the
25
+ * caller. Each entry compensates for something the protocol does not carry:
26
+ *
27
+ * - The plan, because approving one means re-sending it as `planContext`, and
28
+ * a caller asked to echo markdown back paraphrases it - which silently
29
+ * changes what gets built.
30
+ * - The dead start, because the call that failed has already returned. It is
31
+ * the *next* call - a poll, or `get_app` - that would otherwise report
32
+ * `unknown` and preview the untouched starter template as a finished app.
33
+ *
34
+ * It lives here rather than on the session peer so a socket owns a socket. It
35
+ * is a concrete class with no optional members: a collaborator that is always
36
+ * present cannot be confused at a call site with a fact that is absent.
37
+ */
38
+ export class AppState {
39
+ acceptedStarts = new Map();
40
+ plans = new Map();
41
+ decisions = new Map();
42
+ publishes = new Map();
43
+ failedStarts = new Map();
44
+ pendingStarts = new Map();
45
+ failedStartTtlMs;
46
+ maxFailedStarts;
47
+ now;
48
+ pendingStartTtlMs;
49
+ revision = 0;
50
+ constructor(options = {}) {
51
+ this.failedStartTtlMs =
52
+ options.failedStartTtlMs ?? DEFAULT_FAILED_START_TTL_MS;
53
+ this.maxFailedStarts = options.maxFailedStarts ?? MAX_FAILED_STARTS;
54
+ this.now = options.now ?? (() => Date.now());
55
+ this.pendingStartTtlMs =
56
+ options.pendingStartTtlMs ?? DEFAULT_PENDING_START_TTL_MS;
57
+ }
58
+ pendingPlan(applicationId, requestedBranch) {
59
+ const plan = this.plans.get(applicationId);
60
+ return requestedBranch === undefined || plan?.branch === requestedBranch
61
+ ? plan
62
+ : undefined;
63
+ }
64
+ setPendingPlan(applicationId, plan) {
65
+ this.plans.set(applicationId, plan);
66
+ }
67
+ pendingDecision(applicationId, requestedBranch) {
68
+ const decision = this.decisions.get(applicationId);
69
+ return requestedBranch === undefined || decision?.branch === requestedBranch
70
+ ? decision
71
+ : undefined;
72
+ }
73
+ setPendingDecision(applicationId, decision) {
74
+ this.decisions.set(applicationId, decision);
75
+ }
76
+ /**
77
+ * The commit whose deploy `publish_app` handed back still running, so
78
+ * `check_publish_progress` can follow it without the caller carrying the id.
79
+ */
80
+ publishInFlight(applicationId) {
81
+ return this.publishes.get(applicationId)?.commitId;
82
+ }
83
+ publishStartedAtMs(applicationId, commitId) {
84
+ const publish = this.publishes.get(applicationId);
85
+ return publish?.commitId === commitId ? publish.startedAtMs : undefined;
86
+ }
87
+ setPublishInFlight(applicationId, commitId, startedAtMs = this.now()) {
88
+ const claim = ++this.revision;
89
+ this.publishes.set(applicationId, {
90
+ claim,
91
+ commitId,
92
+ missingSinceMs: undefined,
93
+ startedAtMs,
94
+ });
95
+ return claim;
96
+ }
97
+ claimPublishInFlight(applicationId, commitId, startedAtMs = this.now()) {
98
+ const current = this.publishes.get(applicationId);
99
+ const claim = ++this.revision;
100
+ this.publishes.set(applicationId, {
101
+ claim,
102
+ commitId,
103
+ missingSinceMs: current?.commitId === commitId ? current.missingSinceMs : undefined,
104
+ startedAtMs: current?.commitId === commitId ? current.startedAtMs : startedAtMs,
105
+ });
106
+ return claim;
107
+ }
108
+ noteMissingPublishStatus(applicationId, claim, atMs) {
109
+ const publish = this.publishes.get(applicationId);
110
+ if (publish?.claim !== claim) {
111
+ return undefined;
112
+ }
113
+ publish.missingSinceMs ??= atMs;
114
+ return Math.max(0, atMs - publish.missingSinceMs);
115
+ }
116
+ noteVisiblePublishStatus(applicationId, claim) {
117
+ const publish = this.publishes.get(applicationId);
118
+ if (publish?.claim === claim) {
119
+ publish.missingSinceMs = undefined;
120
+ }
121
+ }
122
+ clearPublishInFlight(applicationId, claim) {
123
+ if (this.publishes.get(applicationId)?.claim === claim) {
124
+ this.publishes.delete(applicationId);
125
+ }
126
+ }
127
+ /**
128
+ * Drop the plan alone, for a turn that ended on a decision that is not one.
129
+ * The decision it ended on is written separately and must survive this.
130
+ */
131
+ clearPendingPlan(applicationId) {
132
+ this.plans.delete(applicationId);
133
+ }
134
+ /** Both go together: a plan is one kind of decision Clark waits on. */
135
+ clearPending(applicationId) {
136
+ this.plans.delete(applicationId);
137
+ this.decisions.delete(applicationId);
138
+ }
139
+ markTurnStarted() {
140
+ return ++this.revision;
141
+ }
142
+ failedStart(scope, newerThanRevision) {
143
+ const keys = scope.branch === undefined
144
+ ? [...this.failedStarts.keys()].reverse()
145
+ : [failedStartKey(scope)];
146
+ const prefix = failedStartPrefix(scope);
147
+ let latest;
148
+ let latestRevision = Number.NEGATIVE_INFINITY;
149
+ for (const key of keys) {
150
+ if (!key.startsWith(prefix)) {
151
+ continue;
152
+ }
153
+ const entry = this.failedStarts.get(key);
154
+ if (!entry) {
155
+ continue;
156
+ }
157
+ if (this.now() - entry.atMs >= this.failedStartTtlMs) {
158
+ this.failedStarts.delete(key);
159
+ continue;
160
+ }
161
+ if (newerThanRevision !== undefined &&
162
+ entry.revision <= newerThanRevision) {
163
+ continue;
164
+ }
165
+ if (entry.revision > latestRevision) {
166
+ latest = entry.turn;
167
+ latestRevision = entry.revision;
168
+ }
169
+ }
170
+ return latest;
171
+ }
172
+ recordFailedStart(scope, turn, revision = this.markTurnStarted()) {
173
+ const key = failedStartKey(scope);
174
+ const acceptedRevision = this.acceptedStarts.get(acceptedStartKey(scope.applicationId, scope.branch));
175
+ if (acceptedRevision !== undefined && revision <= acceptedRevision) {
176
+ return;
177
+ }
178
+ const current = this.failedStarts.get(key);
179
+ if (current && current.revision > revision) {
180
+ return;
181
+ }
182
+ // Re-inserted rather than updated in place, so this key becomes the newest
183
+ // and the eviction below stays in insertion order.
184
+ this.failedStarts.delete(key);
185
+ this.failedStarts.set(key, {
186
+ atMs: this.now(),
187
+ revision,
188
+ turn: {
189
+ ...(scope.branch === undefined ? {} : { branch: scope.branch }),
190
+ ...turn,
191
+ },
192
+ });
193
+ for (const oldest of this.failedStarts.keys()) {
194
+ if (this.failedStarts.size <= this.maxFailedStarts) {
195
+ break;
196
+ }
197
+ this.failedStarts.delete(oldest);
198
+ }
199
+ }
200
+ claimReplacementEntitlement(scope, replyWhileClaimed) {
201
+ const turn = this.failedStart(scope);
202
+ if (turn?.recoveryAction !== "start_new_app") {
203
+ return undefined;
204
+ }
205
+ const replyBeforeConsumption = turn.reply;
206
+ delete turn.recoveryAction;
207
+ turn.reply = replyWhileClaimed;
208
+ return () => {
209
+ turn.recoveryAction = "start_new_app";
210
+ turn.reply = replyBeforeConsumption;
211
+ };
212
+ }
213
+ /** Forget every caller's dead start for the accepted application branch. */
214
+ clearFailedStarts(applicationId, branch, throughRevision = Number.POSITIVE_INFINITY) {
215
+ const acceptedKey = acceptedStartKey(applicationId, branch);
216
+ const acceptedRevision = this.acceptedStarts.get(acceptedKey);
217
+ if (acceptedRevision === undefined || throughRevision > acceptedRevision) {
218
+ this.acceptedStarts.delete(acceptedKey);
219
+ this.acceptedStarts.set(acceptedKey, throughRevision);
220
+ }
221
+ const suffix = `\u0000${failedStartBranchKey(branch)}`;
222
+ for (const key of [...this.failedStarts.keys()]) {
223
+ const entry = this.failedStarts.get(key);
224
+ if (entry &&
225
+ entry.revision <= throughRevision &&
226
+ key.startsWith(`${applicationId}\u0000`) &&
227
+ key.endsWith(suffix)) {
228
+ this.failedStarts.delete(key);
229
+ }
230
+ }
231
+ }
232
+ pendingStart(scope, idempotencyKey, token) {
233
+ const keys = scope.branch === undefined
234
+ ? [...this.pendingStarts.keys()].reverse()
235
+ : [failedStartKey(scope)];
236
+ const prefix = failedStartPrefix(scope);
237
+ for (const key of keys) {
238
+ if (!key.startsWith(prefix)) {
239
+ continue;
240
+ }
241
+ const entry = this.pendingStarts.get(key);
242
+ if (!entry) {
243
+ continue;
244
+ }
245
+ if (this.now() - entry.atMs >= this.pendingStartTtlMs) {
246
+ this.pendingStarts.delete(key);
247
+ continue;
248
+ }
249
+ if ((idempotencyKey !== undefined &&
250
+ entry.idempotencyKey !== idempotencyKey) ||
251
+ (token !== undefined && entry.revision !== token)) {
252
+ continue;
253
+ }
254
+ return {
255
+ ...(entry.idempotencyKey === undefined
256
+ ? {}
257
+ : { idempotencyKey: entry.idempotencyKey }),
258
+ ...(entry.retryAction ? { retryAction: entry.retryAction } : {}),
259
+ token: entry.revision,
260
+ };
261
+ }
262
+ return undefined;
263
+ }
264
+ recordPendingStart(scope, value = {}) {
265
+ const now = this.now();
266
+ for (const [pendingKey, pending] of this.pendingStarts) {
267
+ if (now - pending.atMs >= this.pendingStartTtlMs) {
268
+ this.pendingStarts.delete(pendingKey);
269
+ }
270
+ }
271
+ const key = failedStartKey(scope);
272
+ this.pendingStarts.delete(key);
273
+ const revision = ++this.revision;
274
+ this.pendingStarts.set(key, {
275
+ atMs: now,
276
+ revision,
277
+ ...value,
278
+ });
279
+ return revision;
280
+ }
281
+ keepPendingStartAlive(scope, token) {
282
+ const key = failedStartKey(scope);
283
+ const timer = setInterval(() => {
284
+ const pending = this.pendingStarts.get(key);
285
+ if (pending?.revision !== token) {
286
+ clearInterval(timer);
287
+ return;
288
+ }
289
+ pending.atMs = this.now();
290
+ }, Math.max(1, Math.floor(this.pendingStartTtlMs / 2)));
291
+ timer.unref();
292
+ return () => clearInterval(timer);
293
+ }
294
+ clearPendingStart(scope, idempotencyKey, throughRevision = Number.POSITIVE_INFINITY, token) {
295
+ const key = failedStartKey(scope);
296
+ const pending = this.pendingStarts.get(key);
297
+ if (pending &&
298
+ pending.revision <= throughRevision &&
299
+ (token === undefined || pending.revision === token) &&
300
+ (idempotencyKey === undefined ||
301
+ pending.idempotencyKey === idempotencyKey)) {
302
+ return this.pendingStarts.delete(key);
303
+ }
304
+ return false;
305
+ }
306
+ clearPendingStartsThrough(applicationId, revision) {
307
+ for (const [key, pending] of this.pendingStarts) {
308
+ if (pending.revision <= revision &&
309
+ key.startsWith(`${applicationId}\u0000`)) {
310
+ this.pendingStarts.delete(key);
311
+ }
312
+ }
313
+ }
314
+ }
315
+ /**
316
+ * Separated by NUL because no id can contain one. Any printable separator is a
317
+ * character an id could carry, and an id that carried it would key two
318
+ * different callers to the same entry.
319
+ */
320
+ function failedStartKey(scope) {
321
+ return `${failedStartPrefix(scope)}${failedStartBranchKey(scope.branch)}`;
322
+ }
323
+ function acceptedStartKey(applicationId, branch) {
324
+ return `${applicationId}\u0000${failedStartBranchKey(branch)}`;
325
+ }
326
+ function failedStartPrefix(scope) {
327
+ return `${scope.applicationId}\u0000${scope.organizationId}\u0000${scope.userId}\u0000`;
328
+ }
329
+ function failedStartBranchKey(branch) {
330
+ return branch === undefined ? DEFAULT_BRANCH_KEY : `branch:${branch}`;
331
+ }
332
+ //# sourceMappingURL=app-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-state.js","sourceRoot":"","sources":["../../src/sabs/app-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { TurnDecision } from "./session-peer.js";
2
+ /**
3
+ * What Clark is waiting on a human for, assembled from the pushes that carry
4
+ * it.
5
+ *
6
+ * Neither shape arrives whole. A plan opens with one message and streams in
7
+ * deltas, and the caller only has something to approve once the pieces are
8
+ * joined; a question arrives with its options in one of two different push
9
+ * types. Keeping that assembly here is what lets the turn ask a single
10
+ * question - "is Clark waiting on anyone?" - instead of tracking four fields
11
+ * to work it out.
12
+ */
13
+ export declare class AwaitedDecision {
14
+ private readonly integrationRequestFingerprints;
15
+ private readonly integrations;
16
+ private planChunks;
17
+ private planMessageId;
18
+ private planTitle;
19
+ private choice;
20
+ /** A `plan` push: the start of a plan, replacing any plan before it. */
21
+ openPlan(input: {
22
+ messageId?: string;
23
+ title?: string;
24
+ }): void;
25
+ /** A `plan` or `plan-delta` push carrying more of the plan's text. */
26
+ appendPlan(content: string): void;
27
+ /** A `multi_choice` or `searchable_dropdown` push. */
28
+ askChoice(input: {
29
+ messageId?: string;
30
+ options: string[];
31
+ question: string;
32
+ }): void;
33
+ /** A headless integration setup request for the MCP host to fulfill. */
34
+ requireIntegration(input: {
35
+ configuration: Record<string, unknown>;
36
+ name?: string;
37
+ pluginId: string;
38
+ requestFingerprint: string;
39
+ }): void;
40
+ /** True once a plan has streamed any text, whether or not it has finished. */
41
+ hasPlan(): boolean;
42
+ /**
43
+ * The decision to report, preferring a plan over a question when both
44
+ * arrived in the same turn: a plan is what approve/refine acts on, and a
45
+ * question Clark asked on the way to it is not the turn's outcome.
46
+ */
47
+ decision(): TurnDecision | undefined;
48
+ private plan;
49
+ }
@@ -0,0 +1,129 @@
1
+ import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
+ import { getPluginConfigurationSchema } from "@superblocksteam/mcp-server";
3
+ /** Matches library-shared AI_PLAN_STREAMING_END_MARKER. */
4
+ const PLAN_STREAMING_END_MARKER = "[__SUPERBLOCKS_PLAN_DONE__]";
5
+ /**
6
+ * The plugin's configuration form, from the schema bundled in the MCP server.
7
+ *
8
+ * Carrying it with the request is what keeps the host from having to ask for
9
+ * it: a separate schema tool call is a second approval prompt for a lookup
10
+ * that touches nothing. Superblocks can name a plugin the bundle has no
11
+ * schema for, and a missing form is no reason to drop the whole request.
12
+ */
13
+ function pluginConfigurationForm(pluginId) {
14
+ try {
15
+ return getPluginConfigurationSchema(pluginId);
16
+ }
17
+ catch (error) {
18
+ if (error instanceof McpError) {
19
+ return undefined;
20
+ }
21
+ throw error;
22
+ }
23
+ }
24
+ /**
25
+ * What Clark is waiting on a human for, assembled from the pushes that carry
26
+ * it.
27
+ *
28
+ * Neither shape arrives whole. A plan opens with one message and streams in
29
+ * deltas, and the caller only has something to approve once the pieces are
30
+ * joined; a question arrives with its options in one of two different push
31
+ * types. Keeping that assembly here is what lets the turn ask a single
32
+ * question - "is Clark waiting on anyone?" - instead of tracking four fields
33
+ * to work it out.
34
+ */
35
+ export class AwaitedDecision {
36
+ integrationRequestFingerprints = new Set();
37
+ integrations = [];
38
+ planChunks = [];
39
+ planMessageId;
40
+ planTitle;
41
+ choice;
42
+ /** A `plan` push: the start of a plan, replacing any plan before it. */
43
+ openPlan(input) {
44
+ this.planChunks = [];
45
+ if (input.messageId) {
46
+ this.planMessageId = input.messageId;
47
+ }
48
+ if (input.title?.trim()) {
49
+ this.planTitle = input.title.trim();
50
+ }
51
+ }
52
+ /** A `plan` or `plan-delta` push carrying more of the plan's text. */
53
+ appendPlan(content) {
54
+ if (content) {
55
+ this.planChunks.push(content);
56
+ }
57
+ }
58
+ /** A `multi_choice` or `searchable_dropdown` push. */
59
+ askChoice(input) {
60
+ this.choice = {
61
+ ...(input.messageId ? { messageId: input.messageId } : {}),
62
+ options: input.options,
63
+ question: input.question,
64
+ };
65
+ }
66
+ /** A headless integration setup request for the MCP host to fulfill. */
67
+ requireIntegration(input) {
68
+ const pluginId = input.pluginId === "restapi" ? "restapiintegration" : input.pluginId;
69
+ const { baseUrl, ...restConfiguration } = input.configuration;
70
+ const configuration = input.pluginId === "restapi"
71
+ ? {
72
+ ...restConfiguration,
73
+ ...(baseUrl !== undefined && restConfiguration.urlBase === undefined
74
+ ? { urlBase: baseUrl }
75
+ : {}),
76
+ }
77
+ : input.configuration;
78
+ if (this.integrationRequestFingerprints.has(input.requestFingerprint)) {
79
+ return;
80
+ }
81
+ const configurationSchema = pluginConfigurationForm(pluginId);
82
+ this.integrationRequestFingerprints.add(input.requestFingerprint);
83
+ this.integrations.push({
84
+ configuration,
85
+ ...(input.name !== undefined ? { name: input.name } : {}),
86
+ pluginId,
87
+ ...(configurationSchema ? { configurationSchema } : {}),
88
+ });
89
+ }
90
+ /** True once a plan has streamed any text, whether or not it has finished. */
91
+ hasPlan() {
92
+ return this.plan() !== undefined;
93
+ }
94
+ /**
95
+ * The decision to report, preferring a plan over a question when both
96
+ * arrived in the same turn: a plan is what approve/refine acts on, and a
97
+ * question Clark asked on the way to it is not the turn's outcome.
98
+ */
99
+ decision() {
100
+ if (this.integrations.length > 0) {
101
+ return {
102
+ integrations: [...this.integrations],
103
+ kind: "missing_integrations",
104
+ };
105
+ }
106
+ const plan = this.plan();
107
+ if (plan) {
108
+ return {
109
+ kind: "plan",
110
+ ...(this.planMessageId ? { messageId: this.planMessageId } : {}),
111
+ plan,
112
+ ...(this.planTitle ? { title: this.planTitle } : {}),
113
+ };
114
+ }
115
+ return this.choice ? { kind: "multi_choice", ...this.choice } : undefined;
116
+ }
117
+ plan() {
118
+ if (this.planChunks.length === 0) {
119
+ return undefined;
120
+ }
121
+ const plan = this.planChunks
122
+ .join("")
123
+ .split(PLAN_STREAMING_END_MARKER)
124
+ .join("")
125
+ .trimEnd();
126
+ return plan || undefined;
127
+ }
128
+ }
129
+ //# sourceMappingURL=awaited-decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"awaited-decision.js","sourceRoot":"","sources":["../../src/sabs/awaited-decision.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { PromptContextIntegration, SdkApiExecutionResult } from "@superblocksteam/library-shared/types";
1
+ import type { EditorHasDefaultStructure, PromptContextIntegration, SdkApiExecutionResult } from "@superblocksteam/library-shared/types";
2
2
  import { type MethodHandlers, type RequestContextBase } from "@superblocksteam/shared";
3
3
  import type { OrchestratorClient } from "../orchestrator/client.js";
4
4
  import type { SuperblocksServerClient } from "../server/client.js";
@@ -6,7 +6,7 @@ export type IntegrationExecuteResult = {
6
6
  error?: string;
7
7
  response?: string;
8
8
  };
9
- type IntegrationExecutePayload = {
9
+ export type IntegrationExecutePayload = {
10
10
  integrationHint?: {
11
11
  displayName?: string;
12
12
  name: string;
@@ -26,6 +26,7 @@ export type ClarkMessage = {
26
26
  subText?: string;
27
27
  }>;
28
28
  content?: string;
29
+ gatewayObserverSource?: "browser";
29
30
  header?: string;
30
31
  id?: string;
31
32
  name?: string;
@@ -50,14 +51,29 @@ export type ClarkMessage = {
50
51
  export type ClarkPeerEvent = {
51
52
  kind: "message";
52
53
  message: ClarkMessage;
54
+ } | {
55
+ configuration: Record<string, unknown>;
56
+ kind: "missing_integration";
57
+ name?: string;
58
+ pluginId: string;
59
+ requestFingerprint: string;
53
60
  } | {
54
61
  kind: "change_info";
55
62
  label: string;
56
63
  } | {
57
64
  kind: "draft_state";
58
65
  hasDraft: boolean;
66
+ } | {
67
+ hasDefaultStructure: EditorHasDefaultStructure;
68
+ kind: "editor_structure";
59
69
  } | {
60
70
  kind: "generation_state";
71
+ /**
72
+ * The generation this state is about. Absent from dev servers that
73
+ * predate the field, which is why a turn cannot require it.
74
+ */
75
+ generationId?: string;
76
+ gatewayObserverSource?: "browser";
61
77
  hasError?: boolean;
62
78
  hasSuggestions?: boolean;
63
79
  state: string;
@@ -86,6 +102,9 @@ export type EditorSessionContext = {
86
102
  sessionToken: string;
87
103
  waitUntilFilesSynced: () => Promise<boolean>;
88
104
  };
105
+ export type IntegrationExecutionContext = Pick<EditorSessionContext, "apiKey" | "orchestrator" | "organizationId" | "profileKey" | "server" | "sessionToken"> & {
106
+ applicationId?: string;
107
+ };
89
108
  export type EditorClientMethodDeps = {
90
109
  getContext: () => EditorSessionContext | undefined;
91
110
  /**
@@ -115,7 +134,7 @@ export type EditorClientMethodDeps = {
115
134
  * other stored-credential integrations execute here; interactive IdP auth
116
135
  * surfaces as an error asking the user to authenticate in the editor.
117
136
  */
118
- export declare function executeRequestToIntegrationViaOrchestrator(context: EditorSessionContext, payload: IntegrationExecutePayload): Promise<IntegrationExecuteResult>;
137
+ export declare function executeRequestToIntegrationViaOrchestrator(context: IntegrationExecutionContext, payload: IntegrationExecutePayload): Promise<IntegrationExecuteResult>;
119
138
  /**
120
139
  * Prefills Clark's promptContext.integrations the same way the editor does.
121
140
  */
@@ -132,7 +151,7 @@ export declare function mapSdkExecutionResponse(response: unknown): SdkApiExecut
132
151
  * and takes the in-flight Clark build down with it. A browser editor answers
133
152
  * all of them, so a held gateway socket has to as well.
134
153
  *
135
- * Keyed on `EditorClientMethods` rather than a hand-kept list so that a method
154
+ * Keyed on `GatewayClientMethods` rather than a hand-kept list so that a method
136
155
  * added to the protocol upstream fails this package's typecheck instead of
137
156
  * reaching a sandbox and crashing it. Same handler surface as
138
157
  * `createEditorHandlers` in vite-plugin-file-sync's dev-server-ws-smoke-client,
@@ -144,4 +163,3 @@ export declare function mapSdkExecutionResponse(response: unknown): SdkApiExecut
144
163
  * and surface progress over MCP.
145
164
  */
146
165
  export declare function createEditorClientMethods(getListener?: () => ClarkPeerListener | undefined, onInbound?: (method: string) => void, deps?: EditorClientMethodDeps): MethodHandlers<Record<string, never>, Record<string, never>, RequestContextBase>;
147
- export {};