> ## Content Index
> Fetch the complete content index at: https://taiwanding.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 我把 Claude Code 的工作狀態變成了武俠修煉場
- URL: https://taiwanding.com/wo-ba-claude-code-de-gong-zuo-zhuang-tai-bian-cheng-liao-wu-xia-xiu-lian-chang/
- Published: 2026-03-03T09:16:35.000Z
- Updated: 2026-07-09T13:43:27.000Z
- Author: Kevin Chen
- Tags: 武俠, tool, #claude code

## 起心動念

某天在 GitHub 上看到 [pixel-agents](https://github.com/pablodelucca/pixel-agents?ref=taiwanding.com) 這個專案 — 用像素風小人來呈現 AI agent 的工作狀態，覺得很有意思，不過看著看著就想：如果是中文世界的開發者，用武俠風格？

於是「武俠修煉場」就誕生了。

> 原始碼：[github.com/pcc402-art/wuxia-monitor](https://github.com/pcc402-art/wuxia-monitor?ref=taiwanding.com)

![武俠修煉場截圖](https://taiwanding.com/content/images/2026/03/screenshot.png)

## 概念：把 Coding 變成修煉

Claude Code 在幫你工作的時候，其實一直在切換不同的動作：讀檔案、寫程式碼、跑指令、思考下一步... 這些動作對應到武俠世界，就變成了：

| 寫程式的你看到的          | 武林弟子看到的 |
| ----------------- | ------- |
| 讀檔案（Read / Grep）  | 📜 翻閱秘笈 |
| 寫檔案（Write / Edit） | ⚔ 出劍攻伐  |
| 跑指令（Bash）         | 💨 施展輕功 |
| 思考中               | 🌀 運功催動 |
| 閒置                | 🧘 打坐修煉 |
| 完成任務              | ✨ 大功告成  |

角色名字也都從金庸小說裡取的 — 令狐沖、張無忌、蕭峰、小龍女... 每個 agent 進場就隨機分配一個武俠名字和一種顏色的袍子。

## 技術架構

整個專案只有兩個主要檔案：

### Python 後端（wuxia-monitor.py）

Claude Code 在工作時會把所有操作寫成 JSONL 格式的 transcript 檔案，存在 `~/.claude/projects/` 底下。後端做的事情很單純：

1. **掃描** — 每 0.5 秒掃一次所有 `.jsonl` 檔案（只看最近 5 分鐘修改過的）
2. **解析** — 讀取新增的行，判斷 agent 正在做什麼
3. **分類** — 根據 `tool_use` 的工具名稱，分成 reading / writing / running / thinking / done
4. **提供 API** — 一個簡單的 `/api/state` JSON endpoint

判斷邏輯其實就是看 tool 名稱裡有沒有關鍵字：

```python
if any(w in tool_lower for w in ["read", "glob", "grep", "search"]):
    return "reading", tool
if any(w in tool_lower for w in ["write", "edit", "patch"]):
    return "writing", tool
if any(w in tool_lower for w in ["bash", "exec", "run", "shell"]):
    return "running", tool

```

有個小細節花了不少時間 debug：Claude Code 的 `tool_result` 回傳（type=user 且 content 包含 tool\_result）不應該覆蓋狀態，否則角色會在「翻閱秘笈」和「運功催動」之間不停閃爍，因為每次工具回傳都會被誤判為「使用者輸入 → thinking」。

### Canvas 前端（index.html）

一個單檔 HTML，內嵌 CSS 和 JS，不依賴任何框架。

前端每 500ms 輪詢一次 `/api/state`，根據回傳的 agent 列表更新畫面。角色用 Canvas 2D 繪製在 760×400 的設計座標系上，再透過 `devicePixelRatio` 縮放到實際螢幕大小，支援 HiDPI。

角色圖是用 Google Gemini 生成的 PNG，6 種顏色 × 7 種狀態 = 42 張角色圖 + 1 張背景圖，原始圖片 41MB，用 Pillow 壓縮到 1.2MB（縮小到 256×256 + 256 色量化），畫質幾乎看不出差異。

## 開發過程中解決的問題

### 問題一：角色重疊

最初的設計是每個狀態對應一個固定區域，區域裡有幾個預設的站位。問題是：如果所有 agent 都在思考，六個人就擠成一團。

最後的解法是「軸心擴散」— 每個區域有一個中心點，多人時以中心為圓心等角排列，人越多圈越大：

```javascript
function getExpandedPosition(zone, agentIdx, totalInZone) {
  if (totalInZone <= 1) return { x: zone.cx, y: zone.cy };
  const radius = 50 + totalInZone * 10;
  const angle = (agentIdx / totalInZone) * Math.PI * 2 - Math.PI / 2;
  return {
    x: zone.cx + Math.cos(angle) * radius,
    y: zone.cy + Math.sin(angle) * radius * 0.45,  // Y 壓縮做透視
  };
}

```

6 個區域排成 3×2 網格，上排放靜態狀態（打坐、運功、讀經），下排放動態狀態（完成、出劍、輕功），蠻符合武俠的意境。

### 問題二：偵測不到 subagent

Claude Code 的 transcript 結構是這樣的：

- 主 session：`~/.claude/projects/{project}/{uuid}.jsonl`
- subagent：`~/.claude/projects/{project}/{uuid}/subagents/agent-{id}.jsonl`

一開始所有 subagent 都被當成同一個人，因為 JSONL 裡的 `sessionId` 都指向父 session，後來改成用檔名作為 agent ID 才解決。

### 問題三：狀態閃爍

Claude Code 每次呼叫工具後，transcript 會寫入一筆 `tool_result`（type=user）。如果不特別處理，這筆紀錄會讓狀態從「翻閱秘笈」跳回「運功催動」再跳回「翻閱秘笈」，造成角色在兩個區域之間反覆跑。

修法是讓 `tool_result` 回傳 `None`，保持前一個狀態不變。

## 最後

整個專案大概花了一個下午完成（用 Claude Code 開發 Claude Code 的監控工具，有點遞迴的味道）。

如果你也在用 Claude Code，歡迎試玩看看：

```bash
git clone https://github.com/pcc402-art/wuxia-monitor.git
cd wuxia-monitor
python3 wuxia-monitor.py
# 開瀏覽器到 http://localhost:3000

```

然後在另一個終端機開 Claude Code 做事，就能看到你的武林弟子在修煉場裡翻閱秘笈、出劍攻伐了。

> 原始碼：[github.com/pcc402-art/wuxia-monitor](https://github.com/pcc402-art/wuxia-monitor?ref=taiwanding.com)