本文档描述 OpenCode Bridge 的关键实现细节。
permission.asked 事件中 tool 可能不是字符串工具名,实际白名单匹配可能落在 permission 字段
回传接口要求 response 为 once | always | reject,不是 allow | deny
收到权限请求
│
▼
判定白名单
│
├─ 命中 → 自动允许
│
└─ 未命中 → 入队等待人工确认
│
▼
用户确认卡片
│
▼
权限回传 OpenCode
问题渲染为飞书卡片
答案通过用户文字回复解析
解析后按 OpenCode 需要的 answers: string[][] 格式回传
答案纳入撤回历史,保持一致性
文本与思考分流写入输出缓冲
出现思考内容时自动切换卡片模式
卡片支持展开/折叠思考内容
最终态保留完成状态
配置
说明
SHOW_THINKING_CHAIN
全局默认:是否显示 AI 思维链
SHOW_TOOL_CHAIN
全局默认:是否显示工具调用链
*_SHOW_THINKING_CHAIN
平台专用:覆盖全局值
触发 /undo
│
▼
删除平台侧消息
│
▼
对 OpenCode 执行 revert
│
▼
更新本地状态
问答场景可能涉及多条关联消息
使用递归回滚作为复杂场景的兜底
下拉选择动作仅记录会话选择,不依赖卡片重绘
行为与 /panel 的下拉交互保持一致
点击"创建群聊"时才执行建群与绑定
避免因卡片状态同步导致误绑定
6. /clear free session 行为
该命令不做单独清理规则
复用生命周期扫描逻辑
可在不重启进程时手动触发清理扫描
/send <绝对路径> 直接调用飞书上传 API,不经过 AI,零延迟
图片(.png/.jpg/.gif/.webp 等)走图片通道(上限 10MB)
其余走文件通道(上限 30MB),与飞书官方限制一致
内置敏感文件黑名单(.env、id_rsa、.pem 等)
仅允许发送位于 ALLOWED_DIRECTORIES 白名单范围内的文件
未配置 ALLOWED_DIRECTORIES 时,/send 默认拒绝
8. 工作目录策略(DirectoryPolicy)
所有会话创建入口统一经过 DirectoryPolicy.resolve() 9 阶段校验:
阶段
说明
1. 优先级合并
合并各来源的目录候选
2. 格式校验
检查路径格式和长度
3. 路径规范化
统一分隔符、去除冗余
4. 危险路径拦截
拒绝 /etc、/root 等敏感路径
5. 白名单校验
检查 ALLOWED_DIRECTORIES
6. 存在性预检
检查目录是否存在
7. realpath 解析
解析符号链接真实路径
8. Git 根归一化
归一到 Git 仓库根目录
9. 归一后复检
归一化后再次检查白名单
显式输入目录(命令参数)
项目别名(PROJECT_ALIASES)
群默认目录(会话绑定存储)
全局默认目录(DEFAULT_WORK_DIRECTORY)
OpenCode 服务端默认目录
未配置 ALLOWED_DIRECTORIES 时,用户不能自定义路径
错误信息脱敏:用户侧只看到通用提示,完整路径仅写入服务端日志
会话映射存储在 SQLite 数据库
支持跨项目会话查询
自动清理无效会话
状态
说明
active
活跃会话
idle
空闲会话
error
错误会话
事件通过 OpenCodeEventHub 统一分发:
事件
说明
permissionRequest
收到权限请求
questionAsked
收到问题
messagePartUpdated
消息片段更新
sessionStatus
会话状态变化
在事件层只做路由与状态变更
不在事件处理器中拼装平台 UI
由各平台的渲染层处理 UI