npm package: @sheason/struggle-cli
Description: Struggle AI CLI
Latest version: 0.1.3

# @sheason/struggle-cli

`struggle-cli` 是 Struggle AI 的终端命令行工具。通过 ACP over stdio 连接已配置的 ACP agent，并在终端内展示 agent 面板。

## 前置要求

- Node.js >= 22
- 已启用 Corepack，并使用仓库声明的 `pnpm@10`

## 常用命令

在仓库根目录执行：

```bash
pnpm --dir apps/struggle-cli build
node ./apps/struggle-cli/dist/index.js --help
node ./apps/struggle-cli/dist/index.js new --help
node ./apps/struggle-cli/dist/index.js load --help
```

## npm 安装

发布到 npm 后，可直接安装并使用：

```bash
npm install -g @sheason/struggle-cli
struggle --help
```

也可以临时执行：

```bash
npx @sheason/struggle-cli --help
```

## npm 发布流程

### 1. 发布前检查

在仓库根目录执行：

```bash
pnpm --dir apps/struggle-cli run release:preflight
```

该步骤会依次执行：

1. `test`
2. `build`
3. `npm pack --dry-run`（校验最终发布包内容）

### 2. 更新版本号

在仓库根目录执行其中一个命令：

```bash
pnpm --dir apps/struggle-cli run release:version:patch
pnpm --dir apps/struggle-cli run release:version:minor
pnpm --dir apps/struggle-cli run release:version:major
```

### 3. 发布到 npm

先确认登录状态：

```bash
npm whoami
```

然后发布：

```bash
pnpm --dir apps/struggle-cli run release:publish
```

发布成功后可验证：

```bash
npm view @sheason/struggle-cli version
```

如果希望在 monorepo 根目录触发，可使用快捷命令：

```bash
pnpm run release:cli:preflight
pnpm run release:cli:publish
```

## `struggle new` / `struggle load`

面板功能已拆分为两个独立命令：

- `struggle new` — 启动新的 ACP 面板会话
- `struggle load` — 加载已有的 ACP 面板会话

### `struggle new`

启动新的 ACP 面板会话：

1. 解析全局 / 项目配置中的 ACP agent 列表
2. 按 `--agent <name>`、`defaultAgent`、交互式选择的顺序决定本次使用的 agent
3. 启动所选 ACP agent 子进程
4. 通过 JSON-RPC over stdio 完成 `initialize`
5. 创建新会话并在终端中显示 agent 文本输出与工具状态

```bash
node ./apps/struggle-cli/dist/index.js new
node ./apps/struggle-cli/dist/index.js new --agent claude
node ./apps/struggle-cli/dist/index.js new --help
```

### `struggle load`

加载已有的 ACP 面板会话：

1. 根据会话名称查找历史记录
2. 从会话记录中恢复 agent 配置
3. 通过 `session/load` 恢复该会话
4. 在终端中显示 agent 文本输出与工具状态

```bash
node ./apps/struggle-cli/dist/index.js load                      # 列出当前工作目录的会话历史
node ./apps/struggle-cli/dist/index.js load <name>               # 恢复指定会话
node ./apps/struggle-cli/dist/index.js load --help
```

## 配置文件

`struggle-cli` 会同时读取以下两个配置文件：

- 全局配置：`~/.struggle/struggle-cli.yaml`
- 项目配置：`<project-root>/.struggle/struggle-cli.yaml`

其中 `<project-root>` 优先取当前工作目录所在 Git 仓库根目录；如果当前目录不在 Git 仓库内，则回退为当前工作目录。因此项目配置的典型相对路径就是：

```text
.struggle/struggle-cli.yaml
```

当前实现会合并全局配置与项目配置；若同名字段同时存在，则全局配置优先。

示例：

```yaml
defaultAgent: claude
agents:
  aiden:
    command: aiden
    args:
      - acp
  claude:
    command: claude
    args:
      - agent
      - serve
    cwd: /absolute/path/to/agent
    env:
      ANTHROPIC_API_KEY: your-key
```

说明：

- `defaultAgent` 必须指向一个已配置的 agent 名称
- `agents.<name>.command` 为必填项
- `agents.<name>.env` 用于给该 agent 追加环境变量
- `agents.<name>.cwd` 如果提供，必须是绝对路径

## 添加 ACP agent

新增一个 ACP agent 的方式就是在 `struggle-cli.yaml` 的 `agents` 下增加一个名字，并为它配置启动参数。

最小可用配置示例：

```yaml
agents:
  aiden:
    command: aiden
    args:
      - acp
```

如果需要补充工作目录或环境变量，可以继续写：

```yaml
defaultAgent: claude
agents:
  claude:
    command: claude
    args:
      - agent
      - serve
    cwd: /absolute/path/to/agent
    env:
      ANTHROPIC_API_KEY: your-key
```

推荐步骤：

1. 选择配置位置：
   - 想让所有项目都能用，写到 `~/.struggle/struggle-cli.yaml`
   - 只想在当前项目使用，写到 `<project-root>/.struggle/struggle-cli.yaml`
2. 在 `agents` 下新增一个唯一名字，例如 `aiden`、`claude`、`my-agent`
3. 填写该 agent 的 `command`
4. 按需填写 `args`、`env`、`cwd`
5. 如果希望它成为默认选择，再设置 `defaultAgent: <name>`
6. 运行以下命令验证：

```bash
node ./apps/struggle-cli/dist/index.js panel --agent <name>
```

字段含义：

- `command`：启动 ACP agent 的可执行命令
- `args`：传给该命令的参数列表，会按原样透传
- `env`：仅追加到该 agent 进程的环境变量
- `cwd`：该 agent 的启动目录，必须是绝对路径

## `--agent <name>` 用法

在 `struggle new` 中可通过 `--agent <name>` 显式指定本次启动要连接的 ACP agent：

```bash
node ./apps/struggle-cli/dist/index.js new --agent aiden
node ./apps/struggle-cli/dist/index.js new --agent claude
```

选择顺序如下：

1. 如果传入 `--agent <name>`，优先使用该 agent
2. 否则如果配置了 `defaultAgent`，使用默认 agent
3. 否则进入交互式选择

如果传入的 `--agent <name>` 未配置，CLI 会提示该名称不存在，并回退到交互式选择。

## 无 TTY 场景

当满足以下条件时：

- 没有传入 `--agent <name>`
- 配置中也没有 `defaultAgent`
- 当前 stdin / stdout 不是 TTY

CLI 无法进入交互式选择，会直接报错并退出：

```text
Interactive agent selection requires a TTY. Use --agent <name> or configure defaultAgent.
```

因此在 CI、管道或其他非交互环境中，请始终显式传入 `--agent <name>`，或在配置文件中设置 `defaultAgent`。

## 已移除的命令与环境变量

- `struggle panel` 已移除，请改用 `struggle new`（新建会话）或 `struggle load`（加载会话）
- 旧环境变量 `STRUGGLE_AIDEN_ACP_COMMAND` 已移除，不再用于覆盖 ACP 启动命令。请改为在 `~/.struggle/struggle-cli.yaml` 或 `.struggle/struggle-cli.yaml` 中配置 `agents`

## 权限策略

当前权限策略固定为：

- `read` / `search`：自动放行
- `write` / `execute` 以及其他高风险工具：需要用户确认

## 会话与本地状态目录

默认本地状态目录写入：

```text
~/.struggle/struggle-cli/
```

如需在测试或特殊运行环境中覆盖该目录，可设置：

```text
STRUGGLE_CLI_SESSION_BASE_DIR=/custom/session/base/dir
```

会话可通过 `struggle load` 查看历史记录，使用 `struggle load <name>` 恢复指定会话。

## 本地验证

运行指定集成测试：

```bash
pnpm --dir apps/struggle-cli exec vitest run src/integration/panel.integration.test.ts --reporter=verbose
```

运行全部测试：

```bash
pnpm --dir apps/struggle-cli test
```

验证构建产物包含 fake ACP agent：

```bash
pnpm --dir apps/struggle-cli build
test -f ./apps/struggle-cli/dist/testing/fake-acp-agent.js
```