Skip to content
Draft
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
- [2026-04-20] `chattool gh` 已重构为分层实现:CLI 入口收口到 `gh pr ...` / `gh run ...` 嵌套命令树,主要命令业务从 `src/chattool/tools/github/cli.py` 迁出到独立命令实现层,请求访问收口为显式 `get_*` / `post_*` / `patch_*` 函数,`GitHubClient` 同步瘦身为围绕这些提取后能力的薄包装;保留了 repo-scoped token 优先级、`set-token`、`repo-perms`、缺参自动补问、`pr checks --wait`、`pr merge --check` 等 ChatTool 定制行为

### Fixed
- [2026-04-20] `chatloop` bootstrap 首轮现在不允许直接输出 `STATUS: COMPLETE` 或 `<complete>DONE</complete>`;completion gate 仅从后续 continuation 开始生效,避免模型在首轮因习惯性“promise done”过早结束 loop
- [2026-04-20] `chatloop` 插件现在在首次执行 `/chatloop ...` 时不再额外弹出启动完成提示,也不再把 bootstrap PRD 提示作为工具返回文本直接回显;改为异步把首轮 PRD contract 注入当前 session,避免模型把首轮启动误判为“一轮已经结束”
- [2026-04-20] `chattool setup workspace --with-opencode-loop` / `setup opencode --plugin chatloop` 附带的 `chatloop` 插件现在会在启动首轮就强制注入 `PRD.md` 路径、project path 和结构化进度规则,不再把 `/chatloop <message>` 原样转发给模型;同时引入更强的 completion gate,要求每轮输出 `## Completed`、`## Next Steps` 与 `STATUS: IN_PROGRESS` / `STATUS: COMPLETE`,只有在 `Next Steps` 清空、`STATUS: COMPLETE` 与 `<complete>DONE</complete>` 同时满足时才停止 continuation
- `chattool cc start` 现在会捕获启动异常和非零退出码,并把失败原因直接输出给用户;默认连续失败 5 次后才停止重试,避免 cc-connect 因偶发异常直接变成不可用状态
Expand All @@ -35,6 +36,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
- `chattool setup codex` / `chattool setup opencode` 现在默认优先读取保存的 typed env 配置,再回退到 shell 环境变量;显式 `-e/--env` 仍然拥有更高优先级,避免交互默认值被临时环境变量意外抢占

### Added
- [2026-04-20] `chatloop` 新增 `/chatloop-project`,用于直接查看当前解析到的 project 根目录、`PRD.md` 路径、状态文件与事件日志路径;`/chatloop-status` 同步补充最近一次 lifecycle event / reason,减少仅靠日志排查的需要
- [2026-04-20] `chattool setup workspace` 生成的协作脚手架现在默认包含 workspace 级 `reference/`、`docs/themes/` 与 `skills/workspace-maintenance/`,用于长期参考沉淀、按主题维护约定和定期整理 `projects/`
- [2026-04-20] 新增 `docs/env/chatloop-quickstart.md`,用 `arxiv-explore` 示例串起从创建 `PRD.md`、初始化 workspace、显式触发 `/chatloop ...` 到使用 `.opencode/chatloop.events.log` 调试的完整入门流程;`docs/env/index.md`、`workspace.md`、`opencode.md` 同步增加入口链接
- `chattool setup opencode` 新增 `--plugin auto-loop`,可在写入 OpenCode 基础 provider/model 配置时同步把 `opencode-auto-loop` 追加到 `plugin` 数组,方便直接启用现成 auto-loop 插件
- `chattool setup workspace` 默认结构现切换到 `projects/` 模型:workspace 根目录保留 `README.md` / `AGENTS.md` / `MEMORY.md` 作为 general-use 协议与上下文入口,实际工作统一进入 `projects/` 下的单任务或多任务 project 执行
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ chattool explore arxiv get
| PyPI 工具 | `chattool pypi` | 创建、构建、校验、上传与探测 Python 包 |
| MCP 服务 | `chattool mcp start` | 标准 MCP Server,供 Claude/Cursor 调用 |
| 环境安装 | `chattool setup codex/claude/opencode/lark-cli/docker` | 安装或检查常用 CLI / Docker 环境,并在确认后执行建议的系统命令;`setup opencode/codex/claude` 现支持 `--install-only` 纯安装/升级,`setup opencode` 也支持 `--plugin auto-loop` 追加写入 `opencode-auto-loop` |
| OpenCode 会话管理 | `chattool opencode` | 默认直接以 PTY wrapper 模式启动被包裹的 `opencode`;也支持次级 `observe`、控制式 `run` 和日志汇总 `summarize` |
| Workspace | `chattool setup workspace` | 初始化围绕核心项目的人类-AI 协作工作区骨架;当前默认使用 `projects/` 作为实际工作的执行容器,workspace 根目录则保留 general-use 协议与上下文;可选 `--with-opencode-loop` 启用 OpenCode loop-aware 模板并安装本地 `chatloop` 资产 |
| Skills | `chattool skill install` | 安装 ChatTool skills 到 Codex / Claude / OpenCode |
| CC-Connect | `chattool cc` | cc-connect 快速配置与启动 |
Expand Down
1 change: 1 addition & 0 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ chattool nginx -i
| Screenshot | `chattool serve capture` | Local webpage screenshot service |
| Cert Mgmt | `chattool serve cert` / `chattool client cert` | SSL certificate distribution |
| Setup | `chattool setup codex/claude/opencode` | Install or upgrade common agent CLIs; supports `--install-only` for pure install/upgrade flows without writing config |
| OpenCode Session Mgmt | `chattool opencode` | By default directly launches a PTY-wrapped `opencode` session; also supports secondary `observe`, action-driven `run`, and JSONL log `summarize` |
| 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 |
| Skills | `chattool skill install` | Install ChatTool skills to Codex / Claude / OpenCode |
| CC-Connect | `chattool cc` | Quick cc-connect setup and start |
Expand Down
45 changes: 42 additions & 3 deletions docs/env/chatloop-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ chattool setup opencode --install-only --plugin chatloop

```text
/chatloop-help
/chatloop-ralph 按当前 PRD 推进任务
/chatloop-next
/chatloop-project
/chatloop-status
```

如果当前目录还不是 project,`/chatloop-status` 会提示没有找到 `PRD.md`,这是正常的。
如果当前目录本身还没有 `PRD.md`,`/chatloop-status` 会提示当前目录不符合要求,这是正常的。

## 2. 创建 workspace

Expand Down Expand Up @@ -140,14 +143,25 @@ ln -s ../../core/ChatTool ~/workspace/arxiv-demo/projects/04-20-arxiv-explore-to

注意:首轮 bootstrap iteration 只允许进入 `STATUS: IN_PROGRESS`,不允许直接输出 `STATUS: COMPLETE` 或 `<complete>DONE</complete>`。

如果你想要更接近 Ralph Loop 的“每轮 refresh session”模式,可以改用:

```text
/chatloop-ralph 按当前 PRD 开发 arxiv-explore 工具。需要时参考 memory.md 和 progress.md;每轮输出 ## Completed、## Next Steps 和 STATUS: IN_PROGRESS / STATUS: COMPLETE。
```

它和普通 `/chatloop` 的差别是:

- `/chatloop`:在同一个 session 中 continuation
- `/chatloop-ralph`:每次 continuation 都会创建一个新的 session,再把 TUI 切到那个新 session

不建议只输入很短的 `/chatloop ?`。更好的方式是给一条清晰任务指令,让第一轮就覆盖主链路。

## 6. 启动后会发生什么

`/chatloop ...` 触发后,插件会做这些事:

1. 从当前目录向上寻找最近的 `PRD.md`
2. 把这个目录视为当前 project 根目录
1. 检查当前目录本身是否存在 `PRD.md`
2. 把当前目录视为当前 project 根目录
3. 在 project 根目录下写状态文件:`.opencode/chatloop.local.md`
4. 在 project 根目录下的 `.opencode/` 目录追加事件记录:`chatloop.events.log`
5. 把你的初始消息保留为 `Original task`,但首轮就强制注入 `PRD.md` 路径、project path 和结构化进度规则
Expand All @@ -171,6 +185,7 @@ ln -s ../../core/ChatTool ~/workspace/arxiv-demo/projects/04-20-arxiv-explore-to
- `State file`
- `Events file`
- 当前是否 active
- 最近一次 lifecycle event / reason

你还可以直接查看 project 根目录下的:

Expand All @@ -196,6 +211,30 @@ ln -s ../../core/ChatTool ~/workspace/arxiv-demo/projects/04-20-arxiv-explore-to
/chatloop-status
```

查看当前解析到的 project 路径:

```text
/chatloop-project
```

如果当前任务已经完成,想把项目整理成“方便继续讨论下一个需求”的状态,可以执行:

```text
/chatloop-next
```

它的目标是:

- 把当前任务的长期输出收口到项目内 `reference/`
- 更新 `memory.md` / `progress.md`
- 把 `PRD.md` 准备成下一轮需求讨论的入口

如果要走 refresh 模式:

```text
/chatloop-ralph 按当前 PRD 推进任务
```

查看帮助:

```text
Expand Down
15 changes: 15 additions & 0 deletions docs/env/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ chattool setup opencode --install-only

详细文档:[opencode.md](opencode.md)

如果你想从 ChatTool 外层直接启动被 PTY 包裹的 OpenCode,会话主入口现在就是:

```bash
chattool opencode
chattool opencode --cwd .
```

如果你还需要显式观察其他命令、做控制动作验证或汇总日志,再使用:

```bash
chattool opencode observe -- opencode
chattool opencode run --action "send_sigint:2.0" -- opencode
chattool opencode summarize ./.chattool/opencode/session-*.jsonl
```

### Docker 环境检查

使用 `setup docker` 检查 Docker / Docker Compose / docker 组状态。
Expand Down
116 changes: 116 additions & 0 deletions docs/env/opencode.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ chattool setup opencode --plugin chatloop
`chatloop` 安装完成后,常用调试方式是:

- 执行 `/chatloop-help` 查看工作流说明
- 执行 `/chatloop-ralph ...` 启动 refresh-session 风格的 Ralph loop
- 执行 `/chatloop-next` 把当前任务整理成交接态,为下一个需求讨论做准备
- 执行 `/chatloop-project` 查看当前解析到的 project 根目录和文件路径
- 执行 `/chatloop-status` 查看当前 project 根目录、状态文件和事件文件
- 查看当前 project 下的 `.opencode/chatloop.local.md` 和 `.opencode/chatloop.events.log`
- `chatloop` 首轮和每轮 continuation 都会强制注入 `PRD.md` 路径与读取要求
Expand All @@ -118,3 +121,116 @@ chattool setup opencode --plugin chatloop
如果你想看一遍从安装 OpenCode / chatloop 到创建 `PRD.md` 并启动 loop 的完整示例,可参考:

- [chatloop-quickstart.md](chatloop-quickstart.md)

## 6. OpenCode 会话管理(`chattool opencode`)

除了安装和写配置,ChatTool 现在还提供一个运行期 PTY wrapper,用来从 OpenCode 进程外观察或控制交互会话。

### 直接启动 wrapped `opencode`

如果你的目标是“像 `reference/pty-controller-poc/poc.py` 一样,执行后立刻进入被 PTY 包裹的 `opencode` 会话”,最直接的用法就是:

```bash
chattool opencode
```

它会:

- 直接启动被 PTY 包裹的 `opencode`
- 透传当前终端输入输出
- 自动同步 winsize
- 默认把 JSONL 事件日志写到 `./.chattool/opencode/`

如果你想指定工作目录或超时时间:

```bash
chattool opencode --cwd .
chattool opencode --cwd . --timeout 30
```

这就是当前推荐的第一入口,也是和 `poc.py` 最接近的启动方式。

### 只读观察模式

如果你想包起一个真实 CLI,但不主动注入输入或中断,可使用:

```bash
chattool opencode observe -- opencode
```

常见变体:

```bash
# 观察一次 one-shot opencode run,并把日志写到指定文件
chattool opencode observe \
--log-path ./stage1-opencode-run.jsonl \
--timeout 30 \
--mirror-output \
-- opencode run "请只回复 OK 然后结束"

# 显式写出 wrapped command 的等价形式
chattool opencode observe --cwd . -- opencode
```

这一模式会记录:

- `session.start` / `session.end`
- `session.status`(如 `running`、`idle`、`exited`)
- `session.input` / `session.output`
- `session.resize`

同时保证不会因为 ChatTool 自己的 `--action` 安排而偷偷向目标进程注入控制动作。

### 控制模式

如果你要验证外部控制动作,可使用:

```bash
chattool opencode run \
--action "send_text:0.1:print('hello')" \
--action "send_enter:0.2" \
--action "send_eof:0.8" \
-- python3 -i -q
```

当前最小动作集合为:

- `send_text`
- `send_enter`
- `send_sigint`
- `send_eof`

`run` 模式要求显式传入至少一个 `--action`;如果你只是想看会话,不做主动控制,请使用 `observe`。

### 日志汇总

每次运行默认会把 JSONL 事件日志写到当前目录的 `.chattool/opencode/` 下,也可以显式指定 `--log-path`。日志生成后可用:

```bash
chattool opencode summarize ./stage1-opencode-run.jsonl
```

它会输出:

- 各类事件计数
- 状态流转
- 控制动作列表
- 少量输入输出样本

### 最常用启动方式

如果你只是想直接开始用,通常是下面三条:

```bash
# 1) 安装或升级 OpenCode CLI
chattool setup opencode --install-only

# 2) 直接启动被包裹的 opencode 会话(推荐第一入口)
chattool opencode --cwd .

# 3) 需要显式观察其他命令时再用 observe
chattool opencode observe -- python3 -i -q

# 4) 观察完后快速总结日志
chattool opencode summarize ./.chattool/opencode/<latest>.jsonl
```
6 changes: 5 additions & 1 deletion docs/env/workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,20 @@ workspace-level 参考约定:
- 同时把 `chatloop` 全局安装到 OpenCode home(默认 `~/.config/opencode/`,也可通过 `OPENCODE_HOME` 改写),包括:
- `plugins/chatloop/`
- `command/chatloop.md`
- `command/chatloop-project.md`
- `command/chatloop-status.md`
- `command/chatloop-help.md`
- `command/chatloop-stop.md`
- 该版本适合先完善 `PRD.md`,再通过显式 `/chatloop ...` 触发 fresh-start continuation 的工作流
- `chatloop` 可从任意 project 子目录触发,会自动向上寻找最近的 `PRD.md`
- `chatloop` 当前要求执行目录自身直接存在 `PRD.md`;如果要在子目录运行 loop,就把 `PRD.md` 落到该子目录本身
- 运行后,状态文件写入当前 project 根目录 `.opencode/chatloop.local.md`,事件记录直接追加到 `.opencode/chatloop.events.log`
- 可通过 `/chatloop-status` 查看当前解析到的 project 根目录、状态文件和事件文件
- `chatloop` 启动首轮就会强制注入 `PRD.md` 路径与读取要求,而不是简单原样转发用户消息
- `/chatloop` 在同一个 session 中 continuation;`/chatloop-ralph` 则在每次 continuation 时创建新的 refreshed session,更接近 Ralph Loop 风格
- 每轮都要求输出 `## Completed`、`## Next Steps` 和 `STATUS: IN_PROGRESS` / `STATUS: COMPLETE`
- bootstrap 首轮不允许直接完成;只有进入后续 continuation 后,completion gate 才会生效
- 可通过 `/chatloop-project` 直接查看当前解析到的 project 根目录与 `PRD.md` / state / events 路径
- 可通过 `/chatloop-next` 把当前任务输出收口到 project 内 `reference/`,并把 `memory.md` / `progress.md` / `PRD.md` 整理成下一轮需求讨论入口
- 只有同时满足 `STATUS: COMPLETE`、`<complete>DONE</complete>` 且 `Next Steps` 没有未完成项时,插件才会停止 continuation

### ChatTool
Expand Down
1 change: 1 addition & 0 deletions docs/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ ChatTool 提供的各类工具,包括 DNS 管理、AI 绘图、网络扫描、
- [SVG 转 GIF](svg2gif.md)
- [TP-Link 路由器](tplogin.md)
- [CC-Connect 管理](cc/index.md)
- [OpenCode 会话管理](../env/opencode.md):默认直接启动被 PTY 包裹的 `opencode`,也支持次级 `observe/run/summarize`
- [PyPI 工具](pypi/index.md)
2 changes: 1 addition & 1 deletion src/chattool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

__author__ = """Rex Wang"""
__email__ = "1073853456@qq.com"
__version__ = "6.6.2"
__version__ = "6.6.3"

from dotenv import load_dotenv

Expand Down
1 change: 1 addition & 0 deletions src/chattool/client/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def cli():
"mcp": lambda: _load_attr("chattool.mcp.cli", "cli"),
"lark": lambda: _load_attr("chattool.tools.lark.cli", "cli"),
"image": lambda: _load_attr("chattool.tools.image.cli", "cli"),
"opencode": lambda: _load_attr("chattool.tools.opencode.cli", "cli"),
"tplogin": lambda: _load_attr("chattool.tools.tplogin_cli", "cli"),
"gh": lambda: _load_attr("chattool.tools.github.cli", "cli"),
"browser": lambda: _load_attr("chattool.tools.browser.cli", "cli"),
Expand Down
3 changes: 3 additions & 0 deletions src/chattool/setup/assets/opencode_chatloop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ This directory stores the local OpenCode `chatloop` plugin and slash commands th
Current commands:

- `/chatloop`
- `/chatloop-ralph`
- `/chatloop-next`
- `/chatloop-project`
- `/chatloop-status`
- `/chatloop-help`
- `/chatloop-stop`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
description: "Prepare the project for the next chatloop task"
---

# ChatLoop Next

Use this command when the current task is effectively complete and you want to prepare the same project for discussing the next requirement.

Instructions for the model:

1. Review the current project state before making changes:
- `PRD.md`
- `memory.md`
- `progress.md`
- recent outputs and any files created for the current task
2. Package the current task's durable outputs into the project's `reference/` subdirectory.
- prefer creating or updating a clearly named markdown summary inside `reference/`
- do not move or delete source files unless the user explicitly asked for cleanup
3. Update `memory.md` so the next discussion has the right local context:
- what was completed
- where the key outputs now live
- what the next discussion should know before changing direction
4. Update `progress.md` with a concise handoff note for the completed task.
5. Initialize the next-task discussion entrypoint by rewriting or preparing `PRD.md` for the upcoming requirement:
- keep it minimal
- preserve only durable context that still matters
- if the next requirement is still ambiguous, leave a short scaffold with `## 待处理问题` / `## Open Questions`
6. When finished, summarize:
- what was archived into `reference/`
- what changed in `memory.md`
- how `PRD.md` is now prepared for the next discussion

Important constraints:

- this command is for handoff and preparation, not for continuing the current implementation loop
- prefer small, explicit documentation updates over broad file churn
- keep the project reusable for the next requirement discussion
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
description: "Show resolved chatloop project paths"
---

# ChatLoop Project

Call the `chatloop-project` tool and present its output directly.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
description: "Start a PRD-aware refresh loop"
---

# ChatLoop Ralph

Parse `$ARGUMENTS` as the original task.

Call the `chatloop-ralph` tool with:

- `message`: `$ARGUMENTS`

Requirements:

- the current directory itself must contain `PRD.md`
- startup creates a fresh session and switches the TUI to it
- each later continuation runs in another newly refreshed session
- rely on `PRD.md`, `memory.md`, `progress.md`, and structured progress instead of old chat history

Debugging:

- use `/chatloop-project` to inspect the resolved project root and file paths
- use `/chatloop-status` to inspect the current loop mode, state, and last lifecycle reason
- state is written to `.opencode/chatloop.local.md`
- event records are appended to `.opencode/chatloop.events.log`

Completion rule:

- bootstrap iteration is never allowed to complete
- only later iterations may finish with both `STATUS: COMPLETE` and `<complete>DONE</complete>`
Loading