@superblocksteam/gateway 2.0.155-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/LICENSE.txt +87 -0
  2. package/README.md +170 -0
  3. package/dist/agents/resolve-orchestrator-url.d.ts +22 -0
  4. package/dist/agents/resolve-orchestrator-url.js +38 -0
  5. package/dist/agents/resolve-orchestrator-url.js.map +1 -0
  6. package/dist/capabilities/import-prompt.d.ts +11 -0
  7. package/dist/capabilities/import-prompt.js +96 -0
  8. package/dist/capabilities/import-prompt.js.map +1 -0
  9. package/dist/capabilities/lifecycle.d.ts +73 -0
  10. package/dist/capabilities/lifecycle.js +2531 -0
  11. package/dist/capabilities/lifecycle.js.map +1 -0
  12. package/dist/capabilities/persisted-progress.d.ts +46 -0
  13. package/dist/capabilities/persisted-progress.js +246 -0
  14. package/dist/capabilities/persisted-progress.js.map +1 -0
  15. package/dist/capabilities/types.d.ts +446 -0
  16. package/dist/capabilities/types.js +47 -0
  17. package/dist/capabilities/types.js.map +1 -0
  18. package/dist/capture/browser-contract.d.ts +36 -0
  19. package/dist/capture/browser-contract.js +24 -0
  20. package/dist/capture/browser-contract.js.map +1 -0
  21. package/dist/capture/browser-instructions.d.ts +9 -0
  22. package/dist/capture/browser-instructions.js +17 -0
  23. package/dist/capture/browser-instructions.js.map +1 -0
  24. package/dist/capture/capture-library-probe.d.ts +55 -0
  25. package/dist/capture/capture-library-probe.js +177 -0
  26. package/dist/capture/capture-library-probe.js.map +1 -0
  27. package/dist/capture/capture-library.d.ts +52 -0
  28. package/dist/capture/capture-library.js +249 -0
  29. package/dist/capture/capture-library.js.map +1 -0
  30. package/dist/capture/classify-library-paint.d.ts +21 -0
  31. package/dist/capture/classify-library-paint.js +13 -0
  32. package/dist/capture/classify-library-paint.js.map +1 -0
  33. package/dist/capture/host-mcp-scan.d.ts +16 -0
  34. package/dist/capture/host-mcp-scan.js +64 -0
  35. package/dist/capture/host-mcp-scan.js.map +1 -0
  36. package/dist/capture/library-parent-script.d.ts +34 -0
  37. package/dist/capture/library-parent-script.js +82 -0
  38. package/dist/capture/library-parent-script.js.map +1 -0
  39. package/dist/capture/mode.d.ts +22 -0
  40. package/dist/capture/mode.js +45 -0
  41. package/dist/capture/mode.js.map +1 -0
  42. package/dist/config.d.ts +141 -0
  43. package/dist/config.js +109 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/debug.d.ts +2 -0
  46. package/dist/debug.js +9 -0
  47. package/dist/debug.js.map +1 -0
  48. package/dist/deps.d.ts +36 -0
  49. package/dist/deps.js +2 -0
  50. package/dist/deps.js.map +1 -0
  51. package/dist/events/cursor.d.ts +43 -0
  52. package/dist/events/cursor.js +78 -0
  53. package/dist/events/cursor.js.map +1 -0
  54. package/dist/events/memory-event-store.d.ts +34 -0
  55. package/dist/events/memory-event-store.js +110 -0
  56. package/dist/events/memory-event-store.js.map +1 -0
  57. package/dist/events/merge.d.ts +23 -0
  58. package/dist/events/merge.js +97 -0
  59. package/dist/events/merge.js.map +1 -0
  60. package/dist/events/normalized-collector.d.ts +62 -0
  61. package/dist/events/normalized-collector.js +156 -0
  62. package/dist/events/normalized-collector.js.map +1 -0
  63. package/dist/events/schema.d.ts +9 -0
  64. package/dist/events/schema.js +93 -0
  65. package/dist/events/schema.js.map +1 -0
  66. package/dist/events/snapshot.d.ts +32 -0
  67. package/dist/events/snapshot.js +57 -0
  68. package/dist/events/snapshot.js.map +1 -0
  69. package/dist/events/stream-key.d.ts +2 -0
  70. package/dist/events/stream-key.js +31 -0
  71. package/dist/events/stream-key.js.map +1 -0
  72. package/dist/events/types.d.ts +179 -0
  73. package/dist/events/types.js +66 -0
  74. package/dist/events/types.js.map +1 -0
  75. package/dist/health/readiness.d.ts +99 -0
  76. package/dist/health/readiness.js +202 -0
  77. package/dist/health/readiness.js.map +1 -0
  78. package/dist/index.d.ts +10 -0
  79. package/dist/index.js +10 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/integrations/filters.d.ts +8 -0
  82. package/dist/integrations/filters.js +40 -0
  83. package/dist/integrations/filters.js.map +1 -0
  84. package/dist/integrations/map.d.ts +26 -0
  85. package/dist/integrations/map.js +43 -0
  86. package/dist/integrations/map.js.map +1 -0
  87. package/dist/integrations/profile-key.d.ts +19 -0
  88. package/dist/integrations/profile-key.js +35 -0
  89. package/dist/integrations/profile-key.js.map +1 -0
  90. package/dist/main.d.ts +2 -0
  91. package/dist/main.js +5 -0
  92. package/dist/main.js.map +1 -0
  93. package/dist/orchestrator/client.d.ts +62 -0
  94. package/dist/orchestrator/client.js +160 -0
  95. package/dist/orchestrator/client.js.map +1 -0
  96. package/dist/playwright/ensure-chromium.d.ts +26 -0
  97. package/dist/playwright/ensure-chromium.js +60 -0
  98. package/dist/playwright/ensure-chromium.js.map +1 -0
  99. package/dist/preview/capture-screenshot.d.ts +52 -0
  100. package/dist/preview/capture-screenshot.js +158 -0
  101. package/dist/preview/capture-screenshot.js.map +1 -0
  102. package/dist/preview/viewer-url.d.ts +82 -0
  103. package/dist/preview/viewer-url.js +128 -0
  104. package/dist/preview/viewer-url.js.map +1 -0
  105. package/dist/process/fault-barrier.d.ts +55 -0
  106. package/dist/process/fault-barrier.js +113 -0
  107. package/dist/process/fault-barrier.js.map +1 -0
  108. package/dist/resume/memory-progress-store.d.ts +39 -0
  109. package/dist/resume/memory-progress-store.js +82 -0
  110. package/dist/resume/memory-progress-store.js.map +1 -0
  111. package/dist/resume/memory-recent-app-store.d.ts +14 -0
  112. package/dist/resume/memory-recent-app-store.js +27 -0
  113. package/dist/resume/memory-recent-app-store.js.map +1 -0
  114. package/dist/resume/memory-turn-store.d.ts +18 -0
  115. package/dist/resume/memory-turn-store.js +73 -0
  116. package/dist/resume/memory-turn-store.js.map +1 -0
  117. package/dist/resume/progress-key.d.ts +21 -0
  118. package/dist/resume/progress-key.js +58 -0
  119. package/dist/resume/progress-key.js.map +1 -0
  120. package/dist/resume/stores.d.ts +14 -0
  121. package/dist/resume/stores.js +18 -0
  122. package/dist/resume/stores.js.map +1 -0
  123. package/dist/resume/types.d.ts +124 -0
  124. package/dist/resume/types.js +13 -0
  125. package/dist/resume/types.js.map +1 -0
  126. package/dist/sabs/agent-facing-text.d.ts +33 -0
  127. package/dist/sabs/agent-facing-text.js +125 -0
  128. package/dist/sabs/agent-facing-text.js.map +1 -0
  129. package/dist/sabs/browser-context.d.ts +53 -0
  130. package/dist/sabs/browser-context.js +91 -0
  131. package/dist/sabs/browser-context.js.map +1 -0
  132. package/dist/sabs/editor-client-methods.d.ts +147 -0
  133. package/dist/sabs/editor-client-methods.js +715 -0
  134. package/dist/sabs/editor-client-methods.js.map +1 -0
  135. package/dist/sabs/recent-tool-runs.d.ts +14 -0
  136. package/dist/sabs/recent-tool-runs.js +61 -0
  137. package/dist/sabs/recent-tool-runs.js.map +1 -0
  138. package/dist/sabs/session-peer.d.ts +351 -0
  139. package/dist/sabs/session-peer.js +2 -0
  140. package/dist/sabs/session-peer.js.map +1 -0
  141. package/dist/sabs/turn-collector.d.ts +152 -0
  142. package/dist/sabs/turn-collector.js +573 -0
  143. package/dist/sabs/turn-collector.js.map +1 -0
  144. package/dist/sabs/websocket-session-peer.d.ts +514 -0
  145. package/dist/sabs/websocket-session-peer.js +2487 -0
  146. package/dist/sabs/websocket-session-peer.js.map +1 -0
  147. package/dist/security/constant-time.d.ts +9 -0
  148. package/dist/security/constant-time.js +13 -0
  149. package/dist/security/constant-time.js.map +1 -0
  150. package/dist/server/client.d.ts +371 -0
  151. package/dist/server/client.js +572 -0
  152. package/dist/server/client.js.map +1 -0
  153. package/dist/server/identity-reads.d.ts +76 -0
  154. package/dist/server/identity-reads.js +209 -0
  155. package/dist/server/identity-reads.js.map +1 -0
  156. package/dist/start.d.ts +14 -0
  157. package/dist/start.js +75 -0
  158. package/dist/start.js.map +1 -0
  159. package/dist/telemetry/metrics.d.ts +32 -0
  160. package/dist/telemetry/metrics.js +57 -0
  161. package/dist/telemetry/metrics.js.map +1 -0
  162. package/dist/transports/mcp/admin-tools.d.ts +47 -0
  163. package/dist/transports/mcp/admin-tools.js +164 -0
  164. package/dist/transports/mcp/admin-tools.js.map +1 -0
  165. package/dist/transports/mcp/app-status-html.d.ts +15 -0
  166. package/dist/transports/mcp/app-status-html.js +563 -0
  167. package/dist/transports/mcp/app-status-html.js.map +1 -0
  168. package/dist/transports/mcp/decision-elicitation.d.ts +74 -0
  169. package/dist/transports/mcp/decision-elicitation.js +233 -0
  170. package/dist/transports/mcp/decision-elicitation.js.map +1 -0
  171. package/dist/transports/mcp/dispatch-probe.d.ts +24 -0
  172. package/dist/transports/mcp/dispatch-probe.js +48 -0
  173. package/dist/transports/mcp/dispatch-probe.js.map +1 -0
  174. package/dist/transports/mcp/format-tool-content.d.ts +25 -0
  175. package/dist/transports/mcp/format-tool-content.js +48 -0
  176. package/dist/transports/mcp/format-tool-content.js.map +1 -0
  177. package/dist/transports/mcp/mount.d.ts +9 -0
  178. package/dist/transports/mcp/mount.js +469 -0
  179. package/dist/transports/mcp/mount.js.map +1 -0
  180. package/dist/transports/mcp/progress-notifier.d.ts +39 -0
  181. package/dist/transports/mcp/progress-notifier.js +52 -0
  182. package/dist/transports/mcp/progress-notifier.js.map +1 -0
  183. package/package.json +72 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,87 @@
1
+ Superblocks Community Software License
2
+
3
+ This Superblocks Community License Agreement (the “Agreement”) sets forth the terms on which DayZero
4
+ Software, Inc. d/b/a Superblocks (“Superblocks”) makes available certain software made available by Superblocks
5
+ under this Agreement (the “Software”). BY INSTALLING, DOWNLOADING, ACCESSING, USING OR
6
+ DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO THE TERMS AND CONDITIONS OF THIS
7
+ AGREEMENT.IF YOU DO NOT AGREE TO SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE
8
+ SOFTWARE. IF YOU ARE RECEIVING THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU
9
+ REPRESENT AND WARRANT THAT YOU HAVE THE ACTUAL AUTHORITY TO AGREE TO THE
10
+ TERMS AND CONDITIONS OF THIS AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you,
11
+ an individual, or the entity on whose behalf you are receiving the Software.
12
+
13
+ 1. LICENSE GRANT AND CONDITIONS.
14
+
15
+ 1.1 License. Subject to the terms and conditions of this Agreement, Superblocks hereby grants to Licensee a
16
+ non-exclusive, royalty-free, worldwide, non-transferable, non-sublicenseable license during the term of this
17
+ Agreement to: (a) use the Software; (b) prepare modifications and derivative works of the Software; (c)
18
+ distribute the Software (including without limitation in source code or object code form); and (d) reproduce
19
+ copies of the Software (the “License”). Licensee is not granted the right to, and Licensee shall not, exercise the
20
+ License for an Excluded Purpose. For purposes of this Agreement, “Excluded Purpose” means making
21
+ available any software-as-a-service, platform-as-a-service, infrastructure-as-a-service or other similar online
22
+ service that competes with Superblocks’ products or services.
23
+
24
+ 1.2 Conditions. In consideration of the License, Licensee’s distribution of the Software is subject to the
25
+ following conditions:
26
+
27
+ a. Licensee must cause any Software modified by Licensee to carry prominent notices stating that Licensee
28
+ modified the Software.
29
+ b. On each Software copy, Licensee shall reproduce and not remove or alter all Superblocks or third party
30
+ copyright or other proprietary notices contained in the Software, and Licensee must provide the notice
31
+ below with each copy.
32
+
33
+ “This software is made available by DayZero Software, Inc. d/b/a Superblocks, under the terms of the
34
+ Superblocks Community License Agreement. © 2022 DayZero Software, Inc.”
35
+
36
+ 1.3 Licensee Modifications. Licensee may add its own copyright notices to modifications made by Licensee
37
+ and may provide additional or different license terms and conditions for use, reproduction, or distribution of
38
+ Licensee’s modifications. While redistributing the Software or modifications thereof, Licensee may choose to
39
+ offer, for a fee or free of charge, support, warranty, indemnity, or other obligations. Licensee, and not
40
+ Superblocks, will be responsible for any such obligations.
41
+
42
+ 1.4 No Sublicensing. The License does not include the right to sublicense the Software, however, each recipient
43
+ to which Licensee provides the Software may exercise the Licenses so long as such recipient agrees to the terms
44
+ and conditions of this Agreement.
45
+
46
+ 2. TERM AND TERMINATION. This Agreement will continue unless and until earlier terminated as set forth
47
+ herein. If Licensee breaches any of its conditions or obligations under this Agreement, this Agreement will
48
+ terminate automatically and the License will terminate automatically and permanently.
49
+
50
+ 3. INTELLECTUAL PROPERTY. As between the parties, Superblocks will retain all right, title, and interest in
51
+ the Software, and all intellectual property rights therein. Superblocks hereby reserves all rights not expressly
52
+ granted to Licensee in this Agreement. Superblocks hereby reserves all rights in its trademarks and service
53
+ marks, and no licenses therein are granted in this Agreement.
54
+
55
+ 4. DISCLAIMER. SUPERBLOCKS HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND
56
+ CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY
57
+ DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
58
+ PURPOSE, WITH RESPECT TO THE SOFTWARE.
59
+
60
+ 5. LIMITATION OF LIABILITY. SUPERBLOCKS WILL NOT BE LIABLE FOR ANY DAMAGES OF
61
+ ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL,
62
+ SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY
63
+ THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL APPLY TO
64
+ THE EXTENT PERMITTED BY APPLICABLE LAW.
65
+
66
+ 6. GENERAL.
67
+
68
+ 6.1  Governing Law. This Agreement will be governed by and interpreted in accordance with the laws of the
69
+ state of California, without reference to its conflict of laws principles. If Licensee is located within the United
70
+ States, all disputes arising out of this Agreement are subject to the exclusive jurisdiction of courts located in San
71
+ Mateo County, California. USA. If Licensee is located outside of the United States, any dispute, controversy or
72
+ claim arising out of or relating to this Agreement will be referred to and finally determined by arbitration in
73
+ accordance with the JAMS International Arbitration Rules. The tribunal will consist of one neutral arbitrator.
74
+ The place of arbitration will be Palo Alto, California. The language to be used in the arbitral proceedings will be
75
+ English. Judgment upon the award rendered by the arbitrator may be entered in any court having jurisdiction
76
+ thereof.
77
+
78
+ 6.2.  Assignment. Licensee may not assign its rights under this Agreement to any third party. Superblocks may
79
+ freely assign its rights under this Agreement to any third party.
80
+
81
+ 6.3.  Other.  This Agreement is the entire agreement between the parties regarding the subject matter hereof.
82
+ No amendment or modification of this Agreement will be valid or binding upon the parties unless made in
83
+ writing and signed by the duly authorized representatives of both parties. In the event that any provision,
84
+ including without limitation any condition, of this Agreement is held to be unenforceable, this Agreement and
85
+ all licenses and rights granted hereunder will immediately terminate. Waiver by Superblocks of a breach of any
86
+ provision of this Agreement or the failure by Superblocks to exercise any right hereunder will not be construed
87
+ as a waiver of any subsequent breach of that right or as a waiver of any other right.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # Gateway v0
2
+
3
+ Standalone Superblocks entry point for a **single MCP connector** (Admin + Builder)
4
+ over **stdio**, running as the already-logged-in Superblocks CLI user.
5
+
6
+ Builder tools (`start_app`, `import_app`, `edit_app`, `check_app_progress`,
7
+ `get_app`, `preview_app`, `publish_app`) plus customer Admin tools from
8
+ `@superblocksteam/mcp-server` share this process.
9
+
10
+ The MCP host owns process lifecycle: it spawns `superblocks gateway serve`.
11
+ There is no foreground HTTP `/mcp`, no OAuth resource server, and no linked-grant
12
+ exchange. Personal API keys here are the CLI session
13
+ (`~/.superblocks/auth.json` / `SUPERBLOCKS_AUTH_FILE` / `just worktree auth`).
14
+
15
+ Scope notes:
16
+
17
+ - In-memory stores only; no Redis (ENG-5594).
18
+ - CLI identity only. Linked MCP grants, static `GATEWAY_DEV_SUPERBLOCKS_API_KEY`,
19
+ and on-behalf-of exchange are not supported.
20
+ - Missing Playwright Chromium does not block start (ENG-5796). Screenshots fail
21
+ closed when Chromium is absent.
22
+ - No Slack wrapper (ENG-5596).
23
+ - Orchestrator URL is discovered from Server agent inventory, not configured here.
24
+
25
+ ## Internal review
26
+
27
+ ```bash
28
+ # Log in if needed (same CLI session the Gateway will use)
29
+ superblocks login
30
+
31
+ # Write a stdio MCP entry into the client config
32
+ superblocks gateway setup --client claude
33
+ # or: --client cursor / --client claude-desktop / --client generic
34
+
35
+ # Restart the MCP host. It spawns Gateway; do not run gateway serve yourself.
36
+ ```
37
+
38
+ `setup` writes an absolute spawn so the host does not depend on cwd.
39
+ Published `bin/run.js` is the MCP `command` (its `node` shebang applies).
40
+ Worktree `bin/dev.js` is launched with `tsx` and without `--watch`: the
41
+ dev shebang is a file-watcher, which would kill stdio on source edits and
42
+ corrupt JSON-RPC on stdout. When `SUPERBLOCKS_AUTH_FILE` or
43
+ `SUPERBLOCKS_BASE_URL` is set (worktree auth), those are copied into the MCP
44
+ `env` block.
45
+
46
+ Optional: `--with-screenshots` downloads Playwright Chromium for preview
47
+ captures. Omit it; start still succeeds.
48
+
49
+ ## Local run
50
+
51
+ The MCP host spawns Gateway. Do not run `gateway serve` in a TTY.
52
+
53
+ Against a remote Superblocks domain (EE / SaaS IR):
54
+
55
+ ```bash
56
+ cd packages/cli/packages/cli
57
+ ./bin/dev.js config set domain <host>
58
+ ./bin/dev.js login
59
+ ./bin/dev.js gateway setup --client claude
60
+ ```
61
+
62
+ Against a local control plane, start the stack first (`just up <worktree>`),
63
+ then login and `gateway setup` the same way.
64
+
65
+ `superblocks mcp serve` (stdio Admin-only) is deprecated; prefer `gateway setup`.
66
+
67
+ ## Worktree MCP (Cursor / Claude)
68
+
69
+ Until published packages are on PATH, point the MCP host at this checkout.
70
+ Log in and run setup from the worktree CLI (not a globally installed `superblocks`):
71
+
72
+ ```bash
73
+ cd packages/cli/packages/cli
74
+ ./bin/dev.js config set domain <host>
75
+ ./bin/dev.js login
76
+ ./bin/dev.js gateway setup --client cursor
77
+ # or: --client claude
78
+ ```
79
+
80
+ `setup` writes an absolute stdio spawn into the host config (`~/.cursor/mcp.json`
81
+ for Cursor, `~/.claude.json` for Claude Code):
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "superblocks": {
87
+ "command": "/absolute/path/to/tsx/cli.mjs",
88
+ "args": [
89
+ "/absolute/path/to/packages/cli/packages/cli/bin/dev.js",
90
+ "gateway",
91
+ "serve"
92
+ ],
93
+ "env": {
94
+ "SUPERBLOCKS_AUTH_FILE": "/absolute/path/to/worktree/.superblocks/auth.json",
95
+ "SUPERBLOCKS_BASE_URL": "https://your-control-plane"
96
+ }
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ `command` is `tsx` without `--watch`: the `bin/dev.js` shebang is a file
103
+ watcher, which would kill stdio on source edits and corrupt JSON-RPC on
104
+ stdout. `env` only copies the CLI session (`SUPERBLOCKS_AUTH_FILE`,
105
+ `SUPERBLOCKS_BASE_URL`). Do not add `SUPERBLOCKS_GATEWAY_FROM_SOURCE`.
106
+ Optional stderr tees (`2>> ~/.cursor/superblocks-gateway.err`) are host
107
+ specific; `setup` does not write them.
108
+
109
+ Restart the MCP host after `setup` and after every rebuild below.
110
+
111
+ ### Rebuild after source changes
112
+
113
+ Cursor MCP still goes through oclif `dist/index.js`. CLI esbuild inlines
114
+ `@superblocksteam/gateway`, so a Gateway `tsc` alone does not update the
115
+ process the host spawns.
116
+
117
+ | You changed | Rebuild |
118
+ | --------------------------------------------------------------- | ---------------------------------------------- |
119
+ | `packages/shared` (types Gateway imports, e.g. SocketHeartbeat) | `pnpm --filter @superblocksteam/shared build` |
120
+ | `packages/gateway/src` | `pnpm --filter @superblocksteam/gateway build` |
121
+ | Gateway, CLI serve wiring, or anything oclif esbuild inlines | `pnpm --filter @superblocksteam/cli build` |
122
+
123
+ A typical Gateway capture change is shared (if types moved), then Gateway,
124
+ then CLI. Then restart Cursor.
125
+
126
+ Proof the new bundle is live: Gateway stderr logs
127
+ `gateway live canvas capture uses libraryBrowserContext (testingEnabled does not gate it)`
128
+ at boot. A crash that `@superblocksteam/shared` does not export
129
+ `SocketHeartbeat` means shared `dist/` is stale.
130
+
131
+ ## Authentication
132
+
133
+ Gateway tools call the Superblocks control plane with the personal API key from
134
+ the CLI session. Log in first (`superblocks login`). There is no issuer env, no
135
+ consent page, and no second PAT.
136
+
137
+ ## Cloud-Prem laptop agent
138
+
139
+ Set `GATEWAY_LOCAL_AGENT=true` for a single-user corp laptop process. Stores are
140
+ always in-memory; suspended turns and progress cursors do not survive a restart.
141
+ `SUPERBLOCKS_SERVER_URL` (or `GATEWAY_SERVER_URL`) points at the in-VPC control
142
+ plane. The CLI session supplies identity.
143
+
144
+ Set `GATEWAY_ADMIN_TOOLS_ONLY=true` alongside `GATEWAY_LOCAL_AGENT=true` to
145
+ package only the customer Admin surface. Builder tools are not registered.
146
+
147
+ ## MCP tools
148
+
149
+ After `gateway setup`, restart Claude Code or Cursor and call `start_app`,
150
+ `edit_app`, `check_app_progress`, `get_app`, `preview_app`, and `publish_app`.
151
+ See `.env.example` for optional configuration.
152
+
153
+ ## Env
154
+
155
+ See `.env.example`. Stores are in-memory only. Identity comes from the CLI
156
+ session, not from these variables.
157
+
158
+ | Variable | Purpose |
159
+ | -------------------------- | ---------------------------------------------------------- |
160
+ | `SUPERBLOCKS_SERVER_URL` | Control plane URL (default from `auth.json` or localhost). |
161
+ | `GATEWAY_PROFILE_KEY` | Integration profile key (default `default`). |
162
+ | `GATEWAY_LOCAL_AGENT` | Cloud-Prem laptop agent mode. |
163
+ | `GATEWAY_ADMIN_TOOLS_ONLY` | Admin tools only; skip Builder surface. |
164
+ | `SUPERBLOCKS_AUTH_FILE` | Worktree-local CLI session (from `just worktree auth`). |
165
+ | `NODE_DEBUG=gateway` | Tool call stacks and conditional-flow logs on stderr. |
166
+
167
+ Gateway debug logs include tool names, result states, decision branches, and
168
+ entry-point stacks. They intentionally omit credentials, prompts, answers, and
169
+ result payloads. Run `superblocks gateway setup --client <client> --debug`, then
170
+ restart the MCP host. Re-run setup without `--debug` to turn them off.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Picks an orchestrator (agent) base URL the way the browser does: from the
3
+ * Server's agent inventory for the org, filtered by org agent type, Active
4
+ * status, and profile tags. Operators never set this URL.
5
+ */
6
+ export type OrchestratorAgentCandidate = {
7
+ status: string;
8
+ tags: Record<string, string[]>;
9
+ type: number;
10
+ url: string;
11
+ };
12
+ export type PickOrchestratorBaseUrlInput = {
13
+ agentType: number;
14
+ agents: OrchestratorAgentCandidate[];
15
+ profileKey: string;
16
+ };
17
+ /**
18
+ * Returns a single orchestrator base URL from Server-reported agents.
19
+ * Throws when none are eligible — same failure mode as the browser's
20
+ * "No active agent found".
21
+ */
22
+ export declare function pickOrchestratorBaseUrl(input: PickOrchestratorBaseUrlInput): string;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Picks an orchestrator (agent) base URL the way the browser does: from the
3
+ * Server's agent inventory for the org, filtered by org agent type, Active
4
+ * status, and profile tags. Operators never set this URL.
5
+ */
6
+ const ACTIVE_STATUS = "Active";
7
+ function matchesProfile(tags, profileKey) {
8
+ const profiles = tags.profile;
9
+ if (!profiles || profiles.length === 0) {
10
+ // Cloud sentinel and untagged agents are eligible for any profile.
11
+ return true;
12
+ }
13
+ return profiles.includes("*") || profiles.includes(profileKey);
14
+ }
15
+ function withTrailingSlash(url) {
16
+ return url.endsWith("/") ? url : `${url}/`;
17
+ }
18
+ /**
19
+ * Returns a single orchestrator base URL from Server-reported agents.
20
+ * Throws when none are eligible — same failure mode as the browser's
21
+ * "No active agent found".
22
+ */
23
+ export function pickOrchestratorBaseUrl(input) {
24
+ const eligible = input.agents.filter((candidate) => candidate.type === input.agentType &&
25
+ candidate.status === ACTIVE_STATUS &&
26
+ Boolean(candidate.url) &&
27
+ matchesProfile(candidate.tags ?? {}, input.profileKey));
28
+ if (eligible.length === 0) {
29
+ throw new Error(`No active agent found for agentType=${input.agentType} profile=${input.profileKey}`);
30
+ }
31
+ // Browser picks randomly among matches; stable first is fine for gateway.
32
+ const chosen = eligible[0];
33
+ if (!chosen) {
34
+ throw new Error(`No active agent found for agentType=${input.agentType} profile=${input.profileKey}`);
35
+ }
36
+ return withTrailingSlash(chosen.url);
37
+ }
38
+ //# sourceMappingURL=resolve-orchestrator-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-orchestrator-url.js","sourceRoot":"","sources":["../../src/agents/resolve-orchestrator-url.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B,SAAS,cAAc,CACrB,IAA8B,EAC9B,UAAkB;IAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,mEAAmE;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAmC;IAEnC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAClC,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,SAAS;QAClC,SAAS,CAAC,MAAM,KAAK,aAAa;QAClC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC;QACtB,cAAc,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,CACzD,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,UAAU,EAAE,CACrF,CAAC;IACJ,CAAC;IACD,0EAA0E;IAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,UAAU,EAAE,CACrF,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,11 @@
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;
@@ -0,0 +1,96 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-prompt.js","sourceRoot":"","sources":["../../src/capabilities/import-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { CaptureLibraryScreenshot } from "../capture/capture-library.js";
2
+ import type { GatewayConfig } from "../config.js";
3
+ import type { EventStore } from "../events/types.js";
4
+ import type { CapturePreviewScreenshot } from "../preview/capture-screenshot.js";
5
+ import type { CallerRef, ProgressStore, RecentAppStore, TurnStore } from "../resume/types.js";
6
+ import type { SessionPeer } from "../sabs/session-peer.js";
7
+ import type { SuperblocksServerClient } from "../server/client.js";
8
+ import type { CapabilityResult, CheckAppProgressInput, CheckAppProgressResult, EditAppInput, EditAppResult, GetAppInput, GetAppResult, ImportAppInput, ImportAppResult, PreviewAppInput, PreviewAppResult, Principal, ProgressEvent, PublishAppInput, PublishAppResult, StartAppInput, StartAppResult } from "./types.js";
9
+ export { IMPORT_ZIP_MAX_BYTES } from "./types.js";
10
+ export type CapabilityContext = {
11
+ /**
12
+ * Who is polling, for resume. Absent on one-shot capability calls that do
13
+ * not poll, in which case no cursor is kept.
14
+ */
15
+ caller?: CallerRef;
16
+ config: GatewayConfig;
17
+ /**
18
+ * Durable history of the live-edit session. This is what a caller reads
19
+ * when there is no local turn to ask — after a restart, on another replica,
20
+ * or from a channel that never started the build.
21
+ */
22
+ events?: EventStore;
23
+ /** Injected so pacing and stall thresholds are testable without real time. */
24
+ now?: () => number;
25
+ onProgress?: (event: ProgressEvent) => void;
26
+ principal: Principal;
27
+ /** Where each caller's place in the event stream is kept between calls. */
28
+ progressCursors?: ProgressStore;
29
+ recentApps: RecentAppStore;
30
+ /**
31
+ * Optional headless capture of the live library iframe (pitcherURL). Injected
32
+ * in tests; defaults to Playwright in the MCP transport. Distinct from
33
+ * {@link capturePreviewScreenshot} (deployed shell).
34
+ */
35
+ captureLibraryScreenshot?: CaptureLibraryScreenshot;
36
+ /**
37
+ * Optional headless capture used when Claude cannot openLink an https URL.
38
+ * Injected in tests; defaults to Playwright in the MCP transport.
39
+ */
40
+ capturePreviewScreenshot?: CapturePreviewScreenshot;
41
+ server: SuperblocksServerClient;
42
+ sessionPeer: SessionPeer;
43
+ /** The caller gave up on this call (an MCP cancellation, a closed request). */
44
+ signal?: AbortSignal;
45
+ turns: TurnStore;
46
+ };
47
+ export declare function startApp(ctx: CapabilityContext, input: StartAppInput): Promise<CapabilityResult<StartAppResult>>;
48
+ /**
49
+ * Creates a fullstack app, uploads the caller's archive as an app attachment,
50
+ * and hands Clark a migration prompt — the same path as the browser import
51
+ * wizard, without the sessionStorage hop.
52
+ */
53
+ export declare function importApp(ctx: CapabilityContext, input: ImportAppInput): Promise<CapabilityResult<ImportAppResult>>;
54
+ export declare function checkAppProgress(ctx: CapabilityContext, input: CheckAppProgressInput): Promise<CapabilityResult<CheckAppProgressResult>>;
55
+ export declare function editApp(ctx: CapabilityContext, input: EditAppInput): Promise<CapabilityResult<EditAppResult>>;
56
+ /**
57
+ * Shows the app's current work on a real URL without deploying it - the
58
+ * editor's Preview button, driven from here.
59
+ *
60
+ * Three steps, the same ones and in the same order as the editor: snapshot the
61
+ * live-edit state as a commit, make sure a build exists for that commit's
62
+ * content, and hand back the URL that serves it. Builds are keyed on content
63
+ * rather than on the commit, so previewing work that was already built (by an
64
+ * earlier preview, or by a publish) waits on that build instead of starting a
65
+ * second one.
66
+ */
67
+ export declare function previewApp(ctx: CapabilityContext, input: PreviewAppInput): Promise<CapabilityResult<PreviewAppResult>>;
68
+ /**
69
+ * Lovable-style lookup: editor URL always, preview URLs when a build can be
70
+ * ensured (default). Captures a screenshot whenever the preview is ready.
71
+ */
72
+ export declare function getApp(ctx: CapabilityContext, input: GetAppInput): Promise<CapabilityResult<GetAppResult>>;
73
+ export declare function publishApp(ctx: CapabilityContext, input: PublishAppInput): Promise<CapabilityResult<PublishAppResult>>;