# vibe-bot（Telegram → Mac CLI → Telegram 回推）

## 环境依赖

- 建议使用 Homebrew 安装核心命令行工具，保证脚本依赖一致：
  ```bash
  brew install python3 tmux codex
  ```
  Homebrew 官方文档说明可以通过 `brew install` 安装 Python 及 tmux，Codex CLI 官方文档同样推荐使用 Homebrew。安装完成后可执行
  `python3 --version`、`tmux -V` 和 `codex --version` 验证环境。
- 首次使用 Codex CLI 需通过 ChatGPT 登录：
  ```bash
  codex login
  ```
  登录成功后会在本地写入凭据（默认为 `~/.codex/auth.json`）。若需使用 API Key，可执行 `codex login --api-key <key>`。
- 项目脚本默认调用 Homebrew 提供的 `python3`。若需要隔离依赖，建议提前创建虚拟环境：
  ```bash
  python3 -m venv .venv
  source .venv/bin/activate
  ```

## 目录结构

- `bot.py`：aiogram 3 worker，支持多模型会话解析（Codex / ClaudeCode / 预留 Gemini）。
- `scripts/run_bot.sh`：一键启动脚本（自动建 venv、启动 tmux + 模型 CLI + bot）。
- `scripts/stop_bot.sh`：终止当前项目 worker（tmux + bot 进程）。
- `scripts/start_tmux_codex.sh`：底层 tmux/CLI 启动器，被 `run_bot.sh` 调用，默认以 `tmux -u` 强制启用 UTF-8。
- `scripts/models/`：模型配置模块（`common.sh`/`codex.sh`/`claudecode.sh`/`gemini.sh`）。
- `logs/<model>/<project>/`：运行日志（`run_bot.log`、`model.log`、`bot.pid`、`current_session.txt`）。
    - `model.log` 由 `scripts/log_writer.py` 控制，单文件上限 20MB，仅保留最近 24 小时的归档（可通过 `MODEL_LOG_MAX_BYTES`、
      `MODEL_LOG_RETENTION_SECONDS` 覆盖）。
- `.env.example`：环境配置模板（复制为 `.env` 后按需修改）。

## 快速开始

建议通过 PyPI 安装的 `vibego` 命令完成初始化与启动，示例：

```bash
pipx install vibego  # 或者 pip install --user vibego
vibego init          # 初始化配置目录并写入 Master Bot Token
vibego start         # 启动 master 服务
```

若在本仓库内调试，可执行：

1. 安装依赖：`brew install python tmux`（若需要代理，请提前配置）。
2. 初始化配置：`python -m vibego_cli init` 或 `./scripts/vibego init`，按提示输入 Telegram Master Bot Token。
  - 初始化会在 `~/.config/vibego/` 下创建 `.env`、`config/projects.json`、`config/master.db` 等文件。
3. 启动 master：`python -m vibego_cli start`。启动后请在 Telegram 中向 Bot 发送 `/start` 完成授权。
4. 查看状态或停止服务：运行 `python -m vibego_cli status`、`python -m vibego_cli stop`。

> CLI 会自动安装 Python 依赖并在 `~/.config/vibego/` 下准备 `logs/`、`state/` 等运行期目录，避免污染仓库工作区。

## 日志 & 目录

```
logs/
  └─ codex/
      └─ mall-backend/
           ├─ run_bot.log     # run_bot.sh 输出
           ├─ model.log       # tmux pipe-pane 捕获的模型 CLI 输出
           ├─ bot.pid         # 当前 bot 进程 PID（stop_bot.sh 使用）
           └─ current_session.txt  # 最近一次 JSONL 会话指针
```

## 模型切换

- 支持参数：`codex`、`claudecode`、`gemini`（占位）。
- 切换流程：`stop_bot.sh --model <旧>` → `run_bot.sh --model <新>`。
- 每个模型在 `scripts/models/<model>.sh` 中维护独立配置，互不依赖；公共逻辑位于 `scripts/models/common.sh`。
- `ACTIVE_MODEL` 会在 `/start` 回复及日志中显示，并写入环境变量供 `bot.py` 使用。

### Codex

| 变量                   | 说明                                            |
|----------------------|-----------------------------------------------|
| `CODEX_WORKDIR`      | Codex CLI 工作目录（默认 `.env` 中自定义或 fallback ROOT） |
| `CODEX_CMD`          | 启动命令，默认 `codex --dangerously-bypass-...`      |
| `CODEX_SESSION_ROOT` | JSONL 根目录（默认 `~/.codex/sessions`）             |
| `CODEX_SESSION_GLOB` | JSONL 文件匹配（默认 `rollout-*.jsonl`）              |

### ClaudeCode

| 变量                    | 说明                                    |
|-----------------------|---------------------------------------|
| `CLAUDE_WORKDIR`      | 工程目录（默认与 Codex 相同）                    |
| `CLAUDE_CMD`          | CLI 启动命令，示例 `claude --project <path>` |
| `CLAUDE_PROJECT_ROOT` | JSONL 根目录（默认 `~/.claude/projects`）    |
| `CLAUDE_SESSION_GLOB` | JSONL 文件匹配（默认 `*.jsonl`）              |
| `CLAUDE_PROJECT_KEY`  | 可选：显式指定 `~/.claude/projects/<key>` 路径 |

### Gemini（预留）

- `scripts/models/gemini.sh` 暂使用占位命令，可在后续接入官方 CLI 时扩展。

## aiogram Worker 行为

- `/start`：返回 `chat_id`、`MODE`、`ACTIVE_MODEL`；日志打印 `chat_id` 与 `user_id`。
- 文本消息：
    1. 依据 `ACTIVE_MODEL` 选择 `SessionAdapter`，读取 `current_session.txt` 中记录的 JSONL 文件，必要时搜索
       `MODEL_SESSION_ROOT` 以回填。
    2. 将 prompt 注入 tmux（发送 `Esc` 清空模式、`C-j` 换行、`Enter` 提交）。
    3. 首次读取 `SESSION_OFFSETS` 初始化偏移；随后通过 `_deliver_pending_messages()` 补发当前尾部内容并持续轮询 JSONL。
    4. watcher 阶段提示 `ACTIVE_MODEL` 正在处理中，完成后自动推送结果（保留 Markdown）。
- MODE=A 下仍支持 `AGENT_CMD` 直接执行 CLI。

## 新增脚本

- `run_bot.sh`
    - `--model <name>`：codex / claudecode / gemini。
    - `--project <slug>`：日志/会话目录名称；未提供时依据工作目录推导。
    - `--foreground`：前台运行（默认后台 + `nohup`）。
    - `--no-stop`：启动前跳过 stop（默认先执行 `stop_bot.sh` 保证幂等）。
- `stop_bot.sh`
    - 幂等终止：`tmux kill-session`、关闭 `bot.pid` 指向的进程、移除缓存。
    - 示例：`./scripts/stop_bot.sh --model codex --project mall-backend`。

## 配置要点

### `.env`（Master 全局配置）

- 文件位置：`~/.config/vibego/.env`（可通过环境变量 `VIBEGO_CONFIG_DIR` 自定义）。
- `MASTER_BOT_TOKEN`：master bot 的 Token，由 `vibego init` 引导输入，启动时必须存在。
- `MASTER_CHAT_ID` / `MASTER_USER_ID`：首次在 Telegram 与 master 交互时自动写入，表示已授权的管理员账号。
- `MASTER_WHITELIST`：逗号分隔的 chat_id 列表，留空表示不限制；若与自动写入冲突以最新值为准。
- 其他可选变量（代理、日志级别、默认模型等）可按需新增，未设置时脚本使用默认值。

- 项目配置持久化在 `~/.config/vibego/config/master.db`（SQLite），对应的 JSON 镜像为
  `~/.config/vibego/config/projects.json`。如需离线编辑，可参考仓库内的 `config/projects.json.example` 模板。
- Master「⚙️ 项目管理」可新增/编辑/删除项目；仍可离线编辑 JSON，启动时会自动导入并同步至数据库。
- 必填字段：`bot_name`、`bot_token`、`project_slug`、`default_model`。
- 可选字段：`workdir`（项目路径）、`allowed_chat_id`（用于预设授权）。留空时，worker 首次收到消息会自动记录 chat_id 并写回
  `~/.config/vibego/state/master_state.json`。
- 其他自定义字段暂不读取。

### 自动授权 & 状态

- worker 启动时若 `allowed_chat_id` 为空，首次合法消息会写入 `state/state.json` 并立即生效。
- master 重启：先调用 `stop_bot.sh` 清理，再依据 state 还原正在运行的项目。

## 后续规划

- Master bot（8031153139:AAF83jNsfzLTk428HAOVo0pJgHadisxkhCo）将统一轮询多个项目 bot，并调用 run/stop 脚本管理
  worker；当前版本先提供 worker 端结构与日志规范。
- Gemini CLI 接入待官方方案确定后补充。

## 注意

- `~/.config/vibego/.env` 内包含敏感 Token 与管理员信息，请勿提交至版本库。
- 若需减少日志体积，可按需清理 `logs/<model>/<project>/` 或调整脚本输出阈值。

## Master 控制

- 管理员 Bot 使用 `MASTER_BOT_TOKEN` 启动（运行 `python master.py`）。
- 项目列表由 Master 仓库（`~/.config/vibego/config/master.db`）维护，可通过项目管理按钮或
  `~/.config/vibego/config/projects.json` 同步文件更新。示例字段：
    - `bot_name`：对应 Telegram 机器人的用户名（可带或不带 `@`，展示与交互时自动加 `@`）
    - `bot_token`：对应 worker 的 Telegram Token
    - `default_model`：默认模型（codex / claudecode / gemini）
    - `project_slug`：日志/目录名称
    - `workdir`：项目工作目录（可选）
    - `allowed_chat_id`：项目 worker 的授权 chat（用于 run_bot 时注入环境）
- 状态持久化：`~/.config/vibego/state/master_state.json` 自动记录各项目当前模型与运行状态，master 重启时会先 `stop_bot.sh`
  清理现场，再根据状态恢复。

### 管理命令

| 命令                          | 说明                             |
|-----------------------------|--------------------------------|
| `/projects`                 | 列出所有项目当前状态与模型                  |
| `/run <project> [model]`    | 启动指定项目 worker，模型可选（默认使用当前/配置值） |
| `/stop <project>`           | 停止项目 worker                    |
| `/switch <project> <model>` | 停止后以新模型重新启动                    |
| `/start`                    | 显示帮助与项目数量                      |

- `<project>` 参数可填写 `project_slug` 或对应 `@bot_name`，命令回复将自动展示可点击的 `@` 链接。

> master 仅与管理员 bot 交互；项目 bot 仍由 worker（run_bot.sh 启动的 `bot.py`）负责处理业务消息。
