# CLI 命令速查

按任务查找命令，区分原生包登记、更新打包和投放发布。

先看[首次发布](/docs/publish)完成一次更新，再按本页查命令。所有命令在应用根目录执行；带反斜杠续行的示例用于 Bash / zsh，PowerShell 请合并为单行。

## 安装 {#install}

```bash
npm install -g rn-update-cli
```

安装完成后通过 `pakta <命令>` 直接调用。要求 Node.js ≥18.17。登录与首次配置见[发布更新](/docs/publish#setup)。

## 命令速查 {#commands}

| 用途 | 命令 |
| --- | --- |
| 账号 | `login`、`logout`、`me` |
| 应用 | `createApp`、`apps`、`selectApp`、`deleteApp` |
| 渠道 | `channels`、`createChannel`、`updateChannel`、`deleteChannel` |
| 原生包 | `uploadApk`、`uploadAab`、`uploadIpa`、`uploadApp`、`packages`、`deletePackage` |
| 解析 | `parseApk`、`parseAab`、`parseIpa`、`parseApp`、`extractApk` |
| OTA | `bundle`、`publish`、`versions`、`update`、`updateVersionInfo`、`deleteVersion` |
| 差分 | `hdiff`、`hdiffFromApk`、`hdiffFromIpa`、`hdiffFromApp`、`registerPdiff` |
| 诊断 | `symbolicate`、`cache`、`cache clean` |

`pakta list` 输出全部命令。下方使用 cli.json 中的规范参数名（例如 entryFile、hermesBase），避免依赖别名。

## bundle {#bundle}

生成 `.ppk` 更新包（只含 JS bundle 与资源）：

```bash
pakta bundle --platform android --output .pakta/output/android.ppk --no-interactive
```

常用选项：

- `--platform ios|android|harmony` — 目标平台。
- `--output` — `.ppk` 输出路径；建议固定路径，避免时间戳文件名。
- `--entryFile` — 入口脚本（默认 index.js；Expo 由工程推断）。
- `--dev true` — 打开发调试包。
- `--sourcemap` / 默认生成 — Hermes 工程自动合成最终映射。
- `--hermesBase auto|none|<路径>` — Hermes 基线策略；`auto` 复用历史基线以缩小补丁，`none` 关闭，也可传 `.hbc/.ppk/.apk/.ipa` 显式指定。
- `--expo` — Expo 工程打包。
- `--name` — 携带时打包后直接进入发布流程。

## publish {#publish}

```bash
pakta publish <ppk路径> \
  --platform android --name fix-001 \
  --channel default --packageVersion 1.0.0 --rollout 10 \
  --sourcemap .pakta/intermedia/android/index.bundlejs.map
```

- 目标三选一：`--targets targets.json`（多渠道）、`--packageId`（按原生包 ID 解析目标）、或 `--channel + --packageVersion`（单目标）。
- `--rollout` 省略为 100%；`targets.json` 中逐行 `rollout` 优先于全局值。
- `--dryRun` 预检：解析目标与比例，不写任何数据。
- `--deploymentIds id1,id2`：失败后按准确投放 ID 重试。
- `--sourcemap`：归档 sourcemap，供 `symbolicate` 还原堆栈。

发布产物是两个独立对象：登记时的**安装包中用于更新的文件**与本次上传的 **`.ppk`**；完整商店包不会被原样上传。发布成功后，平台在事务中为该渠道 × 原生版本组的每个精确构建创建差分任务，任务完成前 `checkUpdate` 自动回退全量包。

## 版本与差分 {#versions-diff}

```bash
pakta versions                     # 版本列表
```

本地 `hdiff`/`hdiffFromApk`/`hdiffFromIpa`/`hdiffFromApp` 只生成补丁文件；要把补丁挂到精确的原生构建上，需再通过 `registerPdiff` 登记（按 `deploymentId + nativeVersionId` 精确绑定，不会错发给同版本的其他构建）。

## 诊断 {#diagnostics}

```bash
pakta symbolicate stack.txt --platform android --hash <UPDATE_HASH>
```

`hash` 来自 SDK 的 `getUpdateMetadata().currentVersion`，也可用 `--versionId`；堆栈可从 stdin 读入（`-`）。`cache clean` 清理本地 Hermes 基线缓存。

## 环境变量 {#env-vars}

| 变量 | 用途 |
| --- | --- |
| `RNU_SERVICE_URL` | 自托管服务地址（自动补 `/admin/api/v1`） |
| `PAKTA_API_TOKEN` | CI 个人访问令牌，见 [API Key](/docs/api-token) |
| `NO_INTERACTIVE=true` | 关闭全部交互 |
| `RNU_LANG` | `zh`（默认）或 `en` |
| `RNU_DEBUG=1` | 输出错误堆栈 |
| `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` | 代理设置（支持小写） |
| `PAKTA_CACHE_DIR` | Hermes 基线缓存目录 |
| `PAKTA_HERMES_PROBE_TIMEOUT_MS` 等三个 | Hermes 探测/校验/编译期限（毫秒） |
| `RNU_AUTO_UPDATE=0` | 关闭 CLI 后台自动更新 |

## 编程接口 {#provider-api}

构建脚本可以不走命令行，直接使用导出的 Provider：

```typescript
import { CLIProviderImpl } from 'rn-update-cli';

const provider = new CLIProviderImpl();
const bundle = await provider.bundle({
  platform: 'android',
  output: '.pakta/output/android.ppk',
  sourcemap: true,
});
if (!bundle.success) throw new Error(bundle.error);

const release = await provider.publish({
  filePath: '.pakta/output/android.ppk',
  sourcemap: '.pakta/intermedia/android/index.bundlejs.map',
  platform: 'android',
  name: 'fix-001',
  targets: 'targets.json',
});
if (!release.success) throw new Error(release.error);
```

返回 `CommandResult`，消费 `data` 前先检查 `success`。

## 容易混淆的 ID {#identifiers}

`publish --packageId` 输入的是原生包 ID，用于解析目标；发布结果的 `packageId` 则是更新包 ID。不要把结果 ID 原样塞回该选项。多目标优先用 `targets.json`，失败续传使用返回的 `deploymentIds`。
