@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
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@superblocksteam/gateway",
3
- "version": "2.0.161",
3
+ "version": "2.0.162-next.1",
4
4
  "description": "Gateway v0 — MCP entry for app start/edit/publish",
5
5
  "license": "Superblocks Community Software License",
6
6
  "bin": {
7
7
  "superblocks-gateway": "./dist/main.js"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "skills"
11
12
  ],
12
13
  "type": "module",
13
14
  "main": "dist/index.js",
@@ -16,16 +17,23 @@
16
17
  "types": "./dist/index.d.ts",
17
18
  "import": "./dist/index.js",
18
19
  "default": "./dist/index.js"
19
- }
20
+ },
21
+ "./package.json": "./package.json",
22
+ "./skills/superblocks-import/SKILL.md": "./skills/superblocks-import/SKILL.md"
20
23
  },
21
24
  "dependencies": {
22
25
  "@modelcontextprotocol/ext-apps": "^1.7.5",
23
26
  "@modelcontextprotocol/sdk": "^1.30.0",
24
27
  "@opentelemetry/api": "^1.9.1",
25
- "@superblocksteam/library-shared": "2.0.161",
26
- "@superblocksteam/mcp-server": "2.0.161",
27
- "@superblocksteam/shared": "0.9611.2",
28
- "@superblocksteam/telemetry": "2.0.161",
28
+ "@superblocksteam/library-shared": "2.0.162-next.1",
29
+ "@superblocksteam/mcp-server": "2.0.162-next.1",
30
+ "@superblocksteam/shared": "0.9613.1",
31
+ "@superblocksteam/telemetry": "2.0.162-next.1",
32
+ "fflate": "^0.8.3",
33
+ "libpg-query": "^17.7.4",
34
+ "mdast-util-from-markdown": "2.0.2",
35
+ "mdast-util-gfm-autolink-literal": "2.0.1",
36
+ "micromark-extension-gfm-autolink-literal": "2.1.0",
29
37
  "playwright": "1.56.0",
30
38
  "ws": "8.21.0",
31
39
  "zod": "^4.3.6"
@@ -33,6 +41,7 @@
33
41
  "devDependencies": {
34
42
  "@eslint/js": "^9.39.2",
35
43
  "@types/express": "^4.17.21",
44
+ "@types/mdast": "4.0.4",
36
45
  "@types/node": "^24",
37
46
  "@types/ws": "^8.18.1",
38
47
  "eslint": "^9.39.2",
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: superblocks-build
3
+ description: >
4
+ Use when the user asks to build, create, change, update, edit, or modify an
5
+ app, dashboard, internal tool, admin panel, form, or CRUD UI - including one
6
+ they might otherwise make as a local file or artifact. Most requests never
7
+ say which location they mean. An existing or named app is still ambiguous
8
+ unless this conversation already established its location. Ask where it
9
+ should live before creating or editing anything and before using any tool;
10
+ do not list apps to infer the answer.
11
+ ---
12
+
13
+ # Where does this app get built?
14
+
15
+ Two places can build what the user just asked for:
16
+
17
+ - **Superblocks** — a real application. Org datasources, server-side APIs,
18
+ platform auth and permissions, a deploy story, other people can use it.
19
+ - **Here** — a local file or artifact in this chat. Fast and private, but it
20
+ reaches no company data and nobody else can run it.
21
+
22
+ Most requests name neither. Choosing silently is wrong about half the time, and
23
+ the user only finds out once the work already exists in the wrong place.
24
+
25
+ ## Ask first
26
+
27
+ Before creating or editing anything, ask one short question naming both options,
28
+ then wait for the answer:
29
+
30
+ > Do you want this built in Superblocks, or as a local artifact here?
31
+
32
+ If the location is ambiguous, your first action must be the two-option question
33
+ above. Do not call any Superblocks tool, including `list_applications`, or
34
+ create or edit a local artifact until the user answers.
35
+
36
+ Ask once per request. Do not build a local version "to show them" while waiting.
37
+ Building it is the choice.
38
+
39
+ ## Do not ask when they already answered
40
+
41
+ - Said Superblocks, or explicitly named a Superblocks app already established in
42
+ this conversation -> build there.
43
+ - Said local, artifact, file, HTML, "just show me", "quick mockup" -> build here.
44
+ - Answered this question for this same request -> honor it, stay silent.
45
+ - Not an app at all (a script, a chart, an analysis, a document, a snippet)
46
+ -> just do the work.
47
+
48
+ ## Editing counts too
49
+
50
+ The same question applies to changing an app, dashboard, or artifact the user
51
+ names, including one already imported into Superblocks. When you cannot tell
52
+ which copy they mean, ask that instead.
53
+
54
+ ## Once they pick Superblocks
55
+
56
+ - Something new -> `start_app`.
57
+ - Existing source to port -> use the `superblocks-import` skill.
58
+ - An app already in Superblocks -> `list_applications` to find it, then
59
+ `edit_app`.
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: superblocks-import
3
+ description: >
4
+ Import, migrate, or port an existing app (React, Replit, Lovable, v0, Streamlit,
5
+ a zip on disk, or files in the conversation) into Superblocks. Use when the
6
+ user has existing source and wants it as a Superblocks application — not when
7
+ they are only editing an app that already exists in Superblocks.
8
+ ---
9
+
10
+ # Superblocks import (host director)
11
+
12
+ You plan and slice. **Superblocks writes** the application through Builder MCP
13
+ (`start_app` / `edit_app`). Do not invent Superblocks `client/` or `server/`
14
+ files on the laptop. Superblocks already has its own in-sandbox migration
15
+ skillset; your job is to ask for the right slices.
16
+
17
+ ## Choose the source path
18
+
19
+ Check source files and archives for secrets and production data before uploading.
20
+ Keep placeholder configuration such as `.env.example`, not real credentials.
21
+
22
+ When source files are already visible in this conversation, call
23
+ `upload_artifact` with `files: [{ path, content }]`. Keep their original
24
+ relative paths; do not write or zip them first. Pass the returned `artifact` to
25
+ `start_app` in `artifacts` and ask Superblocks to migrate the attached source.
26
+
27
+ When the source is a readable tree on disk, inventory it locally, then
28
+ archive the source and assets with their original relative paths. Exclude
29
+ `.git`, `node_modules`, build output, secrets, and production data; inspect
30
+ the archive before uploading it. Call `upload_artifact` with the archive's
31
+ `filePath` and pass its returned `artifact` unchanged in `start_app.artifacts`.
32
+ Local paths and prose descriptions are not a substitute for the source artifact:
33
+ Superblocks cannot read the host's workspace. Ask Superblocks to read the
34
+ attached source and preserve its UI and behavior, not recreate it from prose.
35
+
36
+ For an existing source archive, call `upload_artifact` with
37
+ `filePath` (never `zipBase64`), then pass its `artifact` to `start_app` in
38
+ `artifacts`. Archives over 50 MB are rejected; request a smaller source export
39
+ without dependencies or build output rather than silently omitting source.
40
+ If the gateway cannot read the host path, use `files` for text within the
41
+ tool's limits. For binary assets, ask for an accessible export; never encode
42
+ them as text or silently leave them out.
43
+
44
+ Keep the returned artifact and application IDs. To resume, reuse the same
45
+ artifact ID with `edit_app` and the same application ID. Do not upload the
46
+ source again, and do not call `start_app` again.
47
+
48
+ Replit / Lovable / v0: clone or export onto this machine first. Do not ask
49
+ the live-edit environment to fetch those clouds.
50
+
51
+ ## Slice order
52
+
53
+ 1. Inventory locally (routes, env keys, ORMs, `fetch`/`axios`, tests). Keep
54
+ the source app running if you can. Map secrets from `.env.example` — never
55
+ paste production `.env` into `edit_app`.
56
+ 2. `list_integrations`. Reuse an existing datasource (`find_apps_by_integration`)
57
+ before `create_integration`.
58
+ 3. `start_app` with the user's import request, named integrations, and the
59
+ uploaded source in `artifacts`. Ask Superblocks to read and migrate that
60
+ source, preserving its UI and behavior.
61
+ `start_app` defaults to Plan mode. Pass `mode: "BUILD"` only if the user
62
+ asks for build mode explicitly (e.g. "use build mode" or "skip the plan").
63
+ Otherwise, follow the returned `agentInstructions` to present the first
64
+ plan and collect the user's decision. When `decision.plan` is returned,
65
+ show it in full, verbatim as Markdown in chat, not inside a form. For this
66
+ plan decision, use the native form only for `Approve` / `Refine` when
67
+ instructed, or use the instructed fallback, then wait for their answer.
68
+ Only if they approve, call `edit_app` with `planAction: "approve"` instead
69
+ of planning it again. Do not run a second “migrate everything” plan.
70
+ Mode is per call and never sticks: every `edit_app` below plans unless it
71
+ passes `mode: "BUILD"`, so send it on each slice.
72
+ 4. One backend operation per `edit_app`, then `check_app_progress` while the
73
+ slice is building, handling any requested decision. For interrupted or
74
+ unknown turns and errors, follow returned `agentInstructions` and
75
+ `pendingAction`, including stop or user continuation requirements; missing
76
+ `recentRuns` alone is not permission to restart. Check the completed slice's
77
+ runtime outcome in `recentRuns` or Superblocks' report. Only for a completed
78
+ slice, if verification is missing or failed, send a focused `edit_app` to
79
+ test or fix the same API, not more polling of a finished turn. Advance only
80
+ when the API passed or testing was explicitly skipped with a reason
81
+ reported as unverified. There is no MCP SQL tool.
82
+ 5. One UI route per `edit_app`, wired to APIs whose verification was resolved
83
+ above.
84
+ 6. Auth, jobs, leftovers last.
85
+ 7. After each slice, `get_application_structure` (and `get_app` URLs). Ground
86
+ the next prompt in what Superblocks actually wrote. `list_knowledge` /
87
+ `get_knowledge` for org playbooks.
88
+
89
+ `list_applications` if `start_app` errors: the app may already exist.
90
+
91
+ Follow `browserNavigation` by opening its exact URL when returned, and
92
+ `agentInstructions` for editor-only decisions. Do not open an app preview
93
+ before `viewStatus` is ready.
94
+
95
+ ## Primitive map (not Next.js)
96
+
97
+ - Backend operations are **named APIs** in a registry, not URL routes.
98
+ - Each UI page is a Superblocks page using `useApi` / `useApiData` /
99
+ `executeApi` from the fullstack template — not Next App Router, not the
100
+ source app’s QueryClient.
101
+ - Datasources are **org integrations** (UUIDs). Credentials live there, not
102
+ `process.env` in generated code. Auth is platform user context; drop the
103
+ source login stack unless Superblocks asks otherwise.
104
+
105
+ ## `edit_app` prompt shape
106
+
107
+ Ask Superblocks to implement **this slice** as fullstack (APIs vs pages vs
108
+ integrations). Tell it to follow its third-party migration skillset. Reuse the
109
+ uploaded artifact in `edit_app.artifacts` and cite its relative source paths;
110
+ small excerpts can clarify a change but do not replace the attached source.
111
+
112
+ For every backend slice, include this in the `edit_app` prompt:
113
+
114
+ > After implementing this API, run `testApi` with representative inputs and
115
+ > verify the expected result, then report the API name, passed/failed/skipped,
116
+ > and the concrete outcome before finishing this slice. For mutating tests,
117
+ > honor the tool's permission checks; if denied or the user explicitly asks
118
+ > to skip testing, report skipped with the reason. Do not claim untested APIs
119
+ > passed.
120
+
121
+ ## Do not
122
+
123
+ - `browser_evaluate` JWTs; `browser_close` / Playwright `--isolated` between
124
+ IdP and retry.
125
+ - Dump `.env` or production data into prompts.
@@ -1,11 +0,0 @@
1
- import type { ImportAppSource } from "./types.js";
2
- /**
3
- * Archive names land in instruction-bearing prompt text. Keep a single-line
4
- * basename so a crafted zip path cannot inject newlines or role-play into Clark.
5
- */
6
- export declare function sanitizeArchiveDisplayName(zipFileName: string): string;
7
- export declare function buildImportPrompt(input: {
8
- extraPrompt?: string;
9
- source: ImportAppSource;
10
- zipFileName: string;
11
- }): string;
@@ -1,96 +0,0 @@
1
- /**
2
- * Migration prompts mirror the browser MigrationModal templates so Clark loads
3
- * the same skills and inspects the attached archive the same way.
4
- */
5
- /**
6
- * The browser migration flow leans on the `third-party-migration` skill, which
7
- * ends by deferring verification to "the user running the app" — and is dropped
8
- * entirely unless the org has `ui.third-party-import.enabled`. Neither holds
9
- * here: no one is clicking through a headless migration, and the gateway hands
10
- * Clark the org's integrations plus a live `testApi` on every turn. Say so in
11
- * the prompt rather than hoping a skill is loaded.
12
- */
13
- const API_VERIFICATION_INSTRUCTION = `Nobody is watching this migration in a browser, so you verify your own work. This turn's context lists the org's integrations — use them for the data sources you find in the project. Run every API you create or change through testApi before you report the migration finished, and say what testApi returned, failures included. Do not defer API verification to the user, and do not treat testApi as unavailable during a migration.`;
14
- function withMigrationSkillInstruction(prompt) {
15
- return `Please follow the migration guidelines as detailed in your skillset.
16
-
17
- ${prompt}`;
18
- }
19
- /**
20
- * Archive names land in instruction-bearing prompt text. Keep a single-line
21
- * basename so a crafted zip path cannot inject newlines or role-play into Clark.
22
- */
23
- export function sanitizeArchiveDisplayName(zipFileName) {
24
- const base = zipFileName.replace(/\\/g, "/").split("/").pop() ?? "archive.zip";
25
- let cleaned = "";
26
- for (const ch of base) {
27
- const code = ch.codePointAt(0) ?? 0;
28
- // Drop C0 controls and DEL so a crafted basename cannot inject newlines
29
- // into instruction-bearing prompt text.
30
- if (code >= 32 && code !== 127) {
31
- cleaned += ch;
32
- }
33
- }
34
- cleaned = cleaned.trim();
35
- return cleaned.length > 0 ? cleaned : "archive.zip";
36
- }
37
- function genericImportPrompt(zipFileName) {
38
- return withMigrationSkillInstruction(`Import this codebase into Superblocks. The project is attached as ${zipFileName}. Inspect the structure, identify the framework and data sources, then migrate it into the current Superblocks fullstack app.`);
39
- }
40
- const SOURCE_PROMPTS = {
41
- chatgpt: genericImportPrompt,
42
- claude: genericImportPrompt,
43
- "claude-design": (zipFileName) => withMigrationSkillInstruction(`Migrate this Claude Design app into Superblocks. The exported project is attached as ${zipFileName}.`),
44
- lovable: (zipFileName) => withMigrationSkillInstruction(`Migrate this Lovable app into Superblocks. The exported project is attached as ${zipFileName}.`),
45
- replit: (zipFileName) => withMigrationSkillInstruction(`Migrate this Replit app into Superblocks. The exported project is attached as ${zipFileName}.`),
46
- streamlit: genericImportPrompt,
47
- v0: (zipFileName) => withMigrationSkillInstruction(`Migrate this v0 app into Superblocks. The exported project is attached as ${zipFileName}.`),
48
- zip: genericImportPrompt,
49
- };
50
- /**
51
- * Builds the Clark prompt for an import turn. Optional `extraPrompt` is the
52
- * caller's intent (e.g. "make it more secure"), appended after the template.
53
- */
54
- function promptForSource(source, zipFileName) {
55
- // Exhaustive switch with direct calls — no dynamic property lookup — so
56
- // CodeQL cannot treat `source` as an unvalidated method name.
57
- switch (source) {
58
- case "chatgpt":
59
- return SOURCE_PROMPTS.chatgpt(zipFileName);
60
- case "claude":
61
- return SOURCE_PROMPTS.claude(zipFileName);
62
- case "claude-design":
63
- return SOURCE_PROMPTS["claude-design"](zipFileName);
64
- case "lovable":
65
- return SOURCE_PROMPTS.lovable(zipFileName);
66
- case "replit":
67
- return SOURCE_PROMPTS.replit(zipFileName);
68
- case "streamlit":
69
- return SOURCE_PROMPTS.streamlit(zipFileName);
70
- case "v0":
71
- return SOURCE_PROMPTS.v0(zipFileName);
72
- case "zip":
73
- return SOURCE_PROMPTS.zip(zipFileName);
74
- default: {
75
- const _exhaustive = source;
76
- throw new Error(`unsupported import source: ${String(_exhaustive)}`);
77
- }
78
- }
79
- }
80
- export function buildImportPrompt(input) {
81
- const zipFileName = sanitizeArchiveDisplayName(input.zipFileName);
82
- const base = promptForSource(input.source, zipFileName);
83
- const extra = input.extraPrompt?.trim();
84
- // Verification goes last: a caller asking to "just get it running" should not
85
- // end up with a migration that reports untested APIs.
86
- const intent = extra
87
- ? `${base}
88
-
89
- Additional instructions from the user:
90
- ${extra}`
91
- : base;
92
- return `${intent}
93
-
94
- ${API_VERIFICATION_INSTRUCTION}`;
95
- }
96
- //# sourceMappingURL=import-prompt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"import-prompt.js","sourceRoot":"","sources":["../../src/capabilities/import-prompt.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,4BAA4B,GAAG,8aAA8a,CAAC;AAEpd,SAAS,6BAA6B,CAAC,MAAc;IACnD,OAAO;;EAEP,MAAM,EAAE,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB;IAC5D,MAAM,IAAI,GACR,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,aAAa,CAAC;IACpE,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,wEAAwE;QACxE,wCAAwC;QACxC,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IACzB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;AACtD,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,OAAO,6BAA6B,CAClC,qEAAqE,WAAW,+HAA+H,CAChN,CAAC;AACJ,CAAC;AAED,MAAM,cAAc,GAClB;IACE,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,mBAAmB;IAC3B,eAAe,EAAE,CAAC,WAAW,EAAE,EAAE,CAC/B,6BAA6B,CAC3B,wFAAwF,WAAW,GAAG,CACvG;IACH,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CACvB,6BAA6B,CAC3B,kFAAkF,WAAW,GAAG,CACjG;IACH,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CACtB,6BAA6B,CAC3B,iFAAiF,WAAW,GAAG,CAChG;IACH,SAAS,EAAE,mBAAmB;IAC9B,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAClB,6BAA6B,CAC3B,6EAA6E,WAAW,GAAG,CAC5F;IACH,GAAG,EAAE,mBAAmB;CACzB,CAAC;AAEJ;;;GAGG;AACH,SAAS,eAAe,CAAC,MAAuB,EAAE,WAAmB;IACnE,wEAAwE;IACxE,8DAA8D;IAC9D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,KAAK,eAAe;YAClB,OAAO,cAAc,CAAC,eAAe,CAAC,CAAC,WAAW,CAAC,CAAC;QACtD,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,KAAK,WAAW;YACd,OAAO,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC/C,KAAK,IAAI;YACP,OAAO,cAAc,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;QACxC,KAAK,KAAK;YACR,OAAO,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,MAAM,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAIjC;IACC,MAAM,WAAW,GAAG,0BAA0B,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACxC,8EAA8E;IAC9E,sDAAsD;IACtD,MAAM,MAAM,GAAG,KAAK;QAClB,CAAC,CAAC,GAAG,IAAI;;;EAGX,KAAK,EAAE;QACL,CAAC,CAAC,IAAI,CAAC;IACT,OAAO,GAAG,MAAM;;EAEhB,4BAA4B,EAAE,CAAC;AACjC,CAAC"}
@@ -1,46 +0,0 @@
1
- import type { EventSnapshot } from "../events/types.js";
2
- import type { BuildStatus, GenerationStatus } from "./types.js";
3
- export type PersistedProgress = {
4
- /** Superblocks' own words since this caller last read, oldest first. */
5
- activity: string[];
6
- /** Set when the build is stuck waiting for an interactive authorization. */
7
- authRequiredReason?: string;
8
- /** Present once the persisted stream shows the turn reached a terminal state. */
9
- generationStatus?: GenerationStatus;
10
- /** Newest assistant message, so a resumed caller can report the outcome. */
11
- reply?: string;
12
- status: BuildStatus;
13
- };
14
- /**
15
- * Reads a build's state out of what was persisted, for a caller that has no
16
- * live turn to ask.
17
- *
18
- * The two halves of a snapshot answer different questions and are used
19
- * differently. Activity comes from the window after the caller's cursor,
20
- * because that is what is new *to this caller*. State comes from the tail of
21
- * the stream regardless of the cursor, because a caller that already consumed
22
- * the terminal event still needs to be told the build finished — reading
23
- * state from the after-cursor window would tell it nothing is known and send
24
- * it back to poll a turn that ended.
25
- */
26
- export declare function readPersistedProgress(snapshot: Pick<EventSnapshot, "events" | "tail">, liveness: StreamLiveness,
27
- /**
28
- * The quiet window a `completed` must outlast, which has to be the same one
29
- * the live turn settled with (`config.clarkSettleMs`). Defaults to the
30
- * collector's constant so a caller with no config in hand still reads the
31
- * stream the way an untuned gateway wrote it.
32
- */
33
- settleMs?: number): PersistedProgress;
34
- /**
35
- * How to judge whether what the stream last said is still true.
36
- *
37
- * Required rather than optional so no caller can read a status the rule was
38
- * never applied to: the whole point of reading state here is that `get_app` and
39
- * `check_app_progress` stop contradicting each other about one app, and an
40
- * omitted rule is how they would drift apart again (ENG-5808).
41
- */
42
- export type StreamLiveness = {
43
- nowMs: number;
44
- /** How long the work can be silent before the stream stops meaning it. */
45
- staleAfterMs: number;
46
- };
@@ -1,246 +0,0 @@
1
- import { DEFAULT_SETTLE_MS } from "../sabs/turn-collector.js";
2
- import { buildStatusOf } from "./types.js";
3
- /**
4
- * Reads a build's state out of what was persisted, for a caller that has no
5
- * live turn to ask.
6
- *
7
- * The two halves of a snapshot answer different questions and are used
8
- * differently. Activity comes from the window after the caller's cursor,
9
- * because that is what is new *to this caller*. State comes from the tail of
10
- * the stream regardless of the cursor, because a caller that already consumed
11
- * the terminal event still needs to be told the build finished — reading
12
- * state from the after-cursor window would tell it nothing is known and send
13
- * it back to poll a turn that ended.
14
- */
15
- export function readPersistedProgress(snapshot, liveness,
16
- /**
17
- * The quiet window a `completed` must outlast, which has to be the same one
18
- * the live turn settled with (`config.clarkSettleMs`). Defaults to the
19
- * collector's constant so a caller with no config in hand still reads the
20
- * stream the way an untuned gateway wrote it.
21
- */
22
- settleMs = DEFAULT_SETTLE_MS) {
23
- const activity = [];
24
- for (const event of snapshot.events) {
25
- const line = activityLine(event);
26
- // The collector drops a repeated progress line for the same reason: a
27
- // build that says "Installing dependencies" twice in a row has not told
28
- // the reader anything the second time.
29
- if (line && line !== activity[activity.length - 1]) {
30
- activity.push(line);
31
- }
32
- }
33
- let authRequiredReason;
34
- let generationStatus;
35
- let reply;
36
- let status = snapshot.tail.length > 0 ? "building" : "unknown";
37
- // When the turn last reported it was done, and when its session went away.
38
- // Whether the first of those had settled before the second decides which of
39
- // them is the outcome.
40
- let completedAtMs;
41
- let teardownAtMs;
42
- for (const event of snapshot.tail) {
43
- if (event.payload.kind === "auth_required") {
44
- authRequiredReason = event.payload.reason ?? "auth_required";
45
- continue;
46
- }
47
- if (event.payload.kind === "chat_message" &&
48
- event.payload.role === "assistant") {
49
- reply = event.payload.text;
50
- continue;
51
- }
52
- if (event.payload.kind === "session") {
53
- // SABS tearing the live edit down settles a turn that never settled
54
- // itself: the dev server exits silently when it loses its lock, so no
55
- // terminal generation_state is coming and a caller reading from the
56
- // stream would otherwise be told "building" forever.
57
- //
58
- // Not every teardown is that, though. Every healthy build ends with its
59
- // session going away too, and reading that as a dead live edit would
60
- // report each finished app as a failure. Which one this is comes down to
61
- // whether the turn had really finished first - see `teardownEndsTurn`.
62
- if (event.payload.status !== "terminated") {
63
- continue;
64
- }
65
- teardownAtMs = event.occurredAtMs;
66
- if (!teardownEndsTurn(generationStatus, completedAtMs, teardownAtMs, settleMs)) {
67
- continue;
68
- }
69
- generationStatus = "live_edit_terminated";
70
- status = buildStatusOf(generationStatus);
71
- continue;
72
- }
73
- if (event.payload.kind !== "generation_state") {
74
- continue;
75
- }
76
- // Later states supersede earlier ones: a build that went back to
77
- // generating after an idle blip is generating.
78
- //
79
- // A torn-down live edit is the exception. The dev server cannot report
80
- // progress after SABS has killed it, so a non-terminal state stamped
81
- // later than the teardown is skew between two producers merged by
82
- // `occurredAtMs`, not news that the turn revived. Letting it through
83
- // would put the caller back to polling the dead session this status
84
- // exists to name. Only another terminal state outranks the teardown.
85
- const state = terminalStatus(event.payload.state);
86
- if (!state && generationStatus === "live_edit_terminated") {
87
- continue;
88
- }
89
- // A `completed` the teardown already cut short does not come back to life
90
- // by being listed second. The two producers stamp their own clocks, so the
91
- // tail can carry the pair either way round; the same pair of facts has to
92
- // reach the same outcome both times.
93
- if (state === "completed" &&
94
- generationStatus === "live_edit_terminated" &&
95
- teardownAtMs !== undefined &&
96
- !outlastedSettleWindow(event.occurredAtMs, teardownAtMs, settleMs)) {
97
- continue;
98
- }
99
- completedAtMs = state === "completed" ? event.occurredAtMs : undefined;
100
- generationStatus = state;
101
- status = state ? buildStatusOf(state) : "building";
102
- }
103
- // Applied after the tail, not before it: the loop above assigns `building` for
104
- // every non-terminal generation state it sees, so a rule that only set the
105
- // initial value would be overwritten by the very events it exists to judge.
106
- //
107
- // Only a non-terminal reading expires. How a turn ended is a fact - a
108
- // completed turn stays completed and a torn-down live edit stays torn down -
109
- // and an old terminal state is the answer a caller needs, not a stale one.
110
- if (!generationStatus && !reportsLiveWork(snapshot.tail, liveness)) {
111
- status = "unknown";
112
- }
113
- return {
114
- activity,
115
- ...(authRequiredReason ? { authRequiredReason } : {}),
116
- ...(generationStatus ? { generationStatus } : {}),
117
- ...(reply ? { reply } : {}),
118
- status,
119
- };
120
- }
121
- /**
122
- * Whether a `completed` had closed its quiet window before the teardown
123
- * landed.
124
- *
125
- * `completed` is provisional until it settles: the gateway checkpoints Clark's
126
- * files only once the window closes, and that checkpoint runs over the socket
127
- * to the dev server. A teardown inside the window therefore means no
128
- * checkpoint could have landed - the same conclusion the live path draws from
129
- * the same pair of facts, so a caller holding the turn and a caller reading
130
- * the stream cannot answer differently. The gateway holds the socket for a
131
- * release grace that outlasts this window, so a healthy build's teardown is
132
- * never mistaken for one.
133
- *
134
- * Distance, not order: the two producers stamp their own clocks.
135
- */
136
- function outlastedSettleWindow(completedAtMs, teardownAtMs, settleMs) {
137
- return Math.abs(teardownAtMs - completedAtMs) >= settleMs;
138
- }
139
- /**
140
- * Whether a teardown is this turn's outcome rather than the tail of one that
141
- * had already finished.
142
- *
143
- * Nothing terminal read yet means the dev server never reported an end and
144
- * never will. `cancelled` and `needs_decision` settle the moment they arrive,
145
- * so a later teardown leaves them standing. Only `completed` has a window it
146
- * can be cut short inside.
147
- */
148
- function teardownEndsTurn(generationStatus, completedAtMs, teardownAtMs, settleMs) {
149
- if (!generationStatus) {
150
- return true;
151
- }
152
- if (generationStatus !== "completed" || completedAtMs === undefined) {
153
- return false;
154
- }
155
- return !outlastedSettleWindow(completedAtMs, teardownAtMs, settleMs);
156
- }
157
- /**
158
- * How a persisted generation state reads as a finished turn, or undefined
159
- * while the build is still going.
160
- *
161
- * `idle` counts as finished for the same reason the live collector treats it
162
- * that way: it is what Superblocks reports when it has stopped working and is
163
- * not waiting for anything.
164
- */
165
- function terminalStatus(state) {
166
- switch (state) {
167
- case "awaiting_user_input":
168
- return "needs_decision";
169
- case "cancelled":
170
- return "cancelled";
171
- case "completed":
172
- case "idle":
173
- return "completed";
174
- default:
175
- return undefined;
176
- }
177
- }
178
- /**
179
- * Whether the tail is evidence of a build that is still going, short of any
180
- * terminal state.
181
- *
182
- * Two things disqualify it. The caller's own prompt coming back is not a report
183
- * of work - which events a producer emits is settled in another package and, for
184
- * SABS, another repository, so this asks to be shown the work rather than
185
- * trusting that a user message is never left in a stream on its own. And the
186
- * tail is bounded, so a turn's terminal event can age out of it and leave a
187
- * finished build looking like a running one forever; work that has been silent
188
- * for longer than a turn can last has ended, whatever the stream still holds.
189
- *
190
- * Both halves read the same events on purpose. Judging the age by anything the
191
- * stream carried, the prompt included, let a new prompt hold the clock open over
192
- * work that had stopped talking a whole turn budget earlier.
193
- *
194
- * TODO(ENG-5896): `occurredAtMs` is stamped by the producer, so the age below is
195
- * arithmetic across two machines' clocks. A stamp from the future is read as
196
- * fresh here rather than stale, which covers a producer running ahead; a
197
- * producer running far enough behind still reads as silent. Closing that needs a
198
- * gateway-side receive timestamp at ingress.
199
- */
200
- function reportsLiveWork(tail, liveness) {
201
- let newestAtMs;
202
- for (const event of tail) {
203
- if (reportsWork(event)) {
204
- newestAtMs = Math.max(newestAtMs ?? 0, event.occurredAtMs);
205
- }
206
- }
207
- if (newestAtMs === undefined) {
208
- return false;
209
- }
210
- const ageMs = liveness.nowMs - newestAtMs;
211
- if (ageMs < 0) {
212
- // Not silence: the producer's clock is ahead of ours. Calling that stale
213
- // would be reading a clock difference as the end of a build.
214
- console.warn("gateway persisted stream is stamped in the future", {
215
- newestAtMs,
216
- nowMs: liveness.nowMs,
217
- skewMs: -ageMs,
218
- });
219
- return true;
220
- }
221
- return ageMs <= liveness.staleAfterMs;
222
- }
223
- /**
224
- * Whether an event says something about the work, as opposed to being the
225
- * caller's own prompt coming back. Anything Superblocks or SABS reports counts -
226
- * a generation state, a progress line, a reply, an auth prompt, the session
227
- * itself - so this excludes only the one event a caller produces.
228
- */
229
- function reportsWork(event) {
230
- return !(event.payload.kind === "chat_message" && event.payload.role === "user");
231
- }
232
- function activityLine(event) {
233
- switch (event.payload.kind) {
234
- case "chat_message":
235
- // A user message is the prompt coming back; relaying it would have the
236
- // caller read its own words out as if they were news.
237
- return event.payload.role === "assistant"
238
- ? event.payload.text
239
- : undefined;
240
- case "progress":
241
- return event.payload.label;
242
- default:
243
- return undefined;
244
- }
245
- }
246
- //# sourceMappingURL=persisted-progress.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"persisted-progress.js","sourceRoot":"","sources":["../../src/capabilities/persisted-progress.ts"],"names":[],"mappings":"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"}