@veris-ai/daytona 0.3.1 → 0.4.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/README.md CHANGED
@@ -45,148 +45,6 @@ await sbx.delete() // deletes the twin too
45
45
  This package re-exports everything from `@daytona/sdk`, so it is the only import
46
46
  you need to change. No particular sandbox image is required.
47
47
 
48
- ### Or skip the code: `veris-daytona run`
49
-
50
- The same four steps as one command, for a test suite that already exists:
51
-
52
- ```sh
53
- npx @veris-ai/daytona run --setup 'pip install -e .' -- pytest tests/integration
54
- ```
55
-
56
- That uploads the current directory into a fresh sandbox (minus `node_modules`,
57
- `.venv`, `.git` and the like), runs the setup command, runs the test command
58
- streaming its output, prints the receipt, and deletes the sandbox and the twin.
59
- The exit code is the test command's — except that a green suite whose twin
60
- received nothing exits 1, because a pass without a receipt is not a pass.
61
-
62
- ```
63
- Veris receipt — twin sbx_a1b2c3
64
- interception: gateway integrity: verified
65
-
66
- 1 request(s) reached the twin:
67
- stripe: 1 request(s)
68
- POST /v1/customers -> 200
69
- ```
70
-
71
- | flag | |
72
- |---|---|
73
- | `--repo <url> [--ref <branch>]` | clone instead of uploading; `GITHUB_TOKEN` is used for a private repo |
74
- | `--environment <id>` | instead of `VERIS_ENVIRONMENT_ID` |
75
- | `--require-service <name>` | the receipt must show this service, repeatable |
76
- | `--image <name>` / `--snapshot <name>` | what to run in; default is Daytona's default snapshot |
77
- | `--env KEY=VALUE` | exported to both commands, repeatable |
78
- | `--timeout <seconds>` | for the test command; default 1800 |
79
- | `--keep` | leave the sandbox up afterwards, and the twin if `run` made it |
80
-
81
- `veris-daytona run --help` lists everything.
82
-
83
- ### Or hand the wired box to something else: `provision`, `push`, `exec`, `teardown`
84
-
85
- `run` does the whole job in one command, and it stays. But when the thing that
86
- installs the dependencies and runs the suite is another tool — the `veris` CLI,
87
- a CI step, an agent — what you want from this package is the first half only:
88
-
89
- ```sh
90
- box=$(npx @veris-ai/daytona provision --sandbox sbx_a1b2c3 --image python:3.12)
91
- ```
92
-
93
- That creates a sandbox attached to a twin you already have, does every
94
- Veris-shaped thing — the egress credential, the gateway pin, the outbound
95
- proxy, the CA bundle, the canary, the trust variables — and
96
- stops. Nothing is uploaded, nothing is run, nothing is deleted. One JSON object
97
- goes to stdout and every human line to stderr, so `$box` is parseable:
98
-
99
- ```json
100
- {
101
- "daytonaSandboxId": "e2a1…",
102
- "verisSandboxId": "sbx_a1b2c3",
103
- "verisEnvironmentId": "env_9f…",
104
- "ownsTwin": false,
105
- "workDir": "/home/daytona/veris-run",
106
- "caBundlePath": "/tmp/veris-ca-bundle.crt",
107
- "trustEnv": { "SSL_CERT_FILE": "/tmp/veris-ca-bundle.crt", "…": "…" },
108
- "trustPrelude": "export SSL_CERT_FILE='/tmp/veris-ca-bundle.crt'; …",
109
- "patchBundledCasCommand": "sh /tmp/veris-patch-bundled-cas.sh",
110
- "pushCommand": "veris-daytona push e2a1…",
111
- "execCommand": "veris-daytona exec e2a1… -- <command>",
112
- "services": ["stripe", "github"],
113
- "expiresAt": "2026-09-04T12:00:00.000Z",
114
- "autoStopMinutes": 30,
115
- "autoDeleteMinutes": 60
116
- }
117
- ```
118
-
119
- | flag | |
120
- |---|---|
121
- | `--sandbox <twin-id>` | the twin to attach to — **required**; `veris up` prints its id |
122
- | `--image <name>` / `--snapshot <name>` | what to run in; default is Daytona's default snapshot |
123
- | `--env KEY=VALUE` | set as a sandbox environment variable, repeatable |
124
-
125
- From there the box is yours. Reading the receipt and deciding what it proved is
126
- the caller's job; that is the whole point of the split.
127
-
128
- ### Getting code in and running it: `push` and `exec`
129
-
130
- Daytona has no route into a box that already exists. Their CLI (v0.210.0) has no
131
- upload, copy or sync command; `daytona ssh` takes exactly one argument, so there
132
- is no `tar | ssh` and no scp or rsync behind it; `--context` is a Docker build
133
- context that only exists on `create`, which `provision` owns; and `git clone`
134
- inside the box is a clone, not an upload of what is on your disk. So two verbs
135
- do it:
136
-
137
- ```sh
138
- id=$(echo "$box" | jq -r .daytonaSandboxId)
139
-
140
- npx @veris-ai/daytona push "$id" # tars the cwd into workDir
141
- npx @veris-ai/daytona exec "$id" -- pip install -e .
142
- npx @veris-ai/daytona exec "$id" -- sh /tmp/veris-patch-bundled-cas.sh
143
- npx @veris-ai/daytona exec "$id" -- python -m pytest tests/integration
144
- ```
145
-
146
- `push` uploads the current directory, minus what gets rebuilt inside
147
- (`node_modules`, `.venv`, `dist`, `__pycache__`, …), and unpacks it in the same
148
- `workDir` the JSON named — so the two chain without carrying the path between
149
- them. `--repo <url> --ref <branch>` clones instead, using `GITHUB_TOKEN` for a
150
- private one.
151
-
152
- `exec` runs one command with `trustEnv` already exported, which is the part that
153
- matters: `daytona exec` has no `--env` flag at all, so a command run through it
154
- inherits Daytona's own CA file and fails on the gateway's certificate unless you
155
- retype the trust prelude every single time. It streams output as it happens
156
- rather than returning at the end, takes `--cwd`, repeatable `--env KEY=VALUE`
157
- and `--timeout <seconds>`, and exits with the command's own status.
158
-
159
- Neither reads a receipt or passes a verdict — take a watermark before and read
160
- `veris sandbox trace --since` after. And once the dependencies are installed,
161
- run `patchBundledCasCommand` **inside the box** to patch the CA bundles an SDK
162
- ships with it; the script is already in there, so a shell caller needs nothing
163
- from this package.
164
-
165
- ### Taking it back: `teardown`
166
-
167
- However it went:
168
-
169
- ```sh
170
- npx @veris-ai/daytona teardown "$(echo "$box" | jq -r .daytonaSandboxId)"
171
- ```
172
-
173
- `teardown` deletes the sandbox and says what it did about the twin: one this
174
- package created goes with it, one it attached to — always the case after
175
- `provision` — is yours and is left running. It exits 1 when there is no such
176
- sandbox, saying plainly that no twin was touched.
177
-
178
- Nothing deletes a provisioned box for you, so it comes up with its own brakes:
179
- it stops after 30 idle minutes, Daytona deletes it an hour after that, and it
180
- is destroyed 4 hours after creation whatever state it is in. The twin's TTL is
181
- untouched — it belongs to whoever created the twin.
182
-
183
- Deleting needs a Daytona key with the `delete:sandboxes` permission, and a key
184
- made with "write sandboxes" alone does not have it. `teardown` then exits 1
185
- saying so: which key, which permissions it has, that the box is still there,
186
- when its own brakes stop and delete it, what happened to the twin, and where a
187
- key that can delete comes from. `provision` and `run` read the key's
188
- permissions first and warn about the same thing *before* creating a box.
189
-
190
48
  ### Why `assertTouched` and not just a green suite
191
49
 
192
50
  A test suite that skipped its integration and one that exercised it look
@@ -238,8 +96,7 @@ console.log(await sbx.veris.patchBundledCas()) // ['…/stripe/data/ca-certifi
238
96
  ```
239
97
 
240
98
  Call it *after* installing dependencies — the bundles arrive with them. It is
241
- idempotent and returns only the files it changed. `veris-daytona run` calls it
242
- for you, between `--setup` and the command; a sandbox from `provision` carries
99
+ idempotent and returns only the files it changed. Every sandbox also carries
243
100
  the same patcher as a script at `/tmp/veris-patch-bundled-cas.sh`, so whoever
244
101
  installed the dependencies can run it with no SDK in hand.
245
102
 
@@ -258,8 +115,7 @@ sets all of them at create time:
258
115
  a command (`--experimental-vm-modules`, `--max-old-space-size`) would drop
259
116
  both flags and every vendor call would fail on DNS or on the certificate. Build
260
117
  the value with `verisNodeOptions(yourOptions)`, which appends the two flags
261
- once, or pass it through `exec --env NODE_OPTIONS=…`, which merges them for
262
- you:
118
+ once:
263
119
 
264
120
  ```ts
265
121
  import { verisNodeOptions } from '@veris-ai/daytona'
@@ -338,9 +194,8 @@ four systems involved refused:
338
194
  (services-sandbox#1044). Without it, `requests` fails with
339
195
  `Missing Authority Key Identifier` while `curl` and Node succeed.
340
196
  - **Daytona overwrites `REQUESTS_CA_BUNDLE`, `SSL_CERT_FILE` and
341
- `CURL_CA_BUNDLE`** with its own CA file, which lacks the Veris CA. `run`
342
- exports the Veris bundle on every command it runs; a command run through
343
- `sandbox.process` yourself needs `sbx.veris.getTrustEnv()` as its env, or
197
+ `CURL_CA_BUNDLE`** with its own CA file, which lacks the Veris CA. A command
198
+ run through `sandbox.process` needs `sbx.veris.getTrustEnv()` as its env, or
344
199
  `sbx.veris.trustPrelude()` in front of the command line.
345
200
  - **An SDK that bundles its own CA reads no variable at all.**
346
201
  `sbx.veris.patchBundledCas()` covers certifi, pip's vendored certifi,
@@ -351,11 +206,12 @@ four systems involved refused:
351
206
  neither yields an IPv4 address, `create()` fails at `credential-mint` naming
352
207
  `veris.egress: 'open'`, which sets no Daytona allowlist and still blocks a
353
208
  process that bypasses the proxy.
354
- - **`teardown` needs `delete:sandboxes` on the Daytona key.** A write-only
355
- key creates boxes it cannot delete; the refusal says when Daytona's own
356
- auto-stop and auto-delete will, and `provision` warns before creating one.
209
+ - **`delete()` needs `delete:sandboxes` on the Daytona key.** A write-only
210
+ key creates boxes it cannot delete; `canDeleteSandboxes()` says so up front,
211
+ and a box it cannot delete lives until Daytona's own auto-stop and
212
+ auto-delete take it.
357
213
  - **A very long run's receipt is a floor.** The twin's log is read in pages up
358
- to a budget; past it, `entry.capped` is true and `run` prints `≥N`.
214
+ to a budget; past it, `entry.capped` is true and the count is a minimum.
359
215
 
360
216
  ## License
361
217
 
package/dist/index.cjs CHANGED
@@ -57,7 +57,6 @@ __export(index_exports, {
57
57
  fetchManual: () => fetchManual,
58
58
  gatewayIps: () => gatewayIps,
59
59
  gatewayProxyUrl: () => gatewayProxyUrl,
60
- isPermissionDenied: () => isPermissionDenied,
61
60
  isVerisSandbox: () => isVerisSandbox,
62
61
  missingKeyMessage: () => missingKeyMessage,
63
62
  nodeOptionsWithProxy: () => nodeOptionsWithProxy,
@@ -67,8 +66,6 @@ __export(index_exports, {
67
66
  profilePath: () => profilePath,
68
67
  requireVerisCredentials: () => requireVerisCredentials,
69
68
  resolveVerisCredentials: () => resolveVerisCredentials,
70
- sandboxBrakes: () => sandboxBrakes,
71
- teardownRefusedMessage: () => teardownRefusedMessage,
72
69
  trustPrelude: () => trustPrelude,
73
70
  twinHosts: () => twinHosts,
74
71
  vendorHosts: () => vendorHosts,
@@ -1028,7 +1025,7 @@ function requireVerisCredentials(opts = {}) {
1028
1025
  }
1029
1026
 
1030
1027
  // src/version.ts
1031
- var SDK_VERSION = true ? "0.3.1" : "0.0.0-dev";
1028
+ var SDK_VERSION = true ? "0.4.0" : "0.0.0-dev";
1032
1029
 
1033
1030
  // src/daytona.ts
1034
1031
  var LABEL = {
@@ -1374,38 +1371,6 @@ var DELETE_PERMISSION_FIX = 'create a key with the "delete sandboxes" permission
1374
1371
  function cannotTeardownWarning(key, autoStopMinutes, autoDeleteMinutes) {
1375
1372
  return `DAYTONA_API_KEY ${describeKey(key)} lacks \`${DELETE_SANDBOXES}\`, so \`veris-daytona teardown\` will be refused for the sandbox about to be created, and \`run\` cannot delete its own. The box still stops after ${autoStopMinutes} idle minutes and is deleted ${autoDeleteMinutes} minutes after it stops. For a teardown that works, ${DELETE_PERMISSION_FIX} and use it instead.`;
1376
1373
  }
1377
-
1378
- // src/teardown.ts
1379
- var TEARDOWN_USAGE = `usage: veris-daytona teardown <daytona-sandbox-id>
1380
-
1381
- Deletes the Daytona sandbox. The id is the one \`veris-daytona provision\`
1382
- printed as daytonaSandboxId \u2014 not the Veris twin's id.
1383
-
1384
- The twin follows the rule it was created under: one this package created is
1385
- deleted with the sandbox, one it attached to (\`provision\`, or \`run --sandbox\`)
1386
- is yours and is left running. Which of the two happened is printed.
1387
-
1388
- needs: DAYTONA_API_KEY with the ${DELETE_SANDBOXES} permission \u2014 a key made with
1389
- "write sandboxes" alone is refused, and the refusal says when Daytona will stop
1390
- and delete the box on its own. To reach a twin that must be deleted, a Veris
1391
- key too: VERIS_API_KEY, or the profile \`veris login\` saved.
1392
-
1393
- exit code: 0 when the sandbox is deleted; 1 when there is no such sandbox, or
1394
- the key may not delete one.`;
1395
- function isPermissionDenied(e) {
1396
- return typeof e === "object" && e !== null && e.statusCode === 403;
1397
- }
1398
- function sandboxBrakes(r) {
1399
- const stop = r.autoStopMinutes && r.autoStopMinutes > 0 ? `stops after ${r.autoStopMinutes} idle minutes` : "never stops on its own";
1400
- const del = r.autoDeleteMinutes === void 0 || r.autoDeleteMinutes < 0 ? "is never auto-deleted" : r.autoDeleteMinutes === 0 ? "is deleted as soon as it stops" : `is deleted ${r.autoDeleteMinutes} minutes after it stops`;
1401
- const destroy = r.expiresAt ? `, and is destroyed at ${r.expiresAt} whatever state it is in` : "";
1402
- return `${stop} and ${del}${destroy}`;
1403
- }
1404
- function teardownRefusedMessage(r) {
1405
- const key = r.key ? `this DAYTONA_API_KEY ${describeKey(r.key)} lacks the \`${DELETE_SANDBOXES}\` permission` : `Daytona answered 403 (Access denied), which is what a DAYTONA_API_KEY without the \`${DELETE_SANDBOXES}\` permission gets \u2014 the key's own record could not be read to confirm it`;
1406
- const twin = r.twinId === void 0 ? "" : r.ownsTwin ? ` Its twin ${r.twinId} was deleted before Daytona refused, so nothing is left on the Veris side.` : ` Twin ${r.twinId} is yours and was not touched.`;
1407
- return `Daytona refused to delete sandbox ${r.sandboxId}: ${key}. The sandbox is still there: it ${sandboxBrakes(r)}.${twin} To delete it sooner, ${DELETE_PERMISSION_FIX}, then run \`veris-daytona teardown ${r.sandboxId}\` with it \u2014 or delete the sandbox in the Daytona dashboard.`;
1408
- }
1409
1374
  // Annotate the CommonJS export names for ESM import in node:
1410
1375
  0 && (module.exports = {
1411
1376
  BUNDLED_CA_FILES,
@@ -1443,7 +1408,6 @@ function teardownRefusedMessage(r) {
1443
1408
  fetchManual,
1444
1409
  gatewayIps,
1445
1410
  gatewayProxyUrl,
1446
- isPermissionDenied,
1447
1411
  isVerisSandbox,
1448
1412
  missingKeyMessage,
1449
1413
  nodeOptionsWithProxy,
@@ -1453,8 +1417,6 @@ function teardownRefusedMessage(r) {
1453
1417
  profilePath,
1454
1418
  requireVerisCredentials,
1455
1419
  resolveVerisCredentials,
1456
- sandboxBrakes,
1457
- teardownRefusedMessage,
1458
1420
  trustPrelude,
1459
1421
  twinHosts,
1460
1422
  vendorHosts,