本节把前台、后台、status、result、cancel、resume 统一成状态机来看。这样比线性文字更容易观察。

总状态机

stateDiagram-v2
  [*] --> Created: /codex:rescue task
  Created --> RunningForeground: default
  Created --> QueuedBackground: --background
  QueuedBackground --> RunningBackground: worker starts
  RunningForeground --> Completed: finalMessage
  RunningForeground --> Failed: error
  RunningBackground --> Completed: finalMessage saved
  RunningBackground --> Failed: error saved
  RunningBackground --> CancelRequested: /codex:cancel
  CancelRequested --> Cancelled
  Completed --> ResultRead: /codex:result
  Failed --> ResultRead: /codex:result

前台任务怎么流动?

sequenceDiagram
  participant U as User
  participant C as Claude Code
  participant N as Node companion
  participant X as Codex app-server
  U->>C: /codex:rescue fix bug
  C->>N: task(prompt)
  N->>X: thread/start + turn/start
  X-->>N: finalMessage
  N-->>C: renderTaskResult
  C-->>U: 展示结果

前台任务适合:

  • 快速问原因。
  • 小范围代码调查。
  • 需要马上看结论的任务。

后台任务怎么流动?

sequenceDiagram
  participant U as User
  participant C as Claude Code
  participant N as Node companion
  participant S as Job Store
  participant W as Worker
  participant X as Codex app-server
  U->>C: /codex:rescue --background investigate
  C->>N: task(background=true)
  N->>S: create jobId
  N->>W: spawn detached worker
  N-->>C: return jobId
  W->>X: thread/start + turn/start
  X-->>W: finalMessage
  W->>S: save result
  U->>C: /codex:result jobId
  C->>N: result(jobId)
  N->>S: read result
  N-->>C: result text

后台任务适合:

  • 大范围代码阅读。
  • 长时间测试或排查。
  • 你想继续和 Claude Code 聊别的事情。

status/result/cancel 分别读什么?

命令核心动作依赖数据
/codex:status查看 job 是否 queued/running/completed/failedjob metadata
/codex:result读取最终输出和摘要finalMessage、log、status
/codex:cancel请求终止后台 workerjobId、pid 或取消标记

resume 是状态机之外的“接线”

--resume 本质上不是一个状态,而是一次寻找历史 threadId 的接线动作

flowchart TD
  A["/codex:rescue --resume 新任务"] --> B[查最近完成或运行过的 task job]
  B --> C{找到 threadId?}
  C -->|是| D[thread/resume]
  C -->|否| E[thread/start]
  D --> F[turn/start]
  E --> F

这里的关键是:resume 依赖 job store 里保存的 threadId。如果没有保存 threadId,恢复就只能退化成新线程。

观察这套设计的角度

不要只看“它有几个命令”,要看命令背后的状态模型:

  • task 创建状态。
  • background 让执行从当前进程分离。
  • status 观察状态。
  • result 消费终态。
  • cancel 改变运行中状态。
  • resume 复用历史执行上下文。
    这就是它比一个简单 shell wrapper 更高级的地方。

相关笔记