# @autocodeflow/cli 中文文档

规范地址：https://npmcn.com/package/%40autocodeflow/cli/

版本：2\.1\.1
npm 元数据更新时间：2026-11-02T18:22:53.722Z
中文译文更新时间：2026-11-08T00:57:14.303Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：297 kB，41 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.12\.0
- 运行依赖：6 个
- 首次发布：2026-09-19T09:03:31.847Z
- 最新版本发布：2026-11-02T18:22:53.488Z
- 近 30 天下载量：1960（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：20（近 12 个月 20 个）

## 中文简介

AutoCodeFlow CLI — 从终端管理任务、执行和应用程序

## 安装

```sh
npm install @autocodeflow/cli
```

也可以使用：`pnpm add @autocodeflow/cli`、`yarn add @autocodeflow/cli`、`bun add @autocodeflow/cli`

## README

# @autocodeflow/cli

AutoCodeFlow CLI —— 在终端里管理任务、执行、应用、执行器与项目。

```bash
npm i -g @autocodeflow/cli

acf login
acf task list --status active
acf task trigger <taskId> --wait
acf exec tail <execId>
```

> **API 地址口径**（2026-10-07）：admin-api 路由带全局 `/api` 前缀。 `--api-url`/`ACF_API_URL`/login 的 URL prompt 对**不带** `/api` 尾段的地址 会在请求期自动补上（缺补已有留——修复了默认 `http://localhost:3105` 对 标准部署恒 404 的开箱缺陷）；已带 `/api` 的地址逐字节原样。唯一不适用： 「剥 `/api` 前缀」的反代且喂根地址——请传剥前缀后的源站地址。

每个命令（含每个子命令）都支持 `acf <命令> --help`：一行用途、参数表，以及 至少一个可直接复制的示例。缺参 / 未知命令 / 未知选项时，报错行之后会紧跟该 命令的完整帮助（含示例），不需要去翻文档。

## 退出码

CLI 的非零退出码按失败类别区分，脚本/CI 可以只按码分支处理（所有非零码都 代表失败，`!= 0` 的既有判断不受影响）：

| 退出码 | 含义 | 典型场景 / 下一步动作 |
| --- | --- | --- |
| `0` | 成功 | 含 `--help` / `--version` / 主动放弃确认（`Aborted.`） |
| `1` | 运行失败 | 服务端拒绝（400/403/404/409/5xx，错误行透出后端 message）；`--wait` 等到失败终态；`acf task lint` 检出语法错误 |
| `2` | 用法 / 参数错误 | 缺参、未知命令/选项、非法取值（如 `--wait-timeout abc`）；本地 payload 问题（JSON 解析失败、`--file` 读不了、`task lint` 无法推断语言）；**非交互 stdin 下的破坏性操作缺 `--yes`**（见下） |
| `3` | 认证失败 | 401：凭据缺失/过期且自动刷新失败 → 运行 `acf login` |
| `4` | 网络失败 | 连接不通 / 超时 / DNS → 检查 `--api-url`、`ACF_API_URL`；`acf exec tail` 流中断或空闲超时 |
| `130` | 中断（SIGINT） | Ctrl+C。输出会补一个换行，不留半行 spinner |

### 退出码 1 的两个高频非「失败」通道（CI 必读）

同样是 `1`，但语义**不是**「操作失败」，不要据此触发回滚/告警：

-   **`--wait` 轮询超时**：执行**仍在运行**，CLI 只是放弃了等待（默认 600s， 用 `--wait-timeout <s>` 放宽）。此时输出会明确写「The execution is still running」，跟进用 `acf exec tail <execId>`。**结果未知 ≠ 失败**。
-   **批量部分失败**：`acf task batch <action>` 与 `acf app upgrade-all` 在 「部分目标被拒」时返回 1（服务端 HTTP 仍是 2xx）。逐项结果看 stdout 的 `✗ <id>: <reason>` 行或 `--json` 输出。

### 破坏性操作的 `--yes`（非交互必读）

破坏性动作有交互确认。**stdin 非 TTY 时（CI、agent、`< NUL`、管道）它们不会 静默放行也不会静默取消，而是以退出码 2 拒绝**，要求显式传 `-y/--yes`：

| 类别 | 命令 |
| --- | --- |
| 删除 | `app delete` / `task delete` / `task batch delete` / `deploy remove` / `mutex delete` |
| 一次性密钥轮换（旧值立即失效） | `executor rotate` / `task webhook enable` / `task webhook rotate` / `task webhook disable` |
| 强制终止（KILLED 是终态，无法恢复） | `task kill` |
| 全量滚动升级（`--strategy canary` 不加门） | `app upgrade-all` |
| 撤销凭据（影响仍在用它的外部系统） | `apikey revoke` |

```bash
acf task delete <id> -y     # 非交互下唯一被接受的确认方式
```

判据是 `process.stdin.isTTY`。同族纪律：`acf login` 在非交互下同样不会对 地址/用户名/密码发问，缺少 `--user` 或 `ACF_PASSWORD` 时直接以退出码 2 报 可操作错误（不再出现「exit 0 但其实没登录」）。

单一事实源在 `src/ui.ts` 的 `EXIT_CODES`；错误分类（401/网络/服务端）在 `src/client.ts` 的 `classifyApiError` 做一次，命令层统一经 `emitError` 出口 消费。

## 机器可读输出（`--json`）

所有只读命令都支持 `--json`（CI/脚本消费面，错误仍走 stderr + 非零退出码）：

-   列表 / 信封形态（`task list`、`task executions`、`app list`、 `app deployments`、`app releases`、`deploy list`、`executor list`、`sop list`、 `agent sessions`、`audit list`）→ 单行紧凑 JSON，信封（`{list|data|items, total}`）原样直出；
-   单对象 / 详情形态（`task get`、`task stats`、`task versions`、 `task compare`、`task logs`、`task trigger`、`app get`、`app versions`、 `executor get`、`sop show`、`project list`、`project members`）→ pretty(2) JSON。
-   部分写面命令同样支持 `--json`（响应对象直出）：`app upload`、 `app upgrade-all`、`task webhook`、`task export`、`task batch`、 `apikey create`。

`--json` 不裁剪字段：后端返回什么就输出什么，消费方按 `--help` 示例里的 形状断言即可。

### 失败时的结构化错误（stderr）

`--json` 调用的失败输出同样是机器可读的**一行 JSON**（写 stderr，stdout 保持 纯净，`| jq` 不被污染）：

```json
{"ok":false,"scope":"Failed to fetch task","code":404,"errorCode":"TASK_NOT_FOUND","category":"not_found","params":{"taskId":"t1"},"message":"任务不存在","exitCode":1}
```

-   `code` = HTTP 状态，`errorCode` = admin-api 的稳定码，`params` = 文案插值参数；
-   `errorCode` / `category` / `params` **只在有值时出现**（未知码或无码时该键缺失， 用 `'errorCode' in payload` 判断最可靠）；
-   `category` ∈ `auth | permission | not_found | conflict | capacity | validation` —— 人类可读输出同样按这 6 类在原文案后追加一句话处置建议（`[CODE] — 建议`）； 未知码与无码**逐字节保持原输出**（透传后端文案）；
-   退出码不因 JSON 化改变（仍见上面的 Exit codes 表）。

## 认证与配置

凭据保存在用户配置目录（`acf config show` 查看实际路径），文件权限 0600； 文件损坏时 CLI 会把坏内容备份到 `<config>.corrupt`、给出 `acf login` 指引， 并用默认配置继续运行。

-   `ACF_TOKEN` / `ACF_REFRESH_TOKEN` / `ACF_API_URL`：环境变量注入（CI/cron 推荐，不落盘）；`--api-url` / `--token` 可单次覆盖。
-   `acf login` 的密码输入不回显；`--password` 参数已标记 deprecated（会进 shell history），CI 请用 `ACF_PASSWORD`。
-   已启用 TOTP（两步验证）的账号：`acf login` 会在密码后提示输入 6 位动态码； CI/非交互场景用 `acf login --user <name> --code <6位码>` 提供（stdin 非交互 且缺 `--code` 时会报可操作的用法错误，退出码 2）。
-   `acf apikey`（AUTH-03）：为 CI/CD 创建限权 API Key（`readonly` / `trigger` / `manage`）。明文（`acf_<64 hex>`）仅在 `acf apikey create` 时回显**一次**， 此后只能 `acf apikey list`（脱敏）/ `acf apikey revoke <id>`（撤销不可逆， 非交互场景加 `-y`）。
-   Access token 过期时自动用 refresh token 换发并重放一次；刷新失败才要求 重新登录（此时退出码为 3）。

## 应用部署（run-mode 语义，2026-10 实测修复）

-   `acf app deploy <appId>`：缺省 `-m scheduled` —— **仅部署、由中台/任务调度触发，部署后不自跑**（批处理/中台定时触发场景的正确模式，存量部署 11/12 用它）。三档语义：
    -   `once`：启动入口脚本一次，退出不重启；
    -   `daemon`：常驻进程——**部署时立刻启动入口脚本**，异常退出自动重启（退出码 0 不重启）；
    -   `scheduled`（别名 `deploy-only`）：只下发代码、**不启动进程**，由任务调度触发。
-   显式传 `once`/`daemon` 时，CLI 会在发请求前打黄色预警「将立刻启动入口脚本」——避免"部署即跑"与后续 `task trigger` 双跑、并发写同一产物目录。
-   部署列表：`acf app deployments [appId]`，或 `acf deploy list [appId]`（同源同契约，deploy 组下的可发现入口）。
-   版本发布追溯：`acf app releases <appId>`（DEP-01 统一视图：版本 × 最近部署——状态/次数/执行器/runMode/触发方式；`app versions` 是过渡期 legacy alias）。
-   清理遗留记录：`acf deploy remove <deploymentId> -y` —— 删除**已终结**的部署记录（failed/stopped）；在途/运行/待审批行服务端 409（先 `stop`，或走审批 `reject`/`cancel`）。

## 任务参数注入（params → AUTOFLOW\_\*）

`task create`/`update` 的 `body.params` 在每次执行时注入为 `AUTOFLOW_<KEY>` 环境变量（键名转大写）。**字符串按裸值注入**（`"nightly"` → `AUTOFLOW_TARGET=nightly`，直接读即可，不加引号）；数字/布尔/对象/数组为 JSON 字面量（`3`、`true`、`["a",1]`）。需要精确类型时另读 `AUTOFLOW_PARAMS_JSON`（整个参数的 JSON 对象，协议 v5 起注入）——逐键通道的值恒为字符串，无法区分字符串 `"true"` 与布尔 `true`（两执行器契约向量见 contract-fixtures 的 `executorEnvSerializationV2`）。

> ⚠️ 2026-10-02 ~ 10-14 期间发布的执行器（A-11）会把**字符串也加一对首尾双引号**（`AUTOFLOW_TARGET='"nightly"'`），空串变成 `'""'`（真值）。该行为已在协议 v5 修复——若目标执行器仍是旧版，脚本需容错剥离首尾引号。

-   **按 run 覆盖参数**：`acf task trigger <id> --params '{"KEY":"value"}'` 覆盖任务默认 params（TriggerTaskDto 同 webhook 面；缺省不发 body，用任务默认值）。block-strategy 闸（N-14）按生效参数判重。
-   **按名/描述搜任务**：`acf task list --search <kw>` 走 `q` 参数（name OR description，控制台搜索框同款）；`-k/--keyword` 仍只搜 name（向后兼容通道）。

## 应用包上传 / 灰度升级 / 审批 / webhook / glue

-   `acf app upload <pkg.zip> --name <name>`：multipart 上传应用包（按名称 upsert；`.zip` 扩展名/魔数/zip-bomb 校验在服务端）。`--runtime` / `--version` 可选；大包上传走独立 300s 超时预算。
-   `acf app upgrade-all <appId>`：对全部 RUNNING 部署触发滚动升级（缺省 = 全量， 既有语义）。`--strategy canary --percentage N`（int 1-100，缺省 50）走灰度： 首批心跳确认 → 健康探测 → 自动提升其余台。**批次由服务端异步推进，受理 ≠ 完成**——进度看 admin 中台（部署行 `rolloutState`）或 `acf app deployments`。
-   `acf approval list | approve <id> --note … | reject <id> | cancel <id>`： DEP-04 审批流。第二人规则在服务端强制（审批者 ≠ 提交者，否则 403）； 撤回自己的请求用 `cancel`；`--note`（≤200 字符）映射契约字段 `reason`。
-   `acf task webhook enable|rotate|disable|status <taskId>`：任务级入站 webhook （HMAC）。secret 仅在 enable/rotate 响应中回显**一次**；`status` 查看 URL 不动密钥；`disable` 后签名请求即刻 401。三个写面都会让**旧 secret 不可逆失效** （enable 对已启用任务等价轮换），非交互场景需 `-y`；`status` 是只读面，不加门。
-   `acf task glue <taskId> -f glue.js`（或 `--stdin`）：在线更新 GLUE 脚本。 语言按扩展名推断（`.js/.mjs/.cjs` → `javascript`），或 `--language python|javascript|shell` 显式指定（执行器运行时白名单）；空脚本本地即拒。

## 应用互斥组（MUTEX-01，2026-10 补齐 CLI 面）

同一组内的应用在**同一台设备上永不并发**（组内并发数默认 1 = 串行）——典型场景 是独占型资源：浏览器实例、单点登录账号（顶号）、GPU 槽位。后端 `mutex-groups` 四端点自 MUTEX-01 起就存在且中台在用，此前 CLI 零接入。

-   `acf mutex list`：拉取可选组（**与中台应用表单下拉同源**），列出 `id` / 名称 / 每设备并发 / 作用域 / 已挂应用数。挂应用时用这里的 `id`。
-   `acf mutex create --name <name> [--max-concurrent N] [--scope device|global] [--description <text>]` ：建组。`--max-concurrent` 取值 1-100（与后端 `@Min/@Max` 同界）； `--scope` 两档语义差别很大：
    -   `device`（默认）：**单机串行、跨设备并发**——每台设备上同时最多 N 条；
    -   `global`：**全平台串行**——整平台同时最多 N 条（单点登录顶号类场景）。
-   `acf mutex update <groupId> [--name] [--max-concurrent] [--scope] [--description]`： 改组。至少给一个字段（空 patch 本地即拒，退出码 2——服务端会「成功但什么都没改」， 容易被误读为已生效）。`--scope` 可即时收紧，在途 WAITING 执行由 sweep 重派自愈。
-   `acf mutex delete <groupId> [-f|--force] [-y|--yes]`：删组。组上仍挂应用时服务端 返回 409 并告知挂载数量；确认后用 `--force` 放行（挂载应用经 FK `SET NULL` 自动回到「不参与互斥」）。属破坏性操作，非交互场景必须显式 `-y`。
-   **把应用挂进组**（沿用既有 `app update`，字段此前未在帮助里列出）： `acf app update <appId> --body '{"mutexGroupId":"<acf mutex list 的 id>"}'`； 传 `null` 摘组。`acf app get <appId> --json` 可读出当前挂的组（表格视图不显示）。 组不存在时服务端 404（`assertMutexGroupExists` 前置校验）。
-   写面（create/update/delete）要求 **ADMIN** 角色；`list` 任意登录用户可读。

## 开发

```bash
npm run test        # vitest run
npm run typecheck   # tsc --noEmit
npm run build       # tsc → dist/
```

## 常见问题

### @autocodeflow/cli 是什么？

AutoCodeFlow CLI — 从终端管理任务、执行和应用程序

### 如何安装 @autocodeflow/cli？

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

### @autocodeflow/cli 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @autocodeflow/cli 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

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

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

### @autocodeflow/cli 可以商用吗？

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

### @autocodeflow/cli 的下载量有多少？

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

### @autocodeflow/cli 还在维护吗？

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

