opensandbox-cli 0.1.1__tar.gz → 1.1.1__tar.gz

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 (33) hide show
  1. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/.gitignore +18 -0
  2. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/PKG-INFO +176 -14
  3. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/README.md +170 -9
  4. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/pyproject.toml +9 -6
  5. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/__init__.py +1 -1
  6. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/__main__.py +1 -1
  7. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/client.py +1 -6
  8. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/__init__.py +1 -1
  9. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/command.py +72 -60
  10. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/config_cmd.py +47 -58
  11. opensandbox_cli-1.1.1/src/opensandbox_cli/commands/credential_vault.py +306 -0
  12. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/devops.py +1 -10
  13. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/diagnostics.py +13 -16
  14. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/egress.py +1 -1
  15. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/file.py +55 -31
  16. opensandbox_cli-1.1.1/src/opensandbox_cli/commands/sandbox.py +1057 -0
  17. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/skills.py +1 -4
  18. opensandbox_cli-1.1.1/src/opensandbox_cli/commands/snapshot.py +170 -0
  19. opensandbox_cli-1.1.1/src/opensandbox_cli/commands/template.py +324 -0
  20. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/config.py +1 -1
  21. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/main.py +7 -6
  22. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/output.py +29 -87
  23. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skill_registry.py +35 -4
  24. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-command-execution.md +2 -1
  25. opensandbox_cli-1.1.1/src/opensandbox_cli/skills/opensandbox-credential-vault.md +136 -0
  26. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-file-operations.md +4 -1
  27. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-sandbox-lifecycle.md +64 -1
  28. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-sandbox-troubleshooting.md +8 -11
  29. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/utils.py +38 -41
  30. opensandbox_cli-0.1.1/src/opensandbox_cli/commands/sandbox.py +0 -580
  31. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/LICENSE +0 -0
  32. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/py.typed +0 -0
  33. {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-network-egress.md +0 -0
@@ -269,6 +269,19 @@ nbdist/
269
269
  generated/
270
270
  **/generated/**
271
271
 
272
+ # Fast Sandbox FastPath gRPC stubs are committed intentionally (deterministic protoc
273
+ # output; the server package needs them at install time, so they are checked
274
+ # in rather than regenerated).
275
+ !server/opensandbox_server/services/fast_sandbox/generated/
276
+ !server/opensandbox_server/services/fast_sandbox/generated/**
277
+ server/opensandbox_server/services/fast_sandbox/generated/__pycache__/
278
+
279
+ # execd eBPF kernel BTF dumps (bpf2go build-time only, never committed —
280
+ # see components/execd/pkg/ebpf/prog/audit.bpf.c; regenerate with:
281
+ # bpftool btf dump file /sys/kernel/btf/vmlinux format c > .../vmlinux.h)
282
+ components/execd/pkg/ebpf/prog/vmlinux.h
283
+ components/execd/pkg/ebpf/prog/vmlinux_*.h
284
+
272
285
  # gVisor runtime binaries (downloaded dynamically)
273
286
  kubernetes/test/kind/gvisor/runsc
274
287
  kubernetes/test/kind/gvisor/containerd-shim-runsc-v1
@@ -276,3 +289,8 @@ bin/
276
289
  obj/
277
290
 
278
291
  .qoder/
292
+ /.vs
293
+
294
+ # fast-sandbox pinned source checkout (materialized by
295
+ # manifests/release/build-fast-sandbox.sh from manifests/third-party/fast-sandbox.commit)
296
+ .fast-sandbox/
@@ -1,11 +1,11 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: opensandbox-cli
3
- Version: 0.1.1
3
+ Version: 1.1.1
4
4
  Summary: OpenSandbox CLI - Command-line interface for managing sandboxes
5
5
  Project-URL: Homepage, https://open-sandbox.ai
6
- Project-URL: Repository, https://github.com/alibaba/OpenSandbox
6
+ Project-URL: Repository, https://github.com/opensandbox-group/OpenSandbox
7
7
  Project-URL: Documentation, https://open-sandbox.ai
8
- Project-URL: Issues, https://github.com/alibaba/OpenSandbox/issues
8
+ Project-URL: Issues, https://github.com/opensandbox-group/OpenSandbox/issues
9
9
  Author-email: OpenSandbox Team <ninan.nn@alibaba-inc.com>
10
10
  License: Apache License
11
11
  Version 2.0, January 2004
@@ -224,10 +224,11 @@ Classifier: Topic :: Software Development :: Libraries
224
224
  Classifier: Typing :: Typed
225
225
  Requires-Python: >=3.10
226
226
  Requires-Dist: click<9.0,>=8.1.0
227
- Requires-Dist: opensandbox<0.2.0,>=0.1.9
227
+ Requires-Dist: opensandbox<2.0.0,>=1.1.1
228
228
  Requires-Dist: pyyaml<7.0,>=6.0
229
229
  Requires-Dist: rich<14.0,>=13.0.0
230
230
  Requires-Dist: tomli>=2.0.0; python_version < '3.11'
231
+ Requires-Dist: tomlkit<1.0,>=0.13.0
231
232
  Description-Content-Type: text/markdown
232
233
 
233
234
  # OpenSandbox CLI
@@ -235,9 +236,11 @@ Description-Content-Type: text/markdown
235
236
  `osb` is the command-line interface for OpenSandbox. It is built for the common day-to-day flows:
236
237
 
237
238
  - create and manage sandboxes
239
+ - build golden-image templates and create sandboxes from templates or snapshots
238
240
  - run commands inside a sandbox
239
241
  - read and modify sandbox files
240
242
  - inspect runtime egress policy
243
+ - manage sandbox-local Credential Vault state
241
244
  - collect low-level diagnostics
242
245
  - install OpenSandbox-specific skills for coding agents
243
246
 
@@ -282,6 +285,7 @@ opensandbox-server
282
285
  osb config init
283
286
  osb config set connection.domain localhost:8080
284
287
  osb config set connection.protocol http
288
+ osb config set connection.api_key <your-api-key>
285
289
  osb config show -o json
286
290
  ```
287
291
 
@@ -379,6 +383,109 @@ osb sandbox create \
379
383
  --volumes-file volumes.json
380
384
  ```
381
385
 
386
+ Create with Credential Vault proxy enabled:
387
+
388
+ ```bash
389
+ osb sandbox create --image python:3.12 --network-policy-file network-policy.json --credential-proxy -o json
390
+ ```
391
+
392
+ Create from a template (golden image):
393
+
394
+ ```bash
395
+ osb sandbox create --template <template-id> --timeout 30m -o json
396
+ ```
397
+
398
+ Template mode fixes the workload shape on the server: `--image`, `--env`,
399
+ `--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot
400
+ be combined with `--template`. Only `--timeout` (required), `--metadata`,
401
+ `--extension`, and `--network-policy-file` may accompany it. Only templates in
402
+ the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
403
+
404
+ Create from a snapshot:
405
+
406
+ ```bash
407
+ osb sandbox create --snapshot-id <snapshot-id> --timeout 30m -o json
408
+ ```
409
+
410
+ `--image`, `--template`, and `--snapshot-id` are mutually exclusive.
411
+
412
+ Create from a request file (`-f`, like `kubectl apply -f`):
413
+
414
+ ```bash
415
+ osb sandbox create -f sandbox-request.json -o json
416
+ ```
417
+
418
+ `sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
419
+ (camelCase keys):
420
+
421
+ ```json
422
+ {
423
+ "image": "python:3.12",
424
+ "timeout": 1800,
425
+ "resourceLimits": { "cpu": "1", "memory": "2Gi" },
426
+ "entrypoint": ["python", "-m", "http.server"],
427
+ "networkPolicy": {
428
+ "defaultAction": "deny",
429
+ "egress": [{ "action": "allow", "target": "pypi.org" }]
430
+ }
431
+ }
432
+ ```
433
+
434
+ - Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
435
+ `templateId`, or `snapshotId` is required; `timeout` is integer seconds, or
436
+ `null` for manual cleanup.
437
+ - Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`,
438
+ `resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`,
439
+ `entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`,
440
+ `lifecycle`.
441
+ - `-f` cannot be combined with request-building flags; `--skip-health-check`,
442
+ `--ready-timeout`, and `-o` still apply. In template mode the file may only
443
+ set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside
444
+ `templateId` (a finite `timeout` is required).
445
+
446
+ ### Manage templates
447
+
448
+ Templates are golden-image builds; the build runs asynchronously, so poll
449
+ `template get` until the status phase is `Succeeded`. Template management
450
+ requires a Kubernetes-backed runtime.
451
+
452
+ ```bash
453
+ osb template create --image python:3.12 --publish s3://bucket/publish -o json
454
+ osb template get <template-id> -o json
455
+ osb template list -o json
456
+ osb template delete <template-id> -o json
457
+ ```
458
+
459
+ `template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`,
460
+ `--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata
461
+ KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and
462
+ `--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest`
463
+ JSON format:
464
+
465
+ ```bash
466
+ osb template create -f template-request.json -o json
467
+ ```
468
+
469
+ ```json
470
+ {
471
+ "image": "python:3.12",
472
+ "publish": "s3://bucket/publish",
473
+ "resourceLimits": { "cpu": "1", "memory": "512Mi" },
474
+ "readiness": { "probe": "tcp://127.0.0.1:44772", "warmupSeconds": 60 }
475
+ }
476
+ ```
477
+
478
+ ### Manage snapshots
479
+
480
+ Snapshots capture a sandbox's state and can back new sandboxes.
481
+
482
+ ```bash
483
+ osb snapshot create <sandbox-id> --name golden -o json
484
+ osb snapshot get <snapshot-id> -o json
485
+ osb snapshot list --sandbox-id <sandbox-id> -o json
486
+ osb snapshot delete <snapshot-id> -o json
487
+ ```
488
+
382
489
  ### List and inspect sandboxes
383
490
 
384
491
  ```bash
@@ -390,6 +497,17 @@ osb sandbox metrics <sandbox-id>
390
497
  osb sandbox metrics <sandbox-id> --watch -o raw
391
498
  ```
392
499
 
500
+ ### Pause a sandbox
501
+
502
+ Pause is asynchronous. `Pause request accepted` confirms that the server accepted
503
+ the request, not that the sandbox has reached the `Paused` state. Poll the sandbox
504
+ until the transition finishes:
505
+
506
+ ```bash
507
+ osb sandbox pause <sandbox-id>
508
+ osb sandbox get <sandbox-id> -o json
509
+ ```
510
+
393
511
  ### Expose a service
394
512
 
395
513
  ```bash
@@ -412,6 +530,21 @@ osb command status <sandbox-id> <execution-id> -o json
412
530
  osb command logs <sandbox-id> <execution-id> -o json
413
531
  ```
414
532
 
533
+ Background start errors or a stream ending before startup confirmation make the
534
+ CLI exit non-zero without success metadata. After a successful start, use
535
+ `command status` and `command logs` to check the process's eventual result.
536
+
537
+ By default the payload after `--` is joined into one shell command string, so
538
+ pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv`
539
+ to pass the arguments to the executable as a literal argv list (no shell) when
540
+ values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the
541
+ process unchanged. `--argv` needs a sandbox image whose execd accepts argv
542
+ requests:
543
+
544
+ ```bash
545
+ osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
546
+ ```
547
+
415
548
  Persistent shell session:
416
549
 
417
550
  ```bash
@@ -433,6 +566,11 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
433
566
  osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
434
567
  ```
435
568
 
569
+ Downloads replace regular files only on success; a failed or interrupted
570
+ download preserves any existing regular file. Existing devices and named pipes
571
+ receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file
572
+ bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
573
+
436
574
  ### Manage runtime egress policy
437
575
 
438
576
  Inspect current policy:
@@ -453,26 +591,46 @@ If you are debugging connectivity, verify behavior with an actual command:
453
591
  osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
454
592
  ```
455
593
 
594
+ ### Manage Credential Vault
595
+
596
+ Credential Vault operations call the sandbox egress sidecar through the Python SDK.
597
+ Create the sandbox with `--credential-proxy` and an explicit network policy before
598
+ writing vault state.
599
+
600
+ ```bash
601
+ osb credential-vault create <sandbox-id> --file vault.yaml -o json
602
+ osb credential-vault get <sandbox-id> -o json
603
+ osb credential-vault patch <sandbox-id> --file mutation.yaml -o json
604
+ osb credential-vault credential list <sandbox-id> -o json
605
+ osb credential-vault binding list <sandbox-id> -o json
606
+ osb credential-vault delete <sandbox-id> -o json
607
+ ```
608
+
609
+ Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext
610
+ credential values as command-line flags; keep them in the payload stream or file.
611
+
456
612
  ### Collect diagnostics
457
613
 
458
614
  Use the stable diagnostics commands for API-backed log and event descriptors.
459
615
 
460
616
  ```bash
461
- osb diagnostics events <sandbox-id> --scope lifecycle -o raw
462
617
  osb diagnostics events <sandbox-id> --scope runtime -o raw
618
+ osb diagnostics events <sandbox-id> --scope all -o raw
463
619
  osb diagnostics logs <sandbox-id> --scope container -o raw
464
- osb diagnostics logs <sandbox-id> --scope lifecycle -o json
620
+ osb diagnostics logs <sandbox-id> --scope all -o json
465
621
  osb diagnostics events <sandbox-id> --scope runtime -o json
466
622
  osb diagnostics logs <sandbox-id> --scope container -o yaml
467
623
  ```
468
624
 
469
- `--scope` is required for stable diagnostics. Common scopes are `lifecycle` and
470
- `container` for logs, and `lifecycle` and `runtime` for events. Raw output
471
- prints inline diagnostic text, or the content URL when diagnostics are
472
- delivered as a temporary URL. Structured CLI output follows the SDK/Python field
473
- style, for example `content_url`, `content_length`, and `expires_at`.
474
- Some server builds may return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped
475
- diagnostics until the stable backend implementation is enabled.
625
+ `--scope` is required for stable diagnostics. The built-in server supports
626
+ `container` and `all` for logs, and `runtime` and `all` for events. It returns
627
+ `DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
628
+ Best-effort scopes may include a `warnings` field when the backend can only
629
+ provide a subset. Raw output prints inline
630
+ diagnostic text, or the content URL when diagnostics are delivered as a
631
+ temporary URL. Structured CLI output follows the SDK/Python field style, for
632
+ example `content_url`, `content_length`, and `expires_at`. Older server builds
633
+ may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
476
634
 
477
635
  Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
478
636
  for stable API-backed log and event collection.
@@ -506,6 +664,8 @@ Not every command supports every format. Use `--help` on the specific command wh
506
664
  The main command groups are:
507
665
 
508
666
  - `osb sandbox`: lifecycle management
667
+ - `osb template`: golden-image template builds
668
+ - `osb snapshot`: snapshot management
509
669
  - `osb command`: command execution and persistent sessions
510
670
  - `osb file`: file and directory operations
511
671
  - `osb egress`: runtime egress policy
@@ -518,6 +678,8 @@ Explore them directly:
518
678
 
519
679
  ```bash
520
680
  osb sandbox --help
681
+ osb template --help
682
+ osb snapshot --help
521
683
  osb command --help
522
684
  osb file --help
523
685
  osb skills --help
@@ -3,9 +3,11 @@
3
3
  `osb` is the command-line interface for OpenSandbox. It is built for the common day-to-day flows:
4
4
 
5
5
  - create and manage sandboxes
6
+ - build golden-image templates and create sandboxes from templates or snapshots
6
7
  - run commands inside a sandbox
7
8
  - read and modify sandbox files
8
9
  - inspect runtime egress policy
10
+ - manage sandbox-local Credential Vault state
9
11
  - collect low-level diagnostics
10
12
  - install OpenSandbox-specific skills for coding agents
11
13
 
@@ -50,6 +52,7 @@ opensandbox-server
50
52
  osb config init
51
53
  osb config set connection.domain localhost:8080
52
54
  osb config set connection.protocol http
55
+ osb config set connection.api_key <your-api-key>
53
56
  osb config show -o json
54
57
  ```
55
58
 
@@ -147,6 +150,109 @@ osb sandbox create \
147
150
  --volumes-file volumes.json
148
151
  ```
149
152
 
153
+ Create with Credential Vault proxy enabled:
154
+
155
+ ```bash
156
+ osb sandbox create --image python:3.12 --network-policy-file network-policy.json --credential-proxy -o json
157
+ ```
158
+
159
+ Create from a template (golden image):
160
+
161
+ ```bash
162
+ osb sandbox create --template <template-id> --timeout 30m -o json
163
+ ```
164
+
165
+ Template mode fixes the workload shape on the server: `--image`, `--env`,
166
+ `--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot
167
+ be combined with `--template`. Only `--timeout` (required), `--metadata`,
168
+ `--extension`, and `--network-policy-file` may accompany it. Only templates in
169
+ the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
170
+
171
+ Create from a snapshot:
172
+
173
+ ```bash
174
+ osb sandbox create --snapshot-id <snapshot-id> --timeout 30m -o json
175
+ ```
176
+
177
+ `--image`, `--template`, and `--snapshot-id` are mutually exclusive.
178
+
179
+ Create from a request file (`-f`, like `kubectl apply -f`):
180
+
181
+ ```bash
182
+ osb sandbox create -f sandbox-request.json -o json
183
+ ```
184
+
185
+ `sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
186
+ (camelCase keys):
187
+
188
+ ```json
189
+ {
190
+ "image": "python:3.12",
191
+ "timeout": 1800,
192
+ "resourceLimits": { "cpu": "1", "memory": "2Gi" },
193
+ "entrypoint": ["python", "-m", "http.server"],
194
+ "networkPolicy": {
195
+ "defaultAction": "deny",
196
+ "egress": [{ "action": "allow", "target": "pypi.org" }]
197
+ }
198
+ }
199
+ ```
200
+
201
+ - Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
202
+ `templateId`, or `snapshotId` is required; `timeout` is integer seconds, or
203
+ `null` for manual cleanup.
204
+ - Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`,
205
+ `resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`,
206
+ `entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`,
207
+ `lifecycle`.
208
+ - `-f` cannot be combined with request-building flags; `--skip-health-check`,
209
+ `--ready-timeout`, and `-o` still apply. In template mode the file may only
210
+ set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside
211
+ `templateId` (a finite `timeout` is required).
212
+
213
+ ### Manage templates
214
+
215
+ Templates are golden-image builds; the build runs asynchronously, so poll
216
+ `template get` until the status phase is `Succeeded`. Template management
217
+ requires a Kubernetes-backed runtime.
218
+
219
+ ```bash
220
+ osb template create --image python:3.12 --publish s3://bucket/publish -o json
221
+ osb template get <template-id> -o json
222
+ osb template list -o json
223
+ osb template delete <template-id> -o json
224
+ ```
225
+
226
+ `template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`,
227
+ `--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata
228
+ KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and
229
+ `--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest`
230
+ JSON format:
231
+
232
+ ```bash
233
+ osb template create -f template-request.json -o json
234
+ ```
235
+
236
+ ```json
237
+ {
238
+ "image": "python:3.12",
239
+ "publish": "s3://bucket/publish",
240
+ "resourceLimits": { "cpu": "1", "memory": "512Mi" },
241
+ "readiness": { "probe": "tcp://127.0.0.1:44772", "warmupSeconds": 60 }
242
+ }
243
+ ```
244
+
245
+ ### Manage snapshots
246
+
247
+ Snapshots capture a sandbox's state and can back new sandboxes.
248
+
249
+ ```bash
250
+ osb snapshot create <sandbox-id> --name golden -o json
251
+ osb snapshot get <snapshot-id> -o json
252
+ osb snapshot list --sandbox-id <sandbox-id> -o json
253
+ osb snapshot delete <snapshot-id> -o json
254
+ ```
255
+
150
256
  ### List and inspect sandboxes
151
257
 
152
258
  ```bash
@@ -158,6 +264,17 @@ osb sandbox metrics <sandbox-id>
158
264
  osb sandbox metrics <sandbox-id> --watch -o raw
159
265
  ```
160
266
 
267
+ ### Pause a sandbox
268
+
269
+ Pause is asynchronous. `Pause request accepted` confirms that the server accepted
270
+ the request, not that the sandbox has reached the `Paused` state. Poll the sandbox
271
+ until the transition finishes:
272
+
273
+ ```bash
274
+ osb sandbox pause <sandbox-id>
275
+ osb sandbox get <sandbox-id> -o json
276
+ ```
277
+
161
278
  ### Expose a service
162
279
 
163
280
  ```bash
@@ -180,6 +297,21 @@ osb command status <sandbox-id> <execution-id> -o json
180
297
  osb command logs <sandbox-id> <execution-id> -o json
181
298
  ```
182
299
 
300
+ Background start errors or a stream ending before startup confirmation make the
301
+ CLI exit non-zero without success metadata. After a successful start, use
302
+ `command status` and `command logs` to check the process's eventual result.
303
+
304
+ By default the payload after `--` is joined into one shell command string, so
305
+ pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv`
306
+ to pass the arguments to the executable as a literal argv list (no shell) when
307
+ values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the
308
+ process unchanged. `--argv` needs a sandbox image whose execd accepts argv
309
+ requests:
310
+
311
+ ```bash
312
+ osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
313
+ ```
314
+
183
315
  Persistent shell session:
184
316
 
185
317
  ```bash
@@ -201,6 +333,11 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
201
333
  osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
202
334
  ```
203
335
 
336
+ Downloads replace regular files only on success; a failed or interrupted
337
+ download preserves any existing regular file. Existing devices and named pipes
338
+ receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file
339
+ bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
340
+
204
341
  ### Manage runtime egress policy
205
342
 
206
343
  Inspect current policy:
@@ -221,26 +358,46 @@ If you are debugging connectivity, verify behavior with an actual command:
221
358
  osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
222
359
  ```
223
360
 
361
+ ### Manage Credential Vault
362
+
363
+ Credential Vault operations call the sandbox egress sidecar through the Python SDK.
364
+ Create the sandbox with `--credential-proxy` and an explicit network policy before
365
+ writing vault state.
366
+
367
+ ```bash
368
+ osb credential-vault create <sandbox-id> --file vault.yaml -o json
369
+ osb credential-vault get <sandbox-id> -o json
370
+ osb credential-vault patch <sandbox-id> --file mutation.yaml -o json
371
+ osb credential-vault credential list <sandbox-id> -o json
372
+ osb credential-vault binding list <sandbox-id> -o json
373
+ osb credential-vault delete <sandbox-id> -o json
374
+ ```
375
+
376
+ Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext
377
+ credential values as command-line flags; keep them in the payload stream or file.
378
+
224
379
  ### Collect diagnostics
225
380
 
226
381
  Use the stable diagnostics commands for API-backed log and event descriptors.
227
382
 
228
383
  ```bash
229
- osb diagnostics events <sandbox-id> --scope lifecycle -o raw
230
384
  osb diagnostics events <sandbox-id> --scope runtime -o raw
385
+ osb diagnostics events <sandbox-id> --scope all -o raw
231
386
  osb diagnostics logs <sandbox-id> --scope container -o raw
232
- osb diagnostics logs <sandbox-id> --scope lifecycle -o json
387
+ osb diagnostics logs <sandbox-id> --scope all -o json
233
388
  osb diagnostics events <sandbox-id> --scope runtime -o json
234
389
  osb diagnostics logs <sandbox-id> --scope container -o yaml
235
390
  ```
236
391
 
237
- `--scope` is required for stable diagnostics. Common scopes are `lifecycle` and
238
- `container` for logs, and `lifecycle` and `runtime` for events. Raw output
239
- prints inline diagnostic text, or the content URL when diagnostics are
240
- delivered as a temporary URL. Structured CLI output follows the SDK/Python field
241
- style, for example `content_url`, `content_length`, and `expires_at`.
242
- Some server builds may return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped
243
- diagnostics until the stable backend implementation is enabled.
392
+ `--scope` is required for stable diagnostics. The built-in server supports
393
+ `container` and `all` for logs, and `runtime` and `all` for events. It returns
394
+ `DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
395
+ Best-effort scopes may include a `warnings` field when the backend can only
396
+ provide a subset. Raw output prints inline
397
+ diagnostic text, or the content URL when diagnostics are delivered as a
398
+ temporary URL. Structured CLI output follows the SDK/Python field style, for
399
+ example `content_url`, `content_length`, and `expires_at`. Older server builds
400
+ may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
244
401
 
245
402
  Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
246
403
  for stable API-backed log and event collection.
@@ -274,6 +431,8 @@ Not every command supports every format. Use `--help` on the specific command wh
274
431
  The main command groups are:
275
432
 
276
433
  - `osb sandbox`: lifecycle management
434
+ - `osb template`: golden-image template builds
435
+ - `osb snapshot`: snapshot management
277
436
  - `osb command`: command execution and persistent sessions
278
437
  - `osb file`: file and directory operations
279
438
  - `osb egress`: runtime egress policy
@@ -286,6 +445,8 @@ Explore them directly:
286
445
 
287
446
  ```bash
288
447
  osb sandbox --help
448
+ osb template --help
449
+ osb snapshot --help
289
450
  osb command --help
290
451
  osb file --help
291
452
  osb skills --help
@@ -1,4 +1,4 @@
1
- # Copyright 2026 Alibaba Group Holding Ltd.
1
+ # Copyright 2026 The OpenSandbox Authors.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -42,18 +42,21 @@ classifiers = [
42
42
  "Typing :: Typed",
43
43
  ]
44
44
  dependencies = [
45
- "opensandbox>=0.1.9,<0.2.0",
45
+ # `command run --argv` passes a list to commands.run; the SDK accepts a
46
+ # list there from 0.1.17. Release the CLI only after that SDK is published.
47
+ "opensandbox>=1.1.1,<2.0.0",
46
48
  "click>=8.1.0,<9.0",
47
49
  "rich>=13.0.0,<14.0",
48
50
  "pyyaml>=6.0,<7.0",
51
+ "tomlkit>=0.13.0,<1.0",
49
52
  "tomli>=2.0.0; python_version < '3.11'",
50
53
  ]
51
54
 
52
55
  [project.urls]
53
56
  Homepage = "https://open-sandbox.ai"
54
- Repository = "https://github.com/alibaba/OpenSandbox"
57
+ Repository = "https://github.com/opensandbox-group/OpenSandbox"
55
58
  Documentation = "https://open-sandbox.ai"
56
- Issues = "https://github.com/alibaba/OpenSandbox/issues"
59
+ Issues = "https://github.com/opensandbox-group/OpenSandbox/issues"
57
60
 
58
61
  [project.scripts]
59
62
  opensandbox = "opensandbox_cli.main:cli"
@@ -64,8 +67,8 @@ source = "vcs"
64
67
 
65
68
  [tool.hatch.version.raw-options]
66
69
  root = ".."
67
- tag_regex = "^cli/v(?P<version>\\d+\\.\\d+\\.\\d+(?:[\\.\\w\\+\\-]*)?)$"
68
- git_describe_command = 'git describe --dirty --tags --long --match "cli/v*"'
70
+ tag_regex = "^release-(?P<version>\\d+\\.\\d+\\.\\d+(?:[\\.\\w\\+\\-]*)?)$"
71
+ git_describe_command = 'git describe --dirty --tags --long --match "release-*"'
69
72
  fallback_version = "0.1.1"
70
73
 
71
74
  [tool.hatch.build]
@@ -1,4 +1,4 @@
1
- # Copyright 2026 Alibaba Group Holding Ltd.
1
+ # Copyright 2026 The OpenSandbox Authors.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2026 Alibaba Group Holding Ltd.
1
+ # Copyright 2026 The OpenSandbox Authors.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2026 Alibaba Group Holding Ltd.
1
+ # Copyright 2026 The OpenSandbox Authors.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -90,15 +90,10 @@ class ClientContext:
90
90
  self._manager = SandboxManagerSync.create(self.connection_config)
91
91
  return self._manager
92
92
 
93
- def resolve_sandbox_id(self, sandbox_id: str) -> str:
94
- """Return the sandbox ID exactly as provided by the user."""
95
- return sandbox_id
96
-
97
93
  def connect_sandbox(
98
94
  self, sandbox_id: str, *, skip_health_check: bool = True
99
95
  ) -> SandboxSync:
100
96
  """Connect to an existing sandbox by ID."""
101
- sandbox_id = self.resolve_sandbox_id(sandbox_id)
102
97
  return SandboxSync.connect(
103
98
  sandbox_id,
104
99
  connection_config=self.connection_config,
@@ -1,4 +1,4 @@
1
- # Copyright 2026 Alibaba Group Holding Ltd.
1
+ # Copyright 2026 The OpenSandbox Authors.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.