# @delta-infra/cli 中文文档

规范地址：https://npmcn.com/package/%40delta-infra/cli/

版本：1\.1\.59
npm 元数据更新时间：2026-11-10T10:03:26.271Z
中文译文更新时间：2026-11-11T21:56:58.404Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40delta-infra/cli
原文对照：https://npmcn.com/package/%40delta-infra/cli/?lang=original
项目主页：https://github.com/yzailab/delta-infra-cli#readme
源码仓库：https://github.com/yzailab/delta-infra-cli

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：538 kB，76 个文件
- TypeScript 类型：未声明
- Node.js 要求：\>=18\.0\.0
- 运行依赖：1 个
- 首次发布：2026-06-16T04:54:08.512Z
- 最新版本发布：2026-11-10T10:03:25.936Z
- 近 30 天下载量：5140（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：141（近 12 个月 141 个）

## 中文简介

Delta Agent Cloud CLI 用于沙盒计算和科学工具.

## 安装

```sh
npm install @delta-infra/cli
```

也可以使用：`pnpm add @delta-infra/cli`、`yarn add @delta-infra/cli`、`bun add @delta-infra/cli`

## README

# delta-cli

Delta Agent Cloud 的命令行工具，用于管理 Delta Sandbox GPU/CPU 计算任务和调用 Science 工具。

## 安装

### 方式一：npx 一键安装（推荐）

```bash
npx @delta-infra/cli@latest install
```

该命令会依次完成：

1.  **全局安装** `@delta-infra/cli`（含 Go 二进制）
2.  **选择 AI 工具平台**（可多选）：通用 Agent 目录 `~/.agents/skills/`（Codex/Cursor/OpenCode）、Claude Code `~/.claude/skills/`、OpenCode 原生 `~/.config/opencode/skills/`、Cursor `~/.cursor/skills/`、Memento-S 开发模式 `~/memento_s/skills/`
3.  **安装 AI Skills** 到所选平台的 skills 目录
4.  **初始化配置** 自动写入默认服务端地址（无需人工填写 base\_url）
5.  **身份认证** `delta-cli auth login`（交互式，非 TTY 跳过）

AI Agent 也可以直接使用以下指令完成安装：

> 帮我安装 delta-cli：https://github.com/yzailab/delta-infra-cli

### 卸载

```bash
npx @delta-infra/cli@latest uninstall
```

清理全局包、所有已知平台的 AI Skills 和配置文件。

### 升级

```bash
# 升级 CLI + AI Skills
delta-cli upgrade

# 只检查是否有更新（不执行升级）
delta-cli upgrade --check

# 只升级 CLI 二进制
delta-cli upgrade --cli-only

# 只升级 AI Skills
delta-cli upgrade --skills-only
```

升级 CLI 时会通过 `npm install -g @delta-infra/cli@latest` 拉取最新版本；升级 Skills 时会通过 `npx skills add` 重新安装 AI Skills。

### 方式二：直接下载 Binary

从 [GitHub Releases](https://github.com/yzailab/delta-infra-cli/releases) 下载对应平台的压缩包（以下使用 `latest` 指向最新版）：

```bash
# macOS (Apple Silicon)
curl -L -o delta-cli.tar.gz https://github.com/yzailab/delta-infra-cli/releases/latest/download/delta-cli-darwin-arm64.tar.gz
tar -xzf delta-cli.tar.gz
sudo mv delta-cli-darwin-arm64 /usr/local/bin/delta-cli
rm delta-cli.tar.gz

# Linux (AMD64)
curl -L -o delta-cli.tar.gz https://github.com/yzailab/delta-infra-cli/releases/latest/download/delta-cli-linux-amd64.tar.gz
tar -xzf delta-cli.tar.gz
chmod +x delta-cli-linux-amd64
sudo mv delta-cli-linux-amd64 /usr/local/bin/delta-cli
rm delta-cli.tar.gz

# Windows (AMD64，PowerShell)
Invoke-WebRequest -Uri https://github.com/yzailab/delta-infra-cli/releases/latest/download/delta-cli-windows-amd64.zip -OutFile delta-cli.zip
Expand-Archive -Path delta-cli.zip -DestinationPath . -Force
Move-Item -Path delta-cli-windows-amd64.exe -Destination delta-cli.exe
Remove-Item -Path delta-cli.zip
# 将 delta-cli.exe 放到 PATH 中的目录
```

### 方式三：一键安装脚本（国内用户推荐 / 无 npm 也可用）

安装脚本会**自动检测环境**：

-   **已有 npm** → 安装 `@delta-infra/cli` npm 包（自动尝试国内 npm 镜像 npmmirror，失败回退 npm 官方源）
-   **没有 npm** → 直接通过纯 shell 方式下载二进制（PowerShell + curl / bash + curl + tar，Windows 10+、macOS、Linux 均自带），**无需安装 Node.js/npm**

```bash
# Linux / macOS
curl -L https://raw.githubusercontent.com/yzailab/delta-infra-cli/main/install.sh | bash

# Windows (PowerShell)
Invoke-RestMethod -Uri https://raw.githubusercontent.com/yzailab/delta-infra-cli/main/install.ps1 | Invoke-Expression
```

脚本下载二进制时会按顺序尝试国内加速镜像（`gh.ddlc.top`、`ghproxy.net`、`gh-proxy.com`），全部失败再用 GitHub 源站，且会校验 SHA-256。可用 `DELTA_CLI_VERSION` 环境变量指定版本。

### 方式四：npm

```bash
npm install -g @delta-infra/cli
```

`postinstall` 会按以下顺序尝试下载当前平台的二进制：

1.  `DELTA_CLI_MIRROR` 环境变量指定的镜像（如果设置，需为 HTTPS 且允许全前缀格式，如 `https://gh.ddlc.top`）
2.  探测国内加速镜像 `gh.ddlc.top`、`ghproxy.net`、`gh-proxy.com`（并行探测），可用的优先
3.  GitHub 源站 `https://github.com/yzailab/delta-infra-cli/releases/download/...`（兜底）

如果安装时下载失败，可以：

-   直接运行一次 `delta-cli`，它会自动重新尝试下载。
-   或者在安装前设置本地压缩包路径：

```bash
DELTA_CLI_ARCHIVE=/path/to/delta-cli-linux-amd64.tar.gz npm install -g @delta-infra/cli
```

常用环境变量：

| 变量 | 说明 |
| --- | --- |
| `DELTA_CLI_MIRROR` | 下载镜像根地址，例如 `https://gh.ddlc.top`。脚本会自动补全为全前缀格式（`<mirror>/https://github.com/...`）。只接受 HTTPS 且需在白名单内。 |
| `DELTA_CLI_MIRROR_ALLOWLIST` | 额外允许的主机列表，逗号分隔。 |
| `DELTA_CLI_ARCHIVE` | 指向预先下载好的 `.tar.gz` / `.zip` 本地路径，跳过网络下载。 |

## 快速开始

### 1\. 初始化配置

```bash
delta-cli config init
```

服务端地址无需人工填写：默认使用 `https://delta-infra-nacos.yangtzeailab.com`（已有配置则沿用其中的 base\_url），仅交互式提示 Bearer Token（可选，也可后续用 `auth login` 配置）。

如需指向自建服务器，可通过 flag 或环境变量一次性指定：

```bash
# 通过 flag
delta-cli config init \
  --base-url http://your-server/api/v1 \
  --token your-token

# 通过环境变量（API Key 或 Token 二选一）
export DELTA_INFRA_BASE_URL=http://your-server/api/v1
export DELTA_INFRA_API_KEY=your-api-key        # 或 DELTA_INFRA_TOKEN
delta-cli config init
```

配置文件保存在 `~/.delta-infra/config.json`（权限 0600）。

### 2\. 认证

支持 **API Key** 与 **Bearer Token** 两种凭据（API Key 优先）。

**获取 API Key**：登录 Delta Agent Cloud **Web 控制台**，在 **API Keys** 页面生成一个 Key。

```bash
# API Key（推荐）
delta-cli auth login --apikey <your-api-key>

# Token
delta-cli auth login --token <your-token>

# 交互式登录（可直接粘贴 Key/Token，CLI 会自动识别格式）
delta-cli auth login

# 查看认证状态
delta-cli auth status
```

也可以通过环境变量指定：`DELTA_INFRA_API_KEY=<key>` / `DELTA_INFRA_TOKEN=<token>`。

### 3\. Sandbox 生命周期

```bash
# 创建带 GPU 的 sandbox（--max-life 默认 30 分钟，长任务请调高）
# ⚠️ 生命周期计时（详见 skills/delta-sandbox/references/lifecycle.md）：
#   - 私有算力：平台从 create 请求被接受时开始计时，镜像拉取/就绪
#     时间也计入 max-life；到期由平台回收。
#   - 第三方算力：从沙箱就绪（本地记录 started_at）开始计时，
#     由服务端 cleanup 在 max-life + 最多 10 分钟宽限后回收。
#   - 自动回收（含平台提前回收）不会做 OSS 写回；需要保留产物请提前 pull 或
#     显式 `sandbox finish`。`sandbox status` 会返回 expires_at / reclaim_source /
#     termination_reason，沙箱结束后仍可查询。
# ⚠️ 资源语义：`--memory` 是容器 CPU 内存【总量】（每沙箱一份）；`--gpu-mem` 是【每张卡】的显存（MiB）——
# `--gpu 2 --gpu-mem 8000` = 每卡 8000MiB、总显存 16000MiB（私有算力直接按每卡注解调度；
# 注意第三方算力后端将 --gpu-mem 视为总显存÷卡数）。单卡显存上限可查 `sandbox resources`（私有算力分组的 `memory_mib`）。
# 注意：服务端已移除 shmSize / devices 资源字段，CLI 的 --shm-size / --devices 已被移除。
# `--ready-timeout` 是**创建阶段**等待沙箱就绪的上限（秒，默认 600，范围 10-1800）：冷节点首次拉取大镜像
# （如 2.9GB 层）常超过 60s，提高它可避免 error_code=SandboxReadyTimeout。对全部算力生效（私有算力 /
# 第三方算力）。注意它与 `--max-life`（创建成功后的存活时长）是两回事。
delta-cli sandbox create \
  --image-name "PyTorch CUDA13 (GPU)" \
  --cpu 4 --memory 16Gi --gpu 1 \
  --max-life 120


# 需要长期存活、不被自动清理的 sandbox：加 --no-auto-cleanup
# （同时关闭平台 TTL 与服务端 cleanup，仅显式 kill/finish 可销毁）
delta-cli sandbox create \
  --image-name "PyTorch CUDA13 (GPU)" \
  --cpu 4 --memory 16Gi --gpu 1 \
  --no-auto-cleanup

# 运行命令（短任务同步执行，长任务用 run-bg 替代 run）
delta-cli sandbox run <sandbox_id> \
  --command "<命令>" \
  --timeout 3600

# v1.0.85+ sandbox run 默认走 SSE 实时流：stdout 为原始 data: 帧（无末尾信封），
# exit_code / log_file / stdout_tail / duration_seconds 在 complete 帧中
delta-cli sandbox run <sandbox_id> --command "echo '{\"status\":\"ok\",\"result\":\"done\"}'" --timeout 60

# 自动化/编排推荐：--format json（等价 --json-result）只输出一个 JSON 信封，
# data 含 execution_id / finished / exit_code / stdout_tail / stderr_tail /
# stdout_size / stderr_size / log_file / duration_seconds / result_summary。
# 字段名与 complete 帧一致；失败时仍是单个对象：
# {"ok":false,"error":{...},"data":{...}}，进程退出码非零。
delta-cli sandbox run <sandbox_id> --command "python run.py" --timeout 600 --format json

# 后台任务 + 等待 + 统一结果
delta-cli sandbox run-bg <sandbox_id> --command "python train.py" --timeout 3600 --wait --format json

# 读取结果文件
delta-cli sandbox read <sandbox_id> --path /workspace/result.json

# 销毁 sandbox（销毁在服务端继续执行，响应带 request_id）
delta-cli sandbox kill <sandbox_id>

# 创建重试幂等 + 事后对账
delta-cli sandbox create --image-name <镜像名> --idempotency-key retry-001
delta-cli sandbox operation <request_id>
```

## 命令列表

### 全局命令

| 命令 | 说明 |
| --- | --- |
| `delta-cli config init` | 初始化配置文件 |
| `delta-cli config show` | 查看当前配置（敏感字段已脱敏） |
| `delta-cli config set <key> <value>` | 修改配置项 |
| `delta-cli config remove <key>` | 移除配置项（支持 `token`、`apikey`） |
| `delta-cli auth login` | 交互式登录（自动识别 API Key / Token） |
| `delta-cli auth login --apikey <key>` | API Key 认证（推荐） |
| `delta-cli auth login --token <token>` | Token 认证 |
| `delta-cli auth status` | 查看认证状态 |
| `delta-cli upgrade` | 升级 CLI 和 AI Skills 到最新版本 |
| `delta-cli upgrade --check` | 检查是否有可用更新 |
| `delta-cli upgrade --cli-only` | 只升级 CLI 二进制 |
| `delta-cli upgrade --skills-only` | 只升级 AI Skills |
| `delta-cli usage` | 查看当前用户信息和剩余 credits（仅积分，不含硬件配额） |
| `delta-cli quota` | 查看账号硬件配额：GPU/显存/CPU/内存/并发的上限、已用、剩余，GPU 试用时长，以及是否允许 GPU 和 provider/型号/镜像白名单（`null`\=不限，`0`\=零额度） |
| `delta-cli quota --pool` | 主账号查看子账号硬件额度池：池子、已分配、剩余可分配（子账号调用返回其继承的生效值） |
| `delta-cli --version` | 显示版本 |

### Sandbox 命令

> **提示**：`sandbox list`（列沙箱实例）与 `sandbox ls <id>`（列目录）不同，注意区分。
> 
> **沙箱内路径**：指向沙箱内部的路径（`--path`、`write-multiple --entry` 的远端部分、`upload --target`、`pull --source`、`run`/`run-bg --log-file`）若为相对路径，会自动拼到沙箱工作目录（`sandbox working-directory <id>` 可查），绝对路径原样使用；指向本地机器的路径（`write --source`、`upload --source`、`pull --target`、`read --output`）不做任何改写。

| 命令 | 说明 |
| --- | --- |
| `delta-cli sandbox list` | 列出当前用户的 sandbox 实例（新服务端默认返回摘要字段 `sandbox_id`/`status`/`image`；需要完整字段请用 `sandbox status <id>`） |
| `delta-cli sandbox resources` | 按算力来源（`compute_sources[].source`：私有/第三方）查看平台当前库存（GPU/显存/核心）；这是平台库存而非账号剩余配额——账号额度请用 `delta-cli quota` |
| `delta-cli sandbox images` | 查看可用镜像列表（每条含 `image_name`/`tags`/`description`/`supports_shared_workspace`；新服务端还可选含 `source`（恒有，private/third\_party）/`provider_label`/`compatible_gpu_types`——后者可用于选择计划内允许的 `--gpu-type`。`supports_shared_workspace=true` 表示该算力来源可开共享工作区，可与 `--shared-workspace` 搭配；实际播种/写回由平台创建时探测镜像内 rclone 决定） |
| `delta-cli sandbox recommend --cpu N --memory XGi` | 获取资源配置推荐（新服务端还可选返回 `source`/`gpu_type`/`provider_label`；`gpu_type` 可直接回填 create 的 `--gpu-type`） |
| `delta-cli sandbox create --image-name <镜像名> [--idempotency-key <key>] [--ready-timeout S] [--no-auto-cleanup] [--shared-workspace=true|false]` | 创建 sandbox 容器（`--image` 为旧别名；**`--idempotency-key`**：网络重试时用同一个键会回放原 sandbox 而不会重复创建，同键换参数会被拒绝；响应含 `request_id`/`operation_status`/`replayed`；`--no-auto-cleanup` 同时关闭平台 TTL 与服务端 cleanup，仅显式 kill/finish 可销毁；`--shared-workspace` 默认 true：启用共享工作区（播种/写回由平台创建时探测镜像内 rclone 决定，镜像无 rclone 时跳过、数据不跨沙箱持久）；false 跳过播种/写回，适合快速任务；`--ready-timeout` 对全部算力生效（默认 600，范围 10-1800），冷节点首次拉大镜像时调高可避免 `error_code=SandboxReadyTimeout`，与 `--max-life`（存活时长）无关。`--shm-size` / `--devices` 已随服务端 shmSize/devices 下线移除） |
| `delta-cli sandbox extend <id> --max-life N` | **动态延长运行中** sandbox 的 max-life（N 必须大于已存活时长且 ≤10080；新的到期时间必须晚于当前到期时间——**只能延长，不能缩短**；提前回收用 `kill`/`finish`；`--no-auto-cleanup` 沙箱无需续期）；不带 `--max-life` 时查询当前生命周期（已存活/剩余/到期时间）；`status` 输出含 `data.lifecycle` 生命周期摘要（已存活/剩余/到期；生命周期接口不可用时省略） |
| `delta-cli sandbox connect <id>` | 连接 sandbox |
| `delta-cli sandbox status <id>` | 查看 sandbox 状态；返回 `expires_at` / `reclaim_source`，已结束的沙箱仍可查询并带 `termination_reason` / `termination_remark` / `terminated_at`（如 `max_life_exceeded` / `platform_gone` / `user_killed` / `user_finished`） |
| `delta-cli sandbox finish <id> [--no-wait]` | 保存结果并销毁；销毁是**服务端任务**，响应含 `request_id`/`operation_status`（`--no-wait` 立即返回 `pending`，断线后任务继续，可用 `sandbox operation <request_id>` 对账） |
| `delta-cli sandbox kill <id> [--no-wait]` | 销毁 sandbox（不保存结果）；响应含 `request_id`/`operation_status`，中断或网络报错后可用 `sandbox operation` 查询真实终态 |
| `delta-cli sandbox operation [request_id] [--sandbox-id <id>] [--operation create|destroy] [--limit N]` | 查询服务端操作账本：带 `request_id` 查单条，否则按条件列出最近的创建/销毁记录（终态、时间、原因），用于计费与资源对账；失败记录附带 `diagnostics` 摘要（`error_code`/`stage`/`hint`/`provider_label`），无需解析嵌套的 `result` |
| `delta-cli sandbox run <id> --command "..." [--timeout <秒>] [--format sse|json] [--json-result] [--summary/--no-summary] [--artifacts]` | 同步运行命令。默认（`--format sse`）把 SSE 原始 `data:` 帧透传到 stdout，无末尾信封，`exit_code`/`log_file`/`stdout_tail`/`duration_seconds` 在 `complete` 帧；`--format json`（或 `--json-result`）只输出**一个** JSON 信封，`data` 含 `execution_id`/`finished`/`exit_code`/`stdout_tail`/`stderr_tail`/`stdout_size`/`stderr_size`/`log_file`/`duration_seconds`/`result_summary`，失败时为 `{ok:false,error,data}` 且进程非零退出；`--summary`/`--artifacts` 仅旧服务器回退路径生效。**退出码语义**：命令非零退出 → `error.type=command_failed`，进程退出码 **8**；命令已结束但**退出状态不可知**（流在 `complete` 帧前中断、或只有 error 帧）→ `error.type=unknown_execution_state`，进程退出码 13，**绝不会合成成功** |
| `delta-cli sandbox run-bg <id> --command "..." [--timeout <秒>] [--wait] [--cancel-on-timeout] [--format sse|json] [--json-result] [--summary/--no-summary] [--artifacts]` | 后台运行命令；不加 `--wait` 立即返回 `{execution_id, sandbox_id}`（`--format json` 时为统一结果对象，`finished=false`）；加 `--wait` 通过 SSE 实时流跟随（默认透传原始 `data:` 帧）；`--format json` 时只输出一个与 `sandbox run --format json` 相同结构的信封。**等待超时** → `error.type=timeout`、进程**非零退出**，`error.details` 保留 `sandbox_id`/`execution_id`/`remote_state`（`not_cancelled`/`cancelled`/`cancel_failed`）以便事后查询或取消；`remote_state=not_cancelled` 表示**只是本地停止等待，远端命令可能仍在运行**。默认不取消远端命令，加 `--cancel-on-timeout` 才会下发取消（取消失败时报 `cancel_failed`） |
| `delta-cli sandbox logs <id> [--execution-id <eid>] [--tail N --grep <pattern> --context N] [--stream]` | 查看后台日志（`--execution-id` 可省略：省略时按 sandbox 维度查询、服务端走 ES，返回按 execution\_id 分组的数组）；默认返回 `stdout_tail`（约 800 字节）+ `stderr_tail`（约 200 字节）+ `stdout_size`/`stderr_size`；`--tail/--grep/--context` 过滤两路输出；`--stream` 实时跟随（SSE） |
| `delta-cli sandbox cancel <id> --execution-id <eid>` | 中断后台命令 |
| `delta-cli sandbox read <id> --path <path> [--output <本地路径>] [--tail N] [--grep <pattern>] [--offset N] [--limit N] [--context N] [--max-bytes N] [--parse-json]` | 读取容器内文件；`--output <path>` 保存到本地；`--tail/--grep` 过滤。**整份拷贝（不带 `--tail/--grep/--offset/--limit/--max-bytes`）走分块下载通道，字节精确**（二进制安全，响应含 `byte_exact:true`/`integrity:"sha256"`/`digest_verified`）；带上述过滤参数时，过滤作用在**原始字节**上，落盘结果是原文件的字节精确切片（`byte_exact:true`/`integrity:"sha1"`）。**直接输出到 stdout 时**：文本文件给 `content`（严格解码，`byte_exact:true`）；**非 UTF-8 文件不给 `content`**（有损预览会误导），精确原始字节放在 `content_base64`（base64 解码即为原文件），并标记 `byte_exact:true`。仅当服务端不支持该协商时才会退回有损文本（`integrity:"text_decoded"`）。`--output` 指向已存在的本地目录时，文件按自身文件名写进该目录（等同 `cp file dir/`） |
| `delta-cli sandbox pull <id> --source <沙箱路径> --target <本地路径> [--pattern <glob>] [--concurrency N] [--no-resume] [--no-verify]` | 从沙箱拉取文件/目录到本地（mirror of `upload`，flag 方向相反：source=远程，target=本地）。**目录始终递归**（`--recursive` 仅为兼容保留，无需再加）；走**分块下载**通道：二进制安全、端到端 **sha256** 校验（响应含 `digest_verified`）、**可断点续传**（`.delta.part`）、多文件/多块**并行**传输（`--concurrency`，默认 4），因此不受单条命令 300s 超时限制。服务端公开的上限随每次响应返回（`limits`）：块大小 4 MiB（最大 16 MiB）、单文件最大 100 GiB、每块超时 120s、整文件摘要超时 600s。`--no-resume` 忽略残留的 `.delta.part`，`--no-verify` 跳过沙箱侧 sha256 比对。**载荷按原始字节直传**（服务端支持时走二进制端点，不再被 base64 撑大 4/3），旧服务端自动回退；**分块必须连续覆盖整个文件**，有缺口或被中断的下载直接报错，不会被当成成功结果。`--target` 指向已存在的本地目录时，文件按自身文件名写进该目录（等同 `cp file dir/`） |
| `delta-cli sandbox write <id> --path <path> --source <本地路径>` | 写入文件。**二进制安全**：内容按原始字节直传（服务端支持时走二进制端点，旧服务端自动回退到 base64），CLI 同时声明 `size`/`sha256`，服务端在落盘前核对，不匹配直接拒绝；响应含 `server_sha256`/`sha256`/`size`/`size_verified`。超过 32 MiB 的 `--source` 走流式上传通道，不整份读入内存 |
| `delta-cli sandbox write-multiple <id> --entry <远程路径>=<本地路径>` | 批量写入 |
| `delta-cli sandbox ls <id> --path <path>` | 列出目录（路径是文件或不存在时给出明确报错，而不是笼统的上游失败） |
| `delta-cli sandbox stat <id> --path <path>` | 文件元数据 |
| `delta-cli sandbox mv <id> --entry <src=dest>` | 移动/重命名 |
| `delta-cli sandbox replace <id> --path <path> --old <文本> --new <文本>` | 替换内容 |
| `delta-cli sandbox chmod <id> --path <path> --mode <八进制>` | 修改权限 |
| `delta-cli sandbox rm <id> --path <path>` | 删除文件。**只删文件**：目录路径会被拒绝（请改用 `rmdir`），路径不存在会报错而不是静默成功 |
| `delta-cli sandbox rmdir <id> --path <路径>` | 递归删除目录（不可撤销）。**只删目录**：文件路径会被拒绝且文件保持不动，路径不存在会报错 |
| `delta-cli sandbox mkdir <id> --path <路径>` | 创建目录 |
| `delta-cli sandbox search <id> --path <根目录> --pattern <glob>` | 搜索文件（括号未闭合的 glob 如 `[` 会被拒绝，而不是静默返回空结果） |
| `delta-cli sandbox working-directory <id>` | 获取沙箱工作目录路径 |
| `delta-cli sandbox upload <id> --source <本地目录> --target <沙箱路径>` | 上传目录（tar.gz + 自动解压） |
| `delta-cli sandbox expose <id> [--port N]` | 将沙箱内服务端口暴露到公网（frp 隧道），默认端口 8700 |
| `delta-cli sandbox exposes <id>` | 列出沙箱当前活跃的公网端口隧道 |
| `delta-cli sandbox dispose <id> --port N` | 回收公网端口隧道（需指定端口号） |

### Science 工具

> Science Server 由 `base_url` 派生（`{base_url}/science_tool`），无需单独配置 `science_base_url`；Sandbox API 同样由 `base_url` 派生（`{base_url}/sandbox/api/v1`）。

| 命令 | 说明 |
| --- | --- |
| `delta-cli science list` | 列出所有已启用的 science 工具 |
| `delta-cli science get <tool_name>` | 查看指定工具的详情 |
| `delta-cli science invoke --tool <tool_name> --endpoint <endpoint_name> [--data '{"key":"value"}'] [--params '{"key":"value"}']` | 调用工具端点 |
| `delta-cli science endpoints list <tool_name>` | 列出指定工具的所有端点 |
| `delta-cli science task submit --tool <tool> --operation <operation> --input '<json>' [--wait]` | 提交持久化 Science 任务 |
| `delta-cli science task get/list/cancel/invocations/artifacts` | 查询、取消任务及读取调用/artifact 元数据 |
| `delta-cli science file invoke --tool <tool> --endpoint <operation> --file <path>` | 调用受控文件/multipart operation |
| `delta-cli science file download --tool <tool> --endpoint <operation> --params '<json>' --output <path>` | 下载原始 artifact 并计算 SHA-256 |

`tools.name` 和 `tool_endpoints.name` 是 Science 工具调用的唯一权威名称。 `science list` 与 `science endpoints list` 原样展示服务端数据库中的启用项， `science invoke` 原样传递 `--tool` 和 `--endpoint`，不执行别名映射或旧名称兼容。

v1.1.1 起线上 catalog 已包含 `qe`（Quantum ESPRESSO DFT，20 个端点：任务提交/查询/ 日志/artifact/PP 库等）与 `materials-design`（持久化材料代理建模，7 个端点： health/capabilities/job-submit(multipart)/job-status/job-cancel 等）。用法见 Skill 文档 `skills/delta-science/references/qe.md` 与 `skills/delta-science/references/materials-design.md`。 云端 XRD 的相识别、artifact、CIF 模拟和精修契约见 `skills/delta-science/references/xrd.md`。

## 输出格式

所有命令返回统一的 JSON envelope：

```json
// 成功
{"ok":true,"data":{"id":"sb-xxx","status":"running"}}

// 错误
{"ok":false,"error":{"type":"auth","message":"not authenticated","hint":"run 'delta-cli auth login'","request_id":"create_a1b2c3"}}
```

`error.hint` 给出可执行的下一步（创建失败时会说明具体原因，例如「镜像未在目标节点缓存，重试或换一个已缓存该镜像的 GPU 型号」），`error.request_id` 用于在服务端日志中定位同一次失败。对于新服务端，创建失败时 `error.details` 还会携带结构化诊断（`diagnostics_version`/`stage`/`retryable`/`suggested_actions`，以及嵌套的 `details`，如 `suggested_gpu_types`、`provider_label`）；当客户端没有对应错误码的提示表时，会优先采用服务端下发的 `hint`。

错误类型及退出码：

| Type | Exit Code | 场景 |
| --- | --- | --- |
| validation | 2 | 参数错误 —— 含"需要目录却给了文件（或反之）"以及非法 glob |
| auth | 3 | 未认证 |
| permission | 4 | 权限不足 |
| not\_found | 5 | 资源不存在 |
| network | 6 | 网络错误 |
| api | 7 | 服务端错误 |
| command\_failed | 8 | 沙箱内命令非零退出 |
| internal | 10 | 客户端内部错误 |
| timeout | 11 | `run-bg --wait` 本地等待超时（远端命令可能仍在运行，见 `error.details`） |
| content\_integrity\_mismatch / content\_size\_mismatch | 12 | 文件传输校验失败（sha256 或字节数不符） |
| unknown\_execution\_state | 13 | 命令已结束但退出状态不可知（**绝不合成成功**） |

## AI Agent Skills

delta-cli 内置 AI Agent 操作手册（Skills），帮助 Claude Code 等 AI 助手正确使用 CLI：

```bash
# 安装仓库中的全部 Skills
npx skills add delta-infra/delta-infra-cli -y -g

# 只安装统一 Science Skill
npx skills add delta-infra/delta-infra-cli -s delta-science
```

Skill 文件位于 `skills/` 目录：

-   `delta-shared/` — 全局通用规则（认证、配置、错误处理）
-   `delta-sandbox/` — Sandbox 操作指南（生命周期、命令路由）
-   `delta-science/` — 唯一 Science 入口，包含统一 Delta CLI wrapper、跨工具工作流和 PubChem、RDKit、pymatgen、XRD、GSAS-II、QE、LAMMPS、Delta-BO、LDM-BO、SynBO、 AntBO、materials-design、strbo 以及蛋白质/生物信息（`huada_protein_tools`）的按需 reference；蛋白质类 endpoint 契约位于 `skills/delta-science/references/protein/`

Memento 等宿主只需要选择 `delta-science`。Skill 根据自然语言科研目标选择 tool 和 operation，并且只加载当前工具对应的 reference，避免大量独立 Skill 给规划器增加 负担。升级时会自动移除旧版独立 Science Skill。

### 添加 Science tool 或 operation

工具目录由 Science Server 数据库维护。新增工具时配置 `tools` 记录及对应的 `tool_endpoints` 记录；停用时设置 `status=false`。CLI 无需同步任何静态表或重新增加 命令。若需要让 AI 根据自然语言自动选择新工具并安全组装请求，再更新 `skills/delta-science/SKILL.md` 的工具选择表和对应的 `skills/delta-science/references/<tool>.md`；references 目录只保存真实工具文档，不能放置 目录、路由、服务映射或跨工具工作流等元文档。数据库中的 canonical tool name 与工具表、 对应 reference 必须完全一致。

## 开发

```bash
# 本地构建
make build

# 运行测试
make test

# 代码检查
make lint

# 跨平台编译（生成各平台二进制文件到 bin/）
make release

# 源码安装到系统 PATH（默认 /usr/local/bin；macOS / Linux）
make install

# 自定义安装前缀
make PREFIX=$HOME/.local install

# Windows 源码安装（二选一）
# 方式 A：在仓库根目录用 go install 安装到 GOPATH/bin
go install ./cmd/delta-cli

# 方式 B：在仓库根目录运行 PowerShell 脚本，构建并添加到用户 PATH
# .\install-from-source.ps1
# .\install-from-source.ps1 -InstallDir "$env:USERPROFILE\bin"
```

### 日常开发流程

修改 `skills/` 或编译 `delta-cli` 后，需要同步到 Memento-S 项目才能生效：

```bash
# 1. 通过安装向导同步完整 Skill 集合
node scripts/install-wizard.js

# 2. 用 Docker 编译 Windows 版本（本地无 Go toolchain 时）
docker run --rm -v "$(pwd):/src" -w /src \
  -e GOPROXY=https://goproxy.cn,direct \
  golang:1.23 \
  sh -c 'go build -buildvcs=false \
    -ldflags "-X github.com/delta-infra/delta-infra-cli/internal/build.Version=$(git describe --tags --always --dirty 2>/dev/null || echo dev)" \
    -o bin/delta-cli-windows-amd64.exe ./cmd/delta-cli'

# 3. 将 delta-cli 放到 Memento-S 的 node_modules/.bin（替换旧版本）
cp bin/delta-cli-windows-amd64.exe \
   <memento-s>/electron_rebuild/node_modules/.bin/delta-cli

# 4. 重启 Memento-S sidecar 使新 binary 生效
#   在 Electron 界面中重新加载，或手动重启 sidecar 进程
```

> **注意**：`delta-cli` 替换后，如果 `~/.delta-infra/config.json` 中已配置 token，则 Sandbox 和 Science Skills 可直接使用；否则需要先用 `auth login` 配置。

## 构建与发布

### 本地构建

```bash
# 本地构建
make build

# 运行测试
make test

# 代码检查
make lint

# 跨平台编译（生成各平台二进制文件到 bin/）
make release
```

> `make release` 仅生成各平台二进制文件（如 `bin/delta-cli-linux-amd64`），不会自动打包。打包与发布请使用下文的 `release.sh`。

### 一键发布（维护者）

项目根目录下的 `release.sh` 脚本负责完整发布流程：

```bash
export GH_TOKEN=<your-github-pat>
export NPM_TOKEN=<your-npm-token>
./release.sh <version>
```

脚本执行步骤：

1.  更新 `package.json` 版本号并交叉编译 5 个平台二进制文件（优先 Docker + `make release`，Docker 不可用时回退本地 Go 工具链）。
2.  在 `bin/` 目录生成 `.tar.gz` / `.zip` 归档及 SHA-256 checksums，并更新仓库根目录的 `checksums.txt`。
3.  运行公开同步计划器测试（`.ci/sync-public-github.test.js`）。
4.  提交 source commit 并打 tag（`chore: release vX.Y.Z`），推送 GitLab `main` 与 tag（`PUSH_SOURCE` 默认为 1，非 1 会直接中止；公开同步依赖这一步）。
5.  同步 allowlist 公开文件树与 tag 到公开仓库 `yzailab/delta-infra-cli`。
6.  通过 `.ci/publish-github-release.js` 创建 GitHub Release 并上传二进制归档及 checksums。
7.  执行 `npm publish --access public` 发布 `@delta-infra/cli`。

需要提前安装 `gh` CLI、Node.js/npm，并配置 `GH_TOKEN` 与 `NPM_TOKEN`。CI 流程可参考 `.gitlab-ci.yml`。

### npm 镜像

如果 GitHub 下载较慢，安装 npm 包时可设置镜像：

```bash
DELTA_CLI_MIRROR="https://gh-proxy.com" npm install -g @delta-infra/cli
```

## 沙箱内镜像源自动配置

创建沙箱时，服务端会**自动检测部署所在网络区域**（中国大陆 / 海外），并在区域为中国大陆时把镜像配置注入到容器里。用户无需任何手动配置，进去即可用。

-   **中国大陆（domestic）**：服务端自动注入镜像配置，`pip install` / `npm install` / `git clone` / HuggingFace 下载会走国内镜像。
-   **海外（overseas）**：不注入镜像，使用各包管理器官方源。
-   服务端通过探测 `pypi.org` / `npmjs.org` 的连通性来判断区域（带缓存、探测失败时按海外兜底，即 fail-open）。

覆盖的 4 类配置：

| 类型 | 说明 | 示例 |
| --- | --- | --- |
| pip index-url | Python 包索引 | `https://pypi.tuna.tsinghua.edu.cn/simple` |
| npm registry | Node 包源 | `https://registry.npmmirror.com` |
| HF\_ENDPOINT | HuggingFace 下载域名 | `https://hf-mirror.com` |
| git insteadOf | GitHub 克隆代理 | `https://gh-proxy.com/https://github.com` |

第三方算力（海外平台）默认关闭镜像注入，仅当运维明确配置开启后才生效。

> **注意区分两套镜像机制**：本沙箱镜像配置针对的是**沙箱里的包管理器**（pip / npm / git / HF）。它与 CLI 自身的下载镜像 `DELTA_CLI_MIRROR` 是两回事——`DELTA_CLI_MIRROR` 只用于**安装 delta-cli 二进制**，不作用于沙箱内。

## 技术栈

-   **语言**: Go 1.23+
-   **CLI 框架**: [Cobra](https://github.com/spf13/cobra)
-   **配置**: JSON 文件（`~/.delta-infra/config.json`，权限 0600）
-   **输出**: JSON envelope（AI-agent 友好，可脚本化）
-   **发布**: GitHub Release（tar.gz/zip） + npm wrapper
-   **架构**: 扁平静态命令树，Factory 依赖注入，惰性初始化

## License

MIT

## 常见问题

### @delta-infra/cli 是什么？

Delta Agent Cloud CLI 用于沙盒计算和科学工具\.

### 如何安装 @delta-infra/cli？

在项目目录运行 npm install @delta-infra/cli，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 delta-cli，可以用 npx delta-cli 直接运行。

### @delta-infra/cli 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/delta-infra\_\_cli 是否存在。

### @delta-infra/cli 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @delta-infra/cli 可以商用吗？

@delta-infra/cli 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @delta-infra/cli 的下载量有多少？

根据 npm 官方下载统计，@delta-infra/cli 在 2026/10/12 – 2026/11/10 这 30 天内被下载 5,140 次，日均约 171 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @delta-infra/cli 还在维护吗？

最新版本 1\.1\.59 发布于 2026/11/10（1 天前）；至今共发布 141 个版本，其中过去 12 个月发布了 141 个；首次发布于 2026/06/16。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

