oy-code-cli 0.5.2

CLI entry point for oy
Documentation
<div align="center">
<h1>OY</h1>
<h3>AI 智能体工作区(CLI + TUI)</h3>
<p>
  <a href="https://github.com/cherish-ltt/oy/actions/workflows/rust-ci.yml">
    <img src="https://img.shields.io/github/actions/workflow/status/cherish-ltt/oy/rust-ci.yml?branch=main" alt="Build Status"/>
  </a>
  <a href="https://github.com/cherish-ltt/u2secure/blob/main/LICENSE">
    <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license"/>
  </a>
  <a href="https://www.rust-lang.org">
    <img src="https://img.shields.io/badge/rust-1.95.0+-orange.svg" alt="license"/>
  </a>
</p>
</div>



> 🚀 一个 Rust 工作区,实现了基于 OpenRouter / 兼容 API 的函数调用 AI 智能体,提供 Read/Write/Edit/Bash 四类工具。基于**领域驱动设计****洋葱架构**原则,构建在四个隔离的 crate 之上。



## 架构

```
oy (CLI 入口, 默认启动 TUI)  ────
                               ├──► oy-agent (编排) ──► oy-ai (AI 提供者抽象)
oy (oy -p "prompt" 直接执行) ────
```

| Crate || 描述 |
| :--- | :--- | :--- |
| [`oy-ai`]./oy-ai/ | 核心 | AI 提供者 trait、值对象(ChatMessage、ToolCall)、OpenRouter 实现 |
| [`oy-agent`]./oy-agent/ | 领域 | Agent 实体、Tool trait、编排器循环、工具实现(Read/Write/Edit/Bash)、会话持久化 |
| [`oy-code-cli`]./oy-code-cli/ | 基础设施 | CLI 参数解析(clap)、二进制入口 `oy` |
| [`oy-tui`]./oy-tui/ | 基础设施 | 基于 ratatui 的 TUI shell,markdown 渲染、命令系统、主题切换 |

### 依赖方向

- `oy-code-cli``oy-agent``oy-ai`
- `oy-tui``oy-agent``oy-ai`
- `oy-code-cli``oy-tui`(无 prompt 时启动 TUI)

## 快速开始

### 前置条件

- Rust 1.85+(`rust-toolchain.toml` 自动配置)
- 一个 OpenRouter 或兼容的 API 密钥

### 配置

`~/.oy-ai-agent/config.toml`:

```toml
api_key = "sk-or-..."
base_url = "https://openrouter.ai/api/v1"
model = "anthropic/claude-haiku-4.5"
theme = "light"          # "light" 或 "dark"
```

也可通过环境变量设置:

```bash
export OPENROUTER_API_KEY="sk-or-..."
export OPENROUTER_BASE_URL="https://openrouter.ai/api/v1"
export OPENROUTER_MODEL="anthropic/claude-haiku-4.5"
```

### 安装与运行

```bash
# 从 crates.io 安装
cargo install oy-code-cli

# 启动 TUI(默认)
oy

# 或直接使用 CLI 模式
oy -p "当前目录下有哪些文件?"
```

### 本地开发

```bash
# 构建
cargo build --workspace

# 启动 TUI
cargo run -p oy-code-cli

# 测试
cargo test --workspace
```

## TUI 功能

### 命令系统

在输入框输入 `/` 弹出命令选择器:

| 命令 | 功能 |
|------|------|
| `/model` | 三步表单设置 API Base URL / API Key / Model,保存 config,重启 agent 且保留会话消息 |
| `/settings``/theme` | 切换 light / dark 主题,持久化到 config.toml |

快捷键:`↑`/`↓` 导航选择器,`Enter` 确认,`Esc` 取消,`Ctrl+O` 展开/折叠工具结果。

### Markdown 渲染

AI 回复内容以 Markdown 格式渲染,支持:

| 语法 | 显示 |
|------|------|
| `**bold**` | 加粗 |
| `*italic*` | 斜体 |
| `` `code` `` | 黑底青字 |
| ` ``` ` 代码块 | 独立段落,代码高亮 |
| `# Heading` | 标题 |
| `- list` | 列表 |
| `> quote` | 引用块 |
| `---` | 分割线 |

### 工具调用 & 结果显示

- 每个工具调用显示为 `🔧 工具调用 · Read`,含实时计时器
- 结果返回后合并显示在调用下方,带用时时长 `✓ (0.5s)`
- Read 结果折叠至前 5 行,Bash 结果折叠至后 5 行
- `Ctrl+O` 展开全部内容

### 主题

内置 light / dark 双主题:
- **light**:白底,消息气泡淡蓝/淡绿/淡紫
- **dark**:黑底,消息气泡深蓝/深绿/深紫

通过 `/settings` → `/theme` 切换,设置持久化到 config.toml。

### 消息背景色

每条消息独立背景色,整行填充:

| 消息类型 | Light 主题 | Dark 主题 |
|---------|-----------|----------|
| User | `Rgb(235,240,255)` 浅蓝 | `Rgb(25,30,50)` 深蓝 |
| Assistant | `Rgb(235,255,235)` 浅绿 | `Rgb(20,30,20)` 深绿 |
| Tool | `Rgb(255,235,255)` 浅紫 | `Rgb(40,20,40)` 深紫 |

### Agent 状态指示器

状态栏显示 agent 运行状态:`•` 空闲,`⠋⠙⠹…` 旋转动画表示工作中。

## 可用工具

| 工具 | 功能 | 输入 |
|------|------|------|
| **Read** | 读取文件内容 | `file_path` |
| **Write** | 创建或覆盖文件 | `file_path`, `content` |
| **Edit** | 精确替换文件中的文本段 | `file_path`, `old_text`, `new_text` |
| **Bash** | 通过 `sh -c` 执行命令 | `command`(含命令黑名单) |

## 项目结构

```
oy/
├── Cargo.toml                     # 工作区
├── oy-ai/                         # AI 提供者抽象
│   └── src/
│       ├── domain/ (AiProvider trait, ChatMessage, ToolCall, AiConfig, AiError)
│       └── infrastructure/ (OpenRouter 实现)
├── oy-agent/                      # 智能体编排
│   ├── tests/integration_test.rs  # MockProvider 集成测试
│   └── src/
│       ├── domain/ (Agent trait, Tool trait, ToolRegistry, AgentError)
│       ├── application/ (Orchestrator 主循环)
│       └── infrastructure/ (ReadTool, WriteTool, EditTool, BashTool, 持久化)
├── oy-code-cli/                   # CLI 二进制 `oy`
│   └── src/ (CliArgs, run())
└── oy-tui/                        # TUI 二进制
    └── src/
        ├── app.rs                 # 应用状态、事件循环、键盘处理、命令执行
        ├── ui.rs                  # ratatui 渲染(消息区、输入框、状态栏、弹出框)
        ├── message.rs             # Message 枚举、to_lines() MD 渲染、visual_line_count
        ├── command.rs             # 命令注册器、CommandInfo、CommandItem
        ├── event.rs               # 事件循环(tick、crossterm、agent 信号)
        ├── load_config.rs         # config.toml 加载/保存
        ├── theme.rs               # Theme 结构体、DARK_THEME / LIGHT_THEME
        ├── agent.rs               # AgentManager
        └── main.rs                # 入口
```

## 测试

```
cargo test --workspace     # 116 个测试
```

| 测试套件 | 位置 | 测试数 |
|---------|------|--------|
| oy-ai 单元 | `oy-ai/src/domain/` | 23 |
| oy-agent 单元 + 工具 | `oy-agent/src/` | 58 |
| oy-agent 集成 | `oy-agent/tests/` | 5 |
| oy-tui 单元 | `oy-tui/src/` | 30 |

## 会话持久化

对话历史自动保存到 `~/.oy-ai-agent/sessions/<项目路径>/<uuidv7>.json`。切换模型时(`/model` 命令),旧 agent 的上下文通过 `oneshot` channel 提取,注入到新 agent,确保会话不丢失。

## 许可证

MIT

---

<div align="center">
  <sub>Built with ❤️ by the OY team</sub>
</div>