| name | engineering-quality |
| description | Project lint, format, and git hooks setup using Biome and Lefthook. Use when modifying biome.json, lefthook config, or troubleshooting pre-commit/pre-push hooks. |
Engineering Quality
用途
專案的 lint、format、git hooks、DI 等品質基礎建設的設定和使用指南。
何時使用
- 新增或修改 biome / lefthook 設定
- 設定 DI(dependency injection)模式
- 處理 pre-commit / pre-push hook 問題
- 新增或修改 zod runtime schema validation
Biome(Lint + Format)
設定檔
/biome.json(root level,server + client 共用):
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"organizeImports": { "enabled": true },
"formatter": {
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"rules": {
"recommended": true,
"suspicious": { "noExplicitAny": "warn" }
}
},
"javascript": {
"formatter": { "quoteStyle": "single", "semicolons": "always" }
}
}
常用命令
pnpm biome check .
pnpm biome check --write .
pnpm biome check apps/server/src/chat/parsers/
pnpm biome ci .
Lefthook(Git Hooks)
設定檔
/lefthook.yml:
pre-commit:
parallel: true
commands:
biome:
glob: "*.{ts,tsx,js,json}"
run: pnpm biome check --write {staged_files}
stage_fixed: true
typecheck-server:
glob: "apps/server/**/*.ts"
run: pnpm --filter server exec tsc --noEmit
typecheck-client:
glob: "apps/web/**/*.{ts,tsx}"
run: pnpm --filter client exec tsc --noEmit
pre-push:
parallel: true
commands:
test-server:
run: pnpm --filter server exec vitest run
test-client:
run: pnpm --filter client exec vitest run
管理命令
pnpm lefthook install
git commit --no-verify -m "emergency fix"
pnpm lefthook run pre-commit
DI 模式(Inversify 7)
專案使用 Inversify 7 做 server-side dependency injection。詳細 patterns 請參考 /inversify-di skill。
核心原則
- Interface first — 依賴型別用 interface,不用 concrete class
- Symbol tokens — 所有 binding token 定義在
types.symbols.ts
- Lazy factory resolution —
toDynamicValue 內的依賴在 factory 被呼叫時才 resolve
- Test via rebindSync — 測試中用
createTestContainer + rebindSync 替換依賴
- Composition root — 只在
container.ts 和 entry point 呼叫 container.get()
Zod Runtime Validation
用途
- 驗證 CLI 輸出格式是否符合預期
- 驗證 WebSocket 事件格式
- 開發時 early warning,production 可關閉
Schema 位置
apps/server/src/chat/schemas/
├── claude.ts # Claude CLI 原始輸出
├── gemini.ts # Gemini CLI 原始輸出
├── events.ts # 統一的 ChatStreamEvent
└── index.ts # re-export
使用方式
import { ClaudeStreamLine } from '../schemas/claude';
const parsed = ClaudeStreamLine.parse(json);
const result = ClaudeStreamLine.safeParse(json);
if (!result.success) {
logger.warn('Unexpected CLI format', result.error);
}
從 ESLint 遷移到 Biome
步驟
- 安裝 biome:
pnpm add -D @biomejs/biome --workspace-root
- 建立
/biome.json
- 執行
pnpm biome check --write . 修正所有檔案
- 刪除
.eslintrc.cjs(server + client)
- 移除 eslint 相關 devDependencies
- 更新
package.json scripts
注意事項
- Biome 和 ESLint 規則不完全對應,遷移後需要 review diff
- Biome 的 import 排序規則與 ESLint 不同
noExplicitAny 設為 warn 而非 error,因為專案中大量使用 any
相關
- 計畫文件:
docs/plans/fixture-driven-testing.md
- Fixture-Driven TDD:
/fixture-driven-tdd
- Parser 開發:
/parser-development