ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

CodeWhale Feishu/Lark 手机桥:用 `codewhale serve --http` 从飞书/ Lark 群聊远程控制终端 Agent

2026/9/10 1:35:12 拓冰建站 浏览量
CodeWhale Feishu/Lark 手机桥:用 `codewhale serve --http` 从飞书/ Lark 群聊远程控制终端 Agent CodeWhale Feishu/Lark 手机桥用codewhale serve --http从飞书/ Lark 群聊远程控制终端 Agent【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale本文以仓库 integrations/feishu-bridge/README.md 为骨架讲解如何用官方 Lark/Feishu Node SDK 长连接模式把本地codewhale serve --http运行时接入飞书Feishu与 Lark 聊天让手机消息驱动本地 Agent 工作。读者将掌握桥的完整安全模型回环绑定、运行时 Token、聊天白名单、审批命令、全部斜杠命令的语义与调用链、环境变量配置、配置校验脚本与 systemd 部署方式并看到其背后的源码实现与测试验证。概述桥是什么、解决什么问题CodeWhale 的本地运行时codewhale serve --http默认只监听本机地址工作区、Shell 与 HTTP 监听器都在本地因此在外面用手机无法直接触达。Feishu/Lark Bridge 用官方 larksuiteoapi/node-sdk 的长连接WebSocket模式建立一条飞书/ Lark 消息 → 本地运行时 HTTP API的通道桥进程作为独立 Node 服务常驻运行订阅飞书开放平台im.message.receive_v1事件把聊天内容转成对运行时/v1/*接口的调用再把运行时返回的状态、摘要与审批事件回复到聊天中。值得强调的是第一版桥不需要公网 Webhook URL——SDK 的 WebSocket 长连接由飞书/Lark 开放平台主动与桥建立桥只需能访问外网即可这在部署到内网服务器或轻量云主机时非常省事。桥只把提示词、状态、线程摘要、审批消息转发给聊天端工作区、Shell 与 HTTP 监听器始终留在本地、由运行时 Token 保护。桥的目录结构如下仓库相对路径integrations/feishu-bridge/src/index.mjs入口事件分发、命令处理、SSE 事件流消费integrations/feishu-bridge/src/lib.mjs身份解析、白名单判定、命令解析、配置校验integrations/feishu-bridge/scripts/validate-config.mjs启动前配置校验脚本integrations/bridge-core/src/lib.mjs与 Telegram/微信桥共享的ThreadStore、SSE 解析、运行时 HTTP 客户端deploy/tencent-lighthouse/examples/feishu-bridge.env.example官方环境变量模板安全模型默认拒绝、逐层收敛桥的安全设计是默认锁定逐层放行回环绑定codewhale serve --http始终绑定127.0.0.1桥通过本机 HTTP 访问它外部网络无法直接触达运行时监听器。运行时 Token所有/v1/*调用都携带CODEWHALE_RUNTIME_TOKEN兼容旧的DEEPSEEK_RUNTIME_TOKEN命名作为 Bearer 凭证。桥与运行时必须持有同一个 Token见 deploy/tencent-lighthouse/examples/runtime.env.example 与 bridge-core 中的 authHeaders()。聊天白名单非白名单聊天一律被拒绝除非为首次配对临时设置CODEWHALE_ALLOW_UNLISTEDtrue。判定逻辑 isAllowed() 会同时检查chat_id、open_id、union_id、user_id四种标识中的任意一种。默认仅私聊群聊控制默认关闭必须显式设置FEISHU_ALLOW_GROUPStrue才启用启用时还强制要求消息以FEISHU_GROUP_PREFIX默认/cw开头防止群成员误触发 Agent。审批文本化工具调用审批通过文本命令/allow approval_id或/deny approval_id完成手机上即可决定放行还是拒绝。校验逻辑里还包含了几条硬红线见 validateBridgeConfig()DEEPSEEK_RUNTIME_URL或CODEWHALE_RUNTIME_URL必须指向 localhost否则报remote_runtime_url错误群控开启的同时禁止白名单留空ALLOW_UNLISTEDtrue否则报open_group_control错误桥与 runtime.env 中的 Token 不一致时报token_mismatch工作区与线程映射文件必须是绝对路径FEISHU_DOMAIN只接受feishu、lark或以https://open.开头的地址。安装与启动依赖与启动cd /opt/codewhale/feishu-bridge npm install --omitdev cp .env.example /etc/codewhale/feishu-bridge.env sudoedit /etc/codewhale/feishu-bridge.env node src/index.mjs桥使用larksuiteoapi/node-sdk^1.52.0与 Node.js ≥18见 integrations/feishu-bridge/package.json。启动时入口 index.mjs 依次完成读取并校验环境变量 → 用Lark.Client创建 REST 客户端、用Lark.WSClient建立长连接 → 打开线程映射存储ThreadStore→ 注册im.message.receive_v1事件 → 启动 WebSocket 并尝试重挂接未完成的 turn。启动前配置校验强烈建议先跑校验脚本它同时读取桥配置与运行时配置做交叉验证npm run validate:config -- \ --env /etc/codewhale/feishu-bridge.env \ --runtime-env /etc/codewhale/runtime.env \ --workspace-root /opt/whalebro \ --check-filesystem脚本实现见 scripts/validate-config.mjs--check-filesystem会实际验证工作区目录可读、线程映射目录可写、两个 env 文件可读--json输出机器可读报告退出码非 0 表示存在阻断性错误。测试用例 lib.test.mjs 覆盖了锁定态 DM 配置通过校验和非安全组合被拒绝两条路径。首次配对First Pairing默认白名单为空时所有聊天都会被拒绝并收到一条包含自身chat_id/open_id/union_id/user_id的拒绝消息pairingRefusalText()。首次配对流程临时把CODEWHALE_ALLOW_UNLISTEDtrue给机器人发/status复制返回的chat_id或open_id/union_id填入CODEWHALE_CHAT_ALLOWLIST立刻把CODEWHALE_ALLOW_UNLISTEDfalse并重启服务。环境变量参考完整清单以官方模板 feishu-bridge.env.example 为准全部变量如下表桥与运行时均兼容CODEWHALE_*与旧DEEPSEEK_*前缀CODEWHALE_*优先见 index.mjs 的 config 组装。变量默认值说明FEISHU_APP_ID必填飞书/Lark 开放平台自建应用的 App IDFEISHU_APP_SECRET必填对应 App SecretFEISHU_DOMAINfeishufeishu/lark或https://open.开头的开放平台域名映射见 resolveLarkDomain()CODEWHALE_RUNTIME_URLhttp://127.0.0.1:7878运行时 HTTP 地址校验强制 localhostCODEWHALE_RUNTIME_TOKEN必填与 runtime.env 一致的 Bearer TokenCODEWHALE_WORKSPACE进程当前目录运行时工作区绝对路径CODEWHALE_MODELauto桥级默认模型/model命令可覆盖CODEWHALE_MODEagent运行时模式创建线程时透传CODEWHALE_ALLOW_SHELLtrue是否允许 Shell 工具CODEWHALE_TRUST_MODEfalse信任模式开关CODEWHALE_AUTO_APPROVEfalse是否自动审批工具调用CODEWHALE_CHAT_ALLOWLIST空逗号分隔的chat_id/open_id/union_id白名单CODEWHALE_ALLOW_UNLISTEDfalse放行所有聊天仅用于首次配对FEISHU_THREAD_MAP_PATH/var/lib/codewhale-feishu-bridge/thread-map.json聊天↔线程映射的 JSON 存储路径FEISHU_ALLOW_GROUPSfalse是否允许群聊控制FEISHU_REQUIRE_PREFIX_IN_GROUPtrue群聊是否强制/cw前缀FEISHU_GROUP_PREFIX/cw群聊触发前缀可自定义FEISHU_MAX_REPLY_CHARS3500单条回复最大字符数超长自动分片CODEWHALE_TURN_TIMEOUT_MS900000单轮 turn 的 SSE 等待超时毫秒布尔值解析接受1/true/yes/onparseBool()列表用英文逗号分隔并自动去空白parseList()。注意这些是 CodeWhale 环境下的推荐名仓库内lib.mjs的校验逻辑与测试仍沿用DEEPSEEK_*前缀旧安装/etc/deepseek/*.env可无缝迁移新部署建议统一使用CODEWHALE_*前缀。聊天命令与消息语义除斜杠命令外其余消息一律作为提示词prompt发送。完整命令清单来源README 与 helpText()/status— 运行时健康、版本、绑定地址、认证要求、工作区 git 状态staged/unstaged/untracked实现见 sendStatus()并发调用/health、/v1/runtime/info、/v1/workspace/status三个接口/threads— 最近 8 个运行时线程含已归档格式thread_id [状态] 标题/摘要/new— 为当前聊天强制新建线程/resume thread_id— 把当前聊天绑定到既有线程并从该线程最新 seq 继续/model name|default— 设置/重置当前聊天的 per-chat 模型default或空参数恢复桥级默认setChatModel()/interrupt— 中断当前活跃 turn/compact— 对当前线程发起压缩reason: phone bridge request/allow approval_id [remember]— 批准待审批的工具调用可附带remember/deny approval_id— 拒绝待审批的工具调用命令解析链路parseCommand()判断是否以/开头bridge-corecommandAction()映射为具体动作并把未知命令降级为普通 promptbridge-core最后 index.mjs 的 handleCommand() 分发。测试 lib.test.mjs 覆盖了这些映射与降级行为。群聊控制群聊控制默认关闭开启后FEISHU_ALLOW_GROUPStrue群消息必须以前缀开头才会被接受/cw check git status and tell me what is dirty前缀剥离逻辑 stripGroupPrefix()私聊p2p无需前缀群聊要求前缀否则整个消息被丢弃accepted: false。如果只发一个孤零零的前缀/cw会被当作/help。测试见 lib.test.mjs。一次对话的完整调用链从用户发消息到收到回复桥内部实际发生如下源码依据handleIncomingMessage() 与 runPrompt()身份解析从im.message.receive_v1事件提取chat_id、message_id、chat_type、open_id等incomingIdentity()话题归属缓存入站消息 ID 到线程映射使回复通过 reply API 留在同一话题内避免话题群每次 bot 回复都新建独立话题类型过滤仅接受文本消息其他类型直接回复 Only text messages are supported群前缀/群开关/白名单三层过滤任一不通过即拒绝或静默丢弃线程创建或复用ensureThread()向POST /v1/threads提交model、workspace、mode、allow_shell、trust_mode、auto_approve与一段面向手机控制的 system prompt发起 turnPOST /v1/threads/{id}/turns记录activeTurnId与lastSeq消费 SSE 事件流streamTurnEvents() 拉取/v1/threads/{id}/events?since_seq...逐条处理item.delta累积 agent 消息、approval.required把审批请求以文本命令形式推给用户、turn.completed回传最终文本、turn.lifecyclefailed/canceled/interrupted状态通知超时与中断整个 SSE 流受turnTimeoutMs控制AbortController超时回复 Turn timed out after Ns。重启恢复入口启动后调用 reattachActiveTurns()遍历线程映射中带activeTurnId的聊天向运行时查询是否仍有queued/in_progress的 turnlatestRunningTurn()有则从上次 seq 继续订阅事件并通知用户无则清空状态。测试 startup-order.test.mjs 专门断言了ThreadStore 初始化 → WS 启动 → 重挂接这一启动顺序。消息分片与回复策略长回复通过 splitMessage() 按字符上限切分切分点优先选换行、其次空白且不会拆散 surrogate pairemoji遇到未闭合的 代码围栏会自动续上前缀、在块尾补后缀保证代码块语义完整。发送时优先用 reply API 把回复留在同一话题失败则回退到chat_id维度的 message createsendText()。systemd 部署Tencent Lighthouse 示例官方示例面向腾讯轻量云Lighthouse将运行时与桥分别作为两个 systemd 服务管理服务定义见 deploy/tencent-lighthouse/systemdsudo systemctl enable --now codewhale-runtime codewhale-feishu-bridge sudo journalctl -u codewhale-feishu-bridge -fcodewhale-feishu-bridge.service 关键点Wants/After声明依赖codewhale-runtime.service确保运行时先就绪环境文件按-前缀加载两处旧的/etc/deepseek/feishu-bridge.env与新的/etc/codewhale/feishu-bridge.env后者优先平滑迁移旧安装以codewhale用户、/opt/codewhale/bridge为工作目录运行node src/index.mjs安全加固NoNewPrivileges、PrivateTmp、ProtectSystemfull仅放行ReadWritePaths/var/lib/codewhale-feishu-bridge线程映射文件落盘于此。环境变量模板runtime.env.example 与 feishu-bridge.env.example中占位符replace-with-*、cli_xxx...会被校验脚本识别为未配置项isPlaceholderValue()部署前务必全部替换。测试与质量保障test/lib.test.mjs覆盖命令解析、前缀剥离、白名单判定、审批参数解析、长文本分片、配置校验的通过/拒绝路径以及 per-chat 模型字段在状态替换时的保留行为preservedChatStateFields()。test/startup-order.test.mjs静态校验启动顺序。运行方式npm testNode 内置 test runner、npm run check语法检查见 package.json。常见问题与边界为什么不需要公网地址桥使用 SDK 的 WebSocket 长连接模式订阅事件飞书开放平台主动连入桥自身无需暴露端口但仍需能访问外网且运行时 HTTP 只监听本机。如何安全开启群控设置FEISHU_ALLOW_GROUPStrue并保持FEISHU_REQUIRE_PREFIX_IN_GROUPtrue默认同时在白名单内加入群chat_id校验器会在群控开放配对或群控无前缀时给出阻断/告警。审批怎么用运行时在需要调用工具时推送approval.required事件桥把tool、approval_id、描述和/allow|/deny approval_id的提示发到聊天用户在手机上回复对应命令即可。/allow id remember会把该审批记住后续不再重复询问。消息太长怎么办回复自动按FEISHU_MAX_REPLY_CHARS分片保护飞书单条消息上限同时尽量在换行/空白处切分并维护代码围栏完整性。切换模型/model name只影响当前聊天per-chat线程内已运行的 turn 不受影响新 turn 使用切换后的模型见 runPrompt() 的effectiveModel逻辑。进一步阅读integrations/telegram-bridge/README.md 与 integrations/wecom-bridge/README.md同构的手机桥实现共享 bridge-core 的ThreadStore与 SSE 客户端docs/WEB.md 与 docs/FLEET.mdcodewhale serve --http运行时协议与线程/会话模型deploy/tencent-lighthouse/systemd运行时与各桥的完整 systemd 单元定义【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考