opensandbox-cli 1.1.1__tar.gz → 1.1.2.dev20261020__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.
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/PKG-INFO +23 -55
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/README.md +22 -54
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/diagnostics.py +18 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/sandbox.py +2 -2
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/skills.py +6 -3
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/config.py +48 -15
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/main.py +38 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/output.py +21 -1
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-command-execution.md +3 -6
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-credential-vault.md +8 -19
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-file-operations.md +4 -8
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-network-egress.md +2 -4
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-sandbox-lifecycle.md +1 -1
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skills/opensandbox-sandbox-troubleshooting.md +6 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/.gitignore +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/LICENSE +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/pyproject.toml +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/__init__.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/__main__.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/client.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/__init__.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/command.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/config_cmd.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/credential_vault.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/devops.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/egress.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/file.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/snapshot.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/template.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/py.typed +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skill_registry.py +0 -0
- {opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: opensandbox-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2.dev20261020
|
|
4
4
|
Summary: OpenSandbox CLI - Command-line interface for managing sandboxes
|
|
5
5
|
Project-URL: Homepage, https://open-sandbox.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/opensandbox-group/OpenSandbox
|
|
@@ -395,11 +395,7 @@ Create from a template (golden image):
|
|
|
395
395
|
osb sandbox create --template <template-id> --timeout 30m -o json
|
|
396
396
|
```
|
|
397
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).
|
|
398
|
+
Template mode fixes the workload shape on the server: `--image`, `--env`, `--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot be combined with `--template`. Only `--timeout` (required), `--metadata`, `--extension`, and `--network-policy-file` may accompany it. Only templates in the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
|
|
403
399
|
|
|
404
400
|
Create from a snapshot:
|
|
405
401
|
|
|
@@ -415,8 +411,7 @@ Create from a request file (`-f`, like `kubectl apply -f`):
|
|
|
415
411
|
osb sandbox create -f sandbox-request.json -o json
|
|
416
412
|
```
|
|
417
413
|
|
|
418
|
-
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
|
|
419
|
-
(camelCase keys):
|
|
414
|
+
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format (camelCase keys):
|
|
420
415
|
|
|
421
416
|
```json
|
|
422
417
|
{
|
|
@@ -431,23 +426,13 @@ osb sandbox create -f sandbox-request.json -o json
|
|
|
431
426
|
}
|
|
432
427
|
```
|
|
433
428
|
|
|
434
|
-
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
|
|
435
|
-
|
|
436
|
-
|
|
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).
|
|
429
|
+
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`), `templateId`, or `snapshotId` is required; `timeout` is integer seconds, or `null` for manual cleanup.
|
|
430
|
+
- Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`, `resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`, `entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`, `lifecycle`.
|
|
431
|
+
- `-f` cannot be combined with request-building flags; `--skip-health-check`, `--ready-timeout`, and `-o` still apply. In template mode the file may only set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside `templateId` (a finite `timeout` is required).
|
|
445
432
|
|
|
446
433
|
### Manage templates
|
|
447
434
|
|
|
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.
|
|
435
|
+
Templates are golden-image builds; the build runs asynchronously, so poll `template get` until the status phase is `Succeeded`. Template management requires a Kubernetes-backed runtime.
|
|
451
436
|
|
|
452
437
|
```bash
|
|
453
438
|
osb template create --image python:3.12 --publish s3://bucket/publish -o json
|
|
@@ -456,11 +441,7 @@ osb template list -o json
|
|
|
456
441
|
osb template delete <template-id> -o json
|
|
457
442
|
```
|
|
458
443
|
|
|
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:
|
|
444
|
+
`template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`, `--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and `--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest` JSON format:
|
|
464
445
|
|
|
465
446
|
```bash
|
|
466
447
|
osb template create -f template-request.json -o json
|
|
@@ -499,9 +480,7 @@ osb sandbox metrics <sandbox-id> --watch -o raw
|
|
|
499
480
|
|
|
500
481
|
### Pause a sandbox
|
|
501
482
|
|
|
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:
|
|
483
|
+
Pause is asynchronous. `Pause request accepted` confirms that the server accepted the request, not that the sandbox has reached the `Paused` state. Poll the sandbox until the transition finishes:
|
|
505
484
|
|
|
506
485
|
```bash
|
|
507
486
|
osb sandbox pause <sandbox-id>
|
|
@@ -530,16 +509,9 @@ osb command status <sandbox-id> <execution-id> -o json
|
|
|
530
509
|
osb command logs <sandbox-id> <execution-id> -o json
|
|
531
510
|
```
|
|
532
511
|
|
|
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.
|
|
512
|
+
Background start errors or a stream ending before startup confirmation make the CLI exit non-zero without success metadata. After a successful start, use `command status` and `command logs` to check the process's eventual result.
|
|
536
513
|
|
|
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:
|
|
514
|
+
By default the payload after `--` is joined into one shell command string, so pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv` to pass the arguments to the executable as a literal argv list (no shell) when values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the process unchanged. `--argv` needs a sandbox image whose execd accepts argv requests:
|
|
543
515
|
|
|
544
516
|
```bash
|
|
545
517
|
osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
|
|
@@ -566,10 +538,7 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
|
|
|
566
538
|
osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
|
|
567
539
|
```
|
|
568
540
|
|
|
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).
|
|
541
|
+
Downloads replace regular files only on success; a failed or interrupted download preserves any existing regular file. Existing devices and named pipes receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
|
|
573
542
|
|
|
574
543
|
### Manage runtime egress policy
|
|
575
544
|
|
|
@@ -593,9 +562,7 @@ osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
|
|
|
593
562
|
|
|
594
563
|
### Manage Credential Vault
|
|
595
564
|
|
|
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.
|
|
565
|
+
Credential Vault operations call the sandbox egress sidecar through the Python SDK. Create the sandbox with `--credential-proxy` and an explicit network policy before writing vault state.
|
|
599
566
|
|
|
600
567
|
```bash
|
|
601
568
|
osb credential-vault create <sandbox-id> --file vault.yaml -o json
|
|
@@ -606,14 +573,14 @@ osb credential-vault binding list <sandbox-id> -o json
|
|
|
606
573
|
osb credential-vault delete <sandbox-id> -o json
|
|
607
574
|
```
|
|
608
575
|
|
|
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.
|
|
576
|
+
Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext credential values as command-line flags; keep them in the payload stream or file.
|
|
611
577
|
|
|
612
578
|
### Collect diagnostics
|
|
613
579
|
|
|
614
|
-
Use the
|
|
580
|
+
Use context to identify the runtime backend, then collect log and event descriptors.
|
|
615
581
|
|
|
616
582
|
```bash
|
|
583
|
+
osb diagnostics context <sandbox-id> -o json
|
|
617
584
|
osb diagnostics events <sandbox-id> --scope runtime -o raw
|
|
618
585
|
osb diagnostics events <sandbox-id> --scope all -o raw
|
|
619
586
|
osb diagnostics logs <sandbox-id> --scope container -o raw
|
|
@@ -622,7 +589,9 @@ osb diagnostics events <sandbox-id> --scope runtime -o json
|
|
|
622
589
|
osb diagnostics logs <sandbox-id> --scope container -o yaml
|
|
623
590
|
```
|
|
624
591
|
|
|
625
|
-
|
|
592
|
+
`context` returns backend routing information without connecting to execd and
|
|
593
|
+
supports table, JSON, and YAML output. `--scope` is required for logs/events.
|
|
594
|
+
The built-in server supports
|
|
626
595
|
`container` and `all` for logs, and `runtime` and `all` for events. It returns
|
|
627
596
|
`DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
|
|
628
597
|
Best-effort scopes may include a `warnings` field when the backend can only
|
|
@@ -632,8 +601,7 @@ temporary URL. Structured CLI output follows the SDK/Python field style, for
|
|
|
632
601
|
example `content_url`, `content_length`, and `expires_at`. Older server builds
|
|
633
602
|
may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
|
|
634
603
|
|
|
635
|
-
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
|
|
636
|
-
for stable API-backed log and event collection.
|
|
604
|
+
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events` for stable API-backed log and event collection.
|
|
637
605
|
|
|
638
606
|
```bash
|
|
639
607
|
osb devops inspect <sandbox-id> -o raw
|
|
@@ -701,12 +669,12 @@ Supported targets:
|
|
|
701
669
|
|
|
702
670
|
| Target | Install location |
|
|
703
671
|
| --- | --- |
|
|
704
|
-
| `claude` | `./.claude/skills
|
|
672
|
+
| `claude` | `./.claude/skills/<name>/SKILL.md` or `~/.claude/skills/<name>/SKILL.md` |
|
|
705
673
|
| `cursor` | `./.cursor/rules/` or `~/.cursor/rules/` |
|
|
706
674
|
| `codex` | `./.codex/skills/<name>/SKILL.md` or `~/.codex/skills/<name>/SKILL.md` |
|
|
707
|
-
| `copilot` | `./.github/copilot-instructions.md` or `~/.
|
|
675
|
+
| `copilot` | `./.github/copilot-instructions.md` or `~/.copilot/copilot-instructions.md` |
|
|
708
676
|
| `windsurf` | `./.windsurfrules` or `~/.windsurfrules` |
|
|
709
|
-
| `cline` | `./.clinerules` or `~/.
|
|
677
|
+
| `cline` | `./.clinerules` or `~/.cline/rules/opensandbox-<name>.md` |
|
|
710
678
|
| `opencode` | `./.agents/skills/<name>/SKILL.md` or `~/.agents/skills/<name>/SKILL.md` |
|
|
711
679
|
|
|
712
680
|
Common flows:
|
|
@@ -162,11 +162,7 @@ Create from a template (golden image):
|
|
|
162
162
|
osb sandbox create --template <template-id> --timeout 30m -o json
|
|
163
163
|
```
|
|
164
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).
|
|
165
|
+
Template mode fixes the workload shape on the server: `--image`, `--env`, `--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot be combined with `--template`. Only `--timeout` (required), `--metadata`, `--extension`, and `--network-policy-file` may accompany it. Only templates in the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
|
|
170
166
|
|
|
171
167
|
Create from a snapshot:
|
|
172
168
|
|
|
@@ -182,8 +178,7 @@ Create from a request file (`-f`, like `kubectl apply -f`):
|
|
|
182
178
|
osb sandbox create -f sandbox-request.json -o json
|
|
183
179
|
```
|
|
184
180
|
|
|
185
|
-
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
|
|
186
|
-
(camelCase keys):
|
|
181
|
+
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format (camelCase keys):
|
|
187
182
|
|
|
188
183
|
```json
|
|
189
184
|
{
|
|
@@ -198,23 +193,13 @@ osb sandbox create -f sandbox-request.json -o json
|
|
|
198
193
|
}
|
|
199
194
|
```
|
|
200
195
|
|
|
201
|
-
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
|
|
202
|
-
|
|
203
|
-
|
|
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).
|
|
196
|
+
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`), `templateId`, or `snapshotId` is required; `timeout` is integer seconds, or `null` for manual cleanup.
|
|
197
|
+
- Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`, `resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`, `entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`, `lifecycle`.
|
|
198
|
+
- `-f` cannot be combined with request-building flags; `--skip-health-check`, `--ready-timeout`, and `-o` still apply. In template mode the file may only set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside `templateId` (a finite `timeout` is required).
|
|
212
199
|
|
|
213
200
|
### Manage templates
|
|
214
201
|
|
|
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.
|
|
202
|
+
Templates are golden-image builds; the build runs asynchronously, so poll `template get` until the status phase is `Succeeded`. Template management requires a Kubernetes-backed runtime.
|
|
218
203
|
|
|
219
204
|
```bash
|
|
220
205
|
osb template create --image python:3.12 --publish s3://bucket/publish -o json
|
|
@@ -223,11 +208,7 @@ osb template list -o json
|
|
|
223
208
|
osb template delete <template-id> -o json
|
|
224
209
|
```
|
|
225
210
|
|
|
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:
|
|
211
|
+
`template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`, `--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and `--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest` JSON format:
|
|
231
212
|
|
|
232
213
|
```bash
|
|
233
214
|
osb template create -f template-request.json -o json
|
|
@@ -266,9 +247,7 @@ osb sandbox metrics <sandbox-id> --watch -o raw
|
|
|
266
247
|
|
|
267
248
|
### Pause a sandbox
|
|
268
249
|
|
|
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:
|
|
250
|
+
Pause is asynchronous. `Pause request accepted` confirms that the server accepted the request, not that the sandbox has reached the `Paused` state. Poll the sandbox until the transition finishes:
|
|
272
251
|
|
|
273
252
|
```bash
|
|
274
253
|
osb sandbox pause <sandbox-id>
|
|
@@ -297,16 +276,9 @@ osb command status <sandbox-id> <execution-id> -o json
|
|
|
297
276
|
osb command logs <sandbox-id> <execution-id> -o json
|
|
298
277
|
```
|
|
299
278
|
|
|
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.
|
|
279
|
+
Background start errors or a stream ending before startup confirmation make the CLI exit non-zero without success metadata. After a successful start, use `command status` and `command logs` to check the process's eventual result.
|
|
303
280
|
|
|
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:
|
|
281
|
+
By default the payload after `--` is joined into one shell command string, so pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv` to pass the arguments to the executable as a literal argv list (no shell) when values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the process unchanged. `--argv` needs a sandbox image whose execd accepts argv requests:
|
|
310
282
|
|
|
311
283
|
```bash
|
|
312
284
|
osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
|
|
@@ -333,10 +305,7 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
|
|
|
333
305
|
osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
|
|
334
306
|
```
|
|
335
307
|
|
|
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).
|
|
308
|
+
Downloads replace regular files only on success; a failed or interrupted download preserves any existing regular file. Existing devices and named pipes receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
|
|
340
309
|
|
|
341
310
|
### Manage runtime egress policy
|
|
342
311
|
|
|
@@ -360,9 +329,7 @@ osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
|
|
|
360
329
|
|
|
361
330
|
### Manage Credential Vault
|
|
362
331
|
|
|
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.
|
|
332
|
+
Credential Vault operations call the sandbox egress sidecar through the Python SDK. Create the sandbox with `--credential-proxy` and an explicit network policy before writing vault state.
|
|
366
333
|
|
|
367
334
|
```bash
|
|
368
335
|
osb credential-vault create <sandbox-id> --file vault.yaml -o json
|
|
@@ -373,14 +340,14 @@ osb credential-vault binding list <sandbox-id> -o json
|
|
|
373
340
|
osb credential-vault delete <sandbox-id> -o json
|
|
374
341
|
```
|
|
375
342
|
|
|
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.
|
|
343
|
+
Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext credential values as command-line flags; keep them in the payload stream or file.
|
|
378
344
|
|
|
379
345
|
### Collect diagnostics
|
|
380
346
|
|
|
381
|
-
Use the
|
|
347
|
+
Use context to identify the runtime backend, then collect log and event descriptors.
|
|
382
348
|
|
|
383
349
|
```bash
|
|
350
|
+
osb diagnostics context <sandbox-id> -o json
|
|
384
351
|
osb diagnostics events <sandbox-id> --scope runtime -o raw
|
|
385
352
|
osb diagnostics events <sandbox-id> --scope all -o raw
|
|
386
353
|
osb diagnostics logs <sandbox-id> --scope container -o raw
|
|
@@ -389,7 +356,9 @@ osb diagnostics events <sandbox-id> --scope runtime -o json
|
|
|
389
356
|
osb diagnostics logs <sandbox-id> --scope container -o yaml
|
|
390
357
|
```
|
|
391
358
|
|
|
392
|
-
|
|
359
|
+
`context` returns backend routing information without connecting to execd and
|
|
360
|
+
supports table, JSON, and YAML output. `--scope` is required for logs/events.
|
|
361
|
+
The built-in server supports
|
|
393
362
|
`container` and `all` for logs, and `runtime` and `all` for events. It returns
|
|
394
363
|
`DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
|
|
395
364
|
Best-effort scopes may include a `warnings` field when the backend can only
|
|
@@ -399,8 +368,7 @@ temporary URL. Structured CLI output follows the SDK/Python field style, for
|
|
|
399
368
|
example `content_url`, `content_length`, and `expires_at`. Older server builds
|
|
400
369
|
may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
|
|
401
370
|
|
|
402
|
-
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
|
|
403
|
-
for stable API-backed log and event collection.
|
|
371
|
+
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events` for stable API-backed log and event collection.
|
|
404
372
|
|
|
405
373
|
```bash
|
|
406
374
|
osb devops inspect <sandbox-id> -o raw
|
|
@@ -468,12 +436,12 @@ Supported targets:
|
|
|
468
436
|
|
|
469
437
|
| Target | Install location |
|
|
470
438
|
| --- | --- |
|
|
471
|
-
| `claude` | `./.claude/skills
|
|
439
|
+
| `claude` | `./.claude/skills/<name>/SKILL.md` or `~/.claude/skills/<name>/SKILL.md` |
|
|
472
440
|
| `cursor` | `./.cursor/rules/` or `~/.cursor/rules/` |
|
|
473
441
|
| `codex` | `./.codex/skills/<name>/SKILL.md` or `~/.codex/skills/<name>/SKILL.md` |
|
|
474
|
-
| `copilot` | `./.github/copilot-instructions.md` or `~/.
|
|
442
|
+
| `copilot` | `./.github/copilot-instructions.md` or `~/.copilot/copilot-instructions.md` |
|
|
475
443
|
| `windsurf` | `./.windsurfrules` or `~/.windsurfrules` |
|
|
476
|
-
| `cline` | `./.clinerules` or `~/.
|
|
444
|
+
| `cline` | `./.clinerules` or `~/.cline/rules/opensandbox-<name>.md` |
|
|
477
445
|
| `opencode` | `./.agents/skills/<name>/SKILL.md` or `~/.agents/skills/<name>/SKILL.md` |
|
|
478
446
|
|
|
479
447
|
Common flows:
|
|
@@ -64,6 +64,24 @@ def diagnostics_group(ctx: click.Context) -> None:
|
|
|
64
64
|
click.echo(ctx.get_help())
|
|
65
65
|
|
|
66
66
|
|
|
67
|
+
@diagnostics_group.command("context")
|
|
68
|
+
@click.argument("sandbox_id")
|
|
69
|
+
@output_option("table", "json", "yaml")
|
|
70
|
+
@click.pass_obj
|
|
71
|
+
@handle_errors
|
|
72
|
+
def diagnostics_context(
|
|
73
|
+
obj: ClientContext,
|
|
74
|
+
sandbox_id: str,
|
|
75
|
+
output_format: str | None,
|
|
76
|
+
) -> None:
|
|
77
|
+
"""Identify the sandbox backend and its diagnostic identifiers."""
|
|
78
|
+
context = obj.get_manager().get_diagnostic_context(sandbox_id)
|
|
79
|
+
output = prepare_output(
|
|
80
|
+
obj, output_format, allowed=("table", "json", "yaml"), fallback="table"
|
|
81
|
+
)
|
|
82
|
+
output.print_dict(context.model_dump(mode="json"), title="Diagnostic Context")
|
|
83
|
+
|
|
84
|
+
|
|
67
85
|
@diagnostics_group.command("logs")
|
|
68
86
|
@click.argument("sandbox_id")
|
|
69
87
|
@click.option(
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/sandbox.py
RENAMED
|
@@ -823,14 +823,14 @@ def sandbox_get(obj: ClientContext, sandbox_id: str, output_format: str | None)
|
|
|
823
823
|
def sandbox_kill(
|
|
824
824
|
obj: ClientContext, sandbox_ids: tuple[str, ...], output_format: str | None
|
|
825
825
|
) -> None:
|
|
826
|
-
"""
|
|
826
|
+
"""Request deletion of one or more sandboxes; cleanup may continue."""
|
|
827
827
|
prepare_output(obj, output_format, allowed=("table", "json", "yaml"), fallback="table")
|
|
828
828
|
mgr = obj.get_manager()
|
|
829
829
|
rows: list[dict[str, str]] = []
|
|
830
830
|
for sid in sandbox_ids:
|
|
831
831
|
with obj.output.spinner(f"Killing sandbox {sid}..."):
|
|
832
832
|
mgr.kill_sandbox(sid)
|
|
833
|
-
rows.append({"sandbox_id": sid, "status": "
|
|
833
|
+
rows.append({"sandbox_id": sid, "status": "deletion_requested"})
|
|
834
834
|
obj.output.print_rows(rows, columns=["sandbox_id", "status"], title="Sandboxes")
|
|
835
835
|
|
|
836
836
|
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/skills.py
RENAMED
|
@@ -69,11 +69,13 @@ _TARGETS = cast(dict[str, TargetConfig], {
|
|
|
69
69
|
"project": {
|
|
70
70
|
"strategy": "copy",
|
|
71
71
|
"dest_dir": Path(".claude") / "skills",
|
|
72
|
+
"dest_file_template": "{slug}/SKILL.md",
|
|
72
73
|
"preserve_frontmatter": True,
|
|
73
74
|
},
|
|
74
75
|
"global": {
|
|
75
76
|
"strategy": "copy",
|
|
76
77
|
"dest_dir": Path.home() / ".claude" / "skills",
|
|
78
|
+
"dest_file_template": "{slug}/SKILL.md",
|
|
77
79
|
"preserve_frontmatter": True,
|
|
78
80
|
}
|
|
79
81
|
},
|
|
@@ -122,7 +124,7 @@ _TARGETS = cast(dict[str, TargetConfig], {
|
|
|
122
124
|
},
|
|
123
125
|
"global": {
|
|
124
126
|
"strategy": "append",
|
|
125
|
-
"dest_file": Path.home() / ".
|
|
127
|
+
"dest_file": Path.home() / ".copilot" / "copilot-instructions.md",
|
|
126
128
|
"preserve_frontmatter": False,
|
|
127
129
|
}
|
|
128
130
|
},
|
|
@@ -151,8 +153,9 @@ _TARGETS = cast(dict[str, TargetConfig], {
|
|
|
151
153
|
"preserve_frontmatter": False,
|
|
152
154
|
},
|
|
153
155
|
"global": {
|
|
154
|
-
"strategy": "
|
|
155
|
-
"
|
|
156
|
+
"strategy": "copy",
|
|
157
|
+
"dest_dir": Path.home() / ".cline" / "rules",
|
|
158
|
+
"dest_file_template": "opensandbox-{slug}.md",
|
|
156
159
|
"preserve_frontmatter": False,
|
|
157
160
|
}
|
|
158
161
|
},
|
|
@@ -85,6 +85,12 @@ def resolve_config(
|
|
|
85
85
|
) -> dict[str, Any]:
|
|
86
86
|
"""Merge config from all sources and return a flat dict.
|
|
87
87
|
|
|
88
|
+
Values that come from the config file are coerced to the type declared for
|
|
89
|
+
each key. A file may legitimately encode a value with a different TOML type
|
|
90
|
+
than the CLI expects (for example an all-digit ``connection.api_key`` or a
|
|
91
|
+
``defaults.timeout`` given in seconds), and callers downstream rely on the
|
|
92
|
+
declared type.
|
|
93
|
+
|
|
88
94
|
Keys returned:
|
|
89
95
|
- api_key, domain, protocol, request_timeout (int seconds), use_server_proxy (bool)
|
|
90
96
|
- default_image, default_timeout (str like "10m")
|
|
@@ -97,27 +103,27 @@ def resolve_config(
|
|
|
97
103
|
return {
|
|
98
104
|
"api_key": cli_api_key
|
|
99
105
|
or os.getenv("OPEN_SANDBOX_API_KEY")
|
|
100
|
-
or conn.get("api_key"),
|
|
106
|
+
or _str_or_none(conn.get("api_key")),
|
|
101
107
|
"domain": cli_domain
|
|
102
108
|
or os.getenv("OPEN_SANDBOX_DOMAIN")
|
|
103
|
-
or conn.get("domain"),
|
|
109
|
+
or _str_or_none(conn.get("domain")),
|
|
104
110
|
"protocol": cli_protocol
|
|
105
111
|
or os.getenv("OPEN_SANDBOX_PROTOCOL")
|
|
106
|
-
or conn.get("protocol")
|
|
112
|
+
or _str_or_none(conn.get("protocol"))
|
|
107
113
|
or "http",
|
|
108
114
|
"request_timeout": cli_timeout
|
|
109
115
|
or _int_or_none(os.getenv("OPEN_SANDBOX_REQUEST_TIMEOUT"))
|
|
110
|
-
or conn.get("request_timeout")
|
|
116
|
+
or _int_or_none(conn.get("request_timeout"))
|
|
111
117
|
or 30,
|
|
112
118
|
"use_server_proxy": _coalesce(
|
|
113
119
|
cli_use_server_proxy,
|
|
114
120
|
_bool_or_none(os.getenv("OPEN_SANDBOX_USE_SERVER_PROXY")),
|
|
115
|
-
conn.get("use_server_proxy"),
|
|
121
|
+
_bool_or_none(conn.get("use_server_proxy")),
|
|
116
122
|
False,
|
|
117
123
|
),
|
|
118
|
-
"color": output_cfg.get("color", True),
|
|
119
|
-
"default_image": defaults.get("image"),
|
|
120
|
-
"default_timeout": defaults.get("timeout"),
|
|
124
|
+
"color": _coalesce(_bool_or_none(output_cfg.get("color")), True),
|
|
125
|
+
"default_image": _str_or_none(defaults.get("image")),
|
|
126
|
+
"default_timeout": _str_or_none(defaults.get("timeout")),
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
|
|
@@ -133,18 +139,34 @@ def init_config_file(config_path: Path | None = None, *, force: bool = False) ->
|
|
|
133
139
|
return path
|
|
134
140
|
|
|
135
141
|
|
|
136
|
-
def _int_or_none(value:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
try:
|
|
140
|
-
return int(value)
|
|
141
|
-
except ValueError:
|
|
142
|
+
def _int_or_none(value: Any) -> int | None:
|
|
143
|
+
"""Coerce a configured value to ``int``, or ``None`` when it is not numeric."""
|
|
144
|
+
if value is None or isinstance(value, bool):
|
|
142
145
|
return None
|
|
146
|
+
if isinstance(value, int):
|
|
147
|
+
return value
|
|
148
|
+
if isinstance(value, (str, float)):
|
|
149
|
+
try:
|
|
150
|
+
return int(value)
|
|
151
|
+
except (TypeError, ValueError, OverflowError):
|
|
152
|
+
return None
|
|
153
|
+
return None
|
|
154
|
+
|
|
143
155
|
|
|
156
|
+
def _bool_or_none(value: Any) -> bool | None:
|
|
157
|
+
"""Coerce a configured value to ``bool``, or ``None`` when it is not boolean.
|
|
144
158
|
|
|
145
|
-
|
|
159
|
+
``0``/``1`` are accepted so hand-edited files that write a TOML integer for a
|
|
160
|
+
boolean key keep resolving instead of silently falling back to the default.
|
|
161
|
+
"""
|
|
146
162
|
if value is None:
|
|
147
163
|
return None
|
|
164
|
+
if isinstance(value, bool):
|
|
165
|
+
return value
|
|
166
|
+
if isinstance(value, (int, float)):
|
|
167
|
+
return bool(value) if value in (0, 1) else None
|
|
168
|
+
if not isinstance(value, str):
|
|
169
|
+
return None
|
|
148
170
|
normalized = value.strip().lower()
|
|
149
171
|
if normalized in ("1", "true", "yes", "on"):
|
|
150
172
|
return True
|
|
@@ -153,6 +175,17 @@ def _bool_or_none(value: str | None) -> bool | None:
|
|
|
153
175
|
return None
|
|
154
176
|
|
|
155
177
|
|
|
178
|
+
def _str_or_none(value: Any) -> str | None:
|
|
179
|
+
"""Coerce a configured value to ``str``, or ``None`` when it has no text form."""
|
|
180
|
+
if value is None or isinstance(value, bool):
|
|
181
|
+
return None
|
|
182
|
+
if isinstance(value, str):
|
|
183
|
+
return value
|
|
184
|
+
if isinstance(value, (int, float)):
|
|
185
|
+
return str(value)
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
|
|
156
189
|
def _coalesce(*values: Any) -> Any:
|
|
157
190
|
for value in values:
|
|
158
191
|
if value is not None:
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
+
import sys
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
|
|
21
22
|
import click
|
|
@@ -48,9 +49,46 @@ BANNER = r"""[bold cyan]
|
|
|
48
49
|
"""
|
|
49
50
|
|
|
50
51
|
|
|
52
|
+
# A representative icon: any encoding that cannot render it would raise on output.
|
|
53
|
+
_OUTPUT_PROBE = "\u2705"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _configure_output_streams() -> None:
|
|
57
|
+
"""Keep CLI output writable when the active encoding cannot represent it.
|
|
58
|
+
|
|
59
|
+
Click and Rich print emoji and box-drawing characters. On a legacy Windows
|
|
60
|
+
code page (cp936, cp1252, ...) or a POSIX ``C`` locale writing them raises
|
|
61
|
+
``UnicodeEncodeError``, which aborts the command - even after the work is
|
|
62
|
+
done - so streams whose encoding cannot represent that output escape the
|
|
63
|
+
characters instead of raising.
|
|
64
|
+
|
|
65
|
+
Escaping (``backslashreplace``) keeps payload writes - raw command and
|
|
66
|
+
file data, machine-readable output - recoverable; ``errors="replace"``
|
|
67
|
+
would silently corrupt them into ``?``. CPython uses the same handler for
|
|
68
|
+
Windows stderr.
|
|
69
|
+
"""
|
|
70
|
+
for stream in (sys.stdout, sys.stderr):
|
|
71
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
72
|
+
encoding = getattr(stream, "encoding", None)
|
|
73
|
+
if reconfigure is None or encoding is None:
|
|
74
|
+
continue
|
|
75
|
+
try:
|
|
76
|
+
_OUTPUT_PROBE.encode(encoding)
|
|
77
|
+
except (LookupError, UnicodeEncodeError):
|
|
78
|
+
try:
|
|
79
|
+
reconfigure(errors="backslashreplace")
|
|
80
|
+
except (OSError, ValueError): # pragma: no cover - detached stream
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
|
|
51
84
|
class BannerGroup(click.Group):
|
|
52
85
|
"""Custom Click group that shows a banner before help text."""
|
|
53
86
|
|
|
87
|
+
def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]:
|
|
88
|
+
"""Configure output streams before Click renders help or runs a command."""
|
|
89
|
+
_configure_output_streams()
|
|
90
|
+
return super().parse_args(ctx, args)
|
|
91
|
+
|
|
54
92
|
def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
|
|
55
93
|
console = Console(stderr=False)
|
|
56
94
|
console.print(BANNER.format(version=__version__))
|
|
@@ -59,6 +59,18 @@ _DIM_COLUMNS = {"created_at", "expires_at", "modified_at", "updated_at"}
|
|
|
59
59
|
_ID_COLUMNS = {"id", "sandbox_id", "execution_id", "context_id"}
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
def _stdout_can_encode(text: str) -> bool:
|
|
63
|
+
"""Return whether stdout can represent ``text`` without substitution."""
|
|
64
|
+
encoding = getattr(sys.stdout, "encoding", None)
|
|
65
|
+
if encoding is None:
|
|
66
|
+
return True
|
|
67
|
+
try:
|
|
68
|
+
text.encode(encoding)
|
|
69
|
+
except (LookupError, UnicodeEncodeError):
|
|
70
|
+
return False
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
|
|
62
74
|
def _style_value(col: str, value: str) -> Text:
|
|
63
75
|
"""Apply contextual styling to a cell value."""
|
|
64
76
|
lower = value.lower()
|
|
@@ -248,7 +260,15 @@ class OutputFormatter:
|
|
|
248
260
|
"PyYAML is not installed. Use --output json instead.", fg="red", err=True
|
|
249
261
|
)
|
|
250
262
|
sys.exit(1)
|
|
251
|
-
|
|
263
|
+
text = yaml.dump(data, default_flow_style=False, allow_unicode=True).rstrip()
|
|
264
|
+
if not _stdout_can_encode(text):
|
|
265
|
+
# Keep machine-readable output valid on limited code pages: escape
|
|
266
|
+
# non-ASCII into round-trippable sequences instead of letting the
|
|
267
|
+
# stream replace characters with "?".
|
|
268
|
+
text = yaml.dump(
|
|
269
|
+
data, default_flow_style=False, allow_unicode=False
|
|
270
|
+
).rstrip()
|
|
271
|
+
click.echo(text)
|
|
252
272
|
|
|
253
273
|
def _print_kv_table(self, data: dict[str, Any], *, title: str | None = None) -> None:
|
|
254
274
|
table = Table(
|
|
@@ -50,12 +50,9 @@ osb command session run <sandbox-id> <session-id> -o raw -- sh -lc 'pwd'
|
|
|
50
50
|
|
|
51
51
|
Treat these as three distinct execution paths:
|
|
52
52
|
|
|
53
|
-
- `osb command run` without `--background`
|
|
54
|
-
|
|
55
|
-
- `osb command
|
|
56
|
-
Use when the user needs an execution ID, later status checks, or log retrieval
|
|
57
|
-
- `osb command session ...`
|
|
58
|
-
Use when shell state must persist across commands, such as exported variables or a working directory
|
|
53
|
+
- `osb command run` without `--background` Use for foreground one-shot commands when the result should stream directly to the terminal
|
|
54
|
+
- `osb command run --background` Use when the user needs an execution ID, later status checks, or log retrieval
|
|
55
|
+
- `osb command session ...` Use when shell state must persist across commands, such as exported variables or a working directory
|
|
59
56
|
|
|
60
57
|
## Golden Paths
|
|
61
58
|
|
|
@@ -5,36 +5,28 @@ description: Use OpenSandbox Credential Vault commands to manage sandbox-local o
|
|
|
5
5
|
|
|
6
6
|
# OpenSandbox Credential Vault
|
|
7
7
|
|
|
8
|
-
Manage outbound credential injection with `osb credential-vault`. Treat vault
|
|
9
|
-
changes as a controlled runtime workflow: confirm the sandbox was created with
|
|
10
|
-
Credential Proxy, write secrets only through payload files or stdin, inspect
|
|
11
|
-
sanitized state, then verify actual outbound behavior from inside the sandbox.
|
|
8
|
+
Manage outbound credential injection with `osb credential-vault`. Treat vault changes as a controlled runtime workflow: confirm the sandbox was created with Credential Proxy, write secrets only through payload files or stdin, inspect sanitized state, then verify actual outbound behavior from inside the sandbox.
|
|
12
9
|
|
|
13
10
|
## When To Use
|
|
14
11
|
|
|
15
12
|
- the user needs real credentials injected into outbound HTTP or HTTPS requests
|
|
16
13
|
- the user wants to create, inspect, patch, or delete Credential Vault state
|
|
17
14
|
- the user needs to add, replace, or remove runtime credentials or bindings
|
|
18
|
-
- the user wants to keep plaintext credentials out of sandbox env vars, files,
|
|
19
|
-
shell history, and command arguments
|
|
15
|
+
- the user wants to keep plaintext credentials out of sandbox env vars, files, shell history, and command arguments
|
|
20
16
|
|
|
21
17
|
## Prerequisites
|
|
22
18
|
|
|
23
|
-
Credential Vault requires an egress sidecar with transparent MITM enabled. Create
|
|
24
|
-
the sandbox with both a network policy and Credential Proxy:
|
|
19
|
+
Credential Vault requires an egress sidecar with transparent MITM enabled. Create the sandbox with both a network policy and Credential Proxy:
|
|
25
20
|
|
|
26
21
|
```bash
|
|
27
22
|
osb sandbox create --image python:3.12 --network-policy-file network-policy.json --credential-proxy -o json
|
|
28
23
|
```
|
|
29
24
|
|
|
30
|
-
If `credential-vault create`, `patch`, or `delete` returns a precondition error,
|
|
31
|
-
the sandbox was likely not created with Credential Proxy, the egress API auth
|
|
32
|
-
token is missing, mitmproxy is not ready, or insecure upstream TLS mode is set.
|
|
25
|
+
If `credential-vault create`, `patch`, or `delete` returns a precondition error, the sandbox was likely not created with Credential Proxy, the egress API auth token is missing, mitmproxy is not ready, or insecure upstream TLS mode is set.
|
|
33
26
|
|
|
34
27
|
## Payload Rules
|
|
35
28
|
|
|
36
|
-
Use JSON or YAML payload files, or `--file -` for stdin. Do not put real secret
|
|
37
|
-
values in command-line flags.
|
|
29
|
+
Use JSON or YAML payload files, or `--file -` for stdin. Do not put real secret values in command-line flags.
|
|
38
30
|
|
|
39
31
|
Create payload shape:
|
|
40
32
|
|
|
@@ -107,8 +99,7 @@ credentials:
|
|
|
107
99
|
|
|
108
100
|
## Inspect Metadata
|
|
109
101
|
|
|
110
|
-
Vault read APIs return sanitized metadata only. Plaintext credential values are
|
|
111
|
-
write-only and should not appear in command output.
|
|
102
|
+
Vault read APIs return sanitized metadata only. Plaintext credential values are write-only and should not appear in command output.
|
|
112
103
|
|
|
113
104
|
```bash
|
|
114
105
|
osb credential-vault credential get <sandbox-id> api-token -o json
|
|
@@ -117,8 +108,7 @@ osb credential-vault binding get <sandbox-id> api -o json
|
|
|
117
108
|
|
|
118
109
|
## Cleanup
|
|
119
110
|
|
|
120
|
-
Delete all sandbox-local vault state when credential injection is no longer
|
|
121
|
-
needed:
|
|
111
|
+
Delete all sandbox-local vault state when credential injection is no longer needed:
|
|
122
112
|
|
|
123
113
|
```bash
|
|
124
114
|
osb credential-vault delete <sandbox-id> -o json
|
|
@@ -132,5 +122,4 @@ When helping a user:
|
|
|
132
122
|
2. Confirm the sandbox was created with `--credential-proxy` and network policy.
|
|
133
123
|
3. Keep secret material in payload files or stdin, never in CLI flags.
|
|
134
124
|
4. Use `get` or `list` to inspect sanitized state.
|
|
135
|
-
5. Verify behavior with `osb command run ... -o raw -- curl ...` when injection
|
|
136
|
-
behavior matters.
|
|
125
|
+
5. Verify behavior with `osb command run ... -o raw -- curl ...` when injection behavior matters.
|
|
@@ -40,14 +40,10 @@ osb config show -o json
|
|
|
40
40
|
|
|
41
41
|
Treat these as distinct categories:
|
|
42
42
|
|
|
43
|
-
- sandbox-only content operations
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
- sandbox-to-host transfer
|
|
48
|
-
`download`
|
|
49
|
-
- discovery before modification
|
|
50
|
-
`search`, then `info`
|
|
43
|
+
- sandbox-only content operations `cat`, `write`, `replace`, `mv`, `mkdir`, `rm`, `rmdir`, `info`, `chmod`
|
|
44
|
+
- host-to-sandbox transfer `upload`
|
|
45
|
+
- sandbox-to-host transfer `download`
|
|
46
|
+
- discovery before modification `search`, then `info`
|
|
51
47
|
|
|
52
48
|
If the path is uncertain, search first. If the file boundary crosses between host and sandbox, use `upload` or `download` instead of `write` or `cat`.
|
|
53
49
|
|
|
@@ -56,10 +56,8 @@ osb config show -o json
|
|
|
56
56
|
|
|
57
57
|
Runtime egress policy consists of:
|
|
58
58
|
|
|
59
|
-
- `defaultAction`
|
|
60
|
-
|
|
61
|
-
- `egress`
|
|
62
|
-
An ordered list of allow or deny rules
|
|
59
|
+
- `defaultAction` The fallback action when no rule matches
|
|
60
|
+
- `egress` An ordered list of allow or deny rules
|
|
63
61
|
|
|
64
62
|
Important semantics:
|
|
65
63
|
|
|
@@ -267,7 +267,7 @@ Rules:
|
|
|
267
267
|
- use `renew` before long-running work instead of waiting for expiry
|
|
268
268
|
- use `pause` only when the workload can tolerate suspension
|
|
269
269
|
- treat the pause result as request acceptance and poll `sandbox get` until the state is `Paused` or `Failed`
|
|
270
|
-
-
|
|
270
|
+
- `kill` returns `deletion_requested` when accepted; poll `sandbox get` until `404` to confirm resource removal. Pool `Noop` preserves processes even after removal.
|
|
271
271
|
|
|
272
272
|
## Runtime Notes
|
|
273
273
|
|
|
@@ -66,11 +66,17 @@ Use this order by default:
|
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
68
|
osb sandbox get <sandbox-id> -o json
|
|
69
|
+
osb diagnostics context <sandbox-id> -o json
|
|
69
70
|
osb sandbox health <sandbox-id> -o json
|
|
70
71
|
osb diagnostics events <sandbox-id> --scope runtime -o raw
|
|
71
72
|
osb diagnostics logs <sandbox-id> --scope container -o raw
|
|
72
73
|
```
|
|
73
74
|
|
|
75
|
+
Use context's `backend_type` and `backend_identifiers` to select backend-specific
|
|
76
|
+
investigation. Context works before execd is ready. Fast Sandbox supports runtime
|
|
77
|
+
events but not container logs; skip log collection for that backend. If context
|
|
78
|
+
is unavailable on an older server, continue with sandbox state and supported diagnostics.
|
|
79
|
+
|
|
74
80
|
Then drill down only where the stable diagnostics point:
|
|
75
81
|
|
|
76
82
|
```bash
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/__init__.py
RENAMED
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/devops.py
RENAMED
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/egress.py
RENAMED
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/file.py
RENAMED
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/snapshot.py
RENAMED
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/commands/template.py
RENAMED
|
File without changes
|
|
File without changes
|
{opensandbox_cli-1.1.1 → opensandbox_cli-1.1.2.dev20261020}/src/opensandbox_cli/skill_registry.py
RENAMED
|
File without changes
|
|
File without changes
|