withruntime 0.23.0 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/COMPATIBILITY.md +66 -5
  2. package/E2B.md +1 -1
  3. package/README.md +36 -2
  4. package/README.src.md +35 -1
  5. package/compatibility-lock.json +3 -3
  6. package/dist/agents/browser.d.ts +12 -0
  7. package/dist/agents/browser.js +12 -0
  8. package/dist/agents/index.d.ts +7 -7
  9. package/dist/agents/index.js +7 -8
  10. package/dist/agents-cli.d.ts +1 -1
  11. package/dist/agents-cli.js +250 -3
  12. package/dist/agents-deploy.d.ts +186 -0
  13. package/dist/agents-deploy.js +752 -0
  14. package/dist/agents-file.d.ts +19 -0
  15. package/dist/agents-file.js +135 -0
  16. package/dist/apps/index.d.ts +10 -0
  17. package/dist/apps/index.js +11 -0
  18. package/dist/apps-cli.d.ts +3 -1
  19. package/dist/apps-cli.js +285 -38
  20. package/dist/blaxel/errors.js +2 -1
  21. package/dist/ci/index.d.ts +13 -0
  22. package/dist/ci/index.js +14 -0
  23. package/dist/ci-cli.d.ts +10 -0
  24. package/dist/ci-cli.js +402 -0
  25. package/dist/ci-import.d.ts +23 -0
  26. package/dist/ci-import.js +565 -0
  27. package/dist/cli.d.ts +18 -7
  28. package/dist/cli.js +775 -85
  29. package/dist/daytona/errors.js +2 -1
  30. package/dist/e2b/errors.js +2 -1
  31. package/dist/e2b/filesystem.d.ts +1 -0
  32. package/dist/e2b/filesystem.js +1 -1
  33. package/dist/e2b/sandbox.d.ts +11 -2
  34. package/dist/e2b/sandbox.js +22 -6
  35. package/dist/errors.d.ts +11 -4
  36. package/dist/errors.js +27 -4
  37. package/dist/fly/index.d.ts +102 -0
  38. package/dist/fly/index.js +930 -0
  39. package/dist/index.d.ts +7 -3
  40. package/dist/machine.d.ts +10 -6
  41. package/dist/machine.js +14 -6
  42. package/dist/modal/index.d.ts +34 -0
  43. package/dist/modal/index.js +128 -22
  44. package/dist/products/agents.d.ts +101 -3
  45. package/dist/products/agents.js +49 -0
  46. package/dist/products/apps.d.ts +206 -10
  47. package/dist/products/apps.js +172 -1
  48. package/dist/products/ci.d.ts +335 -0
  49. package/dist/products/ci.js +108 -0
  50. package/dist/products/index.d.ts +8 -0
  51. package/dist/products/index.js +15 -0
  52. package/dist/products/jobs.d.ts +105 -5
  53. package/dist/products/jobs.js +47 -3
  54. package/dist/products/network.d.ts +13 -0
  55. package/dist/products/observability.d.ts +1 -1
  56. package/dist/products/plans.d.ts +131 -0
  57. package/dist/products/plans.js +24 -0
  58. package/dist/products/reservations.d.ts +108 -0
  59. package/dist/products/reservations.js +41 -0
  60. package/dist/products/resources.d.ts +2 -1
  61. package/dist/products/secrets.d.ts +90 -6
  62. package/dist/products/secrets.js +8 -2
  63. package/dist/proxy.d.ts +3 -3
  64. package/dist/proxy.js +20 -0
  65. package/dist/sandbox.d.ts +29 -1
  66. package/dist/sandbox.js +56 -3
  67. package/dist/snapshots.d.ts +1 -1
  68. package/dist/switched-off.d.ts +5 -0
  69. package/dist/switched-off.js +8 -0
  70. package/dist/tar.d.ts +1 -1
  71. package/dist/tar.js +19 -1
  72. package/dist/transport.d.ts +1 -1
  73. package/dist/transport.js +48 -9
  74. package/dist/types.d.ts +35 -4
  75. package/dist/vercel/errors.d.ts +1 -1
  76. package/dist/vercel/errors.js +2 -1
  77. package/dist/vercel/snapshot.js +4 -2
  78. package/package.json +23 -6
@@ -0,0 +1,335 @@
1
+ import { Page } from "../page.js";
2
+ import type { RequestOptions, Transport } from "../transport.js";
3
+ export type CiCheckState = "queued" | "running" | "passed" | "failed" | "cancelled";
4
+ export type CiJobState = "queued" | "running" | "passed" | "failed" | "flaky" | "cached" | "cancelled" | "skipped";
5
+ /** A GitHub repository connected for checks. */
6
+ export type CiRepository = {
7
+ id: string;
8
+ name: string | null;
9
+ labels: Record<string, string>;
10
+ createdAt: number;
11
+ updatedAt: number;
12
+ deletedAt: number | null;
13
+ error: {
14
+ code: string;
15
+ message: string;
16
+ } | null;
17
+ /** owner/name on GitHub. */
18
+ repository: string;
19
+ /** The branch whose pushes are checked as landed. */
20
+ productionBranch: string;
21
+ /** Where in the repository its checks are written. */
22
+ configPath: string;
23
+ /** The organization's installation of Runtime's GitHub App it is read through. */
24
+ installation: number;
25
+ /** GitHub's id for it, learned from its first event. */
26
+ githubRepositoryId: number | null;
27
+ /** The GitHub Apps (`<app-slug>[bot]`, lowercase, sorted) whose pushes run
28
+ * as the code of someone who can write. */
29
+ trustedApps: string[];
30
+ state: "connected" | "disconnected";
31
+ };
32
+ export type ConnectCiRepository = {
33
+ repository: string;
34
+ productionBranch?: string;
35
+ configPath?: string;
36
+ installation?: number;
37
+ /** Trusted from the connect on, in the same request: a connection trusts
38
+ * no App until told, so one made again names them here. */
39
+ trustedApps?: string[];
40
+ name?: string;
41
+ labels?: Record<string, string>;
42
+ };
43
+ export type ListCiRepositories = {
44
+ limit?: number;
45
+ cursor?: string;
46
+ name?: string;
47
+ /** key:value, each one the repository must have. */
48
+ label?: string[];
49
+ state?: CiRepository["state"][];
50
+ };
51
+ /** One check: a commit of a connected repository, run as its plan of jobs. */
52
+ export type CiCheck = {
53
+ id: string;
54
+ repositoryId: string;
55
+ /** owner/name on GitHub. */
56
+ repository: string;
57
+ commit: string;
58
+ branch: string | null;
59
+ event: "push" | "pull_request" | "merge_group" | "rerun";
60
+ pullRequest: number | null;
61
+ baseCommit: string | null;
62
+ /** The GitHub login that pushed, opened or re-ran it. */
63
+ actor: string | null;
64
+ /** The repository's writers' code. A fork's pull request is not, and runs
65
+ * nothing until a writer re-runs it on GitHub. */
66
+ trusted: boolean;
67
+ /** Queued for a writer's approval: nothing of it runs. */
68
+ waiting: boolean;
69
+ approvedBy: string | null;
70
+ approvedAt: number | null;
71
+ /** Writers' code on the production branch, or a merge group. */
72
+ landed: boolean;
73
+ state: CiCheckState;
74
+ /** Why it ended. */
75
+ reason: string | null;
76
+ /** How many of its jobs are in each state. */
77
+ counts: Partial<Record<CiJobState, number>>;
78
+ /** Where its machines came from and how soon; null until the runner says. */
79
+ machines: CiMachines | null;
80
+ createdAt: number;
81
+ updatedAt: number;
82
+ startedAt: number | null;
83
+ endedAt: number | null;
84
+ };
85
+ /** Where a check's machines came from and how soon: woken from its pull
86
+ * request's own, left paused by its last check (reused), or from the warm
87
+ * pool (pooled); copies of batch forks (forked, in `forks` calls); made from
88
+ * the warm snapshot (created); left paused for its next push (kept); the
89
+ * first machine's, the first ask's whole and the first test's milliseconds;
90
+ * and its wait in the account's line. */
91
+ export type CiMachines = {
92
+ reused: number;
93
+ pooled: number;
94
+ forked: number;
95
+ forks: number;
96
+ created: number;
97
+ kept: number;
98
+ firstMs: number | null;
99
+ readyMs: number | null;
100
+ firstTestMs: number | null;
101
+ lineMs: number;
102
+ };
103
+ /** One job of a check's plan: a step, or one part of a step split in parts. */
104
+ export type CiJob = {
105
+ id: string;
106
+ checkId: string;
107
+ repositoryId: string;
108
+ name: string;
109
+ part: number;
110
+ parts: number;
111
+ needs: string[];
112
+ command: string;
113
+ cacheKey: string | null;
114
+ state: CiJobState;
115
+ /** The passed job a cached one stands on. */
116
+ cachedFrom: string | null;
117
+ exitCode: number | null;
118
+ reason: string | null;
119
+ /** The sandboxes it ran in. A failure's may be kept paused: wake it, or
120
+ * exec in it, with runtime.sandboxes. */
121
+ sandboxIds: string[];
122
+ githubCheckRun: number | null;
123
+ /** A review step's verdict on the commit; null for a command's job. */
124
+ review: CiReview | null;
125
+ ms: number | null;
126
+ createdAt: number;
127
+ updatedAt: number;
128
+ startedAt: number | null;
129
+ endedAt: number | null;
130
+ };
131
+ /** What one finding of a review is about. */
132
+ export type CiReviewKind = "bug" | "missed-case" | "data-at-risk" | "money-at-risk" | "auth-bypass" | "privilege-escalation" | "secret-exposed" | "made-public" | "command-injection" | "manipulation" | "other";
133
+ /** One thing a review found in the change. */
134
+ export type CiReviewFinding = {
135
+ kind: CiReviewKind;
136
+ file: string;
137
+ /** The line in the new file; 0 for the file as a whole. */
138
+ line: number;
139
+ /** What is wrong, and what it breaks. */
140
+ what: string;
141
+ /** What would put it right. */
142
+ fix: string;
143
+ };
144
+ /** A review step's verdict on one commit: it passes only with no findings. */
145
+ export type CiReview = {
146
+ verdict: "pass" | "block";
147
+ summary: string;
148
+ findings: CiReviewFinding[];
149
+ /** Things worth a look that do not block. */
150
+ notes: {
151
+ file: string;
152
+ line: number;
153
+ what: string;
154
+ }[];
155
+ /** The Runtime Agent that reviewed, the account it ran on and its model. */
156
+ agent: string;
157
+ account: string;
158
+ model: string;
159
+ /** The agent session that gave the verdict. */
160
+ session: string;
161
+ /** True when the diff was too long and its end was not read. */
162
+ cut: boolean;
163
+ };
164
+ /** A check with its jobs, in plan order. */
165
+ export type CiCheckDetail = CiCheck & {
166
+ jobs: CiJob[];
167
+ };
168
+ /** A job with the tail of its output: at most 256 KiB, the oldest dropped first. */
169
+ export type CiJobDetail = CiJob & {
170
+ log: string;
171
+ };
172
+ export type ListCiChecks = {
173
+ repositoryId?: string;
174
+ state?: CiCheckState[];
175
+ branch?: string;
176
+ /** A full commit SHA. */
177
+ commit?: string;
178
+ pullRequest?: number;
179
+ limit?: number;
180
+ cursor?: string;
181
+ };
182
+ /** One test file of a repository: its recent time and its last 20 runs. */
183
+ export type CiTest = {
184
+ repositoryId: string;
185
+ file: string;
186
+ ms: number;
187
+ /** Since when its failures do not fail a check; null: they do. */
188
+ quarantinedSince: number | null;
189
+ runs: {
190
+ at: number;
191
+ check: string;
192
+ job: string;
193
+ outcome: "passed" | "failed" | "flaky" | "skipped";
194
+ ms: number | null;
195
+ /** false for an approved outsider's run. */
196
+ writers: boolean;
197
+ }[];
198
+ updatedAt: number;
199
+ };
200
+ export type ListCiTests = {
201
+ quarantined?: boolean;
202
+ limit?: number;
203
+ cursor?: string;
204
+ };
205
+ /** One run of a test file: by commit and content key; its first run, its
206
+ * run again alone after a failure, or a repeat (a new test's 20, a flake's
207
+ * proof of 100). */
208
+ export type CiTestResult = {
209
+ file: string;
210
+ commit: string;
211
+ key: string;
212
+ passed: boolean;
213
+ attempt: "first" | "again" | "repeat";
214
+ ms: number | null;
215
+ machine: string | null;
216
+ checkId: string;
217
+ jobId: string;
218
+ /** A run of the production branch's own commit. */
219
+ main: boolean;
220
+ message: string | null;
221
+ at: number;
222
+ };
223
+ export type CiFlakeState = "quarantined" | "gating" | "fixed" | "deleted";
224
+ /** A test that passed and failed on the same inputs, one run main's:
225
+ * quarantined at once (it still runs and reports, and blocks nothing), or
226
+ * still gating when the repository protects it; handed to an owner with 48
227
+ * hours to fix it or delete it with a reason; fixed once 100 runs of a main
228
+ * commit in parallel forks all pass. */
229
+ export type CiFlake = {
230
+ id: string;
231
+ repositoryId: string;
232
+ file: string;
233
+ state: CiFlakeState;
234
+ gates: {
235
+ why: string;
236
+ words: string;
237
+ } | null;
238
+ proof: {
239
+ key: string;
240
+ commit: string;
241
+ checkId: string;
242
+ jobId: string;
243
+ failedIn: string[];
244
+ passedIn: string[];
245
+ };
246
+ again: number;
247
+ owner: {
248
+ login: string;
249
+ from: "codeowners" | "last change" | "handed" | null;
250
+ pullRequest: number | null;
251
+ branch: string | null;
252
+ } | null;
253
+ since: number;
254
+ dueAt: number;
255
+ overdue: boolean;
256
+ tried: {
257
+ blob: string;
258
+ at: number;
259
+ } | null;
260
+ proveAskedAt: number | null;
261
+ deleteReason: string | null;
262
+ endedAt: number | null;
263
+ endedCheckId: string | null;
264
+ updatedAt: number;
265
+ };
266
+ /** A flake with its test file's newest 200 runs and each failure's job,
267
+ * whose log `jobs.get` reads. */
268
+ export type CiFlakeDetail = CiFlake & {
269
+ runs: CiTestResult[];
270
+ failures: {
271
+ jobId: string;
272
+ checkId: string;
273
+ commit: string;
274
+ message: string | null;
275
+ at: number;
276
+ }[];
277
+ };
278
+ export type ListCiFlakes = {
279
+ repositoryId?: string;
280
+ state?: CiFlakeState[];
281
+ limit?: number;
282
+ cursor?: string;
283
+ };
284
+ /** An owner's say: its proof runs again at main's next commit, a new
285
+ * owner, or why its test is deleted. */
286
+ export type UpdateCiFlake = {
287
+ prove?: true;
288
+ owner?: string;
289
+ deleteReason?: string;
290
+ };
291
+ export declare function ci(t: Transport): {
292
+ repositories: {
293
+ /** Connect a GitHub repository for checks. Only a full key connects
294
+ * one, since every push runs its code for the whole account. */
295
+ connect: (input: ConnectCiRepository, options?: RequestOptions) => Promise<CiRepository>;
296
+ list: (query?: ListCiRepositories, options?: RequestOptions) => Promise<Page<CiRepository>>;
297
+ find: (idOrName: string, options?: RequestOptions) => Promise<CiRepository | undefined>;
298
+ /** Replaces the whole list of trusted Apps; `[]` trusts none. */
299
+ setTrustedApps: (id: string, trustedApps: string[], options?: RequestOptions) => Promise<CiRepository>;
300
+ /** Adds Apps to those it trusts, keeping the rest: `id` is its id or
301
+ * owner/name. */
302
+ trust: (id: string, apps: string[], options?: RequestOptions) => Promise<CiRepository>;
303
+ /** Takes Apps off those it trusts, keeping the rest. */
304
+ untrust: (id: string, apps: string[], options?: RequestOptions) => Promise<CiRepository>;
305
+ /** Disconnect: its checks still going are cancelled; what ended stays. */
306
+ disconnect: (id: string, options?: RequestOptions) => Promise<CiRepository>;
307
+ };
308
+ checks: {
309
+ /** Checks, newest first. */
310
+ list: (query?: ListCiChecks, options?: RequestOptions) => Promise<Page<CiCheck>>;
311
+ /** A check with its jobs in plan order. */
312
+ get: (id: string, options?: RequestOptions) => Promise<CiCheckDetail>;
313
+ /** Cancel a queued or running check: its jobs end and its machines
314
+ * are let go. A check that has ended is answered as it is. */
315
+ cancel: (id: string, options?: RequestOptions) => Promise<CiCheckDetail>;
316
+ };
317
+ jobs: {
318
+ /** A job with the tail of its log and the sandboxes it ran in. */
319
+ get: (id: string, options?: RequestOptions) => Promise<CiJobDetail>;
320
+ };
321
+ tests: {
322
+ /** A repository's test files by name, with their quarantine. */
323
+ list: (repositoryId: string, query?: ListCiTests, options?: RequestOptions) => Promise<Page<CiTest>>;
324
+ };
325
+ flakes: {
326
+ /** Flaky tests, newest first; `state: ["quarantined", "gating"]`
327
+ * lists the open ones. */
328
+ list: (query?: ListCiFlakes, options?: RequestOptions) => Promise<Page<CiFlake>>;
329
+ /** A flaky test with its runs and its failures' jobs. */
330
+ get: (id: string, options?: RequestOptions) => Promise<CiFlakeDetail>;
331
+ /** Ask for its 100 proof runs again, hand it on, or say why its test
332
+ * is deleted. */
333
+ update: (id: string, change: UpdateCiFlake, options?: RequestOptions) => Promise<CiFlakeDetail>;
334
+ };
335
+ };
@@ -0,0 +1,108 @@
1
+ /** CI/CD: each push and pull request of a connected GitHub repository is
2
+ * checked in sandboxes, as the plan its config writes. The runner writes the
3
+ * checks, their jobs and logs; these read them. In a private beta. */
4
+ import { RuntimeError } from "../errors.js";
5
+ import { Page } from "../page.js";
6
+ export function ci(t) {
7
+ const at = (base, id) => `${base}/${encodeURIComponent(id)}`;
8
+ async function paged(path, query, options) {
9
+ const page = await t.json({ method: "GET", path, query, ...options });
10
+ return new Page(page.data, page.nextCursor, (cursor) => paged(path, { ...query, cursor }, options));
11
+ }
12
+ const setTrustedApps = (id, trustedApps, options) => t.json({
13
+ method: "POST",
14
+ path: `${at("/v1/ci/repositories", id)}:update`,
15
+ body: { trustedApps },
16
+ ...options,
17
+ });
18
+ const listRepositories = (query = {}, options) => paged("/v1/ci/repositories", query, options);
19
+ /** A connected repository by its id or its owner/name. */
20
+ const find = async (idOrName, options) => {
21
+ const all = await (await listRepositories({ limit: 100, state: ["connected"] }, options)).toArray(Infinity);
22
+ const wanted = idOrName.toLowerCase();
23
+ return all.find((r) => r.id === wanted || r.repository.toLowerCase() === wanted);
24
+ };
25
+ /** As find, or a not_found that says what this key lists. */
26
+ const needed = async (idOrName, options) => {
27
+ const repo = await find(idOrName, options);
28
+ if (repo)
29
+ return repo;
30
+ throw new RuntimeError({
31
+ message: `No connected CI/CD repository ${idOrName} that this key lists.`,
32
+ code: "not_found",
33
+ status: 404,
34
+ hint: "Any key an owner or admin made lists the account's repositories; another key, only those its own agent connected.",
35
+ });
36
+ };
37
+ return {
38
+ repositories: {
39
+ /** Connect a GitHub repository for checks. Only a full key connects
40
+ * one, since every push runs its code for the whole account. */
41
+ connect: (input, options) => t.json({
42
+ method: "POST",
43
+ path: "/v1/ci/repositories",
44
+ body: input,
45
+ ...options,
46
+ }),
47
+ list: listRepositories,
48
+ find,
49
+ /** Replaces the whole list of trusted Apps; `[]` trusts none. */
50
+ setTrustedApps,
51
+ /** Adds Apps to those it trusts, keeping the rest: `id` is its id or
52
+ * owner/name. */
53
+ trust: async (id, apps, options) => {
54
+ const repo = await needed(id, options);
55
+ const all = [...new Set([...repo.trustedApps, ...apps.map((a) => a.toLowerCase())])];
56
+ return setTrustedApps(repo.id, all, options);
57
+ },
58
+ /** Takes Apps off those it trusts, keeping the rest. */
59
+ untrust: async (id, apps, options) => {
60
+ const repo = await needed(id, options);
61
+ const drop = new Set(apps.map((a) => a.toLowerCase()));
62
+ return setTrustedApps(repo.id, repo.trustedApps.filter((a) => !drop.has(a)), options);
63
+ },
64
+ /** Disconnect: its checks still going are cancelled; what ended stays. */
65
+ disconnect: (id, options) => t.json({
66
+ method: "DELETE",
67
+ path: at("/v1/ci/repositories", id),
68
+ ...options,
69
+ }),
70
+ },
71
+ checks: {
72
+ /** Checks, newest first. */
73
+ list: (query = {}, options) => paged("/v1/ci/checks", query, options),
74
+ /** A check with its jobs in plan order. */
75
+ get: (id, options) => t.json({ method: "GET", path: at("/v1/ci/checks", id), ...options }),
76
+ /** Cancel a queued or running check: its jobs end and its machines
77
+ * are let go. A check that has ended is answered as it is. */
78
+ cancel: (id, options) => t.json({
79
+ method: "POST",
80
+ path: `${at("/v1/ci/checks", id)}:cancel`,
81
+ ...options,
82
+ }),
83
+ },
84
+ jobs: {
85
+ /** A job with the tail of its log and the sandboxes it ran in. */
86
+ get: (id, options) => t.json({ method: "GET", path: at("/v1/ci/jobs", id), ...options }),
87
+ },
88
+ tests: {
89
+ /** A repository's test files by name, with their quarantine. */
90
+ list: (repositoryId, query = {}, options) => paged("/v1/ci/tests", { ...query, repositoryId }, options),
91
+ },
92
+ flakes: {
93
+ /** Flaky tests, newest first; `state: ["quarantined", "gating"]`
94
+ * lists the open ones. */
95
+ list: (query = {}, options) => paged("/v1/ci/flakes", query, options),
96
+ /** A flaky test with its runs and its failures' jobs. */
97
+ get: (id, options) => t.json({ method: "GET", path: at("/v1/ci/flakes", id), ...options }),
98
+ /** Ask for its 100 proof runs again, hand it on, or say why its test
99
+ * is deleted. */
100
+ update: (id, change, options) => t.json({
101
+ method: "POST",
102
+ path: `${at("/v1/ci/flakes", id)}:update`,
103
+ body: change,
104
+ ...options,
105
+ }),
106
+ },
107
+ };
108
+ }
@@ -8,12 +8,14 @@ import { sandboxNetwork } from "./network.js";
8
8
  import { domains, ips, networks, ports } from "./network-products.js";
9
9
  import { sandboxPreviews } from "./previews.js";
10
10
  import { referrals } from "./referrals.js";
11
+ import { plans } from "./plans.js";
11
12
  import { billing } from "./billing.js";
12
13
  import { audit } from "./audit.js";
13
14
  import { sso } from "./sso.js";
14
15
  import { switching } from "./switching.js";
15
16
  import { limits } from "./limits.js";
16
17
  import { keys } from "./api-keys.js";
18
+ import { reservations } from "./reservations.js";
17
19
  import { volumes } from "./volumes.js";
18
20
  import { jobs } from "./jobs.js";
19
21
  import { sandboxMounts } from "./mounts.js";
@@ -23,15 +25,19 @@ import { mcp, sandboxMcp } from "./mcp.js";
23
25
  import { events, otel, sandboxMetrics, webhooks } from "./observability.js";
24
26
  import { agents } from "./agents.js";
25
27
  import { builds } from "./builds.js";
28
+ import { ci } from "./ci.js";
26
29
  import { containers } from "./containers.js";
30
+ import { apps } from "./apps.js";
27
31
  export declare const clientExtensions: {
28
32
  images: typeof images;
29
33
  volumes: typeof volumes;
30
34
  jobs: typeof jobs;
31
35
  referrals: typeof referrals;
36
+ plans: typeof plans;
32
37
  billing: typeof billing;
33
38
  limits: typeof limits;
34
39
  keys: typeof keys;
40
+ reservations: typeof reservations;
35
41
  switching: typeof switching;
36
42
  secrets: typeof secrets;
37
43
  webhooks: typeof webhooks;
@@ -46,7 +52,9 @@ export declare const clientExtensions: {
46
52
  networks: typeof networks;
47
53
  agents: typeof agents;
48
54
  builds: typeof builds;
55
+ ci: typeof ci;
49
56
  containers: typeof containers;
57
+ apps: typeof apps;
50
58
  };
51
59
  export declare const sandboxExtensions: {
52
60
  interpreter: typeof sandboxInterpreter;
@@ -6,12 +6,14 @@ import { sandboxNetwork } from "./network.js";
6
6
  import { domains, ips, networks, ports } from "./network-products.js";
7
7
  import { sandboxPreviews } from "./previews.js";
8
8
  import { referrals } from "./referrals.js";
9
+ import { plans } from "./plans.js";
9
10
  import { billing } from "./billing.js";
10
11
  import { audit } from "./audit.js";
11
12
  import { sso } from "./sso.js";
12
13
  import { switching } from "./switching.js";
13
14
  import { limits } from "./limits.js";
14
15
  import { keys } from "./api-keys.js";
16
+ import { reservations } from "./reservations.js";
15
17
  import { volumes } from "./volumes.js";
16
18
  import { jobs } from "./jobs.js";
17
19
  import { sandboxMounts } from "./mounts.js";
@@ -21,7 +23,13 @@ import { mcp, sandboxMcp } from "./mcp.js";
21
23
  import { events, otel, sandboxMetrics, webhooks } from "./observability.js";
22
24
  import { agents } from "./agents.js";
23
25
  import { builds } from "./builds.js";
26
+ import { ci } from "./ci.js";
24
27
  import { containers } from "./containers.js";
28
+ // The hub loads this file, so it loads apps.ts and resources.ts too: request
29
+ // builders over Transport whose top level holds only types, functions and
30
+ // imports of files the hub loads, so importing them runs nothing in the hub
31
+ // (agents/hub-sdk-products.test.ts parses every product file the hub loads).
32
+ import { apps } from "./apps.js";
25
33
  /* HOW A LANE ADDS A PRODUCT TO THE SDK
26
34
  *
27
35
  * 1. Write src/products/<name>.ts exporting a factory:
@@ -42,9 +50,11 @@ export const clientExtensions = {
42
50
  volumes,
43
51
  jobs,
44
52
  referrals,
53
+ plans,
45
54
  billing,
46
55
  limits,
47
56
  keys,
57
+ reservations,
48
58
  switching,
49
59
  secrets,
50
60
  webhooks,
@@ -60,7 +70,12 @@ export const clientExtensions = {
60
70
  agents,
61
71
  // Builds (beta): the API answers product_in_beta outside its list.
62
72
  builds,
73
+ // CI/CD (beta): the API answers product_in_beta outside its list.
74
+ ci,
63
75
  containers,
76
+ // A private beta (PRODUCT_BETAS): an account outside it is refused with
77
+ // product_in_beta until Apps launches.
78
+ apps,
64
79
  };
65
80
  export const sandboxExtensions = {
66
81
  interpreter: sandboxInterpreter,