trellis 3.2.3 → 3.2.4

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 (194) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +4 -0
  3. package/dist/better-sqlite-backend-CDYOAJDF.js +209 -0
  4. package/dist/boot-middleware-LBJX4N2S.js +9 -0
  5. package/dist/boot-middleware-PATBLD52.js +9 -0
  6. package/dist/bridge-G5DPW6TY.js +2361 -0
  7. package/dist/bridge-JSSPQPRH.js +2389 -0
  8. package/dist/bridge-LNXE4HAW.js +2389 -0
  9. package/dist/bridge-OAAXJWSA.js +2389 -0
  10. package/dist/bridge-SFS63RHC.js +2367 -0
  11. package/dist/bridge-U5TOUBVM.js +2389 -0
  12. package/dist/browser/index.js +12 -12
  13. package/dist/{chunk-KSU2GW22.js → chunk-276W52FK.js} +8 -0
  14. package/dist/{chunk-KFQGP6VL.js → chunk-2ESYSVXG.js} +15 -0
  15. package/dist/{chunk-L5N5PR2S.js → chunk-2WW2X2BR.js} +313 -77
  16. package/dist/chunk-3XCOAP6G.js +48 -0
  17. package/dist/chunk-53PDCTJ3.js +1856 -0
  18. package/dist/{chunk-N6MYZT4O.js → chunk-547FZFKO.js} +1 -1
  19. package/dist/{chunk-7DUMWO5L.js → chunk-7WVOPXJV.js} +3 -3
  20. package/dist/chunk-CMSFD6OV.js +11801 -0
  21. package/dist/{chunk-RSWUFTO2.js → chunk-CPUYCCLT.js} +2 -2
  22. package/dist/{chunk-4HYPLFJD.js → chunk-FA5TFVA5.js} +1 -1
  23. package/dist/{chunk-4XIVMVHC.js → chunk-G3XIHPSQ.js} +1 -1
  24. package/dist/{chunk-JHHEXEDM.js → chunk-GCQF75T4.js} +3 -3
  25. package/dist/{chunk-FKQO5A3H.js → chunk-GHG4H3AS.js} +2 -2
  26. package/dist/{chunk-GLM4HGN4.js → chunk-GRWQPKYK.js} +1 -1
  27. package/dist/{chunk-PZ4XYZ4J.js → chunk-GXA73CNC.js} +33 -8
  28. package/dist/{chunk-6GEZ6DN5.js → chunk-H6VTC5SS.js} +3 -3
  29. package/dist/{chunk-S3XLFZ27.js → chunk-IHHSOBJS.js} +1 -1
  30. package/dist/chunk-IJNC25UD.js +2243 -0
  31. package/dist/{chunk-VDAKEOML.js → chunk-J6OUIION.js} +1 -1
  32. package/dist/chunk-JAVAYMMS.js +6 -0
  33. package/dist/{chunk-S6GBJ2ZB.js → chunk-JCQQFLO5.js} +1 -1
  34. package/dist/{chunk-FWRS4CSC.js → chunk-KQG6ZYXP.js} +3 -3
  35. package/dist/chunk-KXAISKZT.js +119 -0
  36. package/dist/chunk-N3R74ZSR.js +7949 -0
  37. package/dist/{chunk-GU374KWZ.js → chunk-NLFRRGX6.js} +3 -3
  38. package/dist/{chunk-XMQ7G77X.js → chunk-OB4CMMX6.js} +1 -1
  39. package/dist/chunk-OKNASCZY.js +182 -0
  40. package/dist/chunk-ONOPPX5E.js +394 -0
  41. package/dist/chunk-QMSU2RAH.js +98 -0
  42. package/dist/{chunk-TCKXSOBP.js → chunk-RARKFVWU.js} +8 -1
  43. package/dist/{chunk-2AACZRII.js → chunk-SJWVDS5M.js} +751 -162
  44. package/dist/{chunk-SPSPV5BC.js → chunk-SZ3VAB5P.js} +159 -2
  45. package/dist/chunk-V2ASD6RQ.js +147 -0
  46. package/dist/{chunk-KQ4A2D2P.js → chunk-V4YCJDYL.js} +58 -38
  47. package/dist/{chunk-LNUIGRDZ.js → chunk-VWKLKLYB.js} +1 -1
  48. package/dist/chunk-W5PADCDF.js +1856 -0
  49. package/dist/{chunk-MLC5BUYO.js → chunk-WMERMSWI.js} +1 -1
  50. package/dist/chunk-WXAURJUD.js +1948 -0
  51. package/dist/chunk-YC5I32PS.js +147 -0
  52. package/dist/{chunk-VBYUTRXX.js → chunk-YKVB4LUQ.js} +3 -3
  53. package/dist/{chunk-NWSW5YNS.js → chunk-YPT6XMS4.js} +20 -50
  54. package/dist/cli/deploy-cli.d.ts.map +1 -1
  55. package/dist/cli/deploy-cli.js +43 -4
  56. package/dist/cli/gateway-deploy-cli.d.ts +19 -0
  57. package/dist/cli/gateway-deploy-cli.d.ts.map +1 -0
  58. package/dist/cli/index.d.ts.map +1 -1
  59. package/dist/cli/index.js +1360 -881
  60. package/dist/cli/lane.d.ts.map +1 -1
  61. package/dist/cli/protocol.d.ts +6 -0
  62. package/dist/cli/protocol.d.ts.map +1 -0
  63. package/dist/client/index.browser.js +2 -2
  64. package/dist/client/index.js +11 -11
  65. package/dist/client/sdk.browser.js +1 -1
  66. package/dist/client/sdk.js +2 -2
  67. package/dist/cms/index.js +1 -1
  68. package/dist/config-KMY6RRK3.js +19 -0
  69. package/dist/core/index.js +13 -13
  70. package/dist/core/kernel/boot-middleware.d.ts +1 -1
  71. package/dist/core/kernel/boot-middleware.d.ts.map +1 -1
  72. package/dist/core/kernel/schema-middleware.d.ts +2 -1
  73. package/dist/core/kernel/schema-middleware.d.ts.map +1 -1
  74. package/dist/core/kernel/trellis-kernel.d.ts +10 -10
  75. package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
  76. package/dist/core/persist/factory.js +2 -2
  77. package/dist/core/persist/sqljs-backend.js +2 -2
  78. package/dist/db/index.js +30 -25
  79. package/dist/decisions/index.js +4 -4
  80. package/dist/embeddings/index.js +2 -2
  81. package/dist/engine.d.ts +24 -6
  82. package/dist/engine.d.ts.map +1 -1
  83. package/dist/gateway-deploy-cli-4TU4V3QI.js +312 -0
  84. package/dist/gateway-deploy-cli-A4ISTDHJ.js +298 -0
  85. package/dist/gateway-deploy-cli-D3XTKJQJ.js +312 -0
  86. package/dist/gateway-deploy-cli-ECV3OQCN.js +305 -0
  87. package/dist/gateway-deploy-cli-JUHKVIJE.js +296 -0
  88. package/dist/gateway-deploy-cli-NSDW2JLT.js +310 -0
  89. package/dist/gateway-serve-CM5EAZ52.js +113 -0
  90. package/dist/import-AJLYHFIA.js +10 -0
  91. package/dist/index.js +11 -11
  92. package/dist/launch-explorer-FVX6ZABW.js +95 -0
  93. package/dist/links/index.js +2 -2
  94. package/dist/mcp/bridge.d.ts +45 -0
  95. package/dist/mcp/bridge.d.ts.map +1 -0
  96. package/dist/mcp/discovery.d.ts +15 -0
  97. package/dist/mcp/discovery.d.ts.map +1 -0
  98. package/dist/mcp/gateway-config.d.ts +20 -0
  99. package/dist/mcp/gateway-config.d.ts.map +1 -0
  100. package/dist/mcp/gateway-serve.d.ts +19 -0
  101. package/dist/mcp/gateway-serve.d.ts.map +1 -0
  102. package/dist/mcp/gateway-serve.js +119 -0
  103. package/dist/mcp/graph-summary.d.ts +47 -0
  104. package/dist/mcp/graph-summary.d.ts.map +1 -0
  105. package/dist/mcp/room-audit.d.ts +14 -0
  106. package/dist/mcp/room-audit.d.ts.map +1 -0
  107. package/dist/mcp/room-helpers.d.ts +43 -0
  108. package/dist/mcp/room-helpers.d.ts.map +1 -0
  109. package/dist/mcp/room-registry.d.ts +32 -0
  110. package/dist/mcp/room-registry.d.ts.map +1 -0
  111. package/dist/mcp/room.d.ts +28 -0
  112. package/dist/mcp/room.d.ts.map +1 -0
  113. package/dist/plugins/agent-memory/index.js +1 -1
  114. package/dist/plugins/idea-garden/index.js +1 -1
  115. package/dist/plugins/plan-approval/index.js +1 -1
  116. package/dist/plugins/proactive-watcher/index.js +1 -1
  117. package/dist/protocol/envelope.d.ts +30 -0
  118. package/dist/protocol/envelope.d.ts.map +1 -0
  119. package/dist/protocol/index.d.ts +3 -0
  120. package/dist/protocol/index.d.ts.map +1 -0
  121. package/dist/protocol/whereami.d.ts +33 -0
  122. package/dist/protocol/whereami.d.ts.map +1 -0
  123. package/dist/query-KHDDIR5G.js +31 -0
  124. package/dist/react/index.js +1 -1
  125. package/dist/react/realtime.js +1 -1
  126. package/dist/react/schema-hooks.js +5 -5
  127. package/dist/realtime/index.js +3 -3
  128. package/dist/realtime/relay-server.d.ts.map +1 -1
  129. package/dist/realtime/room.d.ts.map +1 -1
  130. package/dist/realtime.bundle.js +2 -0
  131. package/dist/relay-server-BT6DCJ7F.js +12 -0
  132. package/dist/relay-server-MPQVGNQU.js +12 -0
  133. package/dist/relay-server-PAPW2EWC.js +12 -0
  134. package/dist/remote-manager-6ERQUBSL.js +224 -0
  135. package/dist/remote-manager-G665WWYY.js +224 -0
  136. package/dist/remote-manager-HJTEZ4OF.js +224 -0
  137. package/dist/remote-manager-NYP2Y5UR.js +224 -0
  138. package/dist/remote-manager-WGLCAMMC.js +224 -0
  139. package/dist/scaffold/write.d.ts.map +1 -1
  140. package/dist/schema/index.js +1 -1
  141. package/dist/server/cors.d.ts.map +1 -1
  142. package/dist/server/deploy-gateway.d.ts +27 -0
  143. package/dist/server/deploy-gateway.d.ts.map +1 -0
  144. package/dist/server/deploy.d.ts.map +1 -1
  145. package/dist/server/deploy.js +3 -2
  146. package/dist/server/discovery-mcp-gateway.d.ts +13 -0
  147. package/dist/server/discovery-mcp-gateway.d.ts.map +1 -0
  148. package/dist/server/index.js +38 -31
  149. package/dist/server/mcp-gateway.d.ts +27 -0
  150. package/dist/server/mcp-gateway.d.ts.map +1 -0
  151. package/dist/server/mcp-oauth-metadata.d.ts +31 -0
  152. package/dist/server/mcp-oauth-metadata.d.ts.map +1 -0
  153. package/dist/server/node-adapter.d.ts +7 -0
  154. package/dist/server/node-adapter.d.ts.map +1 -1
  155. package/dist/server/node-adapter.js +2 -2
  156. package/dist/server/realtime.d.ts.map +1 -1
  157. package/dist/server/server.d.ts +8 -0
  158. package/dist/server/server.d.ts.map +1 -1
  159. package/dist/server/streamable-mcp-gateway.d.ts +12 -0
  160. package/dist/server/streamable-mcp-gateway.d.ts.map +1 -0
  161. package/dist/server/usage-meter.d.ts +11 -0
  162. package/dist/server/usage-meter.d.ts.map +1 -1
  163. package/dist/server-4VEZHXXS.js +23 -0
  164. package/dist/{server-OGVWNDNK.js → server-556BMK4C.js} +1 -1
  165. package/dist/server-FQT2VYRE.js +23 -0
  166. package/dist/server-HGZE4ECC.js +23 -0
  167. package/dist/server-J4JKEAMH.js +23 -0
  168. package/dist/server-LXPM5TFR.js +23 -0
  169. package/dist/server-POB4NEUX.js +18 -0
  170. package/dist/server-VJKAPGPG.js +23 -0
  171. package/dist/server-YHS3XIIG.js +23 -0
  172. package/dist/server-ZHTPWPXS.js +23 -0
  173. package/dist/sprites-NC6D7YZS.js +27 -0
  174. package/dist/svelte/index.js +3 -3
  175. package/dist/svelte/schema-hooks.js +4 -4
  176. package/dist/sync/index.js +4 -4
  177. package/dist/tenancy-2SZTP4UD.js +16 -0
  178. package/dist/tenancy-7MTSESMJ.js +16 -0
  179. package/dist/tenancy-U4E7ZEAG.js +16 -0
  180. package/dist/vcs/decompose.d.ts.map +1 -1
  181. package/dist/vcs/index.js +5 -5
  182. package/dist/vcs/lane-disk-materialize.d.ts +11 -0
  183. package/dist/vcs/lane-disk-materialize.d.ts.map +1 -0
  184. package/dist/vcs/lane-worktree.d.ts +21 -0
  185. package/dist/vcs/lane-worktree.d.ts.map +1 -0
  186. package/dist/vcs/store.d.ts +28 -0
  187. package/dist/vcs/store.d.ts.map +1 -0
  188. package/dist/vcs/types.d.ts +5 -0
  189. package/dist/vcs/types.d.ts.map +1 -1
  190. package/dist/vm-config-YZRJ3KUB.js +21 -0
  191. package/dist/vue/index.js +3 -3
  192. package/dist/vue/schema-hooks.js +4 -4
  193. package/package.json +4 -3
  194. package/dist/chunk-GFZCJ4EH.js +0 -108
@@ -0,0 +1,296 @@
1
+ import {
2
+ gatewayConfigPath,
3
+ listRegisteredRooms,
4
+ writeGatewayConfig
5
+ } from "./chunk-OA7HD3UA.js";
6
+ import "./chunk-UZRUP7QW.js";
7
+ import {
8
+ DeployNameError,
9
+ SPRITE_PUBLIC_HTTP_PORT,
10
+ buildDeployUrl,
11
+ validateDeployName
12
+ } from "./chunk-3XCOAP6G.js";
13
+ import {
14
+ SPRITE_ENSURE_BUN_SH,
15
+ assertSpriteCli,
16
+ ensureSprite,
17
+ ensureSpritePublicAccess,
18
+ resolveSpritePublicUrl,
19
+ runSpriteCopy,
20
+ runSpriteExec
21
+ } from "./chunk-CAG4FULI.js";
22
+ import "./chunk-JA7AIHRK.js";
23
+ import "./chunk-2ESYSVXG.js";
24
+
25
+ // src/cli/gateway-deploy-cli.ts
26
+ import chalk from "chalk";
27
+
28
+ // src/server/deploy-gateway.ts
29
+ import { execFile } from "child_process";
30
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
31
+ import { dirname, join, resolve } from "path";
32
+ import { fileURLToPath } from "url";
33
+ import { promisify } from "util";
34
+ var GATEWAY_REMOTE_DIR = "/home/sprite/trellis-mcp-gateway";
35
+ var GATEWAY_SERVICE = "trellis-mcp-gateway";
36
+ async function deployMcpGateway(opts) {
37
+ const { configDir = ".", onProgress = () => {
38
+ } } = opts;
39
+ const listenPort = opts.port ?? SPRITE_PUBLIC_HTTP_PORT;
40
+ const name = validateDeployName(opts.name);
41
+ const publicUrl = (opts.publicUrl ?? "https://mcp.trellis.computer").replace(
42
+ /\/$/,
43
+ ""
44
+ );
45
+ const rooms = buildRoomsManifest(configDir, opts.roomsFile);
46
+ onProgress(`Room registry: ${rooms.length} room(s)`);
47
+ if (opts.stub) {
48
+ const url2 = buildDeployUrl(name);
49
+ onProgress("Stub deploy \u2014 skipping Sprites provisioning");
50
+ writeGatewayConfig(
51
+ {
52
+ url: url2,
53
+ publicUrl,
54
+ spriteName: name,
55
+ deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
56
+ port: listenPort
57
+ },
58
+ configDir
59
+ );
60
+ writeRoomsFile(configDir, rooms);
61
+ return { url: url2, publicUrl, name, roomCount: rooms.length };
62
+ }
63
+ onProgress("Checking Sprites CLI...");
64
+ await assertSpriteCli();
65
+ const tmpDir = resolve(configDir, ".trellis-deploy-gateway");
66
+ if (!existsSync(tmpDir)) mkdirSync(tmpDir, { recursive: true });
67
+ const entrypoint = join(tmpDir, "gateway-entry.ts");
68
+ writeFileSync(
69
+ entrypoint,
70
+ generateGatewayEntrypoint({ port: listenPort, publicUrl })
71
+ );
72
+ onProgress("Bundling gateway with Bun...");
73
+ const bundlePath = join(tmpDir, "gateway.js");
74
+ await runBun([
75
+ "build",
76
+ entrypoint,
77
+ "--outfile",
78
+ bundlePath,
79
+ "--target",
80
+ "bun",
81
+ "--format",
82
+ "esm"
83
+ ]);
84
+ onProgress(`Ensuring Sprite: ${name}...`);
85
+ await ensureSprite(name);
86
+ onProgress("Configuring public URL...");
87
+ await ensureSpritePublicAccess(name);
88
+ const url = await resolveSpritePublicUrl(name);
89
+ onProgress("Uploading gateway bundle + room registry...");
90
+ await runSpriteExec(name, `mkdir -p ${GATEWAY_REMOTE_DIR}`);
91
+ await runSpriteCopy(bundlePath, name, `${GATEWAY_REMOTE_DIR}/gateway.js`);
92
+ const roomsPath = join(tmpDir, "rooms.json");
93
+ writeFileSync(roomsPath, JSON.stringify(rooms, null, 2) + "\n", "utf8");
94
+ await runSpriteCopy(roomsPath, name, `${GATEWAY_REMOTE_DIR}/.trellis-rooms.json`);
95
+ onProgress("Ensuring Bun is installed...");
96
+ const bunPath = await runSpriteExec(name, SPRITE_ENSURE_BUN_SH);
97
+ if (!bunPath.includes("bun")) {
98
+ throw new Error(
99
+ `Bun install failed on sprite ${name}: ${bunPath || "(no output)"}`
100
+ );
101
+ }
102
+ onProgress("Starting gateway (sprite-env service)...");
103
+ const bun = bunPath.trim().split("\n").pop().trim();
104
+ await runSpriteExec(
105
+ name,
106
+ `
107
+ export PATH="$HOME/.bun/bin:$PATH"
108
+ ENV="/.sprite/bin/sprite-env"
109
+ BUN="${bun}"
110
+ $ENV services delete ${GATEWAY_SERVICE} 2>/dev/null || true
111
+ $ENV services create ${GATEWAY_SERVICE} \\
112
+ --cmd "$BUN" \\
113
+ --args run,gateway.js \\
114
+ --dir ${GATEWAY_REMOTE_DIR} \\
115
+ --http-port ${listenPort} \\
116
+ --no-stream
117
+ `.trim()
118
+ );
119
+ onProgress("Waiting for health check...");
120
+ await waitForHealth(url, 6e4);
121
+ writeGatewayConfig(
122
+ {
123
+ url,
124
+ publicUrl,
125
+ spriteName: name,
126
+ deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
127
+ port: listenPort
128
+ },
129
+ configDir
130
+ );
131
+ writeRoomsFile(configDir, rooms);
132
+ try {
133
+ const { trackSprite } = await import("./vm-config-YZRJ3KUB.js");
134
+ trackSprite(name, { url, hasTrellis: false });
135
+ } catch {
136
+ }
137
+ return { url, publicUrl, name, roomCount: rooms.length };
138
+ }
139
+ function buildRoomsManifest(configDir, roomsFile) {
140
+ const byUrl = /* @__PURE__ */ new Map();
141
+ for (const room of listRegisteredRooms({ configDir })) {
142
+ byUrl.set(room.url, room);
143
+ }
144
+ if (roomsFile && existsSync(roomsFile)) {
145
+ try {
146
+ const extra = JSON.parse(readFileSync(roomsFile, "utf8"));
147
+ const list = Array.isArray(extra) ? extra : extra.rooms ?? [];
148
+ for (const room of list) {
149
+ if (room.name && room.url) {
150
+ byUrl.set(room.url, {
151
+ ...room,
152
+ mcpUrl: room.mcpUrl ?? `${room.url.replace(/\/$/, "")}/mcp`,
153
+ source: room.source ?? "registry"
154
+ });
155
+ }
156
+ }
157
+ } catch {
158
+ }
159
+ }
160
+ return [...byUrl.values()].sort((a, b) => a.name.localeCompare(b.name));
161
+ }
162
+ function writeRoomsFile(configDir, rooms) {
163
+ const path = resolve(configDir, ".trellis-rooms.json");
164
+ writeFileSync(path, JSON.stringify(rooms, null, 2) + "\n", "utf8");
165
+ }
166
+ function resolveGatewayImport() {
167
+ const root = process.env.TRELLIS_NODE_ROOT?.trim();
168
+ if (root) {
169
+ const js2 = join(root, "dist/mcp/gateway-serve.js");
170
+ const ts2 = join(root, "src/mcp/gateway-serve.ts");
171
+ if (existsSync(js2)) return js2.replace(/\\/g, "/");
172
+ return ts2.replace(/\\/g, "/");
173
+ }
174
+ const here = dirname(fileURLToPath(import.meta.url));
175
+ const js = join(here, "..", "mcp", "gateway-serve.js");
176
+ const ts = join(here, "..", "mcp", "gateway-serve.ts");
177
+ if (existsSync(js)) return js.replace(/\\/g, "/");
178
+ return ts.replace(/\\/g, "/");
179
+ }
180
+ function generateGatewayEntrypoint(opts) {
181
+ const mod = resolveGatewayImport();
182
+ return `
183
+ import { startGatewayServer } from '${mod}';
184
+
185
+ process.env.TRELLIS_MCP_GATEWAY_PUBLIC_URL = '${opts.publicUrl}';
186
+ process.env.TRELLIS_ROOM_REGISTRY = '${GATEWAY_REMOTE_DIR}/.trellis-rooms.json';
187
+
188
+ await startGatewayServer({
189
+ port: ${opts.port},
190
+ configDir: '${GATEWAY_REMOTE_DIR}',
191
+ publicUrl: '${opts.publicUrl}',
192
+ });
193
+
194
+ console.log('Trellis MCP gateway listening on port ${opts.port}');
195
+ console.log('Public URL: ${opts.publicUrl}');
196
+ `;
197
+ }
198
+ async function waitForHealth(url, timeoutMs) {
199
+ const deadline = Date.now() + timeoutMs;
200
+ const healthUrl = `${url.replace(/\/$/, "")}/health`;
201
+ let lastStatus = 0;
202
+ while (Date.now() < deadline) {
203
+ try {
204
+ const res = await fetch(healthUrl);
205
+ lastStatus = res.status;
206
+ if (res.ok) {
207
+ const body = await res.json();
208
+ if (body.service === "trellis-mcp-gateway") return;
209
+ }
210
+ } catch {
211
+ }
212
+ await new Promise((r) => setTimeout(r, 2e3));
213
+ }
214
+ throw new Error(
215
+ `Gateway health check timed out (${healthUrl}${lastStatus ? `, last status ${lastStatus}` : ""})`
216
+ );
217
+ }
218
+ async function runBun(args) {
219
+ const execFileAsync = promisify(execFile);
220
+ try {
221
+ await execFileAsync("bun", args);
222
+ } catch (err) {
223
+ throw new Error(
224
+ `bun ${args[0]} failed (exit ${err.code ?? "?"}): ${err.stderr ?? err.message}`
225
+ );
226
+ }
227
+ }
228
+
229
+ // src/cli/gateway-deploy-cli.ts
230
+ function printGatewayDeploySuccess(result, configDir, stub) {
231
+ const spriteHost = new URL(result.url).hostname;
232
+ console.log("");
233
+ console.log(
234
+ chalk.green(
235
+ stub ? "\u2713 Stub gateway deploy \u2014 config written (no Sprite provisioned)" : "\u2713 Trellis MCP discovery gateway deployed"
236
+ )
237
+ );
238
+ console.log(chalk.dim(` Sprite: ${result.name}`));
239
+ console.log(chalk.dim(` Origin: ${result.url}`));
240
+ console.log(chalk.dim(` Public: ${result.publicUrl}`));
241
+ console.log(chalk.dim(` Rooms: ${result.roomCount}`));
242
+ console.log(chalk.dim(` Config: ${gatewayConfigPath(configDir)}`));
243
+ console.log("");
244
+ console.log(chalk.bold("MCP (use public URL in Cursor):"));
245
+ console.log(chalk.cyan(` ${result.publicUrl}/mcp`));
246
+ console.log("");
247
+ console.log(chalk.bold("DNS (mcp.trellis.computer):"));
248
+ console.log(
249
+ chalk.dim(` CNAME ${new URL(result.publicUrl).hostname} \u2192 ${spriteHost}`)
250
+ );
251
+ console.log(
252
+ chalk.dim(
253
+ " Or ALIAS/redirect at your DNS provider until Sprites custom domains land."
254
+ )
255
+ );
256
+ console.log("");
257
+ console.log(chalk.bold("Until DNS propagates, use the Sprites origin:"));
258
+ console.log(chalk.cyan(` ${result.url}/mcp`));
259
+ console.log("");
260
+ console.log(chalk.bold("Cursor:"));
261
+ console.log(
262
+ chalk.cyan(
263
+ ` { "url": "${result.publicUrl}/mcp" } // or ${result.url}/mcp`
264
+ )
265
+ );
266
+ }
267
+ async function runGatewayDeployCli(opts) {
268
+ const configDir = opts.configDir ?? ".";
269
+ const port = opts.port === void 0 ? void 0 : typeof opts.port === "string" ? parseInt(opts.port, 10) : opts.port;
270
+ const label = opts.stub ? "Stub gateway deploy" : "Deploying MCP gateway";
271
+ console.log(chalk.bold(`${label}: ${opts.name}...`));
272
+ try {
273
+ const result = await deployMcpGateway({
274
+ name: opts.name,
275
+ publicUrl: opts.publicUrl,
276
+ port,
277
+ configDir,
278
+ roomsFile: opts.roomsFile,
279
+ stub: !!opts.stub,
280
+ onProgress: (msg) => console.log(chalk.dim(` ${msg}`))
281
+ });
282
+ printGatewayDeploySuccess(result, configDir, !!opts.stub);
283
+ } catch (err) {
284
+ if (err instanceof DeployNameError) {
285
+ console.error(chalk.red(`Invalid name: ${err.message}`));
286
+ process.exit(1);
287
+ }
288
+ const message = err instanceof Error ? err.message : String(err);
289
+ console.error(chalk.red(`Gateway deploy failed: ${message}`));
290
+ process.exit(1);
291
+ }
292
+ }
293
+ export {
294
+ printGatewayDeploySuccess,
295
+ runGatewayDeployCli
296
+ };
@@ -0,0 +1,310 @@
1
+ import {
2
+ DeployNameError,
3
+ SPRITE_PUBLIC_HTTP_PORT,
4
+ buildDeployUrl,
5
+ validateDeployName
6
+ } from "./chunk-3XCOAP6G.js";
7
+ import {
8
+ SPRITE_ENSURE_BUN_SH,
9
+ assertSpriteCli,
10
+ ensureSprite,
11
+ ensureSpritePublicAccess,
12
+ resolveSpritePublicUrl,
13
+ runSpriteCopy,
14
+ runSpriteExec
15
+ } from "./chunk-CAG4FULI.js";
16
+ import {
17
+ gatewayConfigPath,
18
+ listRegisteredRooms,
19
+ writeGatewayConfig
20
+ } from "./chunk-V2ASD6RQ.js";
21
+ import "./chunk-UZRUP7QW.js";
22
+ import "./chunk-JA7AIHRK.js";
23
+ import "./chunk-2ESYSVXG.js";
24
+
25
+ // src/cli/gateway-deploy-cli.ts
26
+ import chalk from "chalk";
27
+
28
+ // src/server/deploy-gateway.ts
29
+ import { execFile } from "child_process";
30
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
31
+ import { dirname, join, resolve } from "path";
32
+ import { fileURLToPath } from "url";
33
+ import { promisify } from "util";
34
+ var GATEWAY_REMOTE_DIR = "/home/sprite/trellis-mcp-gateway";
35
+ var GATEWAY_SERVICE = "trellis-mcp-gateway";
36
+ async function deployMcpGateway(opts) {
37
+ const { configDir = ".", onProgress = () => {
38
+ } } = opts;
39
+ const listenPort = opts.port ?? SPRITE_PUBLIC_HTTP_PORT;
40
+ const name = validateDeployName(opts.name);
41
+ const publicUrl = (opts.publicUrl ?? "https://mcp.trellis.computer").replace(
42
+ /\/$/,
43
+ ""
44
+ );
45
+ const rooms = buildRoomsManifest(configDir, opts.roomsFile);
46
+ onProgress(`Room registry: ${rooms.length} room(s)`);
47
+ if (opts.stub) {
48
+ const url2 = buildDeployUrl(name);
49
+ onProgress("Stub deploy \u2014 skipping Sprites provisioning");
50
+ writeGatewayConfig(
51
+ {
52
+ url: url2,
53
+ publicUrl,
54
+ spriteName: name,
55
+ deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
56
+ port: listenPort
57
+ },
58
+ configDir
59
+ );
60
+ writeRoomsFile(configDir, rooms);
61
+ return { url: url2, publicUrl, name, roomCount: rooms.length };
62
+ }
63
+ onProgress("Checking Sprites CLI...");
64
+ await assertSpriteCli();
65
+ const tmpDir = resolve(configDir, ".trellis-deploy-gateway");
66
+ if (!existsSync(tmpDir)) mkdirSync(tmpDir, { recursive: true });
67
+ const entrypoint = join(tmpDir, "gateway-entry.ts");
68
+ writeFileSync(
69
+ entrypoint,
70
+ generateGatewayEntrypoint({ port: listenPort, publicUrl })
71
+ );
72
+ onProgress("Bundling gateway with Bun...");
73
+ const bundlePath = join(tmpDir, "gateway.js");
74
+ await runBun([
75
+ "build",
76
+ entrypoint,
77
+ "--outfile",
78
+ bundlePath,
79
+ "--target",
80
+ "bun",
81
+ "--format",
82
+ "esm"
83
+ ]);
84
+ onProgress(`Ensuring Sprite: ${name}...`);
85
+ await ensureSprite(name);
86
+ onProgress("Configuring public URL...");
87
+ await ensureSpritePublicAccess(name);
88
+ const url = await resolveSpritePublicUrl(name);
89
+ onProgress("Uploading gateway bundle + room registry...");
90
+ await runSpriteExec(name, `mkdir -p ${GATEWAY_REMOTE_DIR}`);
91
+ await runSpriteCopy(bundlePath, name, `${GATEWAY_REMOTE_DIR}/gateway.js`);
92
+ const roomsPath = join(tmpDir, "rooms.json");
93
+ writeFileSync(roomsPath, JSON.stringify(rooms, null, 2) + "\n", "utf8");
94
+ await runSpriteCopy(roomsPath, name, `${GATEWAY_REMOTE_DIR}/.trellis-rooms.json`);
95
+ onProgress("Ensuring Bun is installed...");
96
+ const bunPath = await runSpriteExec(name, SPRITE_ENSURE_BUN_SH);
97
+ if (!bunPath.includes("bun")) {
98
+ throw new Error(
99
+ `Bun install failed on sprite ${name}: ${bunPath || "(no output)"}`
100
+ );
101
+ }
102
+ onProgress("Starting gateway (sprite-env service)...");
103
+ const bun = bunPath.trim().split("\n").pop().trim();
104
+ await runSpriteExec(
105
+ name,
106
+ `
107
+ export PATH="$HOME/.bun/bin:$PATH"
108
+ ENV="/.sprite/bin/sprite-env"
109
+ BUN="${bun}"
110
+ $ENV services delete ${GATEWAY_SERVICE} 2>/dev/null || true
111
+ $ENV services create ${GATEWAY_SERVICE} \\
112
+ --cmd "$BUN" \\
113
+ --args run,gateway.js \\
114
+ --dir ${GATEWAY_REMOTE_DIR} \\
115
+ --http-port ${listenPort} \\
116
+ --no-stream
117
+ `.trim()
118
+ );
119
+ onProgress("Waiting for health check...");
120
+ await waitForHealth(url, 6e4);
121
+ writeGatewayConfig(
122
+ {
123
+ url,
124
+ publicUrl,
125
+ spriteName: name,
126
+ deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
127
+ port: listenPort
128
+ },
129
+ configDir
130
+ );
131
+ writeRoomsFile(configDir, rooms);
132
+ try {
133
+ const { trackSprite } = await import("./vm-config-YZRJ3KUB.js");
134
+ trackSprite(name, { url, hasTrellis: false });
135
+ } catch {
136
+ }
137
+ return { url, publicUrl, name, roomCount: rooms.length };
138
+ }
139
+ function buildRoomsManifest(configDir, roomsFile) {
140
+ const byUrl = /* @__PURE__ */ new Map();
141
+ for (const room of listRegisteredRooms({ configDir })) {
142
+ byUrl.set(room.url, room);
143
+ }
144
+ if (roomsFile && existsSync(roomsFile)) {
145
+ try {
146
+ const extra = JSON.parse(readFileSync(roomsFile, "utf8"));
147
+ const list = Array.isArray(extra) ? extra : extra.rooms ?? [];
148
+ for (const room of list) {
149
+ if (room.name && room.url) {
150
+ byUrl.set(room.url, {
151
+ ...room,
152
+ mcpUrl: room.mcpUrl ?? `${room.url.replace(/\/$/, "")}/mcp`,
153
+ source: room.source ?? "registry"
154
+ });
155
+ }
156
+ }
157
+ } catch {
158
+ }
159
+ }
160
+ return [...byUrl.values()].sort((a, b) => a.name.localeCompare(b.name));
161
+ }
162
+ function writeRoomsFile(configDir, rooms) {
163
+ const path = resolve(configDir, ".trellis-rooms.json");
164
+ writeFileSync(path, JSON.stringify(rooms, null, 2) + "\n", "utf8");
165
+ }
166
+ function resolveGatewayImport() {
167
+ const here = dirname(fileURLToPath(import.meta.url));
168
+ const packageRoots = [
169
+ resolve(here, ".."),
170
+ resolve(here, "..", "..")
171
+ ];
172
+ const tried = [];
173
+ for (const packageRoot of packageRoots) {
174
+ const candidates = [
175
+ join(packageRoot, "dist", "mcp", "gateway-serve.js"),
176
+ join(packageRoot, "src", "mcp", "gateway-serve.ts")
177
+ ];
178
+ for (const candidate of candidates) {
179
+ tried.push(candidate);
180
+ if (existsSync(candidate)) {
181
+ return resolve(candidate).replace(/\\/g, "/");
182
+ }
183
+ }
184
+ }
185
+ throw new Error(
186
+ `gateway-serve module not found (tried: ${tried.join(", ")})`
187
+ );
188
+ }
189
+ function generateGatewayEntrypoint(opts) {
190
+ const mod = resolveGatewayImport();
191
+ return `
192
+ import { startGatewayServer } from '${mod}';
193
+
194
+ process.env.TRELLIS_MCP_GATEWAY_PUBLIC_URL = '${opts.publicUrl}';
195
+ process.env.TRELLIS_ROOM_REGISTRY = '${GATEWAY_REMOTE_DIR}/.trellis-rooms.json';
196
+
197
+ await startGatewayServer({
198
+ port: ${opts.port},
199
+ configDir: '${GATEWAY_REMOTE_DIR}',
200
+ publicUrl: '${opts.publicUrl}',
201
+ });
202
+
203
+ console.log('Trellis MCP gateway listening on port ${opts.port}');
204
+ console.log('Public URL: ${opts.publicUrl}');
205
+ `;
206
+ }
207
+ async function waitForHealth(url, timeoutMs) {
208
+ const deadline = Date.now() + timeoutMs;
209
+ const healthUrl = `${url.replace(/\/$/, "")}/health`;
210
+ let lastStatus = 0;
211
+ while (Date.now() < deadline) {
212
+ try {
213
+ const res = await fetch(healthUrl);
214
+ lastStatus = res.status;
215
+ if (res.ok) {
216
+ const body = await res.json();
217
+ if (body.service === "trellis-mcp-gateway") return;
218
+ }
219
+ } catch {
220
+ }
221
+ await new Promise((r) => setTimeout(r, 2e3));
222
+ }
223
+ throw new Error(
224
+ `Gateway health check timed out (${healthUrl}${lastStatus ? `, last status ${lastStatus}` : ""})`
225
+ );
226
+ }
227
+ async function runBun(args) {
228
+ const execFileAsync = promisify(execFile);
229
+ try {
230
+ await execFileAsync("bun", args);
231
+ } catch (err) {
232
+ throw new Error(
233
+ `bun ${args[0]} failed (exit ${err.code ?? "?"}): ${err.stderr ?? err.message}`
234
+ );
235
+ }
236
+ }
237
+
238
+ // src/cli/gateway-deploy-cli.ts
239
+ function printGatewayDeploySuccess(result, configDir, stub) {
240
+ const spriteHost = new URL(result.url).hostname;
241
+ console.log("");
242
+ console.log(
243
+ chalk.green(
244
+ stub ? "\u2713 Stub gateway deploy \u2014 config written (no Sprite provisioned)" : "\u2713 Trellis MCP discovery gateway deployed"
245
+ )
246
+ );
247
+ console.log(chalk.dim(` Sprite: ${result.name}`));
248
+ console.log(chalk.dim(` Origin: ${result.url}`));
249
+ console.log(chalk.dim(` Public: ${result.publicUrl}`));
250
+ console.log(chalk.dim(` Rooms: ${result.roomCount}`));
251
+ console.log(chalk.dim(` Config: ${gatewayConfigPath(configDir)}`));
252
+ console.log("");
253
+ console.log(chalk.bold("MCP (use public URL in Cursor):"));
254
+ console.log(chalk.cyan(` ${result.publicUrl}/gateway/mcp`));
255
+ console.log(
256
+ chalk.dim(
257
+ " On Sprites, /gateway/mcp is canonical (platform reserves /mcp)."
258
+ )
259
+ );
260
+ console.log("");
261
+ console.log(chalk.bold("DNS (mcp.trellis.computer):"));
262
+ console.log(
263
+ chalk.dim(` CNAME ${new URL(result.publicUrl).hostname} \u2192 ${spriteHost}`)
264
+ );
265
+ console.log(
266
+ chalk.dim(
267
+ " Or ALIAS/redirect at your DNS provider until Sprites custom domains land."
268
+ )
269
+ );
270
+ console.log("");
271
+ console.log(chalk.bold("Until DNS propagates, use the Sprites origin:"));
272
+ console.log(chalk.cyan(` ${result.url}/mcp`));
273
+ console.log("");
274
+ console.log(chalk.bold("Cursor:"));
275
+ console.log(
276
+ chalk.cyan(
277
+ ` { "url": "${result.publicUrl}/mcp" } // or ${result.url}/mcp`
278
+ )
279
+ );
280
+ }
281
+ async function runGatewayDeployCli(opts) {
282
+ const configDir = opts.configDir ?? ".";
283
+ const port = opts.port === void 0 ? void 0 : typeof opts.port === "string" ? parseInt(opts.port, 10) : opts.port;
284
+ const label = opts.stub ? "Stub gateway deploy" : "Deploying MCP gateway";
285
+ console.log(chalk.bold(`${label}: ${opts.name}...`));
286
+ try {
287
+ const result = await deployMcpGateway({
288
+ name: opts.name,
289
+ publicUrl: opts.publicUrl,
290
+ port,
291
+ configDir,
292
+ roomsFile: opts.roomsFile,
293
+ stub: !!opts.stub,
294
+ onProgress: (msg) => console.log(chalk.dim(` ${msg}`))
295
+ });
296
+ printGatewayDeploySuccess(result, configDir, !!opts.stub);
297
+ } catch (err) {
298
+ if (err instanceof DeployNameError) {
299
+ console.error(chalk.red(`Invalid name: ${err.message}`));
300
+ process.exit(1);
301
+ }
302
+ const message = err instanceof Error ? err.message : String(err);
303
+ console.error(chalk.red(`Gateway deploy failed: ${message}`));
304
+ process.exit(1);
305
+ }
306
+ }
307
+ export {
308
+ printGatewayDeploySuccess,
309
+ runGatewayDeployCli
310
+ };