Theme / v0.21.4

Oh My Codex (OMX)

Codex CLI 工作流增強層

實戰範例

實戰範例 009:第一次啟動 OMX Autopilot 為 Express API 補上請求驗證

新手導向範例:從 omx setup 到 $deep-interview → $ralplan → $ultragoal,走完 v0.21.x canonical staged flow、Autopilot 與 HUD。

實戰背景

你剛聽說 Oh My Codex (OMX) 可以把一個口述目標自動拆解、執行到驗證完成,想找一個夠小的任務走完第一次完整流程。

痛點與問題描述: 手邊有一個小小的 Express API,其中 POST /api/users 沒有做任何請求 Body 驗證,前端送來空物件時就直接寫進資料庫。你想加上驗證,但不想自己一行行寫 schema 與錯誤處理。這正好是個適合丟給 OMX 的小型 $ultragoal:範圍明確、驗收清楚、不涉及跨服務重構。

本範例記錄從零開始的第一次 OMX 入門體驗,使用 v0.21.x 的 canonical staged flow:$deep-interview → $ralplan → $ultragoal,再搭配 Autopilot、HUD 與 .omx/ 持久化狀態。


第 1 步:安裝與專案初始化

確認環境符合需求:Node.js 20+ 與已認證的 Codex CLI。OMX 的主要支援平台是 macOS 與 Linux;Windows 屬 secondary path,建議在 WSL2 中執行以獲得完整的 HUD 體驗。

# 全域安裝 OMX(theme.yaml 中的 installCommand)
npm install -g oh-my-codex

# 在專案根目錄初始化 OMX,合併 agents 設定
omx setup --scope project --merge-agents

omx setup 會在專案下建立 .omx/ 目錄,後續的任務佇列、日誌與記憶體都會落在這裡,這就是 OMX 的持久化狀態根。


第 2 步:下達 $ultragoal 並進入深度訪談

用一句話把目標告訴 OMX,並掛上 $ultragoal 標記:

$ultragoal 為 POST /api/users 加上請求 Body 驗證:
email 必須合法、name 不得為空,違規時回傳 400 與結構化錯誤訊息。

OMX 不會馬上動工,而是先啟動 $deep-interview 收斂需求:

收到 $ultragoal。動工前先確認兩個技術分歧:

  1. 驗證函式庫:專案要用 zod 還是 joi?目前 package.json 兩者都沒有。
  2. 錯誤回傳格式:錯誤訊息要採 { error: { fields: {...} } } 的巢狀格式,還是 RFC 7807 的 application/problem+json

請回覆這兩點,我會據此產出任務佇列。

這就是蘇格拉底式訪談的核心:在寫任何一行程式碼前,先把會導致返工的假設問清楚。


第 3 步:完成訪談,先經 $ralplan 審查再進入 $ultragoal

回覆選型:

用 zod;錯誤格式採 { error: { fields: { email: "...", name: "..." } } }。

訪談只固定需求決策,接著 $ralplan 由 Planner → Architect → Critic 檢查 schema placement、error contract 與 test evidence。這一階段是 advisory;確認計畫可執行後,才交給 $ultragoal 建立 missions,HUD 顯示:

.omx/queue.json 已寫入 4 個任務:
  Mission 1: 新增 src/schemas/userSchema.ts(zod schema)
  Mission 2: 在 routes/users.ts 接入驗證中介層
  Mission 3: 新增全域錯誤處理器回傳 400 結構化錯誤
  Mission 4: 撰寫 invalid payload 測試並執行 pnpm test

HUD 頂部這時會顯示 Queue: 4 | Active: 0 | Done: 0 | Cost: $0.00。確認無誤後啟動 Autopilot:

omx --autopilot --madmax

第 4 步:Autopilot 連續完成任務 1 與任務 2

Autopilot 依序取出任務。Mission 1 落地 src/schemas/userSchema.ts

import { z } from "zod";

export const userSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

Mission 2 把中介層接上 routes/users.ts

import { userSchema } from "../schemas/userSchema";

router.post("/users", (req, res, next) => {
  const result = userSchema.safeParse(req.body);
  if (!result.success) {
    return next(result.error);
  }
  req.body = result.data;
  next();
});

HUD 推進為 Queue: 4 | Active: 2 | Done: 2。過程中你完全沒有手動介入。


第 5 步:測試失敗,$plan 驅動自愈

Mission 4 執行 pnpm test 時,一個針對「email 為空字串」的測試失敗:

FAIL  test/users.validation.test.ts
  ✕ POST /users with empty email returns 400
    expected 500, received 400

問題出在全域錯誤處理器把 zod 的 ZodError 當成未知例外,回了 500。OMX 啟動 $plan,讀測試日誌、鎖定錯誤碼,補上型別判斷:

// app.ts 全域錯誤處理器
import { ZodError } from "zod";

app.use((err, _req, res, _next) => {
  if (err instanceof ZodError) {
    const fields: Record<string, string> = {};
    for (const issue of err.issues) fields[issue.path[0] as string] = issue.message;
    return res.status(400).json({ error: { fields } });
  }
  res.status(500).json({ error: { message: "internal error" } });
});

第二次 pnpm test 全綠。HUD 顯示 Done: 4 | Cost: $0.12


第 6 步:驗收與 .omx/ 狀態檢查

# 確認任務佇列已清空且日誌落地
cat .omx/queue.json   # { "missions": [], "completed": 4 }
pnpm test             # 5 passed

第一次 OMX 入門流程到這裡結束:需求先經 $deep-interview 收斂,再由 $ralplan 審查,最後 $ultragoal 持久執行到全綠測試。


關鍵學習點

  • 訪談與規劃審查分開$deep-interview 收斂人類決策,$ralplan 再用 Planner → Architect → Critic evidence 挑戰計畫;review 通過不等於自動取得 execution authority。
  • Ultragoal 負責持久完成$ultragoal 承接已收斂的目標與驗收條件,Autopilot 依 .omx/ runtime state 推進直到驗證通過。
  • 測試失敗不是終點$plan 會讀測試日誌、定位錯誤碼、補上最小修補再重跑,形成編譯器與測試的閉環。
  • HUD 讓成本透明:頂部狀態列即時顯示剩餘任務數與累積 token 費用,新手也能放心讓 Autopilot 跑到底。