code-quest-review

star 8

Code Quest project-specific code review checks covering import order, zod schema placement, cross-package event-name alignment, server handler middleware, channel / emitter semantics, client handler organization, React Compiler compatibility, icon facade convention, and FakeSummoner test patterns. Pairs with generic `code-review` skill. Use when reviewing Code Quest code, discussing refactor, checking a PR for protocol/handler/zod alignment, or verifying that recent changes match project conventions.

recca0120 By recca0120 schedule Updated 5/14/2026

name: code-quest-review description: > Code Quest project-specific code review checks covering import order, zod schema placement, cross-package event-name alignment, server handler middleware, channel / emitter semantics, client handler organization, React Compiler compatibility, icon facade convention, and FakeSummoner test patterns. Pairs with generic code-review skill. Use when reviewing Code Quest code, discussing refactor, checking a PR for protocol/handler/zod alignment, or verifying that recent changes match project conventions.

Code Quest 專案特定 Code Review

除通用 /code-review skill 的審查維度外,本專案額外檢查以下項目。

Import

  • import 放在檔案最頂部,不要 inline import(函式中間寫 import)
  • Node.js built-in import(node:path, node:fs)放最上方

isolatedDeclarations

summoner package 開啟了 isolatedDeclarations: true,影響:

  • exported 變數必須有顯式型別標注 — 不可依賴推導,這不是冗餘
  • schema 檔(schemas.tslaunch-options.ts)的縮寫型別別名(OptStrNumBoolUnkLoose)是為了簡化這些必要標注,屬合理設計,不應移除
  • 審查時看到 schema export 帶顯式型別,不要標為「冗餘型別標注」

Zod

  • .passthrough() / .loose() → 改 z.looseObject()(Zod v4 deprecated)
  • shared schema 只有一個 package 使用 → 搬到該 package
  • payload as { ... } inline type assertion → 改用 zod schema parse:
    1. 先查 shared schemas 有沒有現有 schema 可用
    2. 沒有才新建,放 shared 讓前後端共用
    3. 不要 inline z.looseObject({...}).parse(payload) — 那只是換一種 inline,應該抽成 named schema

跨 Package 對齊(shared / summoner / server / client)

  • server emitter.on('event', ...) 的 event name 跟 shared socket-events.ts 定義是否一致
  • server ch.sendRequest('event', ...) 的 event name 跟 adapter REQUEST_MAPPINGS 是否一致
  • adapter transformControlRequest 產出的 event name 跟 server handler 訂閱的是否一致
  • client handler on map 的 event name 跟 server emit 給 client 的是否對齊
  • shared ClientToServerEvents / ServerToClientEvents 定義跟實際 emit/on 是否同步

summoner(CLI adapter)

  • REQUEST_MAPPINGS 是否涵蓋所有 ch.sendRequest 呼叫的 event name
  • adapter transform 每個 case 是否都有 named function(不用 inline arrow)
  • isRecord() 等 util 是否集中在 utils.ts,不重複定義
  • ProcessRunner 終止方法只有 kill()(底層呼叫 handle 的 abort())— 不要再加 abort() wrapper
  • console.debug / console.log → 改用 logger(pino),注意 pino API 第一個參數是 object:logger.debug({ err }, 'message')

server handler

  • middleware 是否正確:
    • 需要 channel 且有 callback → withError(withChannel(handler))
    • 需要 channel 無 callback → withChannel(handler)
    • 需要 socket → withSocket(handler)
    • 不需要 channel → 直接註冊
  • handler 使用 ch.sendRequest('event', payload) 不直接用 protocol subtype
  • handler 使用 named function(不用 arrow)
  • handler 內 respondToRequest 只在 auto-respond 或 CLI-initiated event 使用

server core

  • Channel 的 mutable field 必須 private + getter/setter
  • ChannelEmitteremit / emitToOthers / dispatch 語義區分:
    • emit → broadcast 給 channel sockets(server → client)
    • dispatch → 呼叫 server handler
    • dispatchRunnerEvent → broadcast + dispatch(runner event 專用)

client handler

  • handler 檔案放在 contexts/channel/handlers/
  • 命名對齊 server:file.tsmessage.tspermission.ts...(無 Handler suffix)
  • 只有一個 consumer 的 helper → inline 到 consumer,不獨立檔案
  • handler map export 用 satisfies Record<string, ...> 確保型別
  • effects 和 state handlers 分開 export:xxxHandlerOn + xxxHandlerEffects

Icon 慣例

  • 優先用 ui/Icons facade(re-export heroicons + ActionButton + SlashCommandIcon
  • 新 icon 需求 → 先找 heroicons /24/outline;沒對應才自訂
  • 自訂 SVG 情境(合法):
    • brand mark(
    • extension 視覺 parity(PermissionModeIcons
    • dynamic chart(SparkLegend EffortDots
  • SVG 尺寸慣例:svgBase 用 width: '100%'; height: '100%',由 wrapper w-X h-X 控渲染尺寸(跟 data-font axis 等比縮放)

React Compiler 相容性

已啟用 babel-plugin-react-compiler。檢查:

  • render 時不讀 ref.current(compiler 可能重排序)— ref 只在 useEffect / event handler 裡讀
  • component 必須是純函式(相同 props → 相同 output)
  • 不依賴 render 順序的 side effect
  • 手動 useMemo/useCallback 不必要時可移除(compiler 自動 memoize)

UI / 樣式(design token first)

  • JSX 看到 arbitrary utility(text-[13px] / bg-[#...] / p-[7px] / shadow-[...])先查有沒有對應 @theme token
    • 差 1–2px / 1–2 階 → 就近取內建 utility(text-xs / p-2
    • 超出既有範圍 → 先擴 @theme,不要直接 arbitrary
    • 合法 arbitrary:calc(...)、引用 CSS variable、刻意 off-grid 且有理由
  • 顏色不寫 hex:查 apps/web/src/App.css--color-* 語意 token(accent / surface / text-muted / success / danger…)
  • 細節流程參考 tailwind-v4 skill 的「Design flow: token-first」

測試

測試寫法慣例

  • Summoner 相關測試應使用 FakeSummonerClient / FakeSummonerServer 建立 test double,詳見 fake-summoner-client / fake-summoner-server skill
  • 使用 FakeSummoner + real JSON segments(@code-quest/summoner/tests.*() builder)
  • 驗證 action 發 socket event 用完整 pipeline + claude.received(...),不 spy emit
  • client 測試用 renderWithChannel / renderWithWorkspace + testing-library
  • expect 不變原則:重構不改 expect
Install via CLI
npx skills add https://github.com/recca0120/code-quest --skill code-quest-review
Repository Details
star Stars 8
call_split Forks 2
navigation Branch main
article Path SKILL.md
More from Creator