{"id":50954769,"url":"https://github.com/alloevil/pocket-agent","last_synced_at":"2026-06-18T05:02:30.077Z","repository":{"id":362259605,"uuid":"1258057724","full_name":"alloevil/pocket-agent","owner":"alloevil","description":"📱 用飞书远程遥控本地 Claude Code / opencode / Codex 编码 Agent —— 流式卡片、工具可视化、远程审批、多会话","archived":false,"fork":false,"pushed_at":"2026-06-03T09:43:06.000Z","size":89,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T11:18:16.083Z","etag":null,"topics":["ai-agent","claude-code","codex","coding-agent","feishu","lark","opencode","remote-control"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alloevil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T08:36:56.000Z","updated_at":"2026-06-03T09:43:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/alloevil/pocket-agent","commit_stats":null,"previous_names":["alloevil/pocket-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/alloevil/pocket-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alloevil%2Fpocket-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alloevil%2Fpocket-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alloevil%2Fpocket-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alloevil%2Fpocket-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alloevil","download_url":"https://codeload.github.com/alloevil/pocket-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alloevil%2Fpocket-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34476728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","claude-code","codex","coding-agent","feishu","lark","opencode","remote-control"],"created_at":"2026-06-18T05:02:29.241Z","updated_at":"2026-06-18T05:02:30.065Z","avatar_url":"https://github.com/alloevil.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pocket Agent 🤖\n\n\u003e 用飞书远程遥控本地电脑上的 AI 编码 Agent —— 走路、通勤、开会间隙，一条消息就能让 Claude Code / opencode / Codex 在你的电脑上干活。\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/alloevil/pocket-agent/actions/workflows/tests.yml\"\u003e\u003cimg alt=\"Tests\" src=\"https://github.com/alloevil/pocket-agent/actions/workflows/tests.yml/badge.svg\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Python\" src=\"https://img.shields.io/badge/python-3.10%2B-blue\"\u003e\n  \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-green\"\u003e\n  \u003cimg alt=\"Agents\" src=\"https://img.shields.io/badge/agents-Claude%20Code%20%7C%20opencode%20%7C%20Codex-orange\"\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ 特性\n\n- 🔌 **三种 Agent，一套接口** —— Claude Code、opencode、Codex 任选，统一的归一化事件模型，加新 agent 只需实现一个后端子类。\n- 💬 **飞书富卡片渲染** —— 流式 Markdown（代码块/列表/表格）、工具调用过程、可折叠思考、彩色 diff 审批。\n- 🗂 **多会话管理** —— 同一聊天里 `/new` 开多个对话、`/switch` 切换、`/resume` 恢复历史；不同群/私聊自动隔离。\n- 🔐 **远程审批** —— Agent 执行敏感命令/改文件时推审批卡片，手机一点批准或拒绝，支持「本轮全部允许」。\n- 📱 **为手机遥控而设计** —— 运行中心跳进度、完成主动提醒、命令纠错、首次引导、超长内容折叠。\n- 🛡 **健壮可靠** —— 飞书 API 自动重试、流式去重降级、子进程崩溃自愈、断线重连、首次启动自助引导。\n- 🌐 **零公网 IP** —— 飞书侧 WebSocket 长连接主动外连，Agent 侧本地子进程/端口，无需端口映射。\n\n## 📑 目录\n\n- [工作原理](#-工作原理)\n- [支持的 Agent](#-支持的-agent)\n- [快速开始](#-快速开始)\n- [使用](#-使用)\n- [配置](#-配置)\n- [项目结构](#-项目结构)\n- [测试](#-测试)\n- [许可证](#-许可证)\n\n## 🧭 工作原理\n\n```\n手机飞书 ──消息──► 飞书服务器\n                      │  WebSocket 长连接（SDK 主动外连，零公网 IP）\n                      ▼\n                 Bridge（后端无关）\n                   ├─ FeishuEventClient   接收飞书事件\n                   ├─ AgentBackend（抽象）──► AgentEvent ──► Renderer ──► 飞书卡片\n                   │    ├─ CodexBackend      WebSocket JSON-RPC\n                   │    ├─ ClaudeBackend     claude -p 子进程（stream-json）\n                   │    └─ OpenCodeBackend   opencode serve + REST/SSE\n                   └─ SessionStore        会话分组 / 多会话 / 持久化\n```\n\n核心是一套**归一化事件模型**：每个后端把各自的原生协议（WebSocket、子进程 NDJSON、HTTP SSE）翻译成统一的 `AgentEvent`（文本增量 / 思考 / 工具调用 / 审批 / 完成 / 错误），Bridge 只消费这一种事件，Renderer 统一渲染成飞书卡片。三种完全不同的并发模型藏在同一个抽象之后。\n\n## 🤝 支持的 Agent\n\n| Agent | 连接方式 | 流式文本 | 思考过程 | 工具调用 | 会话续接 | 审批 |\n|-------|----------|:---:|:---:|:---:|:---:|:---:|\n| **Claude Code** | `claude -p` 子进程（stream-json） | ✅ | ✅ | ✅ | `--resume` | ✅ MCP 中继 |\n| **opencode** | `opencode serve` + REST/SSE | ✅ | ✅ | ✅ | session 持久 | ✅ permission |\n| **Codex** | WebSocket JSON-RPC | ✅ | ✅ | ✅ | thread 持久 | ✅ 卡片审批 |\n\n## 🚀 快速开始\n\n### 前置要求\n\n- Python **3.10+**\n- 你要使用的 Agent CLI 之一：\n  - Claude Code — `claude --version`\n  - opencode — `opencode --version`（需 `opencode auth login` 配好模型）\n  - Codex — 另起 `codex remote-control`（默认 `ws://localhost:5123`）\n\n### 1. 一键安装（推荐）\n\n一条命令搞定：安装 uv → 克隆仓库 → 装依赖 → 进入配置向导。\n\n```bash\ncurl -LsSf https://raw.githubusercontent.com/alloevil/pocket-agent/main/install.sh | sh\n```\n\n\u003e 介意 `curl | sh`？先下载看一眼再运行：\n\u003e ```bash\n\u003e curl -LO https://raw.githubusercontent.com/alloevil/pocket-agent/main/install.sh\n\u003e less install.sh \u0026\u0026 sh install.sh\n\u003e ```\n\n脚本默认装到 `~/pocket-agent`（可用 `POCKET_AGENT_DIR=/your/path` 自定义），可重复运行（已存在则更新）。\n\n\u003cdetails\u003e\n\u003csummary\u003e手动安装（用 uv 或传统 venv，点击展开）\u003c/summary\u003e\n\n```bash\ngit clone https://github.com/alloevil/pocket-agent.git\ncd pocket-agent\n\n# 方式 A：uv（推荐，比 pip 快一两个数量级，自动管理虚拟环境）\n# 装 uv：curl -LsSf https://astral.sh/uv/install.sh | sh\nuv sync                          # 按 uv.lock 安装精确依赖\nuv run python main.py setup      # 进入配置向导\n\n# 方式 B：标准 venv + pip\npython3 -m venv .venv\nsource .venv/bin/activate        # Windows: .venv\\Scripts\\activate\npip install -e .\npython main.py setup\n```\n\u003c/details\u003e\n\n\u003e 一键脚本只把**环境**准备到「可以开始配置」——飞书凭证仍需你到开放平台获取（见下一步），向导会引导你完成。\n\n### 2. 创建飞书应用\n\n\u003e 配置向导会分步引导你完成这一步并附直达链接；这里列出供参考。\n\n1. 在[飞书开放平台](https://open.feishu.cn/)创建企业自建应用，启用机器人能力\n2. 权限管理 → **批量导入**，粘贴一段权限 JSON（格式 `{\"scopes\":{\"tenant\":[...],\"user\":[...]}}`）：\n   - 运行 `uv run python main.py setup`，向导第 ① 步会打印**可直接复制的完整权限 JSON**（一次开齐 im / docs / sheets / base / wiki / task 等全部能力，为日后扩展预留）\n   - 本程序**核心只需** `im:message.p2p_msg:readonly`、`im:message:send_as_bot`；推荐再开 `application:application:self_manage`（自动识别主人、免手动绑定）\n3. 事件与回调 → 订阅方式 → **使用长连接接收事件**（⚠️ 选成 Webhook 则长连接能连上但收不到消息）\n4. 添加事件 `im.message.receive_v1`，添加回调 `card.action.trigger`（⚠️ **漏加事件 = 发消息完全没反应且不报错**，最常见的坑）\n5. 发布应用（状态需为「已发布」），在「凭证与基础信息」拿到 **App ID** 和 **App Secret**\n\n### 3. 配置\n\n一键安装会自动进入**配置向导**；手动安装则运行：\n\n```bash\nuv run python main.py setup        # 标准 venv 下用 python main.py setup\n```\n\n向导全程引导：① 分步教你建飞书应用 → ② 填凭证并**立即验证**有效性（支持从后台**整段粘贴**自动识别 App ID / Secret）→ ③ 选 agent →\n④ **绑定使用者**（开了 `self_manage` 权限则**自动识别主人、零操作**；否则回退到「启动后给机器人发条消息」自动绑定）→ 保存并启动。\n\n\u003e 开箱**私有默认**：绑定后只有你能用，其他人发来的消息静默忽略；且**永远锁不死自己**——\n\u003e 程序运行时会周期性从飞书重新确认应用所有者。\n\n\u003cdetails\u003e\n\u003csummary\u003e或手动编辑 config.json（点击展开）\u003c/summary\u003e\n\n```bash\nuv run python main.py     # 首次运行自动生成 config.json 并提示\n# 编辑 config.json：填入飞书凭证、选择 agent、设置 workdir\nuv run python main.py     # 再次运行启动\n```\n\n\u003e 首次直接运行不会报错崩溃：缺 `config.json` 会自动从模板生成并提示下一步；\n\u003e 配置缺凭证 / agent 无效 / CLI 未安装时，启动前会给出清晰提示。\n\u003c/details\u003e\n\n## 📲 使用\n\n在飞书里给机器人**直接发文字**即是给 Agent 的指令，例如「看看当前目录有哪些文件」「修复登录接口的报错」「跑一下测试」。\n\n| 命令 | 说明 |\n|------|------|\n| `/new` | 新对话（旧对话保留，可 `/list` 查看） |\n| `/list` | 列出当前聊天的所有对话 |\n| `/switch \u003cid\u003e` | 切换对话 |\n| `/resume \u003cid\u003e` | 恢复历史对话（续接上下文） |\n| `/history` | 列出 claude 本地历史会话（`/history all` 看全部项目）；`/resume \u003cid\u003e` 可接回 |\n| `/rename \u003c名\u003e` | 重命名当前对话 |\n| `/delete \u003cid\u003e` | 删除指定对话 |\n| `/clear` | 清空当前对话上下文（保留 id，下一轮从零开始） |\n| `/cd \u003c路径\u003e` | 切换工作目录（本会话） |\n| `/pwd` | 查看当前工作目录 |\n| `/model \u003c名\u003e` | 切换模型（本会话，下一轮生效） |\n| `/retry` | 重发上一条指令 |\n| `/loop \u003c任务\u003e` | 让 Agent 反复迭代直到自评完成（`/loop \u003c轮数\u003e \u003c任务\u003e` 可指定上限） |\n| `/stop` | 中断当前任务 |\n| `/status` | 当前 agent / 工作目录 / 活跃会话 / 运行状态一览 |\n| `/usage` | 本会话用量统计（轮数 / 工具调用 / 成本） |\n| `/agent` | 查看当前 agent |\n| `/help` | 帮助 |\n\n\u003e 命令返回均为**彩色卡片**（成功绿 / 信息蓝 / 错误红），一眼可辨。\n\n**消息卡片**随流式输出实时刷新，包含运行状态、可折叠思考、工具调用列表、Markdown 正文、耗时与成本页脚；出错时附带「重试」按钮，文件修改审批展示彩色 diff。\n\n## ⚙️ 配置\n\n`config.json` 字段（完整模板见 [`config.example.json`](config.example.json)）：\n\n| 字段 | 说明 | 默认 |\n|------|------|------|\n| `agent` | 默认后端：`codex` / `claude` / `opencode` | `codex` |\n| `workdir` | claude/opencode 子进程的工作目录 | `.` |\n| `feishu_app_id` / `feishu_app_secret` | 飞书应用凭证 | — |\n| `codex_ws_url` | Codex remote-control 地址 | `ws://127.0.0.1:5123` |\n| `claude_model` / `opencode_model` | 模型（空=各自默认） | `\"\"` |\n| `show_thinking` | 是否展示折叠思考面板 | `true` |\n| `throttle_seconds` | 卡片流式更新节流间隔 | `3.0` |\n| `min_delta_chars` | 流式更新最小增量字符（省 API 调用） | `30` |\n| `idle_minutes` | 空闲超时自动开新会话防上下文漂移；0=关闭 | `0` |\n| `persist_path` | 会话持久化文件路径；空=不持久化 | `\"\"` |\n| `heartbeat_seconds` | 运行中心跳刷新间隔；0=关闭 | `15` |\n| `notify_done_seconds` | 长任务完成主动提醒阈值；0=关闭 | `0` |\n| `allowed_users` | 用户白名单（逗号分隔 open_id，空=不限） | `\"\"` |\n| `bot_owner` | 应用所有者 open_id（向导/运行时自动写入，永远放行，锁不死自己） | `\"\"` |\n| `private_by_default` | 开箱私有：未配白名单且已知所有者时仅所有者可用 | `true` |\n\n## 🗂 项目结构\n\n```\npocket-agent/\n├── main.py                       # 入口 / 配置向导\n├── install.sh                    # 一键安装脚本\n├── config.example.json           # 配置模板\n├── pyproject.toml                # 依赖与项目元数据\n├── uv.lock                       # 锁定的精确依赖（可复现安装）\n├── pocket_agent/\n│   ├── events.py                 # 归一化事件模型 AgentEvent / AgentSession\n│   ├── config.py                 # 配置加载与校验\n│   ├── bridge.py                 # 后端无关桥接核心\n│   ├── session_store.py          # 会话分组 / 多会话 / 持久化\n│   ├── renderer_base.py          # 平台无关的 Renderer 抽象接口\n│   ├── renderer.py               # 飞书富卡片渲染\n│   ├── feishu_client.py          # 飞书 API（含重试）+ WebSocket 事件\n│   ├── codex_client.py           # Codex WebSocket JSON-RPC 客户端\n│   ├── mcp_approval.py           # in-process MCP server（Claude 审批中继）\n│   ├── app.py                    # 应用启动\n│   └── backends/                 # codex / claude / opencode 后端\n└── tests/                        # 80 个测试，12 个文件\n```\n\n## 🧪 测试\n\n```bash\nuv run python tests/run_all.py\n```\n\n包含离线解析测试（喂录制的 NDJSON / SSE / JSON-RPC 样本断言事件序列）和真实\nCLI 端到端测试（claude / opencode / mock WebSocket server）；未安装的 CLI 自动跳过。\n\n## 📄 许可证\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falloevil%2Fpocket-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falloevil%2Fpocket-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falloevil%2Fpocket-agent/lists"}