Codex Plugin (v2.0 daemon-channel)
@hasheeai/codex-plugin 是 Hashee 官方的 Codex 通道适配器,把 OpenAI Codex
(codex CLI / codex app-server)接入 Hashee,让 Hashee 用户可以和你的
Codex 会话直接对话。
技术真源:docs/sdk/Hashee_Codex_Plugin_Spec_v2.0.md (2026-05-08
owner-approved,frozen)。
工作模型
Hashee user Hashee 后端 你的本机 │ 发消息 ──加密──► 盲管道 / 路由 ──WS─► │ ▼ ┌──────────────────────────┐ │ Codex Plugin Daemon │ │ (long-running Node.js) │ │ │ │ ┌────────────────────┐ │ │ │ @hasheeai/ │ │ │ │ agent-sdk-ts (SDK) │ │ │ │ ↕ E2EE │ │ │ └────────────────────┘ │ │ │ │ │ onMessage callback │ │ │ │ │ ▼ │ │ Per-conversation queue │ │ │ │ │ ▼ │ │ CodexAppServerSession │ │ (manages thread_id + │ │ `turn/start` + events) │ │ │ │ │ ▼ │ └───────────┼──────────────┘ │ │ JSON-RPC stdio ▼ ┌──────────────────────────┐ │ codex app-server │ │ --listen stdio:// │ │ (Codex 子进程) │ └──────────────────────────┘特征:
- 插件 daemon 不是 Codex 的 hook,也不注入 prompt。
- 插件用 JSON-RPC 调
codex app-server的thread/start/thread/resume/turn/startAPI,把 Hashee 用户消息原样作为 turn input。 - Codex 的输出(stream delta、tool call、approval、生成的文件)通过子进程 stdout JSONL 事件流回 daemon,daemon 把每个事件转换为对应的 Hashee 操作 (SDK stream / artifact / 文件上传)。
安装
Step 1 — 安装 Codex CLI
参考 Codex 官方文档。本插件假设你已经能用
codex --version 跑通。
Step 2 — 在 Hashee app 创建 Agent
按 在 Hashee app 里创建 Agent
拿到 agent_id 和 agent_token。
Step 3 — 安装插件
npm install -g @hasheeai/codex-pluginhashee-codex-plugin --versionV1 内测期通过 GitHub Packages 私有 registry 分发,需先按 SDK 安装与配置 配置好 .npmrc。V1.x 公开后即可直接 npm install 拉取。
Step 4 — 启动 daemon
HASHEE_CODEX_AGENT_ID="<your-agent-uuid>" \HASHEE_CODEX_AGENT_TOKEN="hsk_..." \HASHEE_CODEX_SERVER_URL="https://api.hashee.ai" \HASHEE_CODEX_WORKDIR="$(pwd)" \HASHEE_CODEX_MODEL="gpt-5.5" \HASHEE_CODEX_REASONING_EFFORT="medium" \pnpm --filter @hasheeai/codex-plugin exec hashee-codex-plugin预期 stderr 日志:
[hashee-codex-daemon] init start mode=websocket[hashee-codex-daemon] init complete[hashee-codex-daemon] handlers registered[hashee-codex-daemon] status=connected完整 env 表:
| env | 必填 | 默认 | 说明 |
|---|---|---|---|
HASHEE_CODEX_AGENT_ID | 是 | — | Agent UUID |
HASHEE_CODEX_AGENT_TOKEN | 是 | — | hsk_... |
HASHEE_CODEX_SERVER_URL | 否 | https://api.hashee.ai | API base URL |
HASHEE_CODEX_WORKDIR | 否 | process.cwd() | Codex 工作目录 |
HASHEE_CODEX_HOME | 否 | $CODEX_HOME | Codex 配置目录 |
HASHEE_CODEX_MODEL | 否 | Codex 默认 | 如 gpt-5.5 |
HASHEE_CODEX_REASONING_EFFORT | 否 | medium | low / medium / high |
HASHEE_CODEX_SANDBOX | 否 | workspace-write | Codex sandbox 等级 |
HASHEE_CODEX_CONVERSATION_ID | 否 | — | 可选,固定绑定某个会话 |
HASHEE_CODEX_PLUGIN_KEYCHAIN | 否 | 0 | 设为 1 用 macOS Keychain 存密钥(仅测试) |
注意 env 前缀是 HASHEE_CODEX_*(避免和 Claude Code Plugin 串号)。
Step 5 — 后台运行(生产)
systemd 单元(Linux):
[Unit]Description=Hashee Codex Plugin daemonAfter=network.target
[Service]Type=simpleUser=hasheeEnvironmentFile=/etc/hashee/codex.envWorkingDirectory=/home/hashee/workExecStart=/usr/local/bin/hashee-codex-pluginRestart=on-failureRestartSec=5
[Install]WantedBy=multi-user.target/etc/hashee/codex.env:
HASHEE_CODEX_AGENT_ID=01906abc-...HASHEE_CODEX_AGENT_TOKEN=hsk_...HASHEE_CODEX_MODEL=gpt-5.5HASHEE_CODEX_REASONING_EFFORT=mediumsudo systemctl enable --now hashee-codex.servicesudo journalctl -u hashee-codex.service -fmacOS 用 launchd,Windows 用 NSSM 类似。
Step 6 — 验证消息往来
诊断命令:
HASHEE_CODEX_AGENT_ID="..." HASHEE_CODEX_AGENT_TOKEN="..." \hashee-codex-plugin doctor预期:
status=okagent_id=01906abc-...server_url=https://api.hashee.aicredential_source=envlaunch_agent=missing # macOS 才显示这一行daemon_process=running在另一终端:
- 打开 Hashee app,搜索你创建的 Agent,添加。
- 发消息 “请生成一个 Python 斐波那契函数”。
- daemon stderr 应出现:
[hashee-codex-daemon] inbound message=01HZ... prompt_chars=24[hashee-codex-daemon] codex event thread id=t_abc...[hashee-codex-daemon] codex event content[hashee-codex-daemon] codex event done[hashee-codex-daemon] turn metrics message=01HZ... queue_ms=12 first_event_ms=420 total_ms=8120 events=18 files=1
- Hashee app 中收到 Codex 流式回复 + 一个 .py 文件附件。
实拍示例 — Codex 生成的项目预览 tarball

图:Codex 跑完 turn 后,把
react-preview-mp7zr01j.tar真的上传到了 Hashee 聊天。用户在 Mobile 上看到的就是一张可点开的文件卡,文件名 / 大小 / Ready 状态都齐了。
实拍示例 — Codex 生成的 HTML 静态预览

图:另一种交付形态—— Codex 把生成的 HTML 预览作为附件交付,Hashee 在 iOS 上能直接打开(黑色顶部条 = iOS 模拟器的真实 navbar)。
12 类桥接能力
| 类别 | 方向 | 说明 |
|---|---|---|
| Text input | Hashee → Codex | 用户文本作为 Codex turn input |
| Attachment input | Hashee → Codex | 附件下载到 workdir,路径喂给 Codex |
| Group routing | Hashee → Codex | 按 @mention / DM 决定是否处理 |
| Stream delta | Codex → Hashee | item/agentMessage/delta → SDK stream 帧 |
| Final message | Codex → Hashee | item/agentMessage/content → 定稿消息 |
| Tool progress | Codex → Hashee | item/commandExecution → Artifact progress |
| Approval request | Codex → Hashee | requestApproval → Artifact approval card |
| Approval response | Hashee → Codex | 用户确认 → JSON-RPC 回 Codex |
| File upload | Codex → Hashee | Codex 生成的文件 → SDK uploadFile |
| Image upload | Codex → Hashee | 同上,mime 自动推 |
| Typing indicator | Codex → Hashee | turn 开始时自动 agent.typing() |
| Done / error | Codex → Hashee | turn 完成时通知 |
持久化文件
~/.hashee/<agent_id>/ 下:
| 文件 | 用途 |
|---|---|
keystore.json | X25519 + Ed25519 私钥(mode 0600) |
keys-sync.json | 上次公钥同步时间戳,避免频繁 sync |
codex-sessions.json | per-conversation 的 Codex thread_id 映射 |
processed-messages.json | 已处理 message_id 集合(幂等去重) |
turn-metrics.jsonl | 性能 metric 滚动日志 |
plugin-event.log | plugin 事件日志(debug 用) |
Codex Channel Rule(强制)
Plugin Channel Parity Rules 对 Codex 集成有最严格的限制:
- ❌ 禁止 hook 注入:
SessionStart/UserPromptSubmit/PreToolUse/PostToolUse/Stop/additionalContext/--append-system-prompt全部禁止。 - ❌ 禁止隐藏 prompt:不能用 test marker / hidden prompt / system prompt 强制 Codex 走预定路径。
- ❌ 禁止反复 re-pair:成功配对后不能反复 re-register / re-pair。
- ❌ 禁止改写用户消息:用户消息原样作为 turn input。
- ❌ 禁止合成假输出:所有 Codex 消息内容必须来自真实 Codex session。
已知踩坑
- v1.0 hook 模型 spec 已废弃 → 不要按 v1.0 做;必须用 v2.0 daemon-channel。
- env 前缀必须
HASHEE_CODEX_*,混用HASHEE_AGENT_*会和 Claude Code Plugin 互相干扰。 HASHEE_CODEX_PLUGIN_KEYCHAIN默认0,避免 daemon 启动时弹 macOS Keychain 提示。- 同 Agent 最多 3 个并发连接——不能同时启 Claude Code + Codex + OpenClaw 用同一 agent_id。
- 文件上传单文件 100 MB 硬上限。
- Codex 接收 attachment 时路径是 daemon workdir 下的临时文件——不在 Codex 的 sandbox 内 时 Codex 拒访问;务必让 daemon 的 workdir 包含在 Codex sandbox 范围内。
- daemon 重启后已存在的 Codex
thread_id会自动通过thread/resume恢复——不会丢上下文。
故障排查
status=ok 但消息发不进 Codex
- 检查
codex app-server是否能正常 spawn(手动跑codex app-server --listen stdio://) - 看 daemon
plugin-event.log是否记录inbound message - 看 daemon 是否有 JSON-RPC 错误(
turn/start failed: ...)
Codex 输出没回到 Hashee
- 检查
codex-sessions.json是否有当前 conversation 的thread_id - 看 daemon 是否捕获
agentMessage/content事件(codex event contentlog) - 检查 SDK status 是否仍 connected
AGENT_KEYS_MISMATCH
rm -rf ~/.hashee/<agent_id>/# 重启 daemon → SDK 重新生成密钥 + 注册演示视频
视频文字版逐节描述
- 00:00 – 00:10 — 终端启动 daemon,stderr 显示
init complete→status=connected。 - 00:10 – 00:20 —
hashee-codex-plugin doctor输出status=ok+daemon_process=running。 - 00:20 – 00:35 — Hashee app 添加 CodexBot,发”请生成一个 Python 斐波那契
函数并保存到 fib.py”。daemon 终端显示
inbound message=...。 - 00:35 – 00:55 — 短暂 typing 后,Hashee app 显示 Codex 流式回复一段说明文字,
紧接收到一个
fib.py文件附件(约 800 字节)。点开看到完整代码。 - 00:55 – 01:15 — 演示 approval:用户问”在我的笔记里搜一下 ‘auth’”。 Codex 决策调用 fs tool;daemon 转发为 Hashee app 的一张 Approval 卡片 “Codex 想要执行 grep 命令在 ~/notes/,是否允许?“。用户点”允许”, 几秒后 Codex 返回搜索结果。
- 01:15 – 01:30 — 演示 daemon restart:Ctrl+C 杀掉 daemon,重新启动;
Hashee app 继续发新消息,daemon 通过
thread/resume自动恢复 Codex session 上下文,回复仍能引用前面”我们刚才搜的 auth”。
下一步
- Claude Code Plugin — 另一个 plugin
- OpenClaw Plugin — 另一个 plugin
- 三个 Plugin 怎么选 — 对比与决策树
- Plugin Channel Parity Rules — Codex Channel Rule 全文