Appearance
后端体系
CodeLark 自己的核心运行数据当前已经主要使用 JSON 文件存储。位于 ~/.codelark/data 目录下。
业务模型
CodeLark 的核心不是“一个 IM 聊天等于一个 Codex 线程”。正确链路是:
text
Codex thread
-> BridgeSession
-> ChannelChat
-> IMChannel / IM chat更具体地说:
Codex thread
Codex 自己的对话线程。CodeLark 不拥有它,只记录它的 id。 Codex thread 可以来自不同入口:
- IM 里发起的一次 SDK turn。
- 本地 Codex CLI / TUI 会话。
- 本地 Codex Native 客户端产生的会话。
- 被
/t从本地 Codex session 列表接管的已有线程。
BridgeSession
BridgeSession 是本地会话容器,负责承载一次可持续对话的业务状态。
保留职责:
- 本地 session id。
- 会话名、工作目录、模型、默认模式、reasoning 设置。
- 运行态:running/queued/idle、health、mirror 状态、stream UI 状态。
- 消息缓存:
messages/<sessionId>.json。 - 当前 runtime 身份:Codex
threadId、ClaudesessionId/cwd或 KimisessionId/cwd。 语义规则: - Codex session 没有
threadId:这是一个尚未创建 Codex thread 的本地 session。 - Codex session 有
threadId:这是一个已经关联 Codex thread 的本地 session。 - Claude/Kimi session 的
sessionId/cwd来自对应 CLI 写出的本地会话文件,可能来自普通 IM 对话,也可能来自用户接管已有本机会话。
ChannelChat
ChannelChat 只表示“某个 IM chat 当前绑定到哪个本地 session”。
保留职责:
- channel instance:
channelType、channelProvider、channelAlias。 - chat 身份:
chatId、chatKind、chatUserId。 - 本地 session 指针:
bridgeSessionId。
字段收敛:
- 一个 IM chat 只有一个 ChannelChat,一个 BridgeSession 也只保留一个聊天绑定。
- 删除旧
workingDirectory、model、mode、chatDisplayName;会话配置覆盖归属 scoped TOML,运行身份和展示状态归属BridgeSession。 - ChannelChat 不再缓存 Codex thread id。
- 所有 thread id 读取都必须从
store.getSession(channelChat.bridgeSessionId)?.runtime.codex.threadId获取。
IMChannel
IMChannel 是配置好的 IM 入口。当前支持飞书。
一个通道实例包含:
- provider:飞书。
- 实例 id。
- 别名。
- 是否启用。
- 平台凭据和连接配置。
- 运行期 adapter 状态。
多个通道实例可以同时存在,例如:
- 飞书主号。
- 飞书备份号。
通道实例不是会话。它只是让某个平台的消息进入 bridge,并把 bridge 输出送回平台。真正的会话身份仍然在 BridgeSession,聊天到会话的关系仍然在 ChannelChat。
线程相关能力
以下能力都基于 BridgeSession.codex_thread_id:
- 普通 IM 对话 resume。
/t选择或接管已有 Codex 会话。- history 读取。
- mirror 订阅。
- reuse 当前 Codex thread。
- tmux provider resume。
当前 JSON 存储
src/storage/json-store.ts 中的 JsonFileStore 是当前 Bridge 运行期数据的主存储实现,数据目录位于 CODELARK_HOME/data。
主要文件包括:
sessions.json:Bridge session 记录。channel-chats.json:IM channel chat 与 session 的绑定关系。channel-default-targets.json:通道默认目标。permissions.json:权限回调链接。offsets.json:消费偏移量。dedup.json:去重键。audit.jsonl:审计日志,当前新记录按 JSONL 追加;旧audit.json仍可读取。messages/<sessionId>.json:单个 Bridge session 的消息缓存。
其它模块也有独立 JSON 状态文件:
config.toml:全局主配置文件。config/sessions/、config/channels/:Session / Channel 级 TOML 覆盖。config.json/config.env:v1 迁移输入,迁移成功后归档,不再作为运行时配置来源。ui-session-meta.json:旧 UI session 名称元数据;启动迁移会合并进sessions.json.name并删除该文件。thread-table-messages.json:线程表格消息置顶/展示记录。runtime/status.json、runtime/ui-server.json:服务运行状态。
存储边界
CodeLark 自有数据:
- 使用 JSON/JSONL。
- 支持人工检查和修复。
- 先保证业务字段清晰,再考虑统一 storage helper。
- 后续可以增加 schema version、迁移、备份和损坏恢复策略。
Codex 外部数据:
- Codex Native session JSONL:只读解析。
- Codex Native
session_index.jsonl:只读读取标题和更新时间。 - Codex CLI/SDK thread id:写入本地 session 的
codex_thread_id,不再写入 ChannelChat。
5. API 层
目标:让 UI server 和 IM 命令共享更清晰的本地后端契约。
计划:
- 为 UI server 的本地接口定义 typed request/response。
- 修改类接口增加输入校验。
- 错误返回统一为:
json
{
"ok": false,
"code": "ERROR_CODE",
"message": "Human readable message",
"details": {}
}- UI 只依赖 API DTO,不直接理解存储文件结构。
6. Runtime 层
目标:统一 bridge、UI server、mirror、health 和 hot update 的状态表达。
计划:
- 梳理
runtime/status.json、runtime/ui-server.json等状态文件。 - 统一字段:
running、pid、port、startedAt、lastError、updatedAt。 - doctor 脚本读取 runtime 状态、配置文件和日志,输出可执行的修复建议。
- 状态查询保持只读,不承担运行态修复动作。