Skip to content

Commit 882ce6b

Browse files
authored
feat: support opencode auto-loop plugin preset (#175)
* feat: support opencode auto-loop plugin preset * docs: add agent loop plugin survey * refactor: switch workspace setup to projects model * feat: add loop-aware workspace template * feat: add install-only setup mode * feat: add install-only setup flows * docs: update setup workspace loop docs * refactor: normalize setup mode prompt * fix: default install-only updates to upgrade * ci: rerun checks * ci: rerun after workspace fixes * test: cover workspace template variants * fix: package workspace templates and loop assets
1 parent 6d95fc4 commit 882ce6b

58 files changed

Lines changed: 2559 additions & 454 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
3030
- `chattool setup codex` / `chattool setup opencode` 现在默认优先读取保存的 typed env 配置,再回退到 shell 环境变量;显式 `-e/--env` 仍然拥有更高优先级,避免交互默认值被临时环境变量意外抢占
3131

3232
### Added
33-
- `chattool setup workspace` 现在会把“任务未完成前不要阶段性邀请 review;默认完整做完后再统一汇报结果”写入新生成的 workspace 协议;开发任务还会明确要求每个阶段先测试通过、更新文档并自行 review
34-
- `chattool setup workspace` 现在区分新建与已有 workspace:新目录直接生成 `AGENTS.md` / `MEMORY.md` / `setup.md`,已有 workspace 则额外生成 `AGENTS.generated.md``MEMORY.generated.md` 与迁移版 `setup.md`,便于模型完成协议迁移后再删除辅助文件
33+
- `chattool setup opencode` 新增 `--plugin auto-loop`,可在写入 OpenCode 基础 provider/model 配置时同步把 `opencode-auto-loop` 追加到 `plugin` 数组,方便直接启用现成 auto-loop 插件
34+
- `chattool setup workspace` 默认结构现切换到 `projects/` 模型:workspace 根目录保留 `README.md` / `AGENTS.md` / `MEMORY.md` 作为 general-use 协议与上下文入口,实际工作统一进入 `projects/` 下的单任务或多任务 project 执行
35+
- `chattool setup workspace` 现在会把“review 由 loop 在模型准备停下时触发,默认完整做完后再统一汇报结果”写入新生成的 workspace 协议;开发任务还会明确要求每个阶段先测试通过、更新文档,再按 `review.md` 规则完成校验与收尾
36+
- `chattool setup workspace` 新增 `--with-opencode-loop` 模板版本:启用后会安装本地 OpenCode `chatloop` plugin / commands 资产,并切换到 loop-aware workspace 模板
37+
- `src/chattool/setup/assets/opencode_chatloop/` 现收纳 ChatTool 管理的 OpenCode `chatloop` 安装源,包括 plugin、slash commands 与最小说明文档
3538
- `chattool pypi init` 新增 `--template default|cli-style`;其中 `cli-style` 会额外生成 `DEVELOP.md``setup.md``CHANGELOG.md``AGENTS.md` 以及 `docs/``tests/cli-tests/``tests/mock-cli-tests/``tests/code-tests/` 的基础说明文件,作为更贴近 ChatTool 当前 CLI/文档/测试/自动化规范的初始仓库模板
3639
- `chattool setup opencode` 现支持 `-e/--env`,可显式复用 ChatTool 的 OpenAI 配置来源;支持 `.env` 文件路径或 `OpenAI` profile 名称,并按 `显式参数 > -e 指定的 OpenAI 配置 > 当前 OpenAI 配置 > 现有 opencode 配置 > 默认值` 回退
3740
- 新增 `chattool setup workspace [PROFILE] [WORKSPACE_DIR]`,用于在核心项目外围初始化人类-AI 协作工作区骨架;支持 `base` profile、默认中文模板、显式 `--language en``--dry-run` 与已完成 `setup.md` 的保护覆盖语义
@@ -40,8 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
4043
- 新增 `chattool nginx`,用于按模板生成常见的 Nginx 配置片段;当前收口为配置导向的最小模板集:基础 `proxy_pass`、HTTPS 入口反代、WebSocket 转发、静态目录站点和重定向,并支持 `-i` 交互式补齐必要参数
4144

4245
### Changed
43-
- `chattool setup workspace` 的任务集汇报结构现统一为 `reports/MM-DD-<set-name>/`:集合目录下直接维护 `TASKSET.md``progress.md` 与各子任务目录,不再额外套一层 `task-sets/``tasks/`
44-
- `chattool setup workspace` 现移除全局 `thoughts/` 面,避免并发任务时出现一个共享的“当前关注点”入口;相关角色统一收口到各任务或任务集的 `reports/` 结构
46+
- `chattool setup workspace` 不再默认生成 `reports/` / `playgrounds/` / `setup.md`,也不再依赖 `AGENTS.generated.md` / `MEMORY.generated.md` 这类 helper files 做主要迁移路径;当前更强调通过根目录 `README.md``projects/README.md` 提供 general-use 入口与结构约定
4547

4648
## [6.5.0] - 2026-03-31
4749

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ chattool explore arxiv get
152152
| Nginx 配置 | `chattool nginx` | 按模板生成常见的反向代理、路径转发和静态目录配置 |
153153
| PyPI 工具 | `chattool pypi` | 创建、构建、校验、上传与探测 Python 包 |
154154
| MCP 服务 | `chattool mcp start` | 标准 MCP Server,供 Claude/Cursor 调用 |
155-
| 环境安装 | `chattool setup codex/claude/opencode/lark-cli/docker` | 安装或检查常用 CLI / Docker 环境,并在确认后执行建议的系统命令 |
156-
| Workspace | `chattool setup workspace` | 初始化围绕核心项目的人类-AI 协作工作区骨架;新目录直接生成协议,已有 workspace 则生成 `setup.md` 迁移指南与辅助协议文件 |
155+
| 环境安装 | `chattool setup codex/claude/opencode/lark-cli/docker` | 安装或检查常用 CLI / Docker 环境,并在确认后执行建议的系统命令`setup opencode/codex/claude` 现支持 `--install-only` 纯安装/升级,`setup opencode` 也支持 `--plugin auto-loop` 追加写入 `opencode-auto-loop` |
156+
| Workspace | `chattool setup workspace` | 初始化围绕核心项目的人类-AI 协作工作区骨架;当前默认使用 `projects/` 作为实际工作的执行容器,workspace 根目录则保留 general-use 协议与上下文;可选 `--with-opencode-loop` 启用 OpenCode loop-aware 模板并安装本地 `chatloop` 资产 |
157157
| Skills | `chattool skill install` | 安装 ChatTool skills 到 Codex / Claude / OpenCode |
158158
| CC-Connect | `chattool cc` | cc-connect 快速配置与启动 |
159159

README_en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ chattool nginx -i
175175
| MCP Server | `chattool mcp info` / `chattool mcp inspect` | Inspect MCP server capabilities (JSON supported) |
176176
| Screenshot | `chattool serve capture` | Local webpage screenshot service |
177177
| Cert Mgmt | `chattool serve cert` / `chattool client cert` | SSL certificate distribution |
178-
| Setup | `chattool setup codex` | Install Codex CLI and write config (supports `--base-url` / `--model`) |
179-
| Workspace | `chattool setup workspace` | Create a collaboration workspace around a core project with task-isolated `reports/` and `playgrounds/` directories |
178+
| Setup | `chattool setup codex/claude/opencode` | Install or upgrade common agent CLIs; supports `--install-only` for pure install/upgrade flows without writing config |
179+
| Workspace | `chattool setup workspace` | Create a collaboration workspace around a core project with `projects/` as the execution container and workspace-level files as the general-use protocol layer; supports `--with-opencode-loop` for a loop-aware OpenCode workspace variant |
180180
| Skills | `chattool skill install` | Install ChatTool skills to Codex / Claude / OpenCode |
181181
| CC-Connect | `chattool cc` | Quick cc-connect setup and start |
182182

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
# Agent Loop 插件调研:OpenCode、Claude Code、Codex 现状与可复用思路
2+
3+
这篇文章记录一次比较具体的调研:如果我们希望给终端 Agent 增加“自动续推 / loop”能力,现成生态里有哪些方案是开箱即用的,哪些方案更适合参考后自己做一层封装。
4+
5+
调研对象主要有三类:
6+
7+
- **OpenCode**:以 `opencode-auto-loop` 为代表的 plugin / session API 路线
8+
- **Claude Code**:以 loop plugin 和 stop hook 为代表的原生插件路线
9+
- **Codex**:以 hooks + skills + support files 为代表的 support-files 路线
10+
11+
目标不是列一个“谁功能最多”的清单,而是回答三个更实际的问题:
12+
13+
1. 有没有 **开箱即用** 的安装方式
14+
2. 交互体感能不能尽量接近原始 TUI
15+
3. 如果我们最后要在 OpenCode 里自己封装一层,最值得复用哪种思路
16+
17+
---
18+
19+
## 一、先说结论
20+
21+
如果优先级是“先找能直接装来用的”,结论非常明确:
22+
23+
- **Claude Code 生态里现成 loop 插件最多,也最接近开箱即用**
24+
- **Codex 生态里有成熟 loop 项目,但多数不是 marketplace 一键装完就能跑**
25+
- **OpenCode 现在最像现成方案的是 `opencode-auto-loop`,但实际加载链路仍需要额外验证**
26+
27+
如果优先级是“交互过程尽量和原始用法一致”,结论也很明确:
28+
29+
- **plugin / hook 型方案的体感最好**
30+
- **外部 runner 次之**
31+
- **PTY 接管终端的方案最容易把体验做坏**
32+
33+
这也是为什么我们最后更倾向于:
34+
35+
- 先调研现成 plugin
36+
- 真要自己做,也优先做 **OpenCode 内部命令 + 会话事件续推**
37+
- 不继续把大量精力压在 PTY 劫持上
38+
39+
---
40+
41+
## 二、OpenCode 现成方案:`opencode-auto-loop`
42+
43+
目前最接近现成方案的是:
44+
45+
- `opencode-auto-loop`
46+
47+
从它的 README 看,设计目标非常直接:
48+
49+
- 在 OpenCode 配置里加一条 `plugin`
50+
- 重启 OpenCode
51+
- 插件第一次运行时自行安装 `commands/``skills/`
52+
53+
看起来像这样:
54+
55+
```json
56+
{
57+
"plugin": ["opencode-auto-loop"]
58+
}
59+
```
60+
61+
后续 loop 续推时,它并不是通过终端输入模拟,而是直接走 OpenCode 内部 session API,等 session 进入 idle 后,再调用类似下面的接口追加消息:
62+
63+
```ts
64+
client.session.promptAsync({
65+
path: { id: sessionId },
66+
body: {
67+
parts: [{ type: "text", text: continuationPrompt }],
68+
},
69+
})
70+
```
71+
72+
这条路线的优点非常大:
73+
74+
- 不劫持终端字符流
75+
- 不污染输入框
76+
- 不依赖 TUI 的重绘细节
77+
- 从产品体验上更接近“原生支持的 loop”
78+
79+
但这次实际验证也暴露了一个关键事实:
80+
81+
- **只把 `plugin: ["opencode-auto-loop"]` 写进配置,还不足以保证本机真的能顺利加载它**
82+
83+
如果本地环境里插件包解析不稳定,结果就会变成:
84+
85+
- 启动时卡顿
86+
- 命令和能力没有真正出现
87+
88+
所以对 OpenCode 来说,`opencode-auto-loop` 当前更准确的定位是:
89+
90+
- **最值得优先验证的现成方案**
91+
- 但还不能直接下结论说“这就已经是完全开箱即用”
92+
93+
---
94+
95+
## 三、Claude Code:现成 loop 插件最成熟
96+
97+
Claude Code 这条线最有价值,因为它已经有非常明确的 plugin / hook 模式。
98+
99+
我们重点看了两个方向。
100+
101+
### 1. `claude-devloop`:最像“原生 loop plugin”
102+
103+
这个项目的结构非常清晰:
104+
105+
```text
106+
claude-loop/
107+
├── .claude-plugin/
108+
│ └── marketplace.json
109+
└── loop/
110+
├── .claude-plugin/plugin.json
111+
├── commands/
112+
│ ├── start.md
113+
│ └── stop.md
114+
├── hooks/
115+
│ ├── hooks.json
116+
│ ├── claim-hook.sh
117+
│ └── stop-hook.sh
118+
└── scripts/
119+
├── setup-loop.sh
120+
└── stop-loop.sh
121+
```
122+
123+
它的核心思路不是外部重启 Claude,而是:
124+
125+
1. 通过 `/loop:start` 创建 loop 状态
126+
2. 通过 `UserPromptSubmit` hook 把当前 session 和状态文件绑定
127+
3. 在 Claude 尝试退出时,由 `Stop` hook 拦截
128+
4. 再把原 prompt 带着 iteration 信息重新喂回去
129+
130+
这个设计非常值得重视,因为它几乎精准满足了“交互体感尽量和原始用法一致”的要求:
131+
132+
- 还是原来的 Claude TUI
133+
- 只是新增一个本地命令
134+
- loop 的接管点发生在宿主原生 hook 上
135+
136+
它还有一个很重要的设计:**每个 session 独立状态文件**
137+
138+
状态文件大概像这样:
139+
140+
```yaml
141+
---
142+
active: true
143+
iteration: 3
144+
max_iterations: 10
145+
completion_promise: "All tests passing"
146+
transcript_path: "/path/to/session/transcript.jsonl"
147+
term_session_id: "..."
148+
started_at: "2024-01-01T12:00:00Z"
149+
---
150+
151+
Your task prompt here
152+
```
153+
154+
这套结构很适合后续参考到 OpenCode:
155+
156+
- 本地命令触发
157+
- 每 session 独立 state file
158+
- 明确的 completion promise
159+
- stop 事件续推
160+
161+
### 2. `ralph-claude-code`:不是 plugin,但策略很完整
162+
163+
`ralph-claude-code` 走的是另一条路线:
164+
165+
- 外部 runner
166+
- shell orchestration
167+
- 状态目录 `.ralph/`
168+
- response analyzer / circuit breaker / rate limiting / session continuity
169+
170+
它的价值不在“交互体感”,而在“控制策略很完整”。
171+
172+
如果从实现经验角度看,最值得借鉴的是:
173+
174+
- dual-condition exit gate
175+
- no-progress / stuck loop 检测
176+
- rate limiting
177+
- circuit breaker
178+
- 可读的状态文件和日志
179+
180+
它不适合直接当 OpenCode 的实现模板,但非常适合给内部状态机提供经验。
181+
182+
---
183+
184+
## 四、Codex:support files 和 hooks 比 plugin 更重要
185+
186+
Codex 这条线最值得看的不是 marketplace 风格 plugin,而是 **hooks + skills + repo-local support files**
187+
188+
重点项目是:
189+
190+
- `autonomous-loop`
191+
192+
它采用“两层安装”模型:
193+
194+
### 1. Machine bootstrap
195+
196+
写到机器全局:
197+
198+
- `$CODEX_HOME/hooks.json`
199+
- `$CODEX_HOME/skills/autonomous-loop/SKILL.md`
200+
- `$CODEX_HOME/autoloop/machine.json`
201+
202+
### 2. Repo install
203+
204+
写到当前仓库:
205+
206+
- `.codex/autoloop.project.json`
207+
- `.codex/hooks.json`
208+
- `.agents/skills/autonomous-loop/SKILL.md`
209+
210+
然后它不只是“不断继续 prompt”,而是维护一份更严格的 contract:
211+
212+
- objective
213+
- required tasks
214+
- evidence
215+
- gate profile
216+
217+
在每次 `Stop` hook 时重新验证:
218+
219+
- 文件系统证据
220+
- trusted commands
221+
- 是否允许 release / block / hard-stop
222+
223+
这套方式非常稳,但明显也更重。
224+
225+
如果只看“有没有现成 loop 方案”,Codex 生态是有的;如果只看“是不是最容易直接装”,那它就不如 Claude plugin 轻。
226+
227+
---
228+
229+
## 五、外部 runner 能不能做?可以,但体感通常不如 plugin
230+
231+
在这次调研之前,我们自己也试过一条路线:
232+
233+
-`ralph.py` 之类的外部 PTY 控制器
234+
- 启动 OpenCode
235+
- 透传输入输出
236+
- 在静默时自动注入 prompt
237+
238+
这条路线不是完全错误,但它有一个核心问题:
239+
240+
- **它太靠近终端字符流了**
241+
242+
一旦靠近这一层,就容易踩到:
243+
244+
- TUI alt-screen 重绘
245+
- resize 同步
246+
- 输入回显
247+
- 鼠标事件和控制序列
248+
- 特殊命令泄漏
249+
- 原始日志难以阅读
250+
251+
从最终产品体验看,这类方案很难做到真正“像原始用法”。
252+
253+
所以更现实的判断是:
254+
255+
- **外部 runner 更适合做概念验证或通用编排器**
256+
- **如果目标是交互过程看起来像原生 TUI,就应该优先走 plugin / hook / session API**
257+
258+
---
259+
260+
## 六、如果以后要在 OpenCode 自己做,最值得复用什么
261+
262+
如果 OpenCode 现成的 `opencode-auto-loop` 最终不能直接满足需求,我们还是可能自己封装一层。
263+
264+
这时候最值得复用的,不是某一个项目的全部实现,而是三套思路的组合:
265+
266+
### 1. 命令与状态模型:参考 `claude-devloop`
267+
268+
最值得抄的点:
269+
270+
- `/loop:start` 这种本地命令入口
271+
- 每 session 一个 state file
272+
- frontmatter + body 的状态格式
273+
- session isolation
274+
- `start` / `stop` 作为明确控制面
275+
276+
### 2. 会话续推方式:参考 `opencode-auto-loop`
277+
278+
最值得抄的点:
279+
280+
- 不碰 PTY/TUI 输入劫持
281+
- 直接在 `session.idle``session.compacted``session.error` 等事件上做续推
282+
- 用内部 `promptAsync` 之类的 API 注入文本
283+
284+
### 3. 风险控制:参考 `autonomous-loop``ralph-claude-code`
285+
286+
最值得抄的点:
287+
288+
- fail-closed 而不是 fail-open
289+
- no-progress / stale state 清理
290+
- rate limit / max iteration
291+
- contract / gate 可以作为第二阶段增强
292+
293+
---
294+
295+
## 七、我们自己验证过的 `ralph.py` 还留下了哪些有效结论
296+
297+
虽然 `ralph.py` 这条 PTY 路线最后没有继续走,但它并不是白做了。
298+
299+
它至少验证了几条非常关键的产品语义:
300+
301+
1. **需要区分 `chat``loop` 两种模式**
302+
2. **prompt 文件应属于控制器,而不是直接暴露给模型**
303+
3. **需要区分“用户主动暂停”和“模型/系统停滞”**
304+
4. **日志应该优先记录动作,而不是原始 PTY 流**
305+
5. **loop 必须由一个显式命令触发,而不是靠自然语言猜测**
306+
307+
这些都和现成项目的设计高度一致,说明方向本身是对的,只是控制层级选错了。
308+
309+
---
310+
311+
## 八、最终建议
312+
313+
如果把问题拆成两个任务:
314+
315+
### 任务 A:先找能直接安装来用的
316+
317+
优先级建议:
318+
319+
1. 先验证 `opencode-auto-loop` 的真实安装与加载链路
320+
2. Claude 生态优先参考 `claude-devloop`
321+
3. Codex 生态优先参考 `autonomous-loop`
322+
323+
### 任务 B:如果最后要自己做一层封装
324+
325+
建议不要从 PTY 继续做,而是:
326+
327+
- 用 OpenCode plugin / command / session API
328+
- 命令与状态模型参考 `claude-devloop`
329+
- 续推方式参考 `opencode-auto-loop`
330+
- 风控策略参考 `autonomous-loop``ralph-claude-code`
331+
332+
一句话总结:
333+
334+
> **开箱即用优先看 Claude,原生体验优先做 plugin/hook,OpenCode 自己做时最值得复用的是 `claude-devloop` 的命令+状态模型,以及 `opencode-auto-loop` 的会话事件续推。**

0 commit comments

Comments
 (0)