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.
Files changed (171) hide show
  1. package/BLAXEL.md +2 -2
  2. package/COMPATIBILITY.md +74 -9
  3. package/DAYTONA.md +33 -5
  4. package/E2B.md +85 -24
  5. package/README.md +11 -10
  6. package/README.src.md +10 -9
  7. package/VERCEL.md +43 -5
  8. package/compatibility-lock.json +58 -49
  9. package/dist/billing-cli.d.ts +1 -1
  10. package/dist/billing-cli.js +85 -5
  11. package/dist/blaxel/errors.d.ts +14 -0
  12. package/dist/blaxel/errors.js +29 -0
  13. package/dist/blaxel/index.d.ts +2 -2
  14. package/dist/blaxel/index.js +4 -4
  15. package/dist/blaxel/interpreter.d.ts +2 -5
  16. package/dist/blaxel/sandbox.d.ts +15 -6
  17. package/dist/blaxel/sandbox.js +64 -8
  18. package/dist/blaxel/snapshot.d.ts +4 -0
  19. package/dist/blaxel/snapshot.js +4 -0
  20. package/dist/cli/logs.d.ts +21 -0
  21. package/dist/cli/logs.js +188 -0
  22. package/dist/cli-extras.d.ts +3 -3
  23. package/dist/cli-extras.js +17 -12
  24. package/dist/cli-words.d.ts +10 -1
  25. package/dist/cli-words.js +18 -0
  26. package/dist/cli.d.ts +22 -3
  27. package/dist/cli.js +647 -273
  28. package/dist/client.d.ts +2 -4
  29. package/dist/client.js +27 -11
  30. package/dist/cloudflare/errors.d.ts +143 -0
  31. package/dist/cloudflare/errors.js +167 -0
  32. package/dist/cloudflare/index.d.ts +175 -6
  33. package/dist/cloudflare/index.js +416 -26
  34. package/dist/cloudflare/interpreter.d.ts +119 -0
  35. package/dist/cloudflare/interpreter.js +223 -0
  36. package/dist/cloudflare/streams.d.ts +38 -0
  37. package/dist/cloudflare/streams.js +145 -0
  38. package/dist/cloudflare/watch.d.ts +9 -0
  39. package/dist/cloudflare/watch.js +24 -0
  40. package/dist/codesandbox/index.d.ts +216 -28
  41. package/dist/codesandbox/index.js +478 -78
  42. package/dist/compat/core.d.ts +18 -0
  43. package/dist/compat/core.js +29 -0
  44. package/dist/compat/files.d.ts +1 -0
  45. package/dist/compat/files.js +25 -5
  46. package/dist/credentials.d.ts +3 -0
  47. package/dist/credentials.js +15 -0
  48. package/dist/daytona/computer-use.d.ts +13 -4
  49. package/dist/daytona/computer-use.js +66 -8
  50. package/dist/daytona/daytona.d.ts +7 -1
  51. package/dist/daytona/daytona.js +31 -4
  52. package/dist/daytona/errors.d.ts +11 -0
  53. package/dist/daytona/errors.js +18 -0
  54. package/dist/daytona/filesystem.js +2 -1
  55. package/dist/daytona/image.d.ts +13 -9
  56. package/dist/daytona/image.js +18 -12
  57. package/dist/daytona/index.d.ts +1 -1
  58. package/dist/daytona/sandbox.d.ts +8 -2
  59. package/dist/daytona/sandbox.js +16 -2
  60. package/dist/domains/index.d.ts +9 -0
  61. package/dist/domains/index.js +10 -0
  62. package/dist/e2b/commands.d.ts +1 -1
  63. package/dist/e2b/commands.js +6 -7
  64. package/dist/e2b/errors.d.ts +17 -0
  65. package/dist/e2b/errors.js +40 -1
  66. package/dist/e2b/index.d.ts +2 -2
  67. package/dist/e2b/index.js +1 -1
  68. package/dist/e2b/sandbox.d.ts +28 -22
  69. package/dist/e2b/sandbox.js +34 -8
  70. package/dist/e2b/unsupported.js +1 -1
  71. package/dist/errors.d.ts +11 -2
  72. package/dist/errors.js +17 -5
  73. package/dist/freestyle/index.d.ts +285 -37
  74. package/dist/freestyle/index.js +656 -144
  75. package/dist/identity.d.ts +3 -0
  76. package/dist/identity.js +27 -0
  77. package/dist/images/index.d.ts +9 -0
  78. package/dist/images/index.js +10 -0
  79. package/dist/index.d.ts +3 -1
  80. package/dist/ips/index.d.ts +9 -0
  81. package/dist/ips/index.js +10 -0
  82. package/dist/jobs/index.d.ts +9 -0
  83. package/dist/jobs/index.js +10 -0
  84. package/dist/keys.js +2 -0
  85. package/dist/login.js +2 -0
  86. package/dist/machine.d.ts +27 -4
  87. package/dist/machine.js +46 -14
  88. package/dist/mcp.js +144 -20
  89. package/dist/modal/index.d.ts +339 -61
  90. package/dist/modal/index.js +781 -121
  91. package/dist/network-cli.d.ts +3 -1
  92. package/dist/network-cli.js +78 -36
  93. package/dist/networks/index.d.ts +11 -0
  94. package/dist/networks/index.js +10 -0
  95. package/dist/ports/index.d.ts +9 -0
  96. package/dist/ports/index.js +10 -0
  97. package/dist/product-names.d.ts +52 -0
  98. package/dist/product-names.js +164 -0
  99. package/dist/product-renames.d.ts +103 -0
  100. package/dist/product-renames.js +189 -0
  101. package/dist/products/api-keys.d.ts +73 -0
  102. package/dist/products/api-keys.js +23 -0
  103. package/dist/products/apps.d.ts +157 -0
  104. package/dist/products/apps.js +60 -0
  105. package/dist/products/balancers.d.ts +87 -0
  106. package/dist/products/balancers.js +8 -0
  107. package/dist/products/billing.d.ts +41 -0
  108. package/dist/products/billing.js +13 -0
  109. package/dist/products/browser.d.ts +10 -0
  110. package/dist/products/browsers.d.ts +71 -0
  111. package/dist/products/browsers.js +102 -0
  112. package/dist/products/builds.d.ts +156 -0
  113. package/dist/products/builds.js +227 -0
  114. package/dist/products/index.d.ts +5 -16
  115. package/dist/products/index.js +5 -14
  116. package/dist/products/jobs.d.ts +19 -2
  117. package/dist/products/jobs.js +28 -11
  118. package/dist/products/logs.d.ts +245 -0
  119. package/dist/products/logs.js +274 -0
  120. package/dist/products/network-products.d.ts +38 -7
  121. package/dist/products/network-products.js +31 -18
  122. package/dist/products/observability.d.ts +8 -2
  123. package/dist/products/private-network.js +1 -1
  124. package/dist/products/queues.d.ts +149 -0
  125. package/dist/products/queues.js +213 -0
  126. package/dist/products/referrals.d.ts +21 -7
  127. package/dist/products/referrals.js +3 -3
  128. package/dist/products/resources.d.ts +54 -0
  129. package/dist/products/resources.js +122 -0
  130. package/dist/products/secrets.d.ts +29 -3
  131. package/dist/products/secrets.js +47 -18
  132. package/dist/products/signed-requests.d.ts +21 -0
  133. package/dist/products/signed-requests.js +11 -0
  134. package/dist/products/streams.d.ts +73 -0
  135. package/dist/products/streams.js +17 -0
  136. package/dist/products/switching.d.ts +35 -7
  137. package/dist/products/switching.js +4 -3
  138. package/dist/products/volumes.d.ts +6 -0
  139. package/dist/record-cli.d.ts +23 -0
  140. package/dist/record-cli.js +308 -0
  141. package/dist/renamed-products.d.ts +38 -0
  142. package/dist/renamed-products.js +34 -0
  143. package/dist/runloop/index.d.ts +9 -2
  144. package/dist/runloop/index.js +29 -8
  145. package/dist/runloop/sdk.d.ts +131 -0
  146. package/dist/runloop/sdk.js +167 -0
  147. package/dist/sandbox.d.ts +7 -2
  148. package/dist/sandbox.js +41 -11
  149. package/dist/sandboxes/index.d.ts +11 -0
  150. package/dist/sandboxes/index.js +12 -0
  151. package/dist/snapshots/index.d.ts +9 -0
  152. package/dist/snapshots/index.js +11 -0
  153. package/dist/snapshots.d.ts +7 -4
  154. package/dist/sprites/index.d.ts +343 -31
  155. package/dist/sprites/index.js +866 -84
  156. package/dist/ssh.d.ts +1 -1
  157. package/dist/ssh.js +11 -11
  158. package/dist/terminal.d.ts +24 -0
  159. package/dist/terminal.js +32 -0
  160. package/dist/transport.d.ts +18 -1
  161. package/dist/transport.js +80 -6
  162. package/dist/tunnel.js +1 -1
  163. package/dist/types.d.ts +71 -4
  164. package/dist/vercel/sandbox.d.ts +1 -1
  165. package/dist/vercel/sandbox.js +6 -4
  166. package/dist/vercel/snapshot.js +10 -2
  167. package/dist/volumes/index.d.ts +9 -0
  168. package/dist/volumes/index.js +10 -0
  169. package/dist/wallet.d.ts +4 -1
  170. package/dist/wallet.js +2 -1
  171. package/package.json +48 -14
@@ -0,0 +1,122 @@
1
+ import { RuntimeError } from "../errors.js";
2
+ import { Page } from "../page.js";
3
+ import { pause } from "../wait.js";
4
+ export const enc = encodeURIComponent;
5
+ function invalid(field) {
6
+ return new RuntimeError({
7
+ code: "invalid_request",
8
+ status: 0,
9
+ message: `${field} must be a finite, nonnegative number.`,
10
+ hint: "Fix the option and call again; nothing was sent.",
11
+ details: { field },
12
+ });
13
+ }
14
+ /** One deadline covers the write, retries and every read. A timed-out delete
15
+ * can be retried after a process restart with this same key. */
16
+ export async function following(options, work) {
17
+ const { pollMs = 250, timeoutMs = 300_000, signal, ...rest } = options;
18
+ if (!Number.isFinite(pollMs) || pollMs < 0)
19
+ throw invalid("pollMs");
20
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0)
21
+ throw invalid("timeoutMs");
22
+ const deadline = new AbortController();
23
+ const combined = signal ? AbortSignal.any([signal, deadline.signal]) : deadline.signal;
24
+ const timer = timeoutMs > 0 ? setTimeout(() => deadline.abort(), timeoutMs) : undefined;
25
+ const request = { ...rest, timeoutMs: 0, signal: combined };
26
+ const poll = () => pause(pollMs, combined);
27
+ try {
28
+ combined.throwIfAborted();
29
+ const result = await work(request, poll);
30
+ combined.throwIfAborted();
31
+ return result;
32
+ }
33
+ catch (cause) {
34
+ if (!combined.aborted) {
35
+ // A read failure still belongs to the write that started this wait.
36
+ // Keep its key so a caller can recover after losing the reply.
37
+ if (cause instanceof RuntimeError && rest.idempotencyKey && !cause.idempotencyKey)
38
+ throw new RuntimeError({
39
+ message: cause.message,
40
+ code: cause.code,
41
+ status: cause.status,
42
+ requestId: cause.requestId,
43
+ hint: cause.hint,
44
+ details: cause.details,
45
+ retryAfterMs: cause.retryAfterMs,
46
+ idempotencyKey: rest.idempotencyKey,
47
+ cause,
48
+ });
49
+ throw cause;
50
+ }
51
+ throw new RuntimeError({
52
+ code: "timeout",
53
+ status: 0,
54
+ message: "Waiting was cancelled or reached its deadline; the resource may still change.",
55
+ hint: "Read the resource to resume waiting. Retry a write with the same idempotencyKey.",
56
+ ...(rest.idempotencyKey === undefined ? {} : { idempotencyKey: rest.idempotencyKey }),
57
+ cause,
58
+ });
59
+ }
60
+ finally {
61
+ clearTimeout(timer);
62
+ }
63
+ }
64
+ /** A resource product's client at `/v1/<path>`. A wait ends at its target
65
+ * or at any of `settled`, which answers with the resource's error. */
66
+ export function resource(t, path, settled) {
67
+ const base = `/v1/${path}`;
68
+ const get = (id, options = {}) => {
69
+ const { waitFor, timeoutSeconds, ...request } = options;
70
+ return t.json({
71
+ method: "GET",
72
+ path: `${base}/${enc(id)}`,
73
+ query: { waitFor, timeoutSeconds },
74
+ ...request,
75
+ });
76
+ };
77
+ const list = async (query = {}, options) => {
78
+ const page = await t.json({
79
+ method: "GET",
80
+ path: base,
81
+ query,
82
+ ...options,
83
+ });
84
+ return new Page(page.data, page.nextCursor, (cursor) => list({ ...query, cursor }, options));
85
+ };
86
+ const follow = async (id, target, request, pause, initial) => {
87
+ let record = initial ?? (await get(id, request));
88
+ for (;;) {
89
+ if (record.state === target)
90
+ return record;
91
+ if (settled.includes(record.state))
92
+ throw new RuntimeError({
93
+ code: record.error?.code ?? "unexpected_state",
94
+ status: 0,
95
+ message: record.error?.message ?? `Expected ${target}, but ${id} reached ${record.state}.`,
96
+ hint: "Read the resource and inspect its error before starting another change.",
97
+ details: { id, state: record.state, target, resource: record },
98
+ ...(request.idempotencyKey === undefined
99
+ ? {}
100
+ : { idempotencyKey: request.idempotencyKey }),
101
+ });
102
+ await pause();
103
+ record = await get(id, request);
104
+ }
105
+ };
106
+ return {
107
+ base,
108
+ /** Defaults belong to the API, so the SDK does not override them. */
109
+ create: (input, options) => t.json({ method: "POST", path: base, body: input, ...options }),
110
+ get,
111
+ list,
112
+ update: (id, input, options) => t.json({ method: "POST", path: `${base}/${enc(id)}:update`, body: input, ...options }),
113
+ wait: (id, target, options = {}) => following(options, (request, pause) => follow(id, target, request, pause)),
114
+ delete: (id, options = {}) => {
115
+ const { wait = false, pollMs, ...request } = options;
116
+ const remove = (rest) => t.json({ method: "DELETE", path: `${base}/${enc(id)}`, ...rest });
117
+ if (!wait)
118
+ return remove(request);
119
+ return following({ ...request, pollMs, idempotencyKey: request.idempotencyKey ?? crypto.randomUUID() }, async (rest, pause) => follow(id, "deleted", rest, pause, await remove(rest)));
120
+ },
121
+ };
122
+ }
@@ -9,10 +9,23 @@ export type SecretRule = {
9
9
  methods?: string[];
10
10
  paths: string[];
11
11
  };
12
+ /** Which sandboxes get a secret: those whose labels hold every pair of any one
13
+ * selector in `labels` (including sandboxes created or labelled later), and
14
+ * those named in `sandboxes`. Any other sandbox of the organization sees no
15
+ * placeholder, and its requests never carry the value. Absent on a secret:
16
+ * every sandbox of the organization. */
17
+ export type SecretScope = {
18
+ /** 1 to 8 selectors of 1 to 8 key/value pairs: `[{ role: "hub" }]`. */
19
+ labels?: Array<Record<string, string>>;
20
+ /** 1 to 100 sandbox ids of the organization. */
21
+ sandboxes?: string[];
22
+ };
12
23
  /** A secret your sandboxes use without seeing it. Every sandbox of your
13
24
  * organization has an environment variable of the secret's name holding
14
- * `placeholder`; the egress proxy puts the value into HTTPS requests to
15
- * `hosts` (in the URL and headers), or sets `header` on every such request.
25
+ * `placeholder`; the egress proxy sets `header` on every HTTPS request to
26
+ * `hosts`, or, without `header`, replaces the placeholder in a credential
27
+ * header (Authorization, x-api-key, x-goog-api-key, api-key, xi-api-key,
28
+ * x-subscription-token, private-token). Never in the URL or another header.
16
29
  * The value is never returned. */
17
30
  export type Secret = {
18
31
  name: string;
@@ -20,6 +33,8 @@ export type Secret = {
20
33
  header?: string;
21
34
  format?: string;
22
35
  rules?: SecretRule[];
36
+ /** Absent: every sandbox of the organization. */
37
+ only?: SecretScope;
23
38
  placeholder: string;
24
39
  valueBytes: number;
25
40
  createdAt: string;
@@ -33,7 +48,9 @@ export type SetSecret = {
33
48
  /** Where the value may go: `api.openai.com`, `*.github.com`. 1 to 16.
34
49
  * Required unless `jobs` is true. */
35
50
  hosts?: string[];
36
- /** Set this header on every request to the hosts, replacing the sandbox's own. */
51
+ /** Set this header on every request to the hosts, replacing the sandbox's
52
+ * own; the value then goes nowhere else. Needed when the API reads its key
53
+ * from a header that is not a credential header (see `Secret`). */
37
54
  header?: string;
38
55
  /** With `header`: its value, `{value}` where the secret goes. Default `{value}`. */
39
56
  format?: string;
@@ -41,6 +58,10 @@ export type SetSecret = {
41
58
  * Absent: every request to the hosts; replacing a secret without rules
42
59
  * clears them. */
43
60
  rules?: SecretRule[];
61
+ /** Only these sandboxes get it. Absent when replacing a secret: the scope it
62
+ * has stays, so a new value never widens who gets it. `{}`: every sandbox of
63
+ * the organization again. */
64
+ only?: SecretScope;
44
65
  /** Also keep a copy for scheduled jobs, which a job puts into its run's
45
66
  * environment (`jobs.create({ secrets: [...] })`). Unlike the sandboxes'
46
67
  * copy, the jobs copy is yours rather than the account's, versioned, and can
@@ -94,6 +115,11 @@ export declare function secrets(t: Transport): {
94
115
  enforced: boolean;
95
116
  }>>;
96
117
  };
118
+ /** Changes which sandboxes get a secret, without its value: `{}` is every
119
+ * sandbox of the organization again. */
120
+ scope: (name: string, only: SecretScope, options?: RequestOptions) => Promise<Secret & {
121
+ enforced: boolean;
122
+ }>;
97
123
  /** The sandboxes' secrets: names, hosts and placeholders. Never values.
98
124
  * `all()` includes the jobs copies. */
99
125
  list: (options?: RequestOptions) => Promise<Secret[]>;
@@ -36,16 +36,47 @@ export function secrets(t) {
36
36
  const key = (options, part) => options?.idempotencyKey
37
37
  ? { ...options, idempotencyKey: `${options.idempotencyKey}:${part}`.slice(0, 128) }
38
38
  : options;
39
+ const create = (name, value, options) => store({ method: "POST", path: "/v1/secrets", body: { name, value }, ...options });
40
+ const rotate = (live, value, version, options) => store({
41
+ method: "POST",
42
+ path: `${jobPath(live.id)}:rotate`,
43
+ body: { value, expectedVersion: version },
44
+ ...options,
45
+ });
46
+ /** Rotates the jobs copy from the version it has now. A key used before,
47
+ * by this same call whose answer was lost, is answered by the identical
48
+ * request again, with no second rotation: the rotate from the version
49
+ * before, or one of `earlier` (a set's create). Until 10 October 2026 the
50
+ * retry read the copy as it is now, changed its request, and was refused
51
+ * as a conflict. */
52
+ async function rotateOrReplay(live, value, options, earlier = []) {
53
+ try {
54
+ return await rotate(live, value, live.version, options);
55
+ }
56
+ catch (error) {
57
+ if (!(error instanceof RuntimeError) || error.code !== "idempotency_conflict")
58
+ throw error;
59
+ const replays = [
60
+ ...earlier,
61
+ ...(live.version > 1 ? [() => rotate(live, value, live.version - 1, options)] : []),
62
+ ];
63
+ for (const replay of replays) {
64
+ const answer = await replay().catch((again) => {
65
+ if (again instanceof RuntimeError && again.status === 409)
66
+ return undefined;
67
+ throw again;
68
+ });
69
+ if (answer)
70
+ return answer;
71
+ }
72
+ throw error;
73
+ }
74
+ }
39
75
  async function setJobCopy(name, value, options) {
40
76
  const copies = await jobCopies(options);
41
77
  const live = copies.find((s) => s.name === name && s.deletedAt === null);
42
78
  if (live)
43
- return store({
44
- method: "POST",
45
- path: `${jobPath(live.id)}:rotate`,
46
- body: { value, expectedVersion: live.version },
47
- ...options,
48
- });
79
+ return rotateOrReplay(live, value, options, [() => create(name, value, options)]);
49
80
  if (copies.some((s) => s.name === name))
50
81
  throw new RuntimeError({
51
82
  message: `A jobs secret named ${name} was deleted, and a deleted name cannot be used again.`,
@@ -54,12 +85,7 @@ export function secrets(t) {
54
85
  hint: "Store it under another name.",
55
86
  details: { field: "name" },
56
87
  });
57
- return store({
58
- method: "POST",
59
- path: "/v1/secrets",
60
- body: { name, value },
61
- ...options,
62
- });
88
+ return create(name, value, options);
63
89
  }
64
90
  async function all(options) {
65
91
  const [forSandboxes, forJobs] = await Promise.all([
@@ -127,6 +153,14 @@ export function secrets(t) {
127
153
  * at once store both; if only the first lands, `SecretPartlyStoredError`
128
154
  * says so and the same call again finishes it. */
129
155
  set,
156
+ /** Changes which sandboxes get a secret, without its value: `{}` is every
157
+ * sandbox of the organization again. */
158
+ scope: (name, only, options) => t.json({
159
+ method: "PUT",
160
+ path: `${path(name)}/sandboxes`,
161
+ body: only,
162
+ ...options,
163
+ }),
130
164
  /** The sandboxes' secrets: names, hosts and placeholders. Never values.
131
165
  * `all()` includes the jobs copies. */
132
166
  list,
@@ -156,12 +190,7 @@ export function secrets(t) {
156
190
  status: 404,
157
191
  hint: "Store one with set(name, { value, jobs: true }). The sandboxes' copy is replaced by set, not rotated.",
158
192
  });
159
- return store({
160
- method: "POST",
161
- path: `${jobPath(live.id)}:rotate`,
162
- body: { value, expectedVersion: live.version },
163
- ...options,
164
- });
193
+ return rotateOrReplay(live, value, options);
165
194
  },
166
195
  /** Read the jobs copy's value back (needs the key's secrets_reveal
167
196
  * permission). The sandboxes' copy can never be read back. */
@@ -0,0 +1,21 @@
1
+ import type { RequestOptions, Transport } from "../transport.js";
2
+ export type SignedRequests = {
3
+ /** Whether your sandboxes may get Runtime's request signature now. */
4
+ enabled: boolean;
5
+ /** Whether this account may turn it on: it must have credit. */
6
+ allowed: boolean;
7
+ /** Why not, when `allowed` is false: `no_credit`, `revoked` or `suspended`. */
8
+ why: string | null;
9
+ enabledAt: string | null;
10
+ disabledAt: string | null;
11
+ };
12
+ export declare function signedRequests(t: Transport): {
13
+ /** On or off, and whether this account may turn it on. */
14
+ get: (options?: RequestOptions) => Promise<SignedRequests>;
15
+ /** `enabled: true` lets your sandboxes get Runtime's request signature;
16
+ * `false` stops new signatures at once, and ones already given expire
17
+ * within 5 minutes. */
18
+ set: (input: {
19
+ enabled: boolean;
20
+ }, options?: RequestOptions) => Promise<SignedRequests>;
21
+ };
@@ -0,0 +1,11 @@
1
+ export function signedRequests(t) {
2
+ const path = "/v1/networks/signed-requests";
3
+ return {
4
+ /** On or off, and whether this account may turn it on. */
5
+ get: (options) => t.json({ method: "GET", path, ...options }),
6
+ /** `enabled: true` lets your sandboxes get Runtime's request signature;
7
+ * `false` stops new signatures at once, and ones already given expire
8
+ * within 5 minutes. */
9
+ set: (input, options) => t.json({ method: "PUT", path, body: input, ...options }),
10
+ };
11
+ }
@@ -0,0 +1,73 @@
1
+ import type { RequestOptions, Transport } from "../transport.js";
2
+ import { type RecordResource } from "./queues.js";
3
+ /** Private until launch.
4
+ * Kafka clients use kafka.bootstrap and kafka.topic unchanged.
5
+ * Offsets and byte counts use decimal strings so JSON never rounds them. */
6
+ export type Stream = RecordResource & {
7
+ partitions: number;
8
+ retentionMs: number;
9
+ retentionBytes: string;
10
+ kafka: {
11
+ bootstrap: string;
12
+ topic: string;
13
+ };
14
+ };
15
+ export type CreateStream = {
16
+ name: string;
17
+ labels?: Record<string, string>;
18
+ partitions?: number;
19
+ retentionMs?: number;
20
+ retentionBytes?: string;
21
+ };
22
+ export type UpdateStream = Partial<CreateStream>;
23
+ /** Text values are UTF-8. Use a Kafka client for arbitrary binary records. */
24
+ export type StreamRecord = {
25
+ key?: string | null;
26
+ value: string | null;
27
+ headers?: {
28
+ key: string;
29
+ value: string | null;
30
+ }[];
31
+ };
32
+ export type PublishRecords = {
33
+ records: StreamRecord[];
34
+ };
35
+ export type ReadStream = {
36
+ partition: number;
37
+ maxBytes?: number;
38
+ waitMs?: number;
39
+ } & ({
40
+ offset: string;
41
+ time?: never;
42
+ } | {
43
+ time: number;
44
+ offset?: never;
45
+ });
46
+ export type PublishedRecord = {
47
+ partition: number;
48
+ offset: string;
49
+ };
50
+ export type StreamRead = {
51
+ records: (StreamRecord & PublishedRecord & {
52
+ time: number;
53
+ })[];
54
+ nextOffset: string;
55
+ };
56
+ /** Private until launch. Proposed routes only; nothing is registered here. */
57
+ export declare function streams(t: Transport): {
58
+ publish: (id: string, input: PublishRecords, options?: RequestOptions) => Promise<{
59
+ records: PublishedRecord[];
60
+ }>;
61
+ read: (id: string, input: ReadStream, options?: RequestOptions) => Promise<StreamRead>;
62
+ /** Trim returns the resource; follow its state with wait(id). */
63
+ trim: (id: string, input: {
64
+ partition: number;
65
+ before: string;
66
+ }, options?: RequestOptions) => Promise<Stream>;
67
+ create: (input: CreateStream, options?: RequestOptions) => Promise<Stream>;
68
+ get: (id: string, options?: RequestOptions) => Promise<Stream>;
69
+ list: (query?: import("./queues.js").RecordListQuery, options?: RequestOptions) => Promise<import("../page.js").Page<Stream>>;
70
+ update: (id: string, input: Partial<CreateStream>, options?: RequestOptions) => Promise<Stream>;
71
+ delete: (id: string, options?: RequestOptions) => Promise<Stream>;
72
+ wait(id: string, target?: "ready" | "deleted", options?: import("./queues.js").RecordWaitOptions): Promise<Stream>;
73
+ };
@@ -0,0 +1,17 @@
1
+ import { recordResources } from "./queues.js";
2
+ /** Private until launch. Proposed routes only; nothing is registered here. */
3
+ export function streams(t) {
4
+ const path = (id) => `/v1/streams/${encodeURIComponent(id)}`;
5
+ return {
6
+ ...recordResources(t, "streams"),
7
+ publish: (id, input, options) => t.json({
8
+ ...options,
9
+ method: "POST",
10
+ path: `${path(id)}:publish`,
11
+ body: input,
12
+ }),
13
+ read: (id, input, options) => t.json({ ...options, method: "GET", path: `${path(id)}:read`, query: input }),
14
+ /** Trim returns the resource; follow its state with wait(id). */
15
+ trim: (id, input, options) => t.json({ ...options, method: "POST", path: `${path(id)}:trim`, body: input }),
16
+ };
17
+ }
@@ -9,7 +9,7 @@ export type SwitchProvider = "e2b" | "daytona" | "vercel" | "modal" | "cloudflar
9
9
  export type SwitchingSummary = {
10
10
  /** False while the programme is paused. */
11
11
  enabled: boolean;
12
- /** The most a first top-up is matched to. */
12
+ /** The most the organization's payments are matched to, in total. */
13
13
  maxMicros: string;
14
14
  providers: SwitchProvider[];
15
15
  /** Whether this organization can record a switch now: none recorded, and
@@ -17,14 +17,41 @@ export type SwitchingSummary = {
17
17
  eligible: boolean;
18
18
  switch: {
19
19
  provider: SwitchProvider;
20
- /** superseded: a referral matched the first top-up instead, which is
20
+ /** superseded: a referral matches the payments instead, which is
21
21
  * never less. The two are never both paid. */
22
22
  status: "pending" | "paid" | "superseded" | "refused" | "reversed";
23
- refusedReason: "program_off" | "suspended" | "same_card" | "fraud" | null;
23
+ refusedReason: "program_off" | "suspended" | "same_card" | "fraud" | "too_late" | null;
24
24
  recordedAt: string;
25
- /** The switching credit this organization got and kept. */
25
+ /** The matches this organization got and kept. */
26
26
  creditMicros: string;
27
27
  } | null;
28
+ /** The welcome match: credit an organization adds within 30 days of
29
+ * signing up is matched, up to $1,000 in total. */
30
+ welcome: WelcomeMatch;
31
+ };
32
+ export type WelcomeMatch = {
33
+ /** False while the match is paused. */
34
+ enabled: boolean;
35
+ /** The most the organization's payments are matched to, in total. */
36
+ maxMicros: string;
37
+ /** When the offer ends: 30 days after the organization signed up. */
38
+ endsAt: string;
39
+ /** Whether credit added now would be matched: some is left, before endsAt. */
40
+ eligible: boolean;
41
+ /** Whether credit has been added. */
42
+ toppedUp: boolean;
43
+ /** Null until a payment is decided; paid while a match is kept.
44
+ * superseded: a referral matches the payments instead, which is never
45
+ * less. */
46
+ status: "pending" | "paid" | "superseded" | "refused" | "reversed" | null;
47
+ /** The matches this organization got and kept. */
48
+ creditMicros: string;
49
+ /** The part of maxMicros used so far. Absent from a server before
50
+ * 8 October 2026. */
51
+ usedMicros?: string;
52
+ /** What credit added now could still get; "0" once the offer ends. Absent
53
+ * from a server before 8 October 2026. */
54
+ leftMicros?: string;
28
55
  };
29
56
  export type UsageComparison = {
30
57
  provider: CompareProvider;
@@ -76,8 +103,9 @@ export type UsageComparison = {
76
103
  switching: SwitchingSummary;
77
104
  };
78
105
  /** `runtime.switching`: compare your usage with a rival's published rates,
79
- * and record the rival you are leaving so your first top-up is matched, up to
80
- * $100, once the payment settles. */
106
+ * record the rival you are leaving, and read the welcome match: credit added
107
+ * within 30 days of signing up is matched, up to $1,000 in total, as each
108
+ * payment settles. */
81
109
  export declare function switching(t: Transport): {
82
110
  /** Your settled sandbox usage over the last `days` (default 30, at most
83
111
  * 90), priced on Runtime and at the rival, with the saving. */
@@ -85,7 +113,7 @@ export declare function switching(t: Transport): {
85
113
  provider: CompareProvider;
86
114
  days?: number;
87
115
  }, options?: RequestOptions) => Promise<UsageComparison>;
88
- /** Whether a switch can still be recorded, and what it paid. */
116
+ /** Whether a switch can still be recorded, and what the welcome match paid. */
89
117
  get: (options?: RequestOptions) => Promise<SwitchingSummary>;
90
118
  /** Once per organization, before its first top-up. Recording the same
91
119
  * provider again answers the same summary; another fails with 409. */
@@ -1,6 +1,7 @@
1
1
  /** `runtime.switching`: compare your usage with a rival's published rates,
2
- * and record the rival you are leaving so your first top-up is matched, up to
3
- * $100, once the payment settles. */
2
+ * record the rival you are leaving, and read the welcome match: credit added
3
+ * within 30 days of signing up is matched, up to $1,000 in total, as each
4
+ * payment settles. */
4
5
  export function switching(t) {
5
6
  return {
6
7
  /** Your settled sandbox usage over the last `days` (default 30, at most
@@ -11,7 +12,7 @@ export function switching(t) {
11
12
  query: { provider: input.provider, days: input.days },
12
13
  ...options,
13
14
  }),
14
- /** Whether a switch can still be recorded, and what it paid. */
15
+ /** Whether a switch can still be recorded, and what the welcome match paid. */
15
16
  get: (options) => t.json({ method: "GET", path: "/v1/switching", ...options }),
16
17
  /** Once per organization, before its first top-up. Recording the same
17
18
  * provider again answers the same summary; another fails with 409. */
@@ -86,7 +86,13 @@ export type VolumeBackup = {
86
86
  storedBytes: number | null;
87
87
  meteredBytes: number | null;
88
88
  error: string | null;
89
+ /** Why it failed, when a code says it: `backup_stalled` when its copy off
90
+ * the host never began; back it up again. */
91
+ errorCode?: string | null;
89
92
  createdAt: string;
93
+ /** When its copy off the volume's server began; null while it waits its
94
+ * turn behind other copies there. */
95
+ copyStartedAt?: string | null;
90
96
  readyAt: string | null;
91
97
  expiresAt: string;
92
98
  };
@@ -0,0 +1,23 @@
1
+ import type { queues } from "./products/queues.js";
2
+ import type { streams } from "./products/streams.js";
3
+ /** Private until launch. CLOUD.md section 4. cli.ts does not call this module. */
4
+ export declare const RECORD_PRODUCTS: readonly ["queue", "stream"];
5
+ export type RecordProduct = (typeof RECORD_PRODUCTS)[number];
6
+ export type RecordClient = {
7
+ queues: ReturnType<typeof queues>;
8
+ streams: ReturnType<typeof streams>;
9
+ };
10
+ type Args = {
11
+ positional: string[];
12
+ flags: Map<string, string[]>;
13
+ rest?: string[];
14
+ };
15
+ type Out = {
16
+ json: boolean;
17
+ write(text: string): void;
18
+ error(text: string): void;
19
+ };
20
+ export declare const RECORD_HELP: Record<RecordProduct, string>;
21
+ /** Parsed like networkProductCommand; never obtains credentials for help or bad flags. */
22
+ export declare function recordCommand(product: RecordProduct, args: Args, out: Out, client: () => Promise<RecordClient>, signal?: AbortSignal): Promise<number>;
23
+ export {};