feat(daemon): add codex app-server provider · +5319 · 25 files · 2026-06-01
kind: 'text' | 'skill' 和 skillName。"skill" 是 Codex wire format,Claude Code / ACP 不这么用。更严重的是 service 层也被污染了——编排层直接构造 { kind: 'skill' }。
execution: 'prompt-expansion',让 runner 的 runControl 内部处理就行。
updatedInput(Codex 用户提问回答)和 updatedPermissions(Codex 权限授予)。两个字段只有 Codex adapter 的 protocol.ts 消费。provider-specific 的审批 payload 应放一个 opaque 字段,不暴露 Codex 的字段名。
providerTurnId 被加在 AgentProviderEventBase(每个事件都带),但只有 Codex runner 内部读它做 turn→run 映射。映射是 adapter 的事,不应穿透到公共事件类型。
SessionSink.setCurrentRun(runId)——service 注入 runId,runner 不碰。PR #41 无视已有设计,改了 emit、startTurn、runControl 三个接口签名让 runner 管 runId 再传回 sink。
routes/agents.ts 里变量名叫 codexControlCommandSchema,9 个 Codex 命令名和参数写在路由层。同时 codexProviderConfigSchema 也在路由层。加新 provider 或 Codex 新增命令都要改路由层,且和 codex/index.ts 的命令定义重复——两处要同步。
解决根源后 3 个 Major 自然消失。AgentInput / ApprovalResponse / 路由硬编码是独立问题。
existsSync 解析 skill 路径。daemon 单线程,同步 I/O 阻塞所有 session 的事件处理和 HTTP 请求。run.completed。emit 失败被 .catch 吞掉,run 停在 running 直到 daemon 重启回收。应先 emit 再 evict。