@veris-ai/daytona 0.2.1 → 0.3.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.
- package/README.md +283 -14
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2138 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-plane.d.ts +13 -5
- package/dist/daytona-key.d.ts +28 -0
- package/dist/daytona.d.ts +86 -10
- package/dist/exec.d.ts +15 -0
- package/dist/gateway.d.ts +41 -1
- package/dist/index.cjs +627 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.js +597 -109
- package/dist/index.js.map +1 -1
- package/dist/network.d.ts +50 -38
- package/dist/profile.d.ts +70 -0
- package/dist/provision.d.ts +100 -0
- package/dist/push.d.ts +11 -0
- package/dist/receipt.d.ts +25 -3
- package/dist/run-receipt.d.ts +13 -0
- package/dist/run.d.ts +87 -0
- package/dist/service-control.d.ts +8 -0
- package/dist/teardown.d.ts +52 -0
- package/dist/trust.d.ts +138 -0
- package/dist/veris-api.d.ts +58 -0
- package/package.json +7 -1
package/dist/control-plane.d.ts
CHANGED
|
@@ -45,11 +45,21 @@ export interface EgressCredential {
|
|
|
45
45
|
expires_at?: string;
|
|
46
46
|
/** Server-served CA trust env map; the SDK's vendored list is the fallback. */
|
|
47
47
|
trust_env?: Record<string, string>;
|
|
48
|
+
/** IPv4 addresses the gateway listens on — what strict mode pins Daytona's
|
|
49
|
+
* networkAllowList to. Absent on a control plane that predates the field;
|
|
50
|
+
* the SDK then resolves the proxy host itself, once. */
|
|
51
|
+
gateway_ips?: string[];
|
|
48
52
|
}
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
53
|
+
/**
|
|
54
|
+
* Mutable fields of a running twin. An OMITTED key is left alone; an explicit
|
|
55
|
+
* null is a value (client_base_url: null unregisters).
|
|
56
|
+
*
|
|
57
|
+
* There is deliberately no ttl_minutes. The server's UpdateSandboxRequest
|
|
58
|
+
* declares client_base_url and nothing else, and pydantic ignores unknown
|
|
59
|
+
* fields rather than refusing them — so a PATCH carrying a TTL answers 200 and
|
|
60
|
+
* changes nothing. See the note where extendTtl used to be.
|
|
61
|
+
*/
|
|
51
62
|
export interface SandboxPatch {
|
|
52
|
-
ttl_minutes?: number;
|
|
53
63
|
client_base_url?: string | null;
|
|
54
64
|
}
|
|
55
65
|
export interface ControlPlaneOpts {
|
|
@@ -82,8 +92,6 @@ export declare class ControlPlane {
|
|
|
82
92
|
mintEgressCredential(environmentId: string, sandboxId: string): Promise<EgressCredential | null>;
|
|
83
93
|
/** PATCH the twin resource. Omitted fields are untouched by the server. */
|
|
84
94
|
updateSandbox(environmentId: string, sandboxId: string, patch: SandboxPatch): Promise<void>;
|
|
85
|
-
/** Extend a twin's TTL so it stays in lockstep with an extended Daytona sandbox. */
|
|
86
|
-
extendTtl(environmentId: string, sandboxId: string, ttlMinutes: number): Promise<void>;
|
|
87
95
|
/** Create-time preflight: is the gateway infrastructure up, per the control plane? */
|
|
88
96
|
gatewayHealth(): Promise<void>;
|
|
89
97
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const DAYTONA_API_URL = "https://app.daytona.io/api";
|
|
2
|
+
/** The permission DELETE /api/sandbox/<id> checks for. */
|
|
3
|
+
export declare const DELETE_SANDBOXES = "delete:sandboxes";
|
|
4
|
+
/** The part of GET /api/api-keys/current this package reads. */
|
|
5
|
+
export interface DaytonaKeyInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
permissions: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Where the Daytona API is, resolved the way @daytona/sdk resolves it. */
|
|
10
|
+
export declare function daytonaApiUrl(env?: NodeJS.ProcessEnv): string;
|
|
11
|
+
/**
|
|
12
|
+
* The key's own record, or undefined when Daytona would not say — a network
|
|
13
|
+
* error, a non-2xx, a body without a permissions list. Undefined means
|
|
14
|
+
* "unknown", and a caller must not read it as "cannot delete".
|
|
15
|
+
*/
|
|
16
|
+
export declare function fetchDaytonaKey(apiKey: string, apiUrl?: string): Promise<DaytonaKeyInfo | undefined>;
|
|
17
|
+
/** True, false, or undefined when the key's permissions are not known. */
|
|
18
|
+
export declare function canDeleteSandboxes(key: DaytonaKeyInfo | undefined): boolean | undefined;
|
|
19
|
+
/** `"ci-key" (permissions: write:sandboxes)` — how a message names the key. */
|
|
20
|
+
export declare function describeKey(key: DaytonaKeyInfo): string;
|
|
21
|
+
/** How to get a key that can delete. One sentence, used wherever the lack is reported. */
|
|
22
|
+
export declare const DELETE_PERMISSION_FIX = "create a key with the \"delete sandboxes\" permission at https://app.daytona.io/dashboard/keys";
|
|
23
|
+
/**
|
|
24
|
+
* The warning `provision` and `run` print before creating a box with a key
|
|
25
|
+
* that cannot delete one. Says what will happen instead — the box's own
|
|
26
|
+
* brakes — so the reader can decide whether that is good enough.
|
|
27
|
+
*/
|
|
28
|
+
export declare function cannotTeardownWarning(key: DaytonaKeyInfo, autoStopMinutes: number, autoDeleteMinutes: number): string;
|
package/dist/daytona.d.ts
CHANGED
|
@@ -4,25 +4,25 @@ import type { VerisApi } from './veris-api';
|
|
|
4
4
|
import type { EgressMode } from './network';
|
|
5
5
|
import { CA_CERT_PATH } from './trust';
|
|
6
6
|
export interface VerisOpts {
|
|
7
|
-
/** Veris API key. Falls back to process.env.VERIS_API_KEY
|
|
7
|
+
/** Veris API key. Falls back to process.env.VERIS_API_KEY, then to the
|
|
8
|
+
* profile `veris login` saved in ~/.veris/twin.yaml. Required. */
|
|
8
9
|
apiKey?: string;
|
|
9
10
|
/** Veris environment the twin is deployed from. Falls back to process.env.VERIS_ENVIRONMENT_ID. */
|
|
10
11
|
environmentId?: string;
|
|
11
|
-
/** Control plane base. Falls back to process.env.VERIS_API_BASE, then
|
|
12
|
+
/** Control plane base. Falls back to process.env.VERIS_API_BASE, then the
|
|
13
|
+
* profile's api_base, then 'https://svc.api.veris.ai'. */
|
|
12
14
|
apiBase?: string;
|
|
13
15
|
/** Attach to an EXISTING twin instead of provisioning one (advanced). delete() will NOT remove it. */
|
|
14
16
|
attachSandboxId?: string;
|
|
15
17
|
/** Twin TTL backstop, minutes. Default 60, kept in step with the sandbox's ttlMinutes. */
|
|
16
18
|
ttlMinutes?: number;
|
|
17
|
-
/** 'strict' (default):
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
/** 'strict' (default): Daytona may reach the Veris gateway's address and
|
|
20
|
+
* nothing else; everything the code dials goes through the gateway, which
|
|
21
|
+
* answers vendor hostnames from the twin and passes registries and other
|
|
22
|
+
* public hosts through. 'open': no Daytona allowlist — for a control plane
|
|
23
|
+
* that has not published the gateway's addresses. Daytona blocks anything
|
|
24
|
+
* that bypasses the proxy in both modes. */
|
|
20
25
|
egress?: EgressMode;
|
|
21
|
-
/** Extra hostnames to allow out. */
|
|
22
|
-
allowOut?: string[];
|
|
23
|
-
/** Allow package registries (npm, PyPI, apt, …). Default true: a coding
|
|
24
|
-
* sandbox that cannot install dependencies is not usable. */
|
|
25
|
-
allowRegistries?: boolean;
|
|
26
26
|
/** Install the gateway CA into the sandbox trust store. Default true; without
|
|
27
27
|
* it every HTTPS call to a vendor host fails certificate validation. */
|
|
28
28
|
installCa?: boolean;
|
|
@@ -43,6 +43,24 @@ export type VerisSandbox = Sandbox & {
|
|
|
43
43
|
};
|
|
44
44
|
/** Is this sandbox one of ours? Narrows for callers who hold a bare Sandbox. */
|
|
45
45
|
export declare function isVerisSandbox(sbx: Sandbox): sbx is VerisSandbox;
|
|
46
|
+
/**
|
|
47
|
+
* The twin id stamped on this sandbox at create, if it has one.
|
|
48
|
+
*
|
|
49
|
+
* Read from the labels rather than from `sandbox.verisSandboxId`, so it answers
|
|
50
|
+
* for a sandbox whose Veris surface could NOT be rehydrated — no VERIS_API_KEY
|
|
51
|
+
* in the environment, say. That is exactly the case where a caller about to
|
|
52
|
+
* delete the sandbox needs telling that a twin exists and is out of reach.
|
|
53
|
+
*/
|
|
54
|
+
export declare function verisTwinId(sandbox: Sandbox): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Does deleting this sandbox delete its twin too?
|
|
57
|
+
*
|
|
58
|
+
* True only for a twin this package created. A twin attached to with
|
|
59
|
+
* `veris.attachSandboxId` belongs to whoever made it and outlives the sandbox,
|
|
60
|
+
* and a sandbox with no twin at all has nothing to delete. This is the same
|
|
61
|
+
* label the wrapped `delete()` reads, so the two can never disagree.
|
|
62
|
+
*/
|
|
63
|
+
export declare function verisOwnsTwin(sandbox: Sandbox): boolean;
|
|
46
64
|
export declare class Daytona extends BaseDaytona {
|
|
47
65
|
private readonly verisDefaults;
|
|
48
66
|
constructor(config?: VerisDaytonaConfig);
|
|
@@ -89,4 +107,62 @@ export declare class Daytona extends BaseDaytona {
|
|
|
89
107
|
private baseCreate;
|
|
90
108
|
}
|
|
91
109
|
export default Daytona;
|
|
110
|
+
/** What a create that threw left behind in Daytona, once it has been read back. */
|
|
111
|
+
export interface FailedSandbox {
|
|
112
|
+
/** The DAYTONA sandbox id. Not the twin's. */
|
|
113
|
+
id: string;
|
|
114
|
+
/** Daytona's own state for it — `build_failed` for an image that never built. */
|
|
115
|
+
state?: string;
|
|
116
|
+
/** Daytona's account of what went wrong, when it kept one. */
|
|
117
|
+
errorReason?: string;
|
|
118
|
+
/** Whether the delete actually went through. The message says either way,
|
|
119
|
+
* because "was deleted" has to be true or it is worse than saying nothing. */
|
|
120
|
+
deleted: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** The parts of a Daytona Sandbox the reaper touches. */
|
|
123
|
+
interface ReapableSandbox {
|
|
124
|
+
id: string;
|
|
125
|
+
state?: string;
|
|
126
|
+
errorReason?: string;
|
|
127
|
+
labels?: Record<string, string>;
|
|
128
|
+
refreshData(): Promise<void>;
|
|
129
|
+
delete(): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Delete the half-built sandbox a failed create() left in Daytona, and bring
|
|
133
|
+
* back the reason Daytona recorded for it.
|
|
134
|
+
*
|
|
135
|
+
* The leak this exists for: `create({ image: 'only-on-my-laptop' })` builds
|
|
136
|
+
* server-side and fails at build time, so the SDK throws instead of returning
|
|
137
|
+
* a Sandbox — and a box sits in `build_failed` that nothing here can delete,
|
|
138
|
+
* until an autoDeleteInterval eventually reaps it. Found by the create id
|
|
139
|
+
* stamped in its labels, which is the one thing about it we know for certain.
|
|
140
|
+
*
|
|
141
|
+
* Best effort throughout: the create is already failing, and a reaper that
|
|
142
|
+
* threw would replace the real reason with its own.
|
|
143
|
+
*/
|
|
144
|
+
export declare function reapFailedCreate(list: (labels: Record<string, string>) => AsyncIterable<ReapableSandbox>, createId: string): Promise<FailedSandbox | undefined>;
|
|
145
|
+
/**
|
|
146
|
+
* What a failed create says.
|
|
147
|
+
*
|
|
148
|
+
* Two things were missing from "Daytona sandbox create failed: Sandbox 7ba4…
|
|
149
|
+
* failed to start with status: build_failed, error reason: null".
|
|
150
|
+
*
|
|
151
|
+
* The reason, first. Daytona's SDK renders `error reason: ${this.errorReason}`
|
|
152
|
+
* off the Sandbox object it was polling, and the state change that ends the
|
|
153
|
+
* wait arrives over the event stream, which carries the new state and not the
|
|
154
|
+
* reason — so the field is still the null it started as, while Daytona's own
|
|
155
|
+
* record for that sandbox says "pull access denied, repository does not
|
|
156
|
+
* exist". Reading the record back is the whole fix.
|
|
157
|
+
*
|
|
158
|
+
* And, for the failure a first-timer actually hits, whose image it is. Daytona
|
|
159
|
+
* resolves and builds it on its own machines, from a registry; the tag sitting
|
|
160
|
+
* in the laptop's Docker daemon is not something it can see.
|
|
161
|
+
*
|
|
162
|
+
* The cause's own text is folded in HERE rather than left to VerisError, whose
|
|
163
|
+
* fold would otherwise append it after the sentences that explain it.
|
|
164
|
+
*/
|
|
165
|
+
export declare function sandboxCreateMessage(cause: unknown, failed: FailedSandbox | undefined, params?: {
|
|
166
|
+
image?: unknown;
|
|
167
|
+
}): string;
|
|
92
168
|
export { CA_CERT_PATH };
|
package/dist/exec.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ExecOptions {
|
|
2
|
+
/** The Daytona sandbox id — `provision`'s daytonaSandboxId. Not the twin's. */
|
|
3
|
+
sandboxId: string;
|
|
4
|
+
/** Directory to run in. Unset: the same workDir `provision` printed. */
|
|
5
|
+
cwd?: string;
|
|
6
|
+
/** KEY=VALUE pairs exported on top of the trust environment. */
|
|
7
|
+
env: Record<string, string>;
|
|
8
|
+
/** Seconds the command may run. */
|
|
9
|
+
timeoutSeconds: number;
|
|
10
|
+
/** The command itself, everything after `--`. */
|
|
11
|
+
command: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const EXEC_USAGE = "usage: veris-daytona exec <daytona-sandbox-id> [options] -- <command>\n\nRuns <command> in a sandbox that already exists \u2014 the id `veris-daytona\nprovision` printed as daytonaSandboxId \u2014 with the Veris trust environment\napplied, and streams the output as it happens.\n\n --cwd <dir> directory to run in (default: <sandbox home>/veris-run, provision's workDir)\n --env KEY=VALUE exported on top of the trust environment (repeatable)\n --timeout <seconds> how long <command> may run (default: 1800)\n\nThe trust environment is applied for you, and that is the point of the verb:\nDaytona overwrites SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE and\nNODE_EXTRA_CA_CERTS inside the sandbox with its own CA file, which cannot verify\nthe twin gateway's certificates, and `daytona exec` has no way to set a variable\nat all. Every command here is run with the Veris values exported in front of it.\n--env is applied after them and wins.\n\nOutput streams rather than arriving at the end, so a long install or suite shows\nits progress. No receipt is read and no verdict is passed \u2014 take a watermark\nbefore and read `veris sandbox trace --since` after.\n\nneeds: DAYTONA_API_KEY.\n\nexit code: the command's own. 124 when it ran out of --timeout; 1 when there is\nno such sandbox; 2 on a usage error.";
|
|
14
|
+
/** Parse everything after `exec`. Pure; throws UsageError with a human message. */
|
|
15
|
+
export declare function parseExecArgs(argv: readonly string[]): ExecOptions;
|
package/dist/gateway.d.ts
CHANGED
|
@@ -25,6 +25,19 @@ export declare function gatewayProxyUrl(credential: {
|
|
|
25
25
|
connect_address?: string;
|
|
26
26
|
username: string;
|
|
27
27
|
}): string;
|
|
28
|
+
/**
|
|
29
|
+
* The gateway's IPv4 addresses, which strict mode pins Daytona to.
|
|
30
|
+
*
|
|
31
|
+
* The credential's own list wins: the control plane publishes the reserved
|
|
32
|
+
* load-balancer address behind the gateway hostname, and that is the authority
|
|
33
|
+
* on where the gateway is. A control plane that predates the field gets one
|
|
34
|
+
* DNS lookup of the proxy host from here — the caller's resolver is a weaker
|
|
35
|
+
* source, but it is what an older plane leaves. Empty when neither answers;
|
|
36
|
+
* buildNetwork turns that into the error that names the fix.
|
|
37
|
+
*/
|
|
38
|
+
export declare function gatewayIps(credential: {
|
|
39
|
+
gateway_ips?: string[];
|
|
40
|
+
}, proxyUrl: string): Promise<string[]>;
|
|
28
41
|
/**
|
|
29
42
|
* Make the gateway's CA trusted, without requiring anything of the image.
|
|
30
43
|
*
|
|
@@ -47,12 +60,39 @@ export declare function gatewayProxyUrl(credential: {
|
|
|
47
60
|
* Daytona overrides the best-known trust variables with its own CA, correctly
|
|
48
61
|
* for its proxy. The dozen it does not set still point at this bundle, which
|
|
49
62
|
* carries both CAs and every public root — so those tools verify rather than
|
|
50
|
-
* break.
|
|
63
|
+
* break. Node is the exception that makes ours load-bearing today: it ignores
|
|
64
|
+
* HTTPS_PROXY, is forwarded end to end, and validates OUR leaf with Daytona's
|
|
65
|
+
* file. Its file is read-only, so the store install above is what carries
|
|
66
|
+
* Node: NODE_TRUST_FLAG makes Node read the directory that install fills.
|
|
51
67
|
*
|
|
52
68
|
* The system-store install still runs when it can, for anything that reads the
|
|
53
69
|
* store directly rather than honouring the variables. It is best-effort.
|
|
54
70
|
*/
|
|
55
71
|
export declare function installCa(sandbox: Sandbox, caPem: string): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Put the Node proxy preload where NODE_OPTIONS names it. Separate from the
|
|
74
|
+
* CA install because it is about routing, not trust: a sandbox created with
|
|
75
|
+
* installCa: false still needs its Node SDKs to reach the gateway.
|
|
76
|
+
*/
|
|
77
|
+
export declare function installNodeProxyPreload(sandbox: Sandbox): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Run the bundled-CA patcher installed above, and report what it changed.
|
|
80
|
+
*
|
|
81
|
+
* The gap it closes: an SDK that ships its own CA bundle and loads it by
|
|
82
|
+
* explicit path reads none of the eighteen trust variables. stripe-python is
|
|
83
|
+
* the measured case — `verify=stripe.ca_bundle_path`, and the first call fails
|
|
84
|
+
* with "Could not verify Stripe's SSL certificate" in a sandbox where curl,
|
|
85
|
+
* Node and `requests` are all fine. This is the Daytona equivalent of the veris
|
|
86
|
+
* CLI's --patch-bundled-cas.
|
|
87
|
+
*
|
|
88
|
+
* Call it AFTER dependencies are installed. Idempotent, so calling it again
|
|
89
|
+
* after installing more costs one filesystem scan and reports nothing new.
|
|
90
|
+
*
|
|
91
|
+
* Never fatal. A sandbox with no such bundle is the normal case, and a scan
|
|
92
|
+
* that could not run is a missed optimisation, not a broken run — the failure
|
|
93
|
+
* it prevents still announces itself clearly in the client's own error.
|
|
94
|
+
*/
|
|
95
|
+
export declare function patchBundledCas(sandbox: Sandbox): Promise<string[]>;
|
|
56
96
|
/**
|
|
57
97
|
* The canary probe: one HTTPS request from inside the sandbox to a reserved
|
|
58
98
|
* hostname only the gateway answers, with the twin id in the body.
|