withruntime 0.33.2 → 0.34.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/E2B.md +7 -0
- package/dist/agents-cli.d.ts +1 -1
- package/dist/agents-cli.js +171 -7
- package/dist/agents-deploy.d.ts +13 -3
- package/dist/agents-deploy.js +68 -9
- package/dist/apps-cli.d.ts +1 -1
- package/dist/apps-cli.js +41 -9
- package/dist/browsers/index.d.ts +9 -0
- package/dist/browsers/index.js +10 -0
- package/dist/browsers-cli.d.ts +13 -0
- package/dist/browsers-cli.js +160 -0
- package/dist/ci-cli.d.ts +1 -1
- package/dist/ci-cli.js +66 -13
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +94 -10
- package/dist/desktops/index.d.ts +9 -0
- package/dist/desktops/index.js +10 -0
- package/dist/e2b/code-interpreter.d.ts +3 -12
- package/dist/e2b/code-interpreter.js +3 -6
- package/dist/e2b/index.d.ts +7 -1
- package/dist/e2b/index.js +9 -2
- package/dist/index.d.ts +6 -4
- package/dist/products/agents.d.ts +162 -8
- package/dist/products/agents.js +108 -3
- package/dist/products/apps.d.ts +46 -5
- package/dist/products/browsers.d.ts +26 -0
- package/dist/products/browsers.js +11 -0
- package/dist/products/ci.d.ts +49 -7
- package/dist/products/ci.js +15 -1
- package/dist/products/desktops.d.ts +71 -0
- package/dist/products/desktops.js +27 -0
- package/dist/products/index.d.ts +4 -0
- package/dist/products/index.js +5 -0
- package/dist/products/network.d.ts +4 -2
- package/dist/products/secrets.d.ts +10 -2
- package/dist/products/secrets.js +27 -7
- package/dist/products/uptime.d.ts +97 -0
- package/dist/products/uptime.js +42 -0
- package/dist/products/volumes.d.ts +41 -9
- package/dist/products/volumes.js +5 -2
- package/dist/transport.d.ts +4 -1
- package/dist/transport.js +2 -2
- package/package.json +13 -2
package/dist/products/agents.js
CHANGED
|
@@ -22,7 +22,9 @@ import { Page } from "../page.js";
|
|
|
22
22
|
const START = 'npx -y @anthropic-ai/claude-code --dangerously-skip-permissions --mcp-config ~/.runtime-agent/mcp.json -p "$(cat ~/.runtime-agent/start.md)"';
|
|
23
23
|
const CODEX = 'npx -y @openai/codex exec --dangerously-bypass-approvals-and-sandbox "$(cat ~/.runtime-agent/start.md)"';
|
|
24
24
|
const GEMINI = 'npx -y @google/gemini-cli --yolo -p "$(cat ~/.runtime-agent/start.md)"';
|
|
25
|
-
|
|
25
|
+
const REVIEW = "python3 ~/.runtime-agent/runtime-agent review";
|
|
26
|
+
const JUDGE = "python3 ~/.runtime-agent/runtime-agent judge";
|
|
27
|
+
/** The harnesses (agents-contract.md); tests/agents.test.ts holds them
|
|
26
28
|
* to packages/cloud-guide/agent-templates.json. */
|
|
27
29
|
export const AGENT_TEMPLATES = {
|
|
28
30
|
"claude-code": {
|
|
@@ -70,6 +72,36 @@ export const AGENT_TEMPLATES = {
|
|
|
70
72
|
subscription: null,
|
|
71
73
|
definition: { command: "python3 ~/agent.py", secrets: ["OPENAI_API_KEY"] },
|
|
72
74
|
},
|
|
75
|
+
review: {
|
|
76
|
+
key: "review",
|
|
77
|
+
title: "Code review",
|
|
78
|
+
command: REVIEW,
|
|
79
|
+
apiKeySecret: "ANTHROPIC_API_KEY",
|
|
80
|
+
apiKeyHost: "api.anthropic.com",
|
|
81
|
+
subscription: "a token per account: run `claude setup-token` on your own computer (Pro/Max) for each, store each with `runtime secrets set CLAUDE_1` scoped to api.anthropic.com, then name them all in pool (--pool CLAUDE_1 --pool CLAUDE_2)",
|
|
82
|
+
definition: {
|
|
83
|
+
command: REVIEW,
|
|
84
|
+
pool: ["ANTHROPIC_API_KEY"],
|
|
85
|
+
vcpu: 2,
|
|
86
|
+
memoryMiB: 2048,
|
|
87
|
+
maxSessionSeconds: 1800,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
judge: {
|
|
91
|
+
key: "judge",
|
|
92
|
+
title: "Your rules",
|
|
93
|
+
command: JUDGE,
|
|
94
|
+
apiKeySecret: "ANTHROPIC_API_KEY",
|
|
95
|
+
apiKeyHost: "api.anthropic.com",
|
|
96
|
+
subscription: "a token per account, as for review: `runtime secrets set CLAUDE_1` scoped to api.anthropic.com for each, then name them all in pool; its instructions are the rules that block",
|
|
97
|
+
definition: {
|
|
98
|
+
command: JUDGE,
|
|
99
|
+
pool: ["ANTHROPIC_API_KEY"],
|
|
100
|
+
vcpu: 2,
|
|
101
|
+
memoryMiB: 2048,
|
|
102
|
+
maxSessionSeconds: 1800,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
73
105
|
};
|
|
74
106
|
/** A harness by a key read from a file or a flag, or undefined. */
|
|
75
107
|
export function agentTemplate(key) {
|
|
@@ -166,6 +198,28 @@ export function agents(t) {
|
|
|
166
198
|
});
|
|
167
199
|
return new Page(page.data, page.nextCursor, (cursor) => listSessions({ ...query, cursor }, options));
|
|
168
200
|
};
|
|
201
|
+
const listAsks = async (query = {}, options) => {
|
|
202
|
+
const { labels, ...rest } = query;
|
|
203
|
+
const page = await t.json({
|
|
204
|
+
method: "GET",
|
|
205
|
+
path: "/v1/agents/asks",
|
|
206
|
+
query: {
|
|
207
|
+
...rest,
|
|
208
|
+
...(labels ? { label: Object.entries(labels).map(([k, v]) => `${k}:${v}`) } : {}),
|
|
209
|
+
},
|
|
210
|
+
...options,
|
|
211
|
+
});
|
|
212
|
+
return new Page(page.data, page.nextCursor, (cursor) => listAsks({ ...query, cursor }, options));
|
|
213
|
+
};
|
|
214
|
+
const listHeld = async (trigger, query = {}, options) => {
|
|
215
|
+
const page = await t.json({
|
|
216
|
+
method: "GET",
|
|
217
|
+
path: `/v1/agents/triggers/${enc(trigger)}/held`,
|
|
218
|
+
query,
|
|
219
|
+
...options,
|
|
220
|
+
});
|
|
221
|
+
return new Page(page.data, page.nextCursor, (cursor) => listHeld(trigger, { ...query, cursor }, options));
|
|
222
|
+
};
|
|
169
223
|
const listMemory = async (agent, query = {}, options) => {
|
|
170
224
|
const page = await t.json({
|
|
171
225
|
method: "GET",
|
|
@@ -227,6 +281,21 @@ export function agents(t) {
|
|
|
227
281
|
});
|
|
228
282
|
},
|
|
229
283
|
},
|
|
284
|
+
/** The account's inbox: the questions its agents' sessions need answered
|
|
285
|
+
* to go on, one row per step however many sessions ask it. */
|
|
286
|
+
asks: {
|
|
287
|
+
/** Newest first; open ones unless `state` says otherwise. */
|
|
288
|
+
list: listAsks,
|
|
289
|
+
get: (id, options) => t.json({ method: "GET", path: `/v1/agents/asks/${enc(id)}`, ...options }),
|
|
290
|
+
/** Every session asking it reads the answer next, and wakes. An ask no
|
|
291
|
+
* longer open is refused with `ask_closed`. */
|
|
292
|
+
answer: (id, answer, options) => t.json({
|
|
293
|
+
method: "POST",
|
|
294
|
+
path: `/v1/agents/asks/${enc(id)}/answer`,
|
|
295
|
+
body: answer,
|
|
296
|
+
...options,
|
|
297
|
+
}),
|
|
298
|
+
},
|
|
230
299
|
triggers: {
|
|
231
300
|
create: (agent, input, options) => t.json({
|
|
232
301
|
method: "POST",
|
|
@@ -239,7 +308,8 @@ export function agents(t) {
|
|
|
239
308
|
path: `/v1/agents/${enc(agent)}/triggers`,
|
|
240
309
|
...options,
|
|
241
310
|
})).data,
|
|
242
|
-
/**
|
|
311
|
+
/** Held: a webhook's calls are kept for you (see `held`), saying
|
|
312
|
+
* `why`; nothing else is held. */
|
|
243
313
|
pause: (id, why, options) => t.json({
|
|
244
314
|
method: "POST",
|
|
245
315
|
path: `/v1/agents/triggers/${enc(id)}/pause`,
|
|
@@ -259,6 +329,40 @@ export function agents(t) {
|
|
|
259
329
|
...options,
|
|
260
330
|
});
|
|
261
331
|
},
|
|
332
|
+
/** Its rules, whole, in place: its secret stays. `{}` is every default. */
|
|
333
|
+
setRules: (id, rules, options) => t.json({
|
|
334
|
+
method: "PATCH",
|
|
335
|
+
path: `/v1/agents/triggers/${enc(id)}`,
|
|
336
|
+
body: { rules },
|
|
337
|
+
...options,
|
|
338
|
+
}),
|
|
339
|
+
/** A webhook trigger's call, as its sender makes it: by the trigger's
|
|
340
|
+
* secret, never your key. A call with the key of an open session joins
|
|
341
|
+
* it. Pass `idempotencyKey` to make a retry the same call. */
|
|
342
|
+
call: (id, secret, call, options) => t.json({
|
|
343
|
+
method: "POST",
|
|
344
|
+
path: `/v1/agents/triggers/${enc(id)}/calls`,
|
|
345
|
+
body: call,
|
|
346
|
+
bearer: secret,
|
|
347
|
+
...options,
|
|
348
|
+
}),
|
|
349
|
+
/** Calls it held for you, newest first. */
|
|
350
|
+
held: listHeld,
|
|
351
|
+
/** Start a held call: one session with it and every call held for its
|
|
352
|
+
* key since, oldest first. */
|
|
353
|
+
startHeld: (id, call, options) => t.json({
|
|
354
|
+
method: "POST",
|
|
355
|
+
path: `/v1/agents/triggers/${enc(id)}/held/${enc(call)}/start`,
|
|
356
|
+
body: {},
|
|
357
|
+
...options,
|
|
358
|
+
}),
|
|
359
|
+
/** Dismiss a held call: nothing runs. */
|
|
360
|
+
dismissHeld: (id, call, options) => t.json({
|
|
361
|
+
method: "POST",
|
|
362
|
+
path: `/v1/agents/triggers/${enc(id)}/held/${enc(call)}/dismiss`,
|
|
363
|
+
body: {},
|
|
364
|
+
...options,
|
|
365
|
+
}),
|
|
262
366
|
},
|
|
263
367
|
/** Its built-in memory: text files kept across sessions, which the
|
|
264
368
|
* agent reads, writes and searches from inside its sessions. A scope is
|
|
@@ -292,7 +396,8 @@ export function agents(t) {
|
|
|
292
396
|
})).deleted,
|
|
293
397
|
},
|
|
294
398
|
/** The harnesses, as data: claude-code, codex, gemini-cli,
|
|
295
|
-
* claude-agent-sdk, openai-agents-sdk
|
|
399
|
+
* claude-agent-sdk, openai-agents-sdk, review (a CI/CD agent step's
|
|
400
|
+
* reviewer) and judge (an agent step held to your instructions alone). */
|
|
296
401
|
templates: AGENT_TEMPLATES,
|
|
297
402
|
/** The uses, as data: support (your customers) and team (your team). */
|
|
298
403
|
uses: AGENT_USES,
|
package/dist/products/apps.d.ts
CHANGED
|
@@ -39,7 +39,42 @@ export type StatefulSettings = {
|
|
|
39
39
|
/** Seconds a stopped copy has after SIGTERM to exit. */
|
|
40
40
|
stopGraceSeconds: number;
|
|
41
41
|
};
|
|
42
|
-
|
|
42
|
+
/** How an App's new version goes live: every copy together (at_once, the
|
|
43
|
+
* default), or staged: one copy of it beside the live version's, then about
|
|
44
|
+
* 10%, 50% and all of them, each stage judged on its visitors' errors and
|
|
45
|
+
* speed before the next. A stage that does worse goes back: its copies
|
|
46
|
+
* finish their requests and stop, then the deploy fails (deploy_stage_failed)
|
|
47
|
+
* and the live version never stops serving. */
|
|
48
|
+
export type ReleaseStages = "at_once" | "staged";
|
|
49
|
+
export type ReleaseSettings = {
|
|
50
|
+
releaseStages: ReleaseStages;
|
|
51
|
+
/** 60 to 3600 seconds; defaults to 300. How long each stage runs once its
|
|
52
|
+
* copies serve before it is judged. */
|
|
53
|
+
releaseSoakSeconds: number;
|
|
54
|
+
};
|
|
55
|
+
/** An App's staged release under way, or its last. */
|
|
56
|
+
export type StagedRelease = {
|
|
57
|
+
version: number;
|
|
58
|
+
/** The version live when it began, serving beside it. */
|
|
59
|
+
from: number;
|
|
60
|
+
/** rolling: its stages go live; back: a stage did worse and its copies
|
|
61
|
+
* leave; done: every copy runs it; failed: it went back (or its copies
|
|
62
|
+
* failed their health check) and the version failed; ended: another
|
|
63
|
+
* deploy or a rollback took its place. */
|
|
64
|
+
state: "rolling" | "back" | "done" | "failed" | "ended";
|
|
65
|
+
stage: number;
|
|
66
|
+
stages: number;
|
|
67
|
+
/** Copies of the new version the stage serves beside the old version's. */
|
|
68
|
+
copies: number;
|
|
69
|
+
/** Copies the release walks to. */
|
|
70
|
+
of: number;
|
|
71
|
+
soakSeconds: number;
|
|
72
|
+
/** Its last step, in words. */
|
|
73
|
+
detail: string;
|
|
74
|
+
startedAt: number;
|
|
75
|
+
updatedAt: number;
|
|
76
|
+
};
|
|
77
|
+
export type App = AppSettings & StatefulSettings & ReleaseSettings & {
|
|
43
78
|
id: string;
|
|
44
79
|
name: string | null;
|
|
45
80
|
/** Its address for life, its name then its account's:
|
|
@@ -58,6 +93,8 @@ export type App = AppSettings & StatefulSettings & {
|
|
|
58
93
|
} | null;
|
|
59
94
|
liveVersion: number | null;
|
|
60
95
|
previousVersion: number | null;
|
|
96
|
+
/** Its staged release under way, or its last; null before its first. */
|
|
97
|
+
stagedRelease: StagedRelease | null;
|
|
61
98
|
/** While a copy waits for room in its region: its account's lane, its
|
|
62
99
|
* place in line (1 is next), how many wait ahead by lane, and why.
|
|
63
100
|
* Higher lanes get room first. Absent while nothing of it waits. */
|
|
@@ -69,7 +106,7 @@ export type AppLine = {
|
|
|
69
106
|
ahead: Record<string, number>;
|
|
70
107
|
words: string;
|
|
71
108
|
};
|
|
72
|
-
export type RuntimeFunction = Omit<App, "minCopies" | keyof StatefulSettings> & {
|
|
109
|
+
export type RuntimeFunction = Omit<App, "minCopies" | keyof StatefulSettings | keyof ReleaseSettings | "stagedRelease"> & {
|
|
73
110
|
minCopies: 0;
|
|
74
111
|
/** 250 to 5000 ms: at most how long a copy stays awake after its last request ends. */
|
|
75
112
|
sleepAfterMs: number;
|
|
@@ -125,14 +162,18 @@ export type CreateApp = Omit<CreateFunction, "minCopies" | "sleepAfterMs"> & {
|
|
|
125
162
|
volume?: AppVolume;
|
|
126
163
|
/** 0 to 900; defaults to 30. */
|
|
127
164
|
stopGraceSeconds?: number;
|
|
165
|
+
/** Defaults to "at_once"; see ReleaseStages. */
|
|
166
|
+
releaseStages?: ReleaseStages;
|
|
167
|
+
/** 60 to 3600; defaults to 300. */
|
|
168
|
+
releaseSoakSeconds?: number;
|
|
128
169
|
};
|
|
129
|
-
export type UpdateApp = Partial<AppSettings & StatefulSettings> & {
|
|
170
|
+
export type UpdateApp = Partial<AppSettings & StatefulSettings & ReleaseSettings> & {
|
|
130
171
|
name?: string | null;
|
|
131
172
|
labels?: Record<string, string>;
|
|
132
173
|
/** Only Functions sleep on this rule; an App is refused it. */
|
|
133
174
|
sleepAfterMs?: never;
|
|
134
175
|
};
|
|
135
|
-
export type UpdateFunction = Omit<UpdateApp, "minCopies" | "sleepAfterMs" | keyof StatefulSettings> & {
|
|
176
|
+
export type UpdateFunction = Omit<UpdateApp, "minCopies" | "sleepAfterMs" | keyof StatefulSettings | keyof ReleaseSettings> & {
|
|
136
177
|
minCopies?: never;
|
|
137
178
|
/** 250 to 5000 ms; see CreateFunction.sleepAfterMs. */
|
|
138
179
|
sleepAfterMs?: number;
|
|
@@ -159,7 +200,7 @@ export type AppDeploy = {
|
|
|
159
200
|
} | {
|
|
160
201
|
state: "failed" | "superseded";
|
|
161
202
|
error: {
|
|
162
|
-
code: "deploy_build_failed" | "deploy_health_failed" | "deploy_stop_failed" | "deploy_switch_failed" | "deploy_superseded";
|
|
203
|
+
code: "deploy_build_failed" | "deploy_health_failed" | "deploy_stop_failed" | "deploy_stage_failed" | "deploy_switch_failed" | "deploy_superseded";
|
|
163
204
|
message: string;
|
|
164
205
|
hint: string;
|
|
165
206
|
lastOutput: string;
|
|
@@ -40,6 +40,28 @@ export type BrowserInfo = {
|
|
|
40
40
|
liveViewUrl?: string;
|
|
41
41
|
hint?: string;
|
|
42
42
|
};
|
|
43
|
+
export type BrowserScreenshot = {
|
|
44
|
+
/** An http(s) address, opened in a new tab that is closed after. */
|
|
45
|
+
url?: string;
|
|
46
|
+
/** The whole page, not only the window. */
|
|
47
|
+
fullPage?: boolean;
|
|
48
|
+
format?: "png" | "jpeg";
|
|
49
|
+
/** 0 to 10000 ms after the page loads, for late scripts. */
|
|
50
|
+
waitMs?: number;
|
|
51
|
+
};
|
|
52
|
+
export type BrowserScreenshotResult = {
|
|
53
|
+
/** Where the page ended, after redirects. */
|
|
54
|
+
url: string;
|
|
55
|
+
title: string;
|
|
56
|
+
/** The page's HTTP status; null for the page already shown. */
|
|
57
|
+
status: number | null;
|
|
58
|
+
mimeType: "image/png" | "image/jpeg";
|
|
59
|
+
bytes: number;
|
|
60
|
+
width: number | null;
|
|
61
|
+
height: number | null;
|
|
62
|
+
/** The image. */
|
|
63
|
+
base64: string;
|
|
64
|
+
};
|
|
43
65
|
export type BrowserConnectOptions = {
|
|
44
66
|
playwright: [endpointURL: string, options: {
|
|
45
67
|
headers: Record<string, string>;
|
|
@@ -66,6 +88,10 @@ export declare function browsers(t: Transport): {
|
|
|
66
88
|
list: (query?: ListBrowsers, options?: RequestOptions) => Promise<Page<Browser>>;
|
|
67
89
|
/** Change a browser's name or labels without changing its compute settings. */
|
|
68
90
|
update(id: string, input: UpdateBrowser, options?: RequestOptions): Promise<Browser>;
|
|
91
|
+
/** Open `url` in a new tab and shoot it once it loads (without `url`, what
|
|
92
|
+
* the browser shows now); the image is `base64`, its page's url, title
|
|
93
|
+
* and HTTP status beside it. Runs inside the browser's own sandbox. */
|
|
94
|
+
screenshot(id: string, input?: BrowserScreenshot, options?: RequestOptions): Promise<BrowserScreenshotResult>;
|
|
69
95
|
/** End a browser by id; pass RequestOptions to bound or deduplicate the request. */
|
|
70
96
|
delete: (id: string, options?: RequestOptions) => Promise<void>;
|
|
71
97
|
};
|
|
@@ -96,6 +96,17 @@ export function browsers(t) {
|
|
|
96
96
|
...options,
|
|
97
97
|
}));
|
|
98
98
|
},
|
|
99
|
+
/** Open `url` in a new tab and shoot it once it loads (without `url`, what
|
|
100
|
+
* the browser shows now); the image is `base64`, its page's url, title
|
|
101
|
+
* and HTTP status beside it. Runs inside the browser's own sandbox. */
|
|
102
|
+
screenshot(id, input = {}, options) {
|
|
103
|
+
return t.json({
|
|
104
|
+
method: "POST",
|
|
105
|
+
path: `${path(id)}:screenshot`,
|
|
106
|
+
body: input,
|
|
107
|
+
...options,
|
|
108
|
+
});
|
|
109
|
+
},
|
|
99
110
|
/** End a browser by id; pass RequestOptions to bound or deduplicate the request. */
|
|
100
111
|
delete: remove,
|
|
101
112
|
};
|
package/dist/products/ci.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export type CiCheck = {
|
|
|
65
65
|
/** The GitHub login that pushed, opened or re-ran it. */
|
|
66
66
|
actor: string | null;
|
|
67
67
|
/** The repository's writers' code. A fork's pull request is not, and runs
|
|
68
|
-
* nothing
|
|
68
|
+
* nothing; a writer can open it again from a branch of the repository. */
|
|
69
69
|
trusted: boolean;
|
|
70
70
|
/** Queued for a writer's approval: nothing of it runs. */
|
|
71
71
|
waiting: boolean;
|
|
@@ -144,7 +144,8 @@ export type CiReviewFinding = {
|
|
|
144
144
|
/** What would put it right. */
|
|
145
145
|
fix: string;
|
|
146
146
|
};
|
|
147
|
-
/**
|
|
147
|
+
/** An agent step's verdict on one commit (`review:` is its short form): it
|
|
148
|
+
* passes only with no findings. */
|
|
148
149
|
export type CiReview = {
|
|
149
150
|
verdict: "pass" | "block";
|
|
150
151
|
summary: string;
|
|
@@ -155,10 +156,11 @@ export type CiReview = {
|
|
|
155
156
|
line: number;
|
|
156
157
|
what: string;
|
|
157
158
|
}[];
|
|
158
|
-
/** The Runtime Agent that
|
|
159
|
+
/** The Runtime Agent that judged, and the model the step asked for. */
|
|
159
160
|
agent: string;
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
model: string | null;
|
|
162
|
+
/** The Claude account a verdict before agent steps ran on. */
|
|
163
|
+
account?: string;
|
|
162
164
|
/** The agent session that gave the verdict. */
|
|
163
165
|
session: string;
|
|
164
166
|
/** True when the diff was too long and its end was not read. */
|
|
@@ -168,6 +170,12 @@ export type CiReview = {
|
|
|
168
170
|
export type CiCheckDetail = CiCheck & {
|
|
169
171
|
jobs: CiJob[];
|
|
170
172
|
};
|
|
173
|
+
/** A cancel's answer to a key that may cancel the check but not read it:
|
|
174
|
+
* its id and state, nothing of its jobs or logs. */
|
|
175
|
+
export type CiCancelled = {
|
|
176
|
+
id: string;
|
|
177
|
+
state: CiCheckState;
|
|
178
|
+
};
|
|
171
179
|
/** A job with the tail of its output: at most 256 KiB, the oldest dropped first. */
|
|
172
180
|
export type CiJobDetail = CiJob & {
|
|
173
181
|
log: string;
|
|
@@ -291,6 +299,30 @@ export type UpdateCiFlake = {
|
|
|
291
299
|
owner?: string;
|
|
292
300
|
deleteReason?: string;
|
|
293
301
|
};
|
|
302
|
+
/** One step a release took, as it took it: a migration's copy test or
|
|
303
|
+
* apply, a deploy ref moved, a server's canary or release, the website's
|
|
304
|
+
* deploy or promote, or a wait with why. */
|
|
305
|
+
export type CiReleaseStep = {
|
|
306
|
+
id: number;
|
|
307
|
+
repositoryId: string;
|
|
308
|
+
/** The commit this step of the release is of. */
|
|
309
|
+
commit: string;
|
|
310
|
+
/** Who took it: `mover` (the release on CI/CD's pass) or the deploy
|
|
311
|
+
* target that walks it (`hostd`, `controller`, `settings`, `follower`). */
|
|
312
|
+
source: string;
|
|
313
|
+
/** The server it was on, when it was on one. */
|
|
314
|
+
host: string | null;
|
|
315
|
+
line: string;
|
|
316
|
+
/** Unix milliseconds. */
|
|
317
|
+
at: number;
|
|
318
|
+
};
|
|
319
|
+
export type ListCiReleaseSteps = {
|
|
320
|
+
repositoryId?: string;
|
|
321
|
+
/** Only this commit's release. */
|
|
322
|
+
commit?: string;
|
|
323
|
+
limit?: number;
|
|
324
|
+
cursor?: string;
|
|
325
|
+
};
|
|
294
326
|
export declare function ci(t: Transport): {
|
|
295
327
|
repositories: {
|
|
296
328
|
/** Connect a GitHub repository for checks. Only a full key connects
|
|
@@ -320,8 +352,13 @@ export declare function ci(t: Transport): {
|
|
|
320
352
|
/** A check with its jobs in plan order. */
|
|
321
353
|
get: (id: string, options?: RequestOptions) => Promise<CiCheckDetail>;
|
|
322
354
|
/** Cancel a queued or running check: its jobs end and its machines
|
|
323
|
-
* are let go. A check that has ended is answered as it is
|
|
324
|
-
|
|
355
|
+
* are let go. A check that has ended is answered as it is; to a key
|
|
356
|
+
* that may cancel it but not read it, with its id and state alone. */
|
|
357
|
+
cancel: (id: string, options?: RequestOptions) => Promise<CiCheckDetail | CiCancelled>;
|
|
358
|
+
/** Run a check again, as GitHub's Re-run does: a new check of the
|
|
359
|
+
* same commit (a pull request's as it would land now), trusted only as
|
|
360
|
+
* the commit's last check was. A check still going is answered as it is. */
|
|
361
|
+
rerun: (id: string, options?: RequestOptions) => Promise<CiCheckDetail | CiCancelled>;
|
|
325
362
|
};
|
|
326
363
|
jobs: {
|
|
327
364
|
/** A job with the tail of its log and the sandboxes it ran in. */
|
|
@@ -331,6 +368,11 @@ export declare function ci(t: Transport): {
|
|
|
331
368
|
/** A repository's test files by name, with their quarantine. */
|
|
332
369
|
list: (repositoryId: string, query?: ListCiTests, options?: RequestOptions) => Promise<Page<CiTest>>;
|
|
333
370
|
};
|
|
371
|
+
releases: {
|
|
372
|
+
/** The steps releases took, newest first, of one repository or one
|
|
373
|
+
* commit: only repositories whose releases CI/CD runs have any. */
|
|
374
|
+
list: (query?: ListCiReleaseSteps, options?: RequestOptions) => Promise<Page<CiReleaseStep>>;
|
|
375
|
+
};
|
|
334
376
|
flakes: {
|
|
335
377
|
/** Flaky tests, newest first; `state: ["quarantined", "gating"]`
|
|
336
378
|
* lists the open ones. */
|
package/dist/products/ci.js
CHANGED
|
@@ -85,12 +85,21 @@ export function ci(t) {
|
|
|
85
85
|
/** A check with its jobs in plan order. */
|
|
86
86
|
get: (id, options) => t.json({ method: "GET", path: at("/v1/ci/checks", id), ...options }),
|
|
87
87
|
/** Cancel a queued or running check: its jobs end and its machines
|
|
88
|
-
* are let go. A check that has ended is answered as it is
|
|
88
|
+
* are let go. A check that has ended is answered as it is; to a key
|
|
89
|
+
* that may cancel it but not read it, with its id and state alone. */
|
|
89
90
|
cancel: (id, options) => t.json({
|
|
90
91
|
method: "POST",
|
|
91
92
|
path: `${at("/v1/ci/checks", id)}:cancel`,
|
|
92
93
|
...options,
|
|
93
94
|
}),
|
|
95
|
+
/** Run a check again, as GitHub's Re-run does: a new check of the
|
|
96
|
+
* same commit (a pull request's as it would land now), trusted only as
|
|
97
|
+
* the commit's last check was. A check still going is answered as it is. */
|
|
98
|
+
rerun: (id, options) => t.json({
|
|
99
|
+
method: "POST",
|
|
100
|
+
path: `${at("/v1/ci/checks", id)}:rerun`,
|
|
101
|
+
...options,
|
|
102
|
+
}),
|
|
94
103
|
},
|
|
95
104
|
jobs: {
|
|
96
105
|
/** A job with the tail of its log and the sandboxes it ran in. */
|
|
@@ -100,6 +109,11 @@ export function ci(t) {
|
|
|
100
109
|
/** A repository's test files by name, with their quarantine. */
|
|
101
110
|
list: (repositoryId, query = {}, options) => paged("/v1/ci/tests", { ...query, repositoryId }, options),
|
|
102
111
|
},
|
|
112
|
+
releases: {
|
|
113
|
+
/** The steps releases took, newest first, of one repository or one
|
|
114
|
+
* commit: only repositories whose releases CI/CD runs have any. */
|
|
115
|
+
list: (query = {}, options) => paged("/v1/ci/releases", query, options),
|
|
116
|
+
},
|
|
103
117
|
flakes: {
|
|
104
118
|
/** Flaky tests, newest first; `state: ["quarantined", "gating"]`
|
|
105
119
|
* lists the open ones. */
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Desktops: a Linux desktop on its own sandbox, billed at the sandbox rates
|
|
2
|
+
* (packages/cloud/src/api/products/desktops.ts), at /v1/desktops, with a
|
|
3
|
+
* private live view and computer use: screenshot and act. In a private beta:
|
|
4
|
+
* an account outside it is refused with product_in_beta (403), and retrying
|
|
5
|
+
* does not change it. */
|
|
6
|
+
import type { RequestOptions, Transport } from "../transport.js";
|
|
7
|
+
import { type ResourceRecord } from "./resources.js";
|
|
8
|
+
export type DesktopState = "starting" | "running" | "paused" | "stopped" | "failed" | "deleted";
|
|
9
|
+
export type Desktop = ResourceRecord & {
|
|
10
|
+
name: string | null;
|
|
11
|
+
labels: Record<string, string>;
|
|
12
|
+
state: DesktopState;
|
|
13
|
+
sandboxId: string;
|
|
14
|
+
createdAt: number;
|
|
15
|
+
updatedAt: number;
|
|
16
|
+
deletedAt: number | null;
|
|
17
|
+
memoryMiB: number;
|
|
18
|
+
vcpu: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
timeoutSeconds: number;
|
|
22
|
+
idlePauseSeconds: number;
|
|
23
|
+
/** Opens the live desktop in a browser; carries a private preview token. */
|
|
24
|
+
liveViewUrl?: string;
|
|
25
|
+
/** When liveViewUrl's token ends; get the desktop again for a fresh one. */
|
|
26
|
+
expiresAt: string | null;
|
|
27
|
+
actions: {
|
|
28
|
+
screenshot: string;
|
|
29
|
+
act: string;
|
|
30
|
+
record: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export type CreateDesktop = {
|
|
34
|
+
/** 1024–16384 MiB; the server defaults to 2048. */
|
|
35
|
+
memoryMiB?: number;
|
|
36
|
+
/** The server defaults to 2 vCPU. */
|
|
37
|
+
vcpu?: number;
|
|
38
|
+
/** The screen, 640x480 to 3840x2160; 1280x800 by default. */
|
|
39
|
+
width?: number;
|
|
40
|
+
height?: number;
|
|
41
|
+
timeoutSeconds?: number;
|
|
42
|
+
idlePauseSeconds?: number;
|
|
43
|
+
name?: string;
|
|
44
|
+
labels?: Record<string, string>;
|
|
45
|
+
};
|
|
46
|
+
/** Only the name and labels change; a null name clears it. */
|
|
47
|
+
export type UpdateDesktop = {
|
|
48
|
+
name?: string | null;
|
|
49
|
+
labels?: Record<string, string>;
|
|
50
|
+
};
|
|
51
|
+
/** One computer-use step, as POST /v1/desktops/{id}:act takes it. */
|
|
52
|
+
export type DesktopAct = {
|
|
53
|
+
action: string;
|
|
54
|
+
} & Record<string, unknown>;
|
|
55
|
+
export declare function desktops(t: Transport): {
|
|
56
|
+
/** The screen as PNG (or JPEG) bytes. A write: it runs in the desktop's
|
|
57
|
+
* sandbox and wakes a paused one, so a read-only key is refused it. */
|
|
58
|
+
screenshot(id: string, shot?: {
|
|
59
|
+
format?: "png" | "jpeg";
|
|
60
|
+
quality?: number;
|
|
61
|
+
}, options?: RequestOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
62
|
+
/** Move, click, drag, scroll, type, press keys, open a URL or launch a program. */
|
|
63
|
+
act(id: string, step: DesktopAct, options?: RequestOptions): Promise<Record<string, unknown>>;
|
|
64
|
+
base: string;
|
|
65
|
+
create: (input: CreateDesktop, options?: RequestOptions) => Promise<Desktop>;
|
|
66
|
+
get: (id: string, options?: import("./resources.js").ResourceGetOptions<"paused" | "stopped" | "starting" | "running" | "deleted" | "failed">) => Promise<Desktop>;
|
|
67
|
+
list: (query?: import("./resources.js").ResourceListQuery<"paused" | "stopped" | "starting" | "running" | "deleted" | "failed">, options?: RequestOptions) => Promise<import("../page.js").Page<Desktop>>;
|
|
68
|
+
update: (id: string, input: UpdateDesktop, options?: RequestOptions) => Promise<Desktop>;
|
|
69
|
+
wait: (id: string, target: "paused" | "stopped" | "starting" | "running" | "deleted" | "failed", options?: import("./resources.js").ResourceWaitOptions) => Promise<Desktop>;
|
|
70
|
+
delete: (id: string, options?: import("./resources.js").ResourceDeleteOptions) => Promise<Desktop>;
|
|
71
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { enc, resource } from "./resources.js";
|
|
2
|
+
/** A wait ends at its target or at one of these, with the desktop's error. */
|
|
3
|
+
const SETTLED = ["failed", "deleted"];
|
|
4
|
+
export function desktops(t) {
|
|
5
|
+
return {
|
|
6
|
+
...resource(t, "desktops", SETTLED),
|
|
7
|
+
/** The screen as PNG (or JPEG) bytes. A write: it runs in the desktop's
|
|
8
|
+
* sandbox and wakes a paused one, so a read-only key is refused it. */
|
|
9
|
+
screenshot(id, shot = {}, options) {
|
|
10
|
+
return t.bytes({
|
|
11
|
+
method: "POST",
|
|
12
|
+
path: `/v1/desktops/${enc(id)}:screenshot`,
|
|
13
|
+
body: shot,
|
|
14
|
+
...options,
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
/** Move, click, drag, scroll, type, press keys, open a URL or launch a program. */
|
|
18
|
+
act(id, step, options) {
|
|
19
|
+
return t.json({
|
|
20
|
+
method: "POST",
|
|
21
|
+
path: `/v1/desktops/${enc(id)}:act`,
|
|
22
|
+
body: step,
|
|
23
|
+
...options,
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
package/dist/products/index.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ import { agents } from "./agents.js";
|
|
|
27
27
|
import { builds } from "./builds.js";
|
|
28
28
|
import { ci } from "./ci.js";
|
|
29
29
|
import { containers } from "./containers.js";
|
|
30
|
+
import { browsers } from "./browsers.js";
|
|
31
|
+
import { desktops } from "./desktops.js";
|
|
30
32
|
import { apps } from "./apps.js";
|
|
31
33
|
export declare const clientExtensions: {
|
|
32
34
|
images: typeof images;
|
|
@@ -54,6 +56,8 @@ export declare const clientExtensions: {
|
|
|
54
56
|
builds: typeof builds;
|
|
55
57
|
ci: typeof ci;
|
|
56
58
|
containers: typeof containers;
|
|
59
|
+
browsers: typeof browsers;
|
|
60
|
+
desktops: typeof desktops;
|
|
57
61
|
apps: typeof apps;
|
|
58
62
|
};
|
|
59
63
|
export declare const sandboxExtensions: {
|
package/dist/products/index.js
CHANGED
|
@@ -25,6 +25,8 @@ import { agents } from "./agents.js";
|
|
|
25
25
|
import { builds } from "./builds.js";
|
|
26
26
|
import { ci } from "./ci.js";
|
|
27
27
|
import { containers } from "./containers.js";
|
|
28
|
+
import { browsers } from "./browsers.js";
|
|
29
|
+
import { desktops } from "./desktops.js";
|
|
28
30
|
// The hub loads this file, so it loads apps.ts and resources.ts too: request
|
|
29
31
|
// builders over Transport whose top level holds only types, functions and
|
|
30
32
|
// imports of files the hub loads, so importing them runs nothing in the hub
|
|
@@ -73,6 +75,9 @@ export const clientExtensions = {
|
|
|
73
75
|
// CI/CD (beta): the API answers product_in_beta outside its list.
|
|
74
76
|
ci,
|
|
75
77
|
containers,
|
|
78
|
+
// Browsers and Desktops (beta): the API answers product_in_beta outside its list.
|
|
79
|
+
browsers,
|
|
80
|
+
desktops,
|
|
76
81
|
// A private beta (PRODUCT_BETAS): an account outside it is refused with
|
|
77
82
|
// product_in_beta until Apps launches.
|
|
78
83
|
apps,
|
|
@@ -2,9 +2,11 @@ import type { Sandbox } from "../sandbox.js";
|
|
|
2
2
|
import type { RequestOptions, Transport } from "../transport.js";
|
|
3
3
|
/** A sandbox's own network rules. */
|
|
4
4
|
export type NetworkRules = {
|
|
5
|
-
/** false refuses every outbound connection
|
|
5
|
+
/** false refuses every outbound connection; with `allow`, everything but the
|
|
6
|
+
* list (allow-list only, stored as `internet: true` with that list). */
|
|
6
7
|
internet: boolean;
|
|
7
|
-
/** When not empty, only these web destinations are reachable
|
|
8
|
+
/** When not empty, only these web destinations are reachable, the internet on
|
|
9
|
+
* or off: `example.com`,
|
|
8
10
|
* `*.example.com` (subdomains, not the apex), an address or a CIDR range. */
|
|
9
11
|
allow?: string[];
|
|
10
12
|
/** Never reachable. Wins over everything. */
|
|
@@ -171,6 +171,13 @@ export type JobSecret = {
|
|
|
171
171
|
/** One secret by name, and where its value may go: to sandboxes through the
|
|
172
172
|
* egress proxy (`sandboxes`), into scheduled jobs' environments (`jobs`), or
|
|
173
173
|
* both. */
|
|
174
|
+
/** A page of `secrets.list`: at most `limit` (1 to 100, default 50) secrets,
|
|
175
|
+
* by name, those named after `after`. The next page's `after` is the last
|
|
176
|
+
* name of this one; a page shorter than `limit` is the last. */
|
|
177
|
+
export type ListSecrets = {
|
|
178
|
+
limit?: number;
|
|
179
|
+
after?: string;
|
|
180
|
+
};
|
|
174
181
|
export type SecretUse = {
|
|
175
182
|
name: string;
|
|
176
183
|
sandboxes: Secret | null;
|
|
@@ -219,8 +226,9 @@ export declare function secrets(t: Transport): {
|
|
|
219
226
|
enforced: boolean;
|
|
220
227
|
}>;
|
|
221
228
|
/** The sandboxes' secrets: names, hosts and placeholders. Never values.
|
|
222
|
-
* `
|
|
223
|
-
|
|
229
|
+
* `list({ limit, after })` gives one page, by name; `all()` includes
|
|
230
|
+
* the jobs copies. */
|
|
231
|
+
list: (query?: ListSecrets & RequestOptions) => Promise<Secret[]>;
|
|
224
232
|
/** Every secret by name, with where its value may go. */
|
|
225
233
|
all: (options?: RequestOptions) => Promise<SecretUse[]>;
|
|
226
234
|
/** One secret by name, with where its value may go. */
|