withruntime 0.11.2 → 0.14.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.
- package/BLAXEL.md +2 -2
- package/COMPATIBILITY.md +74 -9
- package/DAYTONA.md +33 -5
- package/E2B.md +85 -24
- package/README.md +11 -10
- package/README.src.md +10 -9
- package/VERCEL.md +43 -5
- package/compatibility-lock.json +58 -49
- package/dist/billing-cli.d.ts +1 -1
- package/dist/billing-cli.js +85 -5
- package/dist/blaxel/errors.d.ts +14 -0
- package/dist/blaxel/errors.js +29 -0
- package/dist/blaxel/index.d.ts +2 -2
- package/dist/blaxel/index.js +4 -4
- package/dist/blaxel/interpreter.d.ts +2 -5
- package/dist/blaxel/sandbox.d.ts +15 -6
- package/dist/blaxel/sandbox.js +64 -8
- package/dist/blaxel/snapshot.d.ts +4 -0
- package/dist/blaxel/snapshot.js +4 -0
- package/dist/cli/logs.d.ts +21 -0
- package/dist/cli/logs.js +188 -0
- package/dist/cli-extras.d.ts +3 -3
- package/dist/cli-extras.js +17 -12
- package/dist/cli-words.d.ts +10 -1
- package/dist/cli-words.js +18 -0
- package/dist/cli.d.ts +22 -3
- package/dist/cli.js +647 -273
- package/dist/client.d.ts +2 -4
- package/dist/client.js +27 -11
- package/dist/cloudflare/errors.d.ts +143 -0
- package/dist/cloudflare/errors.js +167 -0
- package/dist/cloudflare/index.d.ts +175 -6
- package/dist/cloudflare/index.js +416 -26
- package/dist/cloudflare/interpreter.d.ts +119 -0
- package/dist/cloudflare/interpreter.js +223 -0
- package/dist/cloudflare/streams.d.ts +38 -0
- package/dist/cloudflare/streams.js +145 -0
- package/dist/cloudflare/watch.d.ts +9 -0
- package/dist/cloudflare/watch.js +24 -0
- package/dist/codesandbox/index.d.ts +216 -28
- package/dist/codesandbox/index.js +478 -78
- package/dist/compat/core.d.ts +18 -0
- package/dist/compat/core.js +29 -0
- package/dist/compat/files.d.ts +1 -0
- package/dist/compat/files.js +25 -5
- package/dist/credentials.d.ts +3 -0
- package/dist/credentials.js +15 -0
- package/dist/daytona/computer-use.d.ts +13 -4
- package/dist/daytona/computer-use.js +66 -8
- package/dist/daytona/daytona.d.ts +7 -1
- package/dist/daytona/daytona.js +31 -4
- package/dist/daytona/errors.d.ts +11 -0
- package/dist/daytona/errors.js +18 -0
- package/dist/daytona/filesystem.js +2 -1
- package/dist/daytona/image.d.ts +13 -9
- package/dist/daytona/image.js +18 -12
- package/dist/daytona/index.d.ts +1 -1
- package/dist/daytona/sandbox.d.ts +8 -2
- package/dist/daytona/sandbox.js +16 -2
- package/dist/domains/index.d.ts +9 -0
- package/dist/domains/index.js +10 -0
- package/dist/e2b/commands.d.ts +1 -1
- package/dist/e2b/commands.js +6 -7
- package/dist/e2b/errors.d.ts +17 -0
- package/dist/e2b/errors.js +40 -1
- package/dist/e2b/index.d.ts +2 -2
- package/dist/e2b/index.js +1 -1
- package/dist/e2b/sandbox.d.ts +28 -22
- package/dist/e2b/sandbox.js +34 -8
- package/dist/e2b/unsupported.js +1 -1
- package/dist/errors.d.ts +11 -2
- package/dist/errors.js +17 -5
- package/dist/freestyle/index.d.ts +285 -37
- package/dist/freestyle/index.js +656 -144
- package/dist/identity.d.ts +3 -0
- package/dist/identity.js +27 -0
- package/dist/images/index.d.ts +9 -0
- package/dist/images/index.js +10 -0
- package/dist/index.d.ts +3 -1
- package/dist/ips/index.d.ts +9 -0
- package/dist/ips/index.js +10 -0
- package/dist/jobs/index.d.ts +9 -0
- package/dist/jobs/index.js +10 -0
- package/dist/keys.js +2 -0
- package/dist/login.js +2 -0
- package/dist/machine.d.ts +27 -4
- package/dist/machine.js +46 -14
- package/dist/mcp.js +144 -20
- package/dist/modal/index.d.ts +339 -61
- package/dist/modal/index.js +781 -121
- package/dist/network-cli.d.ts +3 -1
- package/dist/network-cli.js +78 -36
- package/dist/networks/index.d.ts +11 -0
- package/dist/networks/index.js +10 -0
- package/dist/ports/index.d.ts +9 -0
- package/dist/ports/index.js +10 -0
- package/dist/product-names.d.ts +52 -0
- package/dist/product-names.js +164 -0
- package/dist/product-renames.d.ts +103 -0
- package/dist/product-renames.js +189 -0
- package/dist/products/api-keys.d.ts +73 -0
- package/dist/products/api-keys.js +23 -0
- package/dist/products/apps.d.ts +157 -0
- package/dist/products/apps.js +60 -0
- package/dist/products/balancers.d.ts +87 -0
- package/dist/products/balancers.js +8 -0
- package/dist/products/billing.d.ts +41 -0
- package/dist/products/billing.js +13 -0
- package/dist/products/browser.d.ts +10 -0
- package/dist/products/browsers.d.ts +71 -0
- package/dist/products/browsers.js +102 -0
- package/dist/products/builds.d.ts +156 -0
- package/dist/products/builds.js +227 -0
- package/dist/products/index.d.ts +5 -16
- package/dist/products/index.js +5 -14
- package/dist/products/jobs.d.ts +19 -2
- package/dist/products/jobs.js +28 -11
- package/dist/products/logs.d.ts +245 -0
- package/dist/products/logs.js +274 -0
- package/dist/products/network-products.d.ts +38 -7
- package/dist/products/network-products.js +31 -18
- package/dist/products/observability.d.ts +8 -2
- package/dist/products/private-network.js +1 -1
- package/dist/products/queues.d.ts +149 -0
- package/dist/products/queues.js +213 -0
- package/dist/products/referrals.d.ts +21 -7
- package/dist/products/referrals.js +3 -3
- package/dist/products/resources.d.ts +54 -0
- package/dist/products/resources.js +122 -0
- package/dist/products/secrets.d.ts +29 -3
- package/dist/products/secrets.js +47 -18
- package/dist/products/signed-requests.d.ts +21 -0
- package/dist/products/signed-requests.js +11 -0
- package/dist/products/streams.d.ts +73 -0
- package/dist/products/streams.js +17 -0
- package/dist/products/switching.d.ts +35 -7
- package/dist/products/switching.js +4 -3
- package/dist/products/volumes.d.ts +6 -0
- package/dist/record-cli.d.ts +23 -0
- package/dist/record-cli.js +308 -0
- package/dist/renamed-products.d.ts +38 -0
- package/dist/renamed-products.js +34 -0
- package/dist/runloop/index.d.ts +9 -2
- package/dist/runloop/index.js +29 -8
- package/dist/runloop/sdk.d.ts +131 -0
- package/dist/runloop/sdk.js +167 -0
- package/dist/sandbox.d.ts +7 -2
- package/dist/sandbox.js +41 -11
- package/dist/sandboxes/index.d.ts +11 -0
- package/dist/sandboxes/index.js +12 -0
- package/dist/snapshots/index.d.ts +9 -0
- package/dist/snapshots/index.js +11 -0
- package/dist/snapshots.d.ts +7 -4
- package/dist/sprites/index.d.ts +343 -31
- package/dist/sprites/index.js +866 -84
- package/dist/ssh.d.ts +1 -1
- package/dist/ssh.js +11 -11
- package/dist/terminal.d.ts +24 -0
- package/dist/terminal.js +32 -0
- package/dist/transport.d.ts +18 -1
- package/dist/transport.js +80 -6
- package/dist/tunnel.js +1 -1
- package/dist/types.d.ts +71 -4
- package/dist/vercel/sandbox.d.ts +1 -1
- package/dist/vercel/sandbox.js +6 -4
- package/dist/vercel/snapshot.js +10 -2
- package/dist/volumes/index.d.ts +9 -0
- package/dist/volumes/index.js +10 -0
- package/dist/wallet.d.ts +4 -1
- package/dist/wallet.js +2 -1
- package/package.json +48 -14
package/dist/network-cli.d.ts
CHANGED
|
@@ -8,8 +8,10 @@ type Args = {
|
|
|
8
8
|
positional: string[];
|
|
9
9
|
flags: Map<string, string[]>;
|
|
10
10
|
};
|
|
11
|
-
export declare const NETWORK_PRODUCTS: readonly ["
|
|
11
|
+
export declare const NETWORK_PRODUCTS: readonly ["domains", "ports", "ips", "wireguard", "networks"];
|
|
12
12
|
export type NetworkProduct = (typeof NETWORK_PRODUCTS)[number];
|
|
13
|
+
/** The command each is typed as: WireGuard is inside networks. */
|
|
14
|
+
export declare const NETWORK_COMMAND: Record<NetworkProduct, string>;
|
|
13
15
|
export declare const NETWORK_HELP: Record<NetworkProduct, string>;
|
|
14
16
|
export declare function networkProductCommand(product: NetworkProduct, argv: string[], args: Args, out: Out, client: () => Promise<Runtime>): Promise<number>;
|
|
15
17
|
export {};
|
package/dist/network-cli.js
CHANGED
|
@@ -14,9 +14,17 @@ function fundingState(value) {
|
|
|
14
14
|
? `Funded until ${value.fundedUntil}.`
|
|
15
15
|
: "Funding active; no deadline reported.";
|
|
16
16
|
}
|
|
17
|
-
export const NETWORK_PRODUCTS = ["
|
|
17
|
+
export const NETWORK_PRODUCTS = ["domains", "ports", "ips", "wireguard", "networks"];
|
|
18
|
+
/** The command each is typed as: WireGuard is inside networks. */
|
|
19
|
+
export const NETWORK_COMMAND = {
|
|
20
|
+
domains: "domains",
|
|
21
|
+
ports: "ports",
|
|
22
|
+
ips: "ips",
|
|
23
|
+
wireguard: "networks wireguard",
|
|
24
|
+
networks: "networks",
|
|
25
|
+
};
|
|
18
26
|
export const NETWORK_HELP = {
|
|
19
|
-
|
|
27
|
+
domains: `runtime domains <command>
|
|
20
28
|
|
|
21
29
|
add <hostname> <sandbox> <port> Serve a sandbox's port at your own hostname, with HTTPS
|
|
22
30
|
Prints the DNS records to set: a TXT that proves the
|
|
@@ -27,7 +35,7 @@ export const NETWORK_HELP = {
|
|
|
27
35
|
rm <hostname> Stop serving it
|
|
28
36
|
Needs a kept top-up. The first visit gets the certificate, in a few seconds.
|
|
29
37
|
`,
|
|
30
|
-
|
|
38
|
+
ports: `runtime ports <command>
|
|
31
39
|
|
|
32
40
|
open <sandbox> <port> A public TCP port to a port in the sandbox: Postgres,
|
|
33
41
|
Redis, a game server, anything that is not HTTP
|
|
@@ -36,7 +44,7 @@ export const NETWORK_HELP = {
|
|
|
36
44
|
close <portId> Close one, its open connections too
|
|
37
45
|
Needs a kept top-up. TCP, carried as it is: use your service's own password and TLS.
|
|
38
46
|
`,
|
|
39
|
-
|
|
47
|
+
ips: `runtime ips <command>
|
|
40
48
|
|
|
41
49
|
reserve [--ipv6] A dedicated outbound address: every sandbox of your
|
|
42
50
|
account sends from it, for allow-lists
|
|
@@ -44,7 +52,7 @@ export const NETWORK_HELP = {
|
|
|
44
52
|
release <addressId> Give it back; sandboxes use the shared addresses again
|
|
45
53
|
Needs credit on the account.
|
|
46
54
|
`,
|
|
47
|
-
|
|
55
|
+
wireguard: `runtime networks wireguard <command>
|
|
48
56
|
|
|
49
57
|
create [--subnet 10.250.0.0/16] A WireGuard tunnel from your network into your sandboxes
|
|
50
58
|
get The tunnel, its peers, and each sandbox's address in it
|
|
@@ -58,7 +66,9 @@ export const NETWORK_HELP = {
|
|
|
58
66
|
peer rm <peerId> Remove it; its tunnel ends within seconds
|
|
59
67
|
--route: your own ranges behind the peer that sandboxes may reach. Needs a kept top-up.
|
|
60
68
|
`,
|
|
61
|
-
|
|
69
|
+
networks: `runtime networks <command>
|
|
70
|
+
wireguard <command> A WireGuard tunnel from your network into your
|
|
71
|
+
sandboxes: runtime networks wireguard help
|
|
62
72
|
|
|
63
73
|
upstream-proxy set <http://host:port|https://host:port> [--secret NAME] [--host <host>]...
|
|
64
74
|
Send your sandboxes' outbound connections through your
|
|
@@ -76,6 +86,12 @@ export const NETWORK_HELP = {
|
|
|
76
86
|
private off They stop; open connections between them are cut
|
|
77
87
|
private status On or off
|
|
78
88
|
Only your own sandboxes answer. Needs a kept top-up; free.
|
|
89
|
+
|
|
90
|
+
signed-requests on Your sandboxes can get Runtime's Web Bot Auth signature
|
|
91
|
+
for outbound HTTP requests (https://withruntime.com/docs/egress)
|
|
92
|
+
signed-requests off New signatures stop at once; given ones expire within 5 minutes
|
|
93
|
+
signed-requests status On or off
|
|
94
|
+
Needs credit on the account; free.
|
|
79
95
|
`,
|
|
80
96
|
};
|
|
81
97
|
function usage(product, message) {
|
|
@@ -83,7 +99,7 @@ function usage(product, message) {
|
|
|
83
99
|
message,
|
|
84
100
|
code: "usage",
|
|
85
101
|
status: 0,
|
|
86
|
-
hint: `Run \`${named("runtime")} ${product} help\`.`,
|
|
102
|
+
hint: `Run \`${named("runtime")} ${NETWORK_COMMAND[product]} help\`.`,
|
|
87
103
|
});
|
|
88
104
|
}
|
|
89
105
|
function table(rows) {
|
|
@@ -127,7 +143,7 @@ async function prepareOutput(path, privateKey) {
|
|
|
127
143
|
try {
|
|
128
144
|
const info = await lstat(path);
|
|
129
145
|
if (!info.isFile() || info.isSymbolicLink())
|
|
130
|
-
throw usage("
|
|
146
|
+
throw usage("wireguard", "The output must be a regular file, not a directory or symbolic link.");
|
|
131
147
|
}
|
|
132
148
|
catch (error) {
|
|
133
149
|
if (error.code !== "ENOENT")
|
|
@@ -181,7 +197,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
181
197
|
return 0;
|
|
182
198
|
}
|
|
183
199
|
const runtime = await client();
|
|
184
|
-
if (product === "
|
|
200
|
+
if (product === "domains") {
|
|
185
201
|
const records = (domain) => table([
|
|
186
202
|
["TYPE", "NAME", "VALUE"],
|
|
187
203
|
...domain.records.map((record) => [record.type, record.name, record.value]),
|
|
@@ -214,7 +230,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
214
230
|
String(d.port),
|
|
215
231
|
]),
|
|
216
232
|
])
|
|
217
|
-
: named("No domains. Add one: runtime
|
|
233
|
+
: named("No domains. Add one: runtime domains add app.example.com <sandbox> 3000"), all);
|
|
218
234
|
return 0;
|
|
219
235
|
}
|
|
220
236
|
case "get": {
|
|
@@ -230,7 +246,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
230
246
|
}
|
|
231
247
|
}
|
|
232
248
|
}
|
|
233
|
-
if (product === "
|
|
249
|
+
if (product === "ports") {
|
|
234
250
|
switch (verb) {
|
|
235
251
|
case "open": {
|
|
236
252
|
const opened = await runtime.ports.open({
|
|
@@ -251,7 +267,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
251
267
|
["ID", "CONNECT", "SANDBOX", "PORT"],
|
|
252
268
|
...all.map((p) => [p.id, p.connect, p.sandboxId, String(p.port)]),
|
|
253
269
|
])
|
|
254
|
-
: named("No open ports. Open one: runtime
|
|
270
|
+
: named("No open ports. Open one: runtime ports open <sandbox> 5432"), all);
|
|
255
271
|
return 0;
|
|
256
272
|
}
|
|
257
273
|
case "close":
|
|
@@ -262,10 +278,10 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
262
278
|
}
|
|
263
279
|
}
|
|
264
280
|
}
|
|
265
|
-
if (product === "
|
|
281
|
+
if (product === "ips") {
|
|
266
282
|
switch (verb) {
|
|
267
283
|
case "reserve": {
|
|
268
|
-
const reserved = await runtime.
|
|
284
|
+
const reserved = await runtime.ips.reserve({ family: has("ipv6") ? 6 : 4 });
|
|
269
285
|
if (!out.json)
|
|
270
286
|
out.error(reserved.funded === true
|
|
271
287
|
? `Every sandbox of this account sends from it. ${fundingState(reserved)}`
|
|
@@ -275,24 +291,24 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
275
291
|
}
|
|
276
292
|
case "ls":
|
|
277
293
|
case "list": {
|
|
278
|
-
const all = await runtime.
|
|
294
|
+
const all = await runtime.ips.list();
|
|
279
295
|
print(all.length
|
|
280
296
|
? table([
|
|
281
297
|
["ID", "ADDRESS", "FAMILY", "FUNDING"],
|
|
282
298
|
...all.map((a) => [a.id, a.address, `IPv${a.family}`, fundingState(a)]),
|
|
283
299
|
])
|
|
284
|
-
: named("No dedicated address. Reserve one: runtime
|
|
300
|
+
: named("No dedicated address. Reserve one: runtime ips reserve"), all);
|
|
285
301
|
return 0;
|
|
286
302
|
}
|
|
287
303
|
case "release":
|
|
288
304
|
case "rm": {
|
|
289
|
-
const gone = await runtime.
|
|
305
|
+
const gone = await runtime.ips.release(need(rest[0], "an address id"));
|
|
290
306
|
print(`Released ${gone.address}.`, gone);
|
|
291
307
|
return 0;
|
|
292
308
|
}
|
|
293
309
|
}
|
|
294
310
|
}
|
|
295
|
-
if (product === "
|
|
311
|
+
if (product === "wireguard") {
|
|
296
312
|
const view = (tunnel) => [
|
|
297
313
|
fundingState(tunnel),
|
|
298
314
|
`Endpoint ${tunnel.endpoint}, subnet ${tunnel.subnet}, gateway key ${tunnel.gatewayPublicKey ?? "(starting)"}`,
|
|
@@ -302,7 +318,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
302
318
|
["PEER", "NAME", "ADDRESS", "ROUTES"],
|
|
303
319
|
...tunnel.peers.map((p) => [p.id, p.name, p.address, p.routes.join(",") || "-"]),
|
|
304
320
|
])
|
|
305
|
-
: named("No peers. Add one: runtime
|
|
321
|
+
: named("No peers. Add one: runtime networks wireguard peer add office --route 10.0.0.0/16"),
|
|
306
322
|
"",
|
|
307
323
|
tunnel.sandboxes.length
|
|
308
324
|
? table([
|
|
@@ -313,19 +329,19 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
313
329
|
].join("\n");
|
|
314
330
|
switch (verb) {
|
|
315
331
|
case "create": {
|
|
316
|
-
const made = await runtime.
|
|
332
|
+
const made = await runtime.networks.wireguard.create(flag("subnet") ? { subnet: flag("subnet") } : {});
|
|
317
333
|
print(view(made), made);
|
|
318
334
|
return 0;
|
|
319
335
|
}
|
|
320
336
|
case "get":
|
|
321
337
|
case "ls": {
|
|
322
|
-
const found = await runtime.
|
|
338
|
+
const found = await runtime.networks.wireguard.get();
|
|
323
339
|
print(view(found), found);
|
|
324
340
|
return 0;
|
|
325
341
|
}
|
|
326
342
|
case "rm":
|
|
327
343
|
case "delete": {
|
|
328
|
-
const gone = await runtime.
|
|
344
|
+
const gone = await runtime.networks.wireguard.delete();
|
|
329
345
|
print(`Deleted the tunnel ${gone.id}.`, gone);
|
|
330
346
|
return 0;
|
|
331
347
|
}
|
|
@@ -343,14 +359,14 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
343
359
|
const prepared = path ? await prepareOutput(path, pair?.privateKey) : undefined;
|
|
344
360
|
try {
|
|
345
361
|
const answer = action === "add"
|
|
346
|
-
? await runtime.
|
|
362
|
+
? await runtime.networks.wireguard.addPeer({
|
|
347
363
|
name: argument,
|
|
348
364
|
publicKey,
|
|
349
365
|
routes: args.flags.get("route") ?? [],
|
|
350
366
|
})
|
|
351
|
-
: await runtime.
|
|
367
|
+
: await runtime.networks.wireguard.rotatePeer(argument, { publicKey });
|
|
352
368
|
const configReady = answer.configReady ?? !!answer.config;
|
|
353
|
-
const draftHint = "Keep this file: it preserves your private key. Read runtime
|
|
369
|
+
const draftHint = "Keep this file: it preserves your private key. Read runtime networks wireguard get when the gateway is ready, replace PublicKey in [Peer] with gatewayPublicKey, then run wg-quick up.";
|
|
354
370
|
// Older servers returned no config while the gateway was starting.
|
|
355
371
|
// Preserve the locally generated key in a draft rather than discard it.
|
|
356
372
|
const supplied = answer.config ??
|
|
@@ -361,7 +377,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
361
377
|
`Address = ${answer.peer.address}/32`,
|
|
362
378
|
"",
|
|
363
379
|
"[Peer]",
|
|
364
|
-
`PublicKey = ${answer.tunnel.gatewayPublicKey ?? "<gatewayPublicKey from runtime
|
|
380
|
+
`PublicKey = ${answer.tunnel.gatewayPublicKey ?? "<gatewayPublicKey from runtime networks wireguard get>"}`,
|
|
365
381
|
`Endpoint = ${answer.tunnel.endpoint}`,
|
|
366
382
|
`AllowedIPs = ${answer.tunnel.subnet}`,
|
|
367
383
|
"PersistentKeepalive = 25",
|
|
@@ -398,7 +414,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
398
414
|
}
|
|
399
415
|
}
|
|
400
416
|
if (action === "rm" || action === "remove") {
|
|
401
|
-
const after = await runtime.
|
|
417
|
+
const after = await runtime.networks.wireguard.removePeer(need(rest[1], "a peer id"));
|
|
402
418
|
print(`Removed. ${after.peers.length} peer(s) left.`, after);
|
|
403
419
|
return 0;
|
|
404
420
|
}
|
|
@@ -406,32 +422,58 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
406
422
|
}
|
|
407
423
|
}
|
|
408
424
|
}
|
|
409
|
-
if (product === "
|
|
425
|
+
if (product === "networks" && verb === "private") {
|
|
410
426
|
const describe = (state) => state.enabled
|
|
411
427
|
? "On: your sandboxes reach each other at <name>.sandbox.internal:<port> over TCP."
|
|
412
428
|
: state.allowed
|
|
413
|
-
? "Off. Turn it on: runtime
|
|
429
|
+
? "Off. Turn it on: runtime networks private on"
|
|
414
430
|
: "Off. Reaching your sandboxes by name needs a kept top-up.";
|
|
415
431
|
switch (rest[0]) {
|
|
416
432
|
case "on":
|
|
417
433
|
case "off": {
|
|
418
|
-
const state = await runtime.
|
|
434
|
+
const state = await runtime.networks.private.set({ enabled: rest[0] === "on" });
|
|
419
435
|
print(state.enabled ? describe(state) : "Off. Open connections between your sandboxes are cut.", state);
|
|
420
436
|
return 0;
|
|
421
437
|
}
|
|
422
438
|
case "status":
|
|
423
439
|
case undefined: {
|
|
424
|
-
const state = await runtime.
|
|
440
|
+
const state = await runtime.networks.private.get();
|
|
425
441
|
print(describe(state), state);
|
|
426
442
|
return 0;
|
|
427
443
|
}
|
|
428
444
|
}
|
|
429
445
|
throw usage(product, "private takes on, off or status.");
|
|
430
446
|
}
|
|
431
|
-
if (product === "
|
|
447
|
+
if (product === "networks" && verb === "signed-requests") {
|
|
448
|
+
const describe = (state) => state.enabled
|
|
449
|
+
? "On. Each site's headers: https://withruntime.com/docs/egress"
|
|
450
|
+
: state.allowed
|
|
451
|
+
? "Off. Turn it on: runtime networks signed-requests on"
|
|
452
|
+
: state.why === "no_credit"
|
|
453
|
+
? "Needs credit on the account."
|
|
454
|
+
: `Not available (${state.why ?? "unknown"}).`;
|
|
455
|
+
switch (rest[0]) {
|
|
456
|
+
case "on":
|
|
457
|
+
case "off": {
|
|
458
|
+
const state = await runtime.networks.signedRequests.set({ enabled: rest[0] === "on" });
|
|
459
|
+
print(state.enabled
|
|
460
|
+
? describe(state)
|
|
461
|
+
: "Off. New signatures stop at once; ones already given expire within 5 minutes.", state);
|
|
462
|
+
return 0;
|
|
463
|
+
}
|
|
464
|
+
case "status":
|
|
465
|
+
case undefined: {
|
|
466
|
+
const state = await runtime.networks.signedRequests.get();
|
|
467
|
+
print(describe(state), state);
|
|
468
|
+
return 0;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
throw usage(product, "signed-requests takes on, off or status.");
|
|
472
|
+
}
|
|
473
|
+
if (product === "networks") {
|
|
432
474
|
if (verb !== "upstream-proxy")
|
|
433
|
-
throw usage(product, `Unknown
|
|
434
|
-
const upstream = runtime.
|
|
475
|
+
throw usage(product, `Unknown networks command ${verb}.`);
|
|
476
|
+
const upstream = runtime.networks.upstreamProxy;
|
|
435
477
|
const describe = (proxy) => [
|
|
436
478
|
`Outbound connections${proxy.hosts?.length ? ` to ${proxy.hosts.join(", ")}` : ""} go through ${proxy.url}.`,
|
|
437
479
|
...(proxy.secret ? [`${proxy.secret} is sent as Proxy-Authorization.`] : []),
|
|
@@ -462,7 +504,7 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
462
504
|
catch (error) {
|
|
463
505
|
if (!(error instanceof RuntimeError) || error.code !== "not_found")
|
|
464
506
|
throw error;
|
|
465
|
-
print(named("No upstream proxy. Set one: runtime
|
|
507
|
+
print(named("No upstream proxy. Set one: runtime networks upstream-proxy set http://proxy.example.com:3128"), null);
|
|
466
508
|
return 0;
|
|
467
509
|
}
|
|
468
510
|
print(describe(found), found);
|
|
@@ -477,5 +519,5 @@ export async function networkProductCommand(product, argv, args, out, client) {
|
|
|
477
519
|
}
|
|
478
520
|
throw usage(product, "upstream-proxy takes set, get or remove.");
|
|
479
521
|
}
|
|
480
|
-
throw usage(product, `Unknown ${product} command ${verb}.`);
|
|
522
|
+
throw usage(product, `Unknown ${NETWORK_COMMAND[product]} command ${verb}.`);
|
|
481
523
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** `withruntime/networks`: Networks alone. The account's networks: WireGuard in, sandboxes by name, your proxy out.
|
|
2
|
+
*
|
|
3
|
+
* import { networks } from "withruntime/networks";
|
|
4
|
+
* const client = networks(); // RUNTIME_API_KEY, or this machine's saved connection
|
|
5
|
+
*/
|
|
6
|
+
import { Runtime, type RuntimeOptions } from "../client.js";
|
|
7
|
+
export type { Tunnel, TunnelPeer, TunnelPeerCreated, UpstreamProxy, SetUpstreamProxy, } from "../products/network-products.js";
|
|
8
|
+
export type { PrivateNetwork } from "../products/private-network.js";
|
|
9
|
+
export type { SignedRequests } from "../products/signed-requests.js";
|
|
10
|
+
/** `runtime.networks` of a client made with `options`. */
|
|
11
|
+
export declare function networks(options?: RuntimeOptions): Runtime["networks"];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** `withruntime/networks`: Networks alone. The account's networks: WireGuard in, sandboxes by name, your proxy out.
|
|
2
|
+
*
|
|
3
|
+
* import { networks } from "withruntime/networks";
|
|
4
|
+
* const client = networks(); // RUNTIME_API_KEY, or this machine's saved connection
|
|
5
|
+
*/
|
|
6
|
+
import { Runtime } from "../client.js";
|
|
7
|
+
/** `runtime.networks` of a client made with `options`. */
|
|
8
|
+
export function networks(options) {
|
|
9
|
+
return new Runtime(options).networks;
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `withruntime/ports`: Ports alone. A public TCP port to a sandbox's port.
|
|
2
|
+
*
|
|
3
|
+
* import { ports } from "withruntime/ports";
|
|
4
|
+
* const client = ports(); // RUNTIME_API_KEY, or this machine's saved connection
|
|
5
|
+
*/
|
|
6
|
+
import { Runtime, type RuntimeOptions } from "../client.js";
|
|
7
|
+
export type { TcpPort } from "../products/network-products.js";
|
|
8
|
+
/** `runtime.ports` of a client made with `options`. */
|
|
9
|
+
export declare function ports(options?: RuntimeOptions): Runtime["ports"];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** `withruntime/ports`: Ports alone. A public TCP port to a sandbox's port.
|
|
2
|
+
*
|
|
3
|
+
* import { ports } from "withruntime/ports";
|
|
4
|
+
* const client = ports(); // RUNTIME_API_KEY, or this machine's saved connection
|
|
5
|
+
*/
|
|
6
|
+
import { Runtime } from "../client.js";
|
|
7
|
+
/** `runtime.ports` of a client made with `options`. */
|
|
8
|
+
export function ports(options) {
|
|
9
|
+
return new Runtime(options).ports;
|
|
10
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** CLOUD.md section 4: one plural word per product on every interface (Marc,
|
|
2
|
+
* 6 October 2026). The API path `/v1/<name>`, the SDK's `runtime.<name>`, the
|
|
3
|
+
* CLI's `runtime <name>` and the MCP's `runtime_<name>` all use `name` below;
|
|
4
|
+
* the CLI also takes `singular` as a typing shortcut, and nothing else does.
|
|
5
|
+
*
|
|
6
|
+
* An old name keeps working for ALIAS_DAYS after the rename ships, with a
|
|
7
|
+
* warning naming the new one, then fails with `name_retired` and a hint. Its
|
|
8
|
+
* `retires` is null until the deploy that ships the rename sets it: the date
|
|
9
|
+
* is the deploy's, never a guess made before it.
|
|
10
|
+
*
|
|
11
|
+
* This is the one table of product names. PRODUCT_LAUNCHES in mcp-groups.ts
|
|
12
|
+
* says whether a product is open; this says what it is called. */
|
|
13
|
+
export declare const ALIAS_DAYS = 30;
|
|
14
|
+
/** CLOUD.md section 2's seven engines. */
|
|
15
|
+
export type Engine = "machine" | "disk" | "record" | "address" | "identity" | "meter" | "database";
|
|
16
|
+
export type OldName = {
|
|
17
|
+
/** The old word, as it appeared on any interface: `sandbox` stands for
|
|
18
|
+
* `/v1/sandbox`, `runtime.sandbox`, `runtime sandbox` and
|
|
19
|
+
* `runtime_sandbox_*`. Separators are compared as one (`-` and `_`). */
|
|
20
|
+
readonly name: string;
|
|
21
|
+
/** ISO date (UTC midnight) on which the old name stops working; null until
|
|
22
|
+
* the rename's deploy sets it to that day plus ALIAS_DAYS. */
|
|
23
|
+
readonly retires: string | null;
|
|
24
|
+
/** Where the old word's things now live inside the product, when not at
|
|
25
|
+
* its root: the WireGuard tunnel was `tunnel` and is `networks/wireguard`,
|
|
26
|
+
* leaving `/v1/networks` free to list private networks. */
|
|
27
|
+
readonly under?: string;
|
|
28
|
+
};
|
|
29
|
+
export type ProductName = {
|
|
30
|
+
/** The plural word on every interface. */
|
|
31
|
+
readonly name: string;
|
|
32
|
+
/** What a customer reads in a title. */
|
|
33
|
+
readonly title: string;
|
|
34
|
+
readonly engine: Engine;
|
|
35
|
+
/** The CLI-only shortcut; absent when the name has no singular. */
|
|
36
|
+
readonly singular?: string;
|
|
37
|
+
readonly old: readonly OldName[];
|
|
38
|
+
};
|
|
39
|
+
/** Every product, in CLOUD.md section 2's order. Old names are only the ones a
|
|
40
|
+
* customer could have called: a planned name that never shipped has none. */
|
|
41
|
+
export declare const PRODUCT_NAMES: readonly ProductName[];
|
|
42
|
+
/** CLOUD.md section 4: what spans products, at the top level, as it is. */
|
|
43
|
+
export declare const TOP_LEVEL: readonly string[];
|
|
44
|
+
/** `-` and `_` are one separator: the API path says `web-analytics`, the MCP
|
|
45
|
+
* tool `runtime_web_analytics`. */
|
|
46
|
+
export declare function wordOf(name: string): string;
|
|
47
|
+
/** The table's own rules: each word means one thing. No shortcut or old name
|
|
48
|
+
* is a product's name. An old name may equal a shortcut: its own product's
|
|
49
|
+
* (`sandbox`, silent in the CLI, a warning elsewhere) or another's (`tunnel`,
|
|
50
|
+
* whose old name wins until it retires, and then the shortcut takes over).
|
|
51
|
+
* Returns the problems found. */
|
|
52
|
+
export declare function validateProductNames(table?: readonly ProductName[]): string[];
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** CLOUD.md section 4: one plural word per product on every interface (Marc,
|
|
2
|
+
* 6 October 2026). The API path `/v1/<name>`, the SDK's `runtime.<name>`, the
|
|
3
|
+
* CLI's `runtime <name>` and the MCP's `runtime_<name>` all use `name` below;
|
|
4
|
+
* the CLI also takes `singular` as a typing shortcut, and nothing else does.
|
|
5
|
+
*
|
|
6
|
+
* An old name keeps working for ALIAS_DAYS after the rename ships, with a
|
|
7
|
+
* warning naming the new one, then fails with `name_retired` and a hint. Its
|
|
8
|
+
* `retires` is null until the deploy that ships the rename sets it: the date
|
|
9
|
+
* is the deploy's, never a guess made before it.
|
|
10
|
+
*
|
|
11
|
+
* This is the one table of product names. PRODUCT_LAUNCHES in mcp-groups.ts
|
|
12
|
+
* says whether a product is open; this says what it is called. */
|
|
13
|
+
export const ALIAS_DAYS = 30;
|
|
14
|
+
/** The batch of 6 October 2026: shared by every old name it retired. Set at
|
|
15
|
+
* its deploy to that day plus ALIAS_DAYS. */
|
|
16
|
+
const RENAME_OF_6_OCTOBER = null;
|
|
17
|
+
const was = (...names) => names.map((name) => ({ name, retires: RENAME_OF_6_OCTOBER }));
|
|
18
|
+
/** Every product, in CLOUD.md section 2's order. Old names are only the ones a
|
|
19
|
+
* customer could have called: a planned name that never shipped has none. */
|
|
20
|
+
export const PRODUCT_NAMES = [
|
|
21
|
+
// Machine
|
|
22
|
+
{
|
|
23
|
+
name: "sandboxes",
|
|
24
|
+
title: "Sandboxes",
|
|
25
|
+
engine: "machine",
|
|
26
|
+
singular: "sandbox",
|
|
27
|
+
old: was("sandbox"),
|
|
28
|
+
},
|
|
29
|
+
{ name: "browsers", title: "Browsers", engine: "machine", singular: "browser", old: [] },
|
|
30
|
+
{ name: "desktops", title: "Desktops", engine: "machine", singular: "desktop", old: [] },
|
|
31
|
+
{ name: "apps", title: "Apps", engine: "machine", singular: "app", old: [] },
|
|
32
|
+
{ name: "functions", title: "Functions", engine: "machine", singular: "function", old: [] },
|
|
33
|
+
{ name: "containers", title: "Containers", engine: "machine", singular: "container", old: [] },
|
|
34
|
+
{ name: "jobs", title: "Jobs", engine: "machine", singular: "job", old: was("job") },
|
|
35
|
+
{ name: "workflows", title: "Workflows", engine: "machine", singular: "workflow", old: [] },
|
|
36
|
+
{ name: "builds", title: "Builds", engine: "machine", singular: "build", old: [] },
|
|
37
|
+
// Disk
|
|
38
|
+
{ name: "volumes", title: "Volumes", engine: "disk", singular: "volume", old: was("volume") },
|
|
39
|
+
{
|
|
40
|
+
name: "snapshots",
|
|
41
|
+
title: "Snapshots",
|
|
42
|
+
engine: "disk",
|
|
43
|
+
singular: "snapshot",
|
|
44
|
+
old: was("snapshot"),
|
|
45
|
+
},
|
|
46
|
+
{ name: "images", title: "Images", engine: "disk", singular: "image", old: was("image") },
|
|
47
|
+
{ name: "buckets", title: "Buckets", engine: "disk", singular: "bucket", old: [] },
|
|
48
|
+
{ name: "backups", title: "Backups", engine: "disk", singular: "backup", old: [] },
|
|
49
|
+
// Record
|
|
50
|
+
{ name: "queues", title: "Queues", engine: "record", singular: "queue", old: [] },
|
|
51
|
+
{ name: "streams", title: "Streams", engine: "record", singular: "stream", old: [] },
|
|
52
|
+
{ name: "realtime", title: "Realtime", engine: "record", old: [] },
|
|
53
|
+
{ name: "events", title: "Events", engine: "record", old: [] },
|
|
54
|
+
{ name: "webhooks", title: "Webhooks", engine: "record", singular: "webhook", old: [] },
|
|
55
|
+
{ name: "logs", title: "Logs", engine: "record", singular: "log", old: [] },
|
|
56
|
+
{ name: "traces", title: "Traces", engine: "record", singular: "trace", old: [] },
|
|
57
|
+
{ name: "alerts", title: "Alerts", engine: "record", singular: "alert", old: [] },
|
|
58
|
+
// Address. `networks` is the private network, which the guides called
|
|
59
|
+
// `runtime tunnel` (WireGuard) and `runtime network`; `tunnels` is incoming
|
|
60
|
+
// tunnels, ngrok's kind. Static IPs were `runtime address`.
|
|
61
|
+
{ name: "domains", title: "Domains", engine: "address", singular: "domain", old: was("domain") },
|
|
62
|
+
{ name: "dns", title: "DNS", engine: "address", old: [] },
|
|
63
|
+
{ name: "balancers", title: "Load balancers", engine: "address", singular: "balancer", old: [] },
|
|
64
|
+
{ name: "cdn", title: "CDN", engine: "address", old: [] },
|
|
65
|
+
{
|
|
66
|
+
name: "networks",
|
|
67
|
+
title: "Private networks",
|
|
68
|
+
engine: "address",
|
|
69
|
+
singular: "network",
|
|
70
|
+
old: [...was("network"), { name: "tunnel", retires: RENAME_OF_6_OCTOBER, under: "wireguard" }],
|
|
71
|
+
},
|
|
72
|
+
{ name: "tunnels", title: "Tunnels", engine: "address", singular: "tunnel", old: [] },
|
|
73
|
+
{
|
|
74
|
+
name: "ips",
|
|
75
|
+
title: "Static IPs",
|
|
76
|
+
engine: "address",
|
|
77
|
+
singular: "ip",
|
|
78
|
+
old: was("address", "addresses"),
|
|
79
|
+
},
|
|
80
|
+
{ name: "ports", title: "Public ports", engine: "address", singular: "port", old: was("port") },
|
|
81
|
+
{ name: "firewall", title: "Firewall", engine: "address", old: [] },
|
|
82
|
+
{ name: "uptime", title: "Uptime checks", engine: "address", old: [] },
|
|
83
|
+
// Identity
|
|
84
|
+
{ name: "teams", title: "Teams", engine: "identity", singular: "team", old: [] },
|
|
85
|
+
{ name: "keys", title: "API keys", engine: "identity", singular: "key", old: [] },
|
|
86
|
+
{ name: "sso", title: "Single sign-on", engine: "identity", old: [] },
|
|
87
|
+
{ name: "secrets", title: "Secrets", engine: "identity", singular: "secret", old: [] },
|
|
88
|
+
{ name: "audit", title: "Audit log", engine: "identity", old: [] },
|
|
89
|
+
{ name: "tokens", title: "Identity tokens", engine: "identity", singular: "token", old: [] },
|
|
90
|
+
// Meter
|
|
91
|
+
{ name: "usage", title: "Usage", engine: "meter", old: [] },
|
|
92
|
+
{ name: "billing", title: "Billing", engine: "meter", old: [] },
|
|
93
|
+
{ name: "metrics", title: "Metrics", engine: "meter", old: [] },
|
|
94
|
+
// Database (not now: CLOUD.md section 2)
|
|
95
|
+
{ name: "postgres", title: "Postgres", engine: "database", old: [] },
|
|
96
|
+
{ name: "mysql", title: "MySQL", engine: "database", old: [] },
|
|
97
|
+
{ name: "redis", title: "Redis", engine: "database", old: [] },
|
|
98
|
+
{ name: "vector", title: "Vector", engine: "database", old: [] },
|
|
99
|
+
{ name: "search", title: "Search", engine: "database", old: [] },
|
|
100
|
+
{ name: "analytics", title: "Analytics", engine: "database", old: [] },
|
|
101
|
+
{ name: "web-analytics", title: "Web analytics", engine: "database", old: [] },
|
|
102
|
+
];
|
|
103
|
+
/** CLOUD.md section 4: what spans products, at the top level, as it is. */
|
|
104
|
+
export const TOP_LEVEL = [
|
|
105
|
+
"account",
|
|
106
|
+
"billing",
|
|
107
|
+
"usage",
|
|
108
|
+
"compare",
|
|
109
|
+
"keys",
|
|
110
|
+
"secrets",
|
|
111
|
+
"events",
|
|
112
|
+
"webhooks",
|
|
113
|
+
"ls",
|
|
114
|
+
"feedback",
|
|
115
|
+
"support",
|
|
116
|
+
];
|
|
117
|
+
/** `-` and `_` are one separator: the API path says `web-analytics`, the MCP
|
|
118
|
+
* tool `runtime_web_analytics`. */
|
|
119
|
+
export function wordOf(name) {
|
|
120
|
+
return name.toLowerCase().replaceAll("_", "-");
|
|
121
|
+
}
|
|
122
|
+
/** The table's own rules: each word means one thing. No shortcut or old name
|
|
123
|
+
* is a product's name. An old name may equal a shortcut: its own product's
|
|
124
|
+
* (`sandbox`, silent in the CLI, a warning elsewhere) or another's (`tunnel`,
|
|
125
|
+
* whose old name wins until it retires, and then the shortcut takes over).
|
|
126
|
+
* Returns the problems found. */
|
|
127
|
+
export function validateProductNames(table = PRODUCT_NAMES) {
|
|
128
|
+
const problems = [];
|
|
129
|
+
const current = new Map();
|
|
130
|
+
for (const product of table) {
|
|
131
|
+
const word = wordOf(product.name);
|
|
132
|
+
if (word !== product.name)
|
|
133
|
+
problems.push(`${product.name}: write the name in its API form`);
|
|
134
|
+
if (current.has(word))
|
|
135
|
+
problems.push(`${word}: named twice`);
|
|
136
|
+
current.set(word, product.name);
|
|
137
|
+
}
|
|
138
|
+
const shortcuts = new Map();
|
|
139
|
+
for (const product of table) {
|
|
140
|
+
if (!product.singular)
|
|
141
|
+
continue;
|
|
142
|
+
const word = wordOf(product.singular);
|
|
143
|
+
if (current.has(word))
|
|
144
|
+
problems.push(`${product.name}: shortcut ${word} is a product's name`);
|
|
145
|
+
if (shortcuts.has(word))
|
|
146
|
+
problems.push(`${word}: shortcut of two products`);
|
|
147
|
+
shortcuts.set(word, product.name);
|
|
148
|
+
}
|
|
149
|
+
const olds = new Set();
|
|
150
|
+
for (const product of table) {
|
|
151
|
+
for (const old of product.old) {
|
|
152
|
+
const word = wordOf(old.name);
|
|
153
|
+
if (current.has(word))
|
|
154
|
+
problems.push(`${product.name}: old name ${word} is a product's name`);
|
|
155
|
+
if (olds.has(word))
|
|
156
|
+
problems.push(`${word}: old name of two products`);
|
|
157
|
+
if (old.retires !== null && !/^\d{4}-\d{2}-\d{2}$/.test(old.retires)) {
|
|
158
|
+
problems.push(`${word}: retires must be a date, YYYY-MM-DD`);
|
|
159
|
+
}
|
|
160
|
+
olds.add(word);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return problems;
|
|
164
|
+
}
|