@delta-agentcloud/cli 1.1.32 → 1.1.36

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
@@ -281,19 +281,19 @@ delta-cli sandbox operation <request_id>
281
281
  | `delta-cli sandbox run-bg <id> --command "..." [--timeout <sec>] [--wait] [--cancel-on-timeout] [--format sse\|json] [--json-result] [--summary/--no-summary] [--artifacts]` | Run a command in the background; without `--wait` it returns `{execution_id, sandbox_id}` immediately (with `--format json`, the unified result object with `finished=false`); with `--wait` it follows via SSE (raw `data:` frames to stdout, no trailing envelope); `--format json` prints exactly one envelope with the same structure as `sandbox run --format json`. **On a wait timeout** → `error.type=timeout` and a **non-zero** process exit code, with `error.details` keeping `sandbox_id`/`execution_id`/`remote_state` (`not_cancelled`/`cancelled`/`cancel_failed`) so the command can be queried or cancelled afterwards; `remote_state=not_cancelled` means only the local wait stopped and **the remote command may still be running**. The remote command is left running by default — add `--cancel-on-timeout` to cancel it (a failed cancel is reported as `cancel_failed`) |
282
282
  | `delta-cli sandbox logs <id> --execution-id <eid> [--tail N --grep <pattern> --context N --max-bytes N]` | Show background logs; returns `stderr_size + stderr_tail` by default (avoids context blow-up); filter with `--tail/--grep` |
283
283
  | `delta-cli sandbox cancel <id> --execution-id <eid>` | Interrupt a background command |
284
- | `delta-cli sandbox read <id> --path <path> [--output <local path>] [--tail N] [--grep <pattern>] [--offset N] [--limit N] [--context N] [--max-bytes N] [--parse-json]` | Read a file in the container; `--output <path>` saves locally; filter with `--tail/--grep`. **A full copy (without `--tail/--grep/--offset/--limit/--max-bytes`) is byte-exact**: it goes through the chunked download path (binary-safe, sha256-verified — the envelope reports `byte_exact:true`, `integrity:"sha256"`, `digest_verified`); with any range filter it falls back to the text channel, where the server decodes as UTF-8 and replaces invalid bytes with U+FFFD, so the envelope then reports `byte_exact:false` / `integrity:"text_decoded"` and a warning is printed to stderr — **use `sandbox pull` to copy a binary file**. When the result is printed inline and the file is not valid UTF-8, `content` is the lossy text and the **exact original bytes** are in `content_base64` (base64-decode it); the envelope is marked `byte_exact:true`. Text files carry no `content_base64` |
285
- | `delta-cli sandbox pull <id> --source <sandbox path> --target <local path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` | Pull files/dirs from the sandbox to local (mirror of `upload`; flag direction reversed: source=remote, target=local). **Directories are always pulled recursively** (`--recursive` is deprecated and no longer needed); the transfer uses the **chunked download** path: binary-safe, end-to-end **sha256** verified (`digest_verified`), **resumable** (a partial `<target>.delta.part` is reused), and **parallel** across files and chunks (`--concurrency`, default 4) — so a large file is not bound by a single command timeout. The server publishes its limits with every response (`limits`): 4 MiB chunks (16 MiB max), 100 GiB max per file, 120 s per chunk, 600 s for the whole-file digest. `--no-resume` ignores a leftover `.delta.part`; `--no-verify` skips the sandbox-side sha256 comparison. **The payload moves as raw bytes** (the server's binary endpoint, so it is not inflated by base64; older servers fall back automatically), and **the chunks must tile the whole file**: a gap or an interrupted transfer is reported as a failure, never as a successful download |
284
+ | `delta-cli sandbox read <id> --path <path> [--output <local path>] [--tail N] [--grep <pattern>] [--offset N] [--limit N] [--context N] [--max-bytes N] [--parse-json]` | Read a file in the container; `--output <path>` saves it locally; `--tail`/`--grep` filter the output. **A full copy (no `--tail`/`--grep`/`--offset`/`--limit`/`--max-bytes`) is byte-exact**: it goes through the chunked download path (binary-safe, sha256-verified — the envelope reports `byte_exact:true`, `integrity:"sha256"`, `digest_verified`). With a range filter the filter is applied to the **exact bytes**, so the copy is a byte-exact slice of the original (`byte_exact:true`, `integrity:"sha1"`). Printed inline, a text file gives `content` (strictly decoded, `byte_exact:true`) while a **non-UTF-8 file gives no `content` at all** — the exact original bytes are in `content_base64` (base64-decode it) and the envelope is marked `byte_exact:true`. Only a server that does not support that negotiation returns the lossy text (`integrity:"text_decoded"`, with a warning on stderr). An `--output` that names an existing local directory receives the file inside it, under its own name (the way `cp file dir/` works). |
285
+ | `delta-cli sandbox pull <id> --source <sandbox path> --target <local path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` | Pull files/dirs from the sandbox to local (mirror of `upload`; flag direction reversed: source=remote, target=local). **Directories are always pulled recursively** (`--recursive` is deprecated and no longer needed); the transfer uses the **chunked download** path: binary-safe, end-to-end **sha256** verified (`digest_verified`), **resumable** (a partial `<target>.delta.part` is reused), and **parallel** across files and chunks (`--concurrency`, default 4) — so a large file is not bound by a single command timeout. The server publishes its limits with every response (`limits`): 4 MiB chunks (16 MiB max), 100 GiB max per file, 120 s per chunk, 600 s for the whole-file digest. `--no-resume` ignores a leftover `.delta.part`; `--no-verify` skips the sandbox-side sha256 comparison. **The payload moves as raw bytes** (the server's binary endpoint, so it is not inflated by base64; older servers fall back automatically), and **the chunks must tile the whole file**: a gap or an interrupted transfer is reported as a failure, never as a successful download. When `--target` names an existing local directory, the file is written inside it under its own name (the way `cp file dir/` works) |
286
286
  | `delta-cli sandbox write <id> --path <path> --source <local path>` | Write a file. **Binary-safe**: the content travels as raw bytes (the server's binary endpoint, with a base64 fallback for older servers) and the CLI declares its `size`/`sha256`, which the server verifies before writing (a mismatch is rejected); the response carries `server_sha256`/`sha256`/`size`/`size_verified`. A `--source` above 32 MiB goes through the streaming upload path instead of being read into memory |
287
287
  | `delta-cli sandbox write-multiple <id> --entry <remote path>=<local path>` | Write multiple files |
288
- | `delta-cli sandbox ls <id> --path <path>` | List a directory |
288
+ | `delta-cli sandbox ls <id> --path <path>` | List a directory (a path that is a file, or is missing, is rejected with an explicit error instead of a generic provider failure) |
289
289
  | `delta-cli sandbox stat <id> --path <path>` | File metadata |
290
290
  | `delta-cli sandbox mv <id> --entry <src=dest>` | Move/rename |
291
291
  | `delta-cli sandbox replace <id> --path <path> --old <text> --new <text>` | Replace content |
292
292
  | `delta-cli sandbox chmod <id> --path <path> --mode <octal>` | Change permissions |
293
- | `delta-cli sandbox rm <id> --path <path>` | Delete a file |
294
- | `delta-cli sandbox rmdir <id> --path <dir>` | Recursively delete a directory |
293
+ | `delta-cli sandbox rm <id> --path <path>` | Delete a file. **Files only**: a directory path is rejected (use `rmdir`), and a path that does not exist is an error rather than a silent success |
294
+ | `delta-cli sandbox rmdir <id> --path <dir>` | Recursively delete a directory (cannot be undone). **Directories only**: a file path is rejected and the file is left untouched, and a path that does not exist is an error |
295
295
  | `delta-cli sandbox mkdir <id> --path <dir>` | Create a directory |
296
- | `delta-cli sandbox search <id> --path <root> --pattern <glob>` | Search files |
296
+ | `delta-cli sandbox search <id> --path <root> --pattern <glob>` | Search files (an unterminated glob such as `[` is rejected instead of silently matching nothing) |
297
297
  | `delta-cli sandbox working-directory <id>` | Get the sandbox working directory path |
298
298
  | `delta-cli sandbox upload <id> --source <local dir> --target <sandbox path>` | Upload a directory (tar.gz + auto-extract) |
299
299
  | `delta-cli sandbox expose <id> [--port N]` | Expose a sandbox service port to the public internet (frp tunnel), default port 8700 |
@@ -346,7 +346,7 @@ Error types and exit codes:
346
346
 
347
347
  | Type | Exit Code | Scenario |
348
348
  |------|-----------|----------|
349
- | validation | 2 | Argument error |
349
+ | validation | 2 | Argument error — includes a file path used where a directory is required (or the reverse) and an invalid glob |
350
350
  | auth | 3 | Not authenticated |
351
351
  | permission | 4 | Insufficient permission |
352
352
  | not_found | 5 | Resource does not exist |
package/checksums.txt CHANGED
@@ -1,5 +1,5 @@
1
- 7b0f7b586921d997251890127fb983fb01ab8a2b3c06f8c4eccea108e5a96ebf delta-cli-darwin-amd64.tar.gz
2
- e92b9722828a454dc57aeb6ea91f2810ea38fd617c42ecaa25f02f7502f68215 delta-cli-darwin-arm64.tar.gz
3
- faecf702bca55268c33b5a916053e4fa600d6b0e8f19b9aac1645a4415df2a62 delta-cli-linux-amd64.tar.gz
4
- 31bd5981840b5822e9b20bf58458110d8ff5a182f3baf4940218029fbc6b9fda delta-cli-linux-arm64.tar.gz
5
- 3382cb55ce3535df1085366513736f14564b1086438c9841983a432bc4e3fa65 delta-cli-windows-amd64.zip
1
+ a5849fc18ba0e949dc76732e400315f23d176229b228aadb2a541cafe257a6a3 delta-cli-darwin-amd64.tar.gz
2
+ b81d1ae7ab9eb8df3f24ae36753ff692889cb2246da178af60b46f81df7eea48 delta-cli-darwin-arm64.tar.gz
3
+ 486c35b03928d4919357f1d47ae4aea87e9a5d58d6a2697279c334653546b29f delta-cli-linux-amd64.tar.gz
4
+ 9a9ca196de3a29e57364a032b82088d8755dd9be330bd63861d927c8102feb2f delta-cli-linux-arm64.tar.gz
5
+ 3e21ac2e5c3c24da77ad06a1869047da0ef5c114ee0383cd228c36f873d73b19 delta-cli-windows-amd64.zip
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delta-agentcloud/cli",
3
- "version": "1.1.32",
3
+ "version": "1.1.36",
4
4
  "description": "Delta Agent Cloud CLI for sandbox compute and science tools.",
5
5
  "bin": {
6
6
  "delta-cli": "scripts/run.js"
@@ -174,8 +174,8 @@ The reason is that, after running a command, this skill reads `log_file` from th
174
174
  | List active tunnels | `sandbox exposes <id>` — list the public tunnels currently active for this sandbox |
175
175
  | Reclaim a tunnel | `sandbox dispose <id> --port N` — explicitly reclaim a single tunnel (stop frpc and release the public port); killing the sandbox also reclaims all its tunnels |
176
176
  | **File operations** | |
177
- | Read a file | `sandbox read <id> --path <path> [--output <local-path> --tail N --grep <pattern> --offset N --limit N --context N --max-bytes N --parse-json]` — **a full copy is byte-exact** (chunked download, sha256-verified); with `--tail`/`--grep`/`--offset`/`--limit` it uses the text channel and the envelope reports `byte_exact:false` — use `sandbox pull` for binary files. Printed inline, a non-UTF-8 file puts the **exact bytes** in `content_base64` (`content` is the lossy text) |
178
- | Pull a file/directory | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` — pull a single file or **recursively** pull a directory (directories are always recursive), over the **chunked** path: bytes move verbatim (no base64 inflation), binary-safe, sha256-verified, resumable and parallel (the reverse of upload: source=remote, target=local) |
177
+ | Read a file | `sandbox read <id> --path <path> [--output <local-path> --tail N --grep <pattern> --offset N --limit N --context N --max-bytes N --parse-json]` — **byte-exact**: a full copy goes through the chunked download (sha256-verified) and a filtered copy is a byte-exact slice of the original. Printed inline, a text file gives `content`; a **non-UTF-8 file gives no `content`** — the exact bytes are in `content_base64` |
178
+ | Pull a file/directory | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` — pull a single file or **recursively** pull a directory (directories are always recursive), over the **chunked** path: bytes move verbatim (no base64 inflation), binary-safe, sha256-verified, resumable and parallel (the reverse of upload: source=remote, target=local). A `--target` that names an existing local directory receives the file inside it, under its own name |
179
179
  | View the working directory | `sandbox working-directory <id>` (returns `data.path`, such as `/workspace/{user_id}/{sandbox_id}`) |
180
180
  | Write a file | `sandbox write <id> --source <filename>` (without `--path`, writes to the working directory by default); **every sandbox-side path** — `--path`, the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, `run`/`run-bg --log-file` — is prefixed with the working directory when relative, while an absolute path is used as given. The content is **binary-safe** (raw bytes, with a base64 fallback for older servers) and the server verifies the declared `size`/`sha256` before writing, so the response's `server_sha256`/`size_verified` can be compared with the local file |
181
181
  | Write multiple files | `sandbox write-multiple <id> --entry <remote-path>=<local-path> [--entry ...]` |
@@ -185,10 +185,10 @@ The reason is that, after running a command, this skill reads `log_file` from th
185
185
  | Move/rename | `sandbox mv <id> --entry <src=dest> [--entry ...]` |
186
186
  | Replace content | `sandbox replace <id> --path <path> --old <text> --new <text>` |
187
187
  | Change permissions | `sandbox chmod <id> --path <path> --mode <octal>` |
188
- | Delete files | `sandbox rm <id> --path <path> [--path ...]` |
189
- | Delete directories | `sandbox rmdir <id> --path <path> [--path ...]` |
188
+ | Delete files | `sandbox rm <id> --path <path> [--path ...]` — files only; a directory path is rejected, a missing path is an error |
189
+ | Delete directories | `sandbox rmdir <id> --path <path> [--path ...]` — directories only; a file path is rejected and the file is left untouched, a missing path is an error |
190
190
  | Create directories | `sandbox mkdir <id> --path <path> [--path ...]` |
191
- | Search files | `sandbox search <id> --path <root-directory> --pattern <glob>` |
191
+ | Search files | `sandbox search <id> --path <root-directory> --pattern <glob>` — an unterminated glob such as `[` is rejected, not silently empty |
192
192
 
193
193
  ## Full lifecycle
194
194
 
@@ -392,7 +392,7 @@ This skill is designed to make the conclusion self-contained: when execution end
392
392
  |-------------|----------|
393
393
  | `error.type: not_found` | Check whether `sandbox_id` is correct and whether the sandbox has been killed |
394
394
  | `error.type: network` | Check `base_url` and network connectivity |
395
- | `error.type: validation` | Check parameter formats and required flags |
395
+ | `error.type: validation` | Check parameter formats and required flags. This also covers a file path used where a directory is required (or the reverse) and an invalid glob; `error.hint` names what to change |
396
396
  | `error.type: auth / permission` | Follow the permission-denied guidance in delta-shared |
397
397
  | `error.type: api` (5xx) | Server error; check the API service status |
398
398
  | `sandbox create` failed | Read `error.hint` — it states the cause and the next step (for example, the image was not cached on the target node, so the initial pull exceeded the readiness timeout: retry once, or pick a GPU type whose node already has the image). A failed create leaves no sandbox behind, so retrying is safe. `error.request_id` identifies the failure in the server log. |
@@ -38,22 +38,22 @@
38
38
 
39
39
  | Command | Description |
40
40
  |------|------|
41
- | `sandbox read <id> --path <path> [--output <local-path>] [--tail N] [--grep <pattern>] [--offset N] [--limit N] [--context N] [--max-bytes N] [--parse-json]` | Read a file; returns `content` + `size` + `content_length`. `--output <path>` saves it locally; `--tail`/`--grep` filter the output. **A full copy (no `--tail`/`--grep`/`--offset`/`--limit`/`--max-bytes`) is byte-exact**: it goes through the chunked download path (binary-safe, sha256-verified — the envelope reports `byte_exact:true`, `integrity:"sha256"`, `digest_verified`). With any range filter it falls back to the text channel, where the server decodes as UTF-8 and replaces invalid bytes with U+FFFD; the envelope then reports `byte_exact:false` / `integrity:"text_decoded"` and a warning is printed to stderr. **Use `sandbox pull` to copy a binary file.** When the result is printed inline and the file is not valid UTF-8, `content` is the lossy text and the **exact original bytes** are in `content_base64` (base64-decode it); the envelope is marked `byte_exact:true`. Text files carry no `content_base64`. |
41
+ | `sandbox read <id> --path <path> [--output <local-path>] [--tail N] [--grep <pattern>] [--offset N] [--limit N] [--context N] [--max-bytes N] [--parse-json]` | Read a file; returns `content` + `size` + `content_length`. `--output <path>` saves it locally; `--tail`/`--grep` filter the output. **A full copy (no `--tail`/`--grep`/`--offset`/`--limit`/`--max-bytes`) is byte-exact**: it goes through the chunked download path (binary-safe, sha256-verified — the envelope reports `byte_exact:true`, `integrity:"sha256"`, `digest_verified`). With a range filter the filter is applied to the **exact bytes**, so the copy is a byte-exact slice of the original (`byte_exact:true`, `integrity:"sha1"`). Printed inline, a text file gives `content` (strictly decoded, `byte_exact:true`) while a **non-UTF-8 file gives no `content` at all** — the exact original bytes are in `content_base64` (base64-decode it) and the envelope is marked `byte_exact:true`. Only a server that does not support that negotiation returns the lossy text (`integrity:"text_decoded"`, with a warning on stderr). |
42
42
  | `sandbox working-directory <id>` | Get the sandbox's current working directory (absolute path `/workspace/{user_id}/{sandbox_id}`). |
43
43
  | `sandbox write <id> [--path <path>] --source <filename>` | Write a file (recommended). If `--path` is omitted, write to the working directory (`<working-directory>/<filename>`); a relative `--path` is also resolved under the working directory. An absolute `--path` is used as-is (but the `/workspace/<filename>` root path is outside the OSS sync scope and is not recommended). **Binary-safe**: the content travels as raw bytes (the server's binary endpoint, with a base64 fallback for older servers) and the CLI declares its `size`/`sha256`, which the server verifies before writing (a mismatch is rejected). The response carries `server_sha256`/`sha256`/`size`/`size_verified`. |
44
44
  | `sandbox write <id> --path <absolute-path> --data "..."` | Write a small amount of inline content (`--data` has no source filename, so `--path` must be specified explicitly). |
45
45
  | `sandbox write-multiple <id> --entry <remote-path>=<local-path> [--entry ...]` | Write multiple files in one operation (a relative target `path` is also resolved under the working directory). |
46
- | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` | Pull files/directories to the local machine (the reverse of `upload`; flag directions are reversed: `--source`=remote sandbox path, `--target`=local path). Single files are detected automatically; **directories are always traversed recursively** (`--recursive` is deprecated and no longer needed). The transfer uses the **chunked download** path: the bytes move verbatim (no base64 inflation) when the server offers the binary endpoint, binary-safe, end-to-end **sha256** verified (`digest_verified`), **resumable** (a partial `<target>.delta.part` is reused), and **parallel** across files and chunks (`--concurrency`, default 4) — so a large file is not bound by a single command timeout. The server publishes its limits with every response (`limits`): 4 MiB chunks (16 MiB max), 100 GiB max per file, 120 s per chunk, 600 s for the whole-file digest. `--no-resume` ignores a leftover `.delta.part`; `--no-verify` skips the sandbox-side sha256 comparison. |
46
+ | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` | Pull files/directories to the local machine (the reverse of `upload`; flag directions are reversed: `--source`=remote sandbox path, `--target`=local path). Single files are detected automatically; **directories are always traversed recursively** (`--recursive` is deprecated and no longer needed). The transfer uses the **chunked download** path: the bytes move verbatim (no base64 inflation) when the server offers the binary endpoint, binary-safe, end-to-end **sha256** verified (`digest_verified`), **resumable** (a partial `<target>.delta.part` is reused), and **parallel** across files and chunks (`--concurrency`, default 4) — so a large file is not bound by a single command timeout. The server publishes its limits with every response (`limits`): 4 MiB chunks (16 MiB max), 100 GiB max per file, 120 s per chunk, 600 s for the whole-file digest. `--no-resume` ignores a leftover `.delta.part`; `--no-verify` skips the sandbox-side sha256 comparison. When `--target` names an existing local directory, the file is written inside it under its own name (the way `cp file dir/` works). |
47
47
  | `sandbox upload <id> --source <local-directory> --target <sandbox-path>` | Upload a local directory (packaged as tar.gz, extracted server-side) and verify the resulting file list against the local manifest. `--source` is local, `--target` is inside the sandbox. |
48
48
  | `sandbox ls <id> --path <path>` | List directory contents (defaults to `.`). |
49
49
  | `sandbox stat <id> --path <path>` | Get file metadata (size / mode / owner / group). |
50
50
  | `sandbox mv <id> --entry <source=dest> [--entry ...]` | Move or rename files. |
51
51
  | `sandbox replace <id> --path <path> --old <text> --new <text> [--regex] [--ignore-case]` | Replace file contents. |
52
52
  | `sandbox chmod <id> --path <path> --mode <octal>` | Change file permissions. |
53
- | `sandbox rm <id> --path <path> [--path ...]` | Delete files. |
54
- | `sandbox rmdir <id> --path <path> [--path ...]` | Delete directories recursively (cannot be undone). |
53
+ | `sandbox rm <id> --path <path> [--path ...]` | Delete files. Files only: a directory path is rejected (use `rmdir`), and a missing path is an error, not a silent success. |
54
+ | `sandbox rmdir <id> --path <path> [--path ...]` | Delete directories recursively (cannot be undone). Directories only: a file path is rejected and the file is left untouched; a missing path is an error. |
55
55
  | `sandbox mkdir <id> --path <path> [--path ...]` | Create directories (`mkdir -p`). |
56
- | `sandbox search <id> --path <root-directory> --pattern <glob>` | Search for files. |
56
+ | `sandbox search <id> --path <root-directory> --pattern <glob>` | Search for files. An unterminated glob such as `[` is rejected instead of silently matching nothing. |
57
57
 
58
58
  ## Tunnelling (port exposure)
59
59