Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 48 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

# Coding Code

**手写 ReAct Loop · 零框架依赖 · 多端统一 · 深度可配置**
**手写 ReAct Loop · 零框架依赖**

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/)

终端原生的 AI 编程助手。核心引擎纯手写 ReAct 循环,通过 HTTP 服务化对外暴露,Desktop / SDK 等所有端共享同一份编排逻辑。没有黑盒,所有行为都可定制。
面向终端的 AI 编程助手。核心引擎纯手写 ReAct 循环,不依赖任何 Agent 框架。没有黑盒,所有行为都可定制。

</div>

Expand All @@ -15,12 +15,14 @@
## 核心特性

- 🔄 **手写 ReAct 循环** — 不依赖外部 Agent 框架,完全可控的 Agent 引擎
- 🌐 **HTTP 服务化** — Agent 作为独立 HTTP 服务运行,任何端平等接入
- 🔧 **深度可配置** — 子智能体、工具、提示词、钩子、模型全部可定制
- 🛡️ **审批流水线** — 六层决策链 + 预设安全规则,开箱即用
- 🤖 **多子智能体后台委派** — 父智能体通过 `spawn_agent` 派生子会话,立即返回、继续并行工作;`wait_agent` 只在结果阻塞下一步时等待
- 📬 **会话级 Mailbox** — 子智能体终态异步回注父会话,在回合边界统一吸收,不打断当前推理
- 🎛️ **完整回合状态机** — 状态轴(running / complete / interrupt / error)与终态原因分离,出生登记、相位转移、幂等终结、级联停止全部显式管理
- 🛡️ **审批流水线** — 五层决策链,规则引擎 + 权限模式 + 钩子 + 用户确认 + 审计
- 🧠 **长期记忆** — 跨会话自动提取和加载用户/项目上下文
- 🔌 **MCP 集成** — 通过 Model Context Protocol 扩展工具能力
- 📡 **实时流式** — SSE 推送,多端同步响应
- 🪝 **可插拔钩子** — 12 个钩子点,在工具执行、回合生命周期、子智能体派发等关键节点注入自定义逻辑
- 🎯 **技能系统** — 可复用的 Markdown 技能包,按需加载
- 💾 **Checkpoint** — Shadow Git 变更跟踪与一键回滚

---
Expand All @@ -30,7 +32,7 @@
### 前置要求

- Node.js >= 18
- 一个 LLM API Key(支持 DeepSeek、OpenAI、Gemini 等厂商)
- 一个 LLM API Key

### 安装与启动

Expand All @@ -47,7 +49,7 @@ export DEEPSEEK_API_KEY=sk-xxx
pnpm start
```

启动成功后,HTTP server 开始监听并打印 `CODINGCODE_SERVER_READY:<port>`,可用 Desktop 或 SDK 接入。
启动成功后,HTTP server 开始监听并打印 `CODINGCODE_SERVER_READY:<port>`。

### SDK 调用示例

Expand All @@ -71,85 +73,75 @@ for await (const frame of clients.agent.sendMessage('帮我写一个快排', {

```
┌──────────────────────────────────────────────────────────┐
│ 客户端层 │
│ 客户端层 │
│ @codingcode/desktop (Electron) │
│ @codingcode/sdk(AgentClient 契约 + HTTP/SSE 实现) │
│ @codingcode/sdk(契约 + HTTP/SSE 实现) │
└──────────────────────────┬───────────────────────────────┘
│ HTTP / SSE(AgentClient 接口)
│ HTTP / SSE
┌──────────────────────────┴───────────────────────────────┐
│ 核心引擎层 │
│ @codingcode/core │
│ ReAct Loop · 工具 · MCP · 上下文 · 记忆 · Checkpoint │
│ 钩子 · 子智能体 · 技能 · 审批 · 会话 · 调度 │
│ 钩子 · 子智能体 · 技能 · 审批 · 会话 · 回合 · 调度 │
│ 模型清单 · 应用配置 · YAML 存取 · 日志 · 共享类型 │
└──────────────────────────────────────────────────────────┘
```

**设计原则**:Agent 是纯 ReAct 循环,不持有 Session、不感知传输协议。所有端通过统一的 `AgentClient` 接口接入,共享同一份编排逻辑。Effect TS 托管依赖注入,编译期强制处理错误。
**设计原则**:Agent 是纯 ReAct 循环,不持有 Session、不感知传输协议。核心作为独立 HTTP 服务运行,帧流经 SSE 推送。Effect TS 托管依赖注入,编译期强制处理错误。

---

## 配置

所有行为都可配置。核心配置文件:

| 配置文件 | 作用 | 详见 |
|---------|------|------|
| `config/models.json` | 模型厂商、模型列表、API 地址 | [→ configuration.md](docs/configuration.md) |
| `codingcode.yaml` | 应用级配置(并发数、超时等) | [→ configuration.md](docs/configuration.md) |
| `~/.codingcode/rules.md` + `./AGENTS.md` | 全局 + 项目级规则,注入 system prompt | [→ configuration.md](docs/configuration.md) |
| `mcp.yaml` (可选) | MCP 服务配置 | [→ mcp.md](docs/mcp.md) |

快速配置模型(`config/models.json`):

```json
{
"providers": [{
"name": "deepseek",
"driver": "deepseek",
"base_url": "https://api.deepseek.com",
"api_key_env": "DEEPSEEK_API_KEY",
"default_model": "deepseek-v4-flash",
"models": [
{ "id": "deepseek-v4-flash", "name": "DeepSeek V4 Flash", "context_window": 1048576, "max_output_tokens": 384000 }
]
}]
}
```
用户可配置项:

| 配置文件 | 位置 | 作用 | 详见 |
|---------|------|------|------|
| `config.yaml` | `~/.codingcode/config.yaml` | 应用级配置(步数、权限模式、记忆、子智能体并发等) | [→ configuration.md](docs/configuration.md) |
| `rules.md` | `~/.codingcode/rules.md` | 全局规则,注入 system prompt | [→ configuration.md](docs/configuration.md) |
| `AGENTS.md` | `./AGENTS.md` | 项目级规则,注入 system prompt | [→ configuration.md](docs/configuration.md) |
| `mcp.yaml` | `~/.codingcode/mcp.yaml` + `.codingcode/mcp.yaml` | MCP 服务配置 | [→ mcp.md](docs/mcp.md) |
| `hooks.yaml` | `~/.codingcode/hooks.yaml` + `.codingcode/hooks.yaml` | 钩子配置 | [→ hooks.md](docs/hooks.md) |
| `memory.md` | `./.codingcode/memory.md` | 长期记忆(项目级) | [→ memory.md](docs/memory.md) |

应用级配置示例(`~/.codingcode/config.yaml`):

`driver` 支持 `"deepseek"`(原生 SDK)、`"openai"`(OpenAI 兼容 API)和 `"gemini"`(Google Gemini)。运行时可在客户端中切换模型。
```yaml
maxSteps: 200 # Agent 最大步数
maxStopContinuations: 2 # 最大停止续行次数
activeProfile: build # agent 模式
permissionMode: askBeforeExec # 权限模式

context:
compactionModel: "" # 压缩用模型,空字符串回退主模型

memory:
enabled: false # 启用长期记忆
model: "" # 记忆提取模型,空字符串回退主模型
promptMaxBytes: 8192 # 注入提示的记忆内容最大字节数

subagent:
maxBackground: 4 # 单父会话并发子智能体上限
```

---

## 功能导航

| 功能 | 说明 | 文档 |
|------|------|------|
| 🛠️ 工具系统 | 内置文件/命令/网络工具 + 自定义工具注册 + 审批流水线 | [→ tools.md](docs/tools.md) |
| 🛠️ 工具系统 | 内置文件/命令/网络工具 + 审批流水线 | [→ tools.md](docs/tools.md) |
| 🤖 子智能体 | 后台派生独立 ReAct 会话,结果经 mailbox 回注 | [→ subagent.md](docs/subagent.md) |
| 🎛️ 回合状态机 | 会话状态登记、相位转移与生命周期管理 | [→ turn.md](docs/turn.md) |
| 🧠 长期记忆 | 跨会话自动提取用户偏好、项目上下文,支持手动编辑 | [→ memory.md](docs/memory.md) |
| 🔌 MCP 集成 | 通过 Model Context Protocol 连接外部工具服务 | [→ mcp.md](docs/mcp.md) |
| 💾 Checkpoint | Shadow Git 变更跟踪、Diff 视图、一键回滚 | [→ checkpoint.md](docs/checkpoint.md) |
| 🪝 钩子系统 | 18 个可插拔钩子点,在关键节点注入自定义逻辑 | [→ hooks.md](docs/hooks.md) |
| 🤖 子智能体 | 独立 ReAct 实例,受限工具集,可并行委派任务 | [→ subagent.md](docs/subagent.md) |
| 🪝 钩子系统 | 12 个可插拔钩子点,在关键节点注入自定义逻辑 | [→ hooks.md](docs/hooks.md) |
| 📦 上下文压缩 | 超预算自动压缩,截断/总结两种策略 | [→ context.md](docs/context.md) |
| 🎯 技能系统 | 可插拔的 Markdown 技能包,扩展 Agent 能力 | [→ skills.md](docs/skills.md) |

---

## 工作流

```
用户输入 → System Prompt(角色 + 规则 + 记忆 + 技能)→ LLM 调用 → ReAct Loop
├── Tool Call → Approval → Execution → Hook
├── Subagent Delegation(可选,并行)
└── Context Compression(自动触发)
→ SSE 流式响应 → 会话持久化 → Checkpoint → Memory 提取
```

每个环节都可配置,没有黑盒。

---

## 技术栈

| 关注点 | 选型 |
Expand Down
92 changes: 43 additions & 49 deletions docs/checkpoint.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
# Checkpoint 系统

Coding Code 记录所有文件变更,支持查看历史和回滚。本文档介绍 Shadow Git、Ledger、Diff 视图和回滚功能。
Coding Code 记录所有文件变更,支持查看历史和回滚。本文档介绍 Shadow Git、Diff 视图和回滚功能。

---

## 工作原理

Checkpoint 系统基于 Shadow Git 实现——一个独立于用户 `.git` 的变更日志系统:

- **存储位置**:`~/.codingcode/project/{encodedProjectPath}/checkpoint/repo.git`
- **隔离机制**:使用 `--git-dir` 和 `--work-tree` 分离,不影响用户仓库
- **大小上限**:1024 MB
- **文件锁**:`repo.lock` 防止并发写入
- **存储位置**:项目的 checkpoint 数据目录下(`projectDataDir` 派生)
- **大小上限**:`SIZE_CAP_MB = 1024`(超过则不继续跟踪)
- **文件锁**:项目锁(`project-lock.ts`)防止并发写入

### 忽略规则

以下目录和文件不会被跟踪:
以下目录和文件不会被跟踪(写入 shadow repo 的 `exclude`):

- `node_modules/`、`.venv/`、`dist/`、`build/`
- `*.log`、`.env`、`.DS_Store`

### 提交格式

Shadow Git 的提交消息格式为:

- `turn-{shortSid}-{turnId}-baseline`:轮次开始前的快照
- `turn-{shortSid}-{turnId}-final`:轮次结束后的快照
```
node_modules/ .venv/ venv/ dist/ build/
*.log .env .env.* *.tmp *.temp
.DS_Store Thumbs.db
```

---

Expand Down Expand Up @@ -71,51 +67,49 @@ interface CheckpointDiff {
| `/api/sessions/:id/rollback-context` | POST | `{ cwd, throughTurnId }` | 上下文回退到指定 turn |
| `/api/sessions/:id/rollback-both-to-turn` | POST | `{ cwd, throughTurnId }` | 代码 + 上下文同时回滚 |

### 撤销回滚

| 路由 | 方法 | Body | 说明 |
|------|------|------|------|
| `/api/sessions/:id/undo-code-rollback` | POST | `{ cwd, force?, files? }` | 撤销上次代码回滚 |
| `/api/sessions/:id/rollback-state` | GET | - | 获取当前回退状态 |
回滚到指定轮次需要一次预览确认:`rollback-preview` 返回 `RollbackPreviewDiff`,其中列出受影响的 turn 与 diff。

---

## Ledger 数据结构

每次回滚操作记录为 `CodeRestoreEntry`:
## 数据结构

```typescript
interface CodeRestoreEntry {
id: string; // 唯一标识
sessionId: string; // 会话 ID
action: 'checkpoint-files' | 'rollback-to-turn'; // 操作类型
throughTurnId: number; // 回退到的轮次
affectedTurns: number[]; // 受影响的轮次列表
selectedFiles: string[]; // 受影响的文件列表
safetyCommit: string; // 安全提交的 SHA
timestamp: string; // 操作时间
interface CodeRollbackResult {
reverted: boolean;
throughTurnId: number;
affectedTurns: number[];
selectedFiles: string[];
}
```

存储位置:`{gitDir}/../last-restore-{shortSid}.json`

---
interface RollbackPreviewDiff {
throughTurnId: number;
affectedTurns: number[];
diff: string;
}

## 回退状态查询
interface RestorePlan {
throughTurnId: number;
affectedTurns: number[];
baseline: string;
}
```

通过 `GET /api/sessions/:id/rollback-state` 获取当前回退状态:
上下文回退在会话 transcript 中记录为 `RollbackEvent`:

```typescript
interface RollbackState {
context: {
active: boolean;
currentThroughTurnId: number | null;
};
code: {
canUndoLast: boolean;
lastEntry: CodeRestoreEntry | null;
revertedFiles: string[];
lastEntryId: string | null;
};
interface RollbackEvent {
type: 'rollback';
throughTurnId: number;
reason: string;
}
```

---

## Session Fork

从某个历史 turn 分叉出新会话:

| 路由 | 方法 | Body | 说明 |
|------|------|------|------|
| `/api/sessions/:id/fork` | POST | `{ cwd, atTurnId? }` | 复制到指定 turn 为止的会话历史,生成新会话 |
Loading
Loading