~/blog/claude-code-mods-resource-dashboard

AI Workflow · part 23

[Claude Code] 六段 prompt 做出自己的資源儀表板:Claude Code mods 實作

❯ cat --toc

TL;DR

Claude Code 2.1.287 起支援 mods:放在 plugin 裡的 TypeScript 小程式,能在終端機畫面板、加按鈕、給 Claude 新工具。我照這篇的六段 prompt 在乾淨的 session 實測,第一段 3 分 41 秒就做出顯示 GPU 與硬碟的面板,之後每段加一張卡,最後 Claude 自己也能呼叫它查資源。不用寫程式,但每段都要讓它跑 claude plugin validate 到通過。

米白紙底的蠟筆手繪封面。左上大標題「六段 prompt 做出自己的資源儀表板」,副標「Claude Code mods · 第一段 3 分 41 秒」。左下一台有笑臉的筆電舉著一塊畫了三條進度條的小面板,旁邊兩台有笑臉的小伺服器。右側四張彩色卡片:GPU 與硬碟(每 10 秒更新)、Claude 額度(5 小時・每週)、本地模型(連得到就列出來)、派工前(Claude 自己先查)。底部寫著「程式碼一行都不用寫,每段只要它 validate 到通過。」

前言

開進停車場,入口的看板會寫 B1 剩 3 格、B2 已滿,你不用每層繞一圈找位子。

我的 Claude Code 以前沒有這塊看板。手上有幾台跑模型的機器、幾個 AI 訂閱,Claude 每次派工前都要自己一台一台 ssh 上去跑 nvidia-smi,看哪台有空,等於每層都繞一圈。

Claude Code 10 月初出了 mods,可以在終端機裡畫面板。我花一天做出自己的面板,再把做法拆成六段 prompt。照著貼完,就會長出這樣一塊面板:

六段 prompt 做完的面板:Claude 額度、GPU、家目錄硬碟、地端模型(附開啟按鈕)、立即更新按鈕

這篇不教你抄我的程式碼。我的面板接的是我家的機器,對你沒用。六段 prompt 照順序貼給 Claude,它會做出連到你自己機器的版本。每一段我都開乾淨的 session 實際跑過。


mods 是什麼:一支能改 Claude Code 畫面與行為的小程式

把它想成 Claude Code 的外掛:裝上去以後,終端機裡會多出你自己設計的畫面和按鈕。技術上,mod 是放在 plugin 裡的一個 TypeScript 函式。Claude Code 啟動時呼叫它,它可以註冊自己要接哪些事件:

  • 畫畫面:在終端機開一個面板(Pane),放文字、進度條、按鈕。
  • 給 Claude 新工具:註冊一個工具,Claude 就能像呼叫 Bash 一樣呼叫它。
  • 攔截工具呼叫:Claude 每次要跑工具之前,mod 可以先看一眼,必要時擋下來。
  • 加斜線指令:例如 /my-dash 重新打開面板。

官方的介紹在 Claude Code mods 公告,完整 API 在 mods 文件。

有一件事要先知道:mod 跟 Claude Code 同權限,沒有沙箱。它讀得到你的環境變數、看得到整段對話。所以裝來路不明的 mod 前,要先用 claude plugin validate 看它到底碰了什麼。這篇每段 prompt 我都叫 Claude 跑這個指令,一方面檢查語法,一方面你也看得到它掛了哪些事件。

開始前:確認版本、準備一個資料夾

mods 要 Claude Code v2.1.287 以上:

claude --version
# 2.1.289 (Claude Code)

版本不夠就 claude update。然後開一個空資料夾當工作區,在裡面啟動 Claude Code:

mkdir ~/my-dash-work && cd ~/my-dash-work
claude

接下來的六段 prompt 直接在這個 session 裡連續貼就好。我實測時每段都開新的 session(claude -p),只是為了確認 prompt 本身就夠清楚,不靠前一段的對話記憶。

第一段:3 分 41 秒做出 GPU 與硬碟面板

幫我做一個 Claude Code mod:在右邊開一個面板,顯示這台電腦的 GPU 顯示卡記憶體用量(有 NVIDIA 卡就用 nvidia-smi,沒有就顯示「沒有 NVIDIA 顯卡」)和家目錄所在硬碟還剩多少空間,每一項都畫一條用量條,每 10 秒自動更新一次。
mod 放在目前資料夾的 my-dash/ 底下。做完用 claude plugin validate 檢查到通過為止,最後告訴我怎麼讓 Claude Code 載入它。

我這次實測花 3 分 41 秒。Claude 做出來的資料夾長這樣:

my-dash/
├── .claude-plugin/plugin.json   名稱、版本、說明
├── hooks/hooks.json             指向 register.tsx
├── hooks/register.tsx           面板、/my-dash 指令、每 10 秒更新
├── hooks/parse.ts               解析 nvidia-smi 和 df 的輸出、畫用量條
├── hooks/my-dash.test.ts        測試
└── types/index.d.ts             面板讀的資料格式

它還順手寫了測試,終端機和 Desktop app 兩種介面各測一次。測試不是我要的,是 Claude Code 內建的 mod 寫作指引本來就要它寫。

載入方式它也會告訴你:

claude --plugin-dir ~/my-dash-work/my-dash

打開後面板就出現在對話上方,有兩欄:GPU 和家目錄硬碟,底下寫最後更新時間。我的 MacBook 沒有 NVIDIA 卡,所以 GPU 那欄顯示「沒有 NVIDIA 顯卡」,我截圖時硬碟那欄是「剩 232.0 GiB / 共 926.4 GiB」。

面板沒自己出現的話,打 /my-dash 就會打開。Claude 回報裡寫終端機要 144 欄以上才會在啟動時自動開,比較窄就要手動叫。

第二段:加 Claude 額度卡,每張卡都能收合

在 my-dash 面板加一張「Claude 額度」卡:顯示 5 小時和每週額度各用了幾 %、多久後重置(mod 可以從 session 的用量資訊讀到)。每張卡的標題都要能點一下就收合、再點一下展開。改完用 claude plugin validate 檢查到通過。

實測 136 秒。額度不用自己打 API 抓,mod 可以直接讀 Claude Code 狀態列用的那份用量資料。額度數字要等你用訂閱帳號送出第一則訊息之後才有,在那之前卡片會顯示「尚無額度資料(送出第一則訊息後才有)」。用 API key 的帳號一直都是這個狀態。

第三段:接上你的本地模型

在 my-dash 再加一張「地端模型」卡:每 10 秒打一次 http://localhost:8080/v1/models(我的本地模型服務是 OpenAI 相容 API),列出現在提供哪些模型;連不上就顯示「沒在跑」。網址寫成檔案開頭的一個常數,方便我改。validate 到通過。

實測 119 秒。/v1/models 是模型服務用來回報「我現在有哪些模型」的網址,格式跟 OpenAI 的一樣,所以叫 OpenAI 相容。網址換成你自己的服務就好,llama.cpp、vLLM、LM Studio、Ollama 都有 OpenAI 相容的 /v1/models,只是預設 port 不同。我把另一台機器的模型服務轉到本機 8080,Claude 做完還自己打了一次,確認回應格式對得上,卡片會列出 qwen38-27b-ud。

它還補了幾種例外處理:服務 3 秒沒回應也算「沒在跑」,免得整個面板等它;回錯誤碼時用紅字寫出原因,例如「讀取失敗:HTTP 503」;服務在跑但沒有模型時,顯示「服務在跑,但沒有提供模型」。

第四段:讓 Claude 自己也讀得到

讓 Claude 自己也讀得到這個面板:在 my-dash 註冊一個 Claude 可以呼叫的工具,叫 my_resources,回傳一段很短的文字,只講「能不能用」:Claude 額度還夠不夠、GPU 和硬碟還剩多少、地端模型有沒有在跑。validate 到通過,最後告訴我這個工具的完整名稱,以及我該怎麼請 Claude 在派工前先查它。

實測 196 秒。工具的完整名稱是 mcp__my-dash__my_resources,格式固定是 mcp__<mod 名稱>__<工具名>。我開一個新 session,叫 Claude 呼叫它、原文貼回來,拿到的是:

✓ Claude 額度:夠用(已用 5 小時 51%、每週 7%)
— GPU:這台沒有 NVIDIA 顯卡
✓ 硬碟 /System/Volumes/Data:剩 232.0 GiB(26%)
✓ 地端模型:在跑(qwen38-27b-ud)

要 Claude 派工前先查,把這句寫進專案的 CLAUDE.md:「派工前先呼叫 mcp__my-dash__my_resources,它標成不能用的資源不要派。」工具的說明裡已經寫了用途,但寫進 CLAUDE.md 比較穩。

一個 mod 讀一次資料,面板給你看,工具給 Claude 查

我的面板一開始把所有細節都塞給 Claude,後來改成只回三塊「能不能用」:額度、地端模型、ComfyUI。Claude 派工前要的是「可不可以派」,不是 tok/s 和 VRAM 數字。

第五段:加按鈕

在 my-dash 的「地端模型」卡加一個「開啟」按鈕,按下去用瀏覽器打開 http://localhost:8080;面板最下面加一個「立即更新」按鈕,按下去馬上重新讀一次所有資料。validate 到通過。

實測 93 秒。「開啟」在 macOS 用 open、Linux 用 xdg-open,兩個都失敗就跳一則提示請你自己開網址。

按鈕按下去跑的是你電腦上的動作,可以是開網頁、跑一支腳本、寫一個旗標檔。我面板上的「暫停」就是寫旗標檔,讓 Claude 暫時不准派工到那台機器。

第六段:Desktop app 也要好看

my-dash 也要在 Claude Desktop app 裡好看:Desktop 用比例字型,用字元畫的進度條會溢出欄位、蓋住後面的數字。請在 Desktop 上改用 SVG 畫進度條,終端機維持原樣。validate 到通過。

實測 185 秒。Claude 中途踩到一個坑、自己修掉了:它一開始用「元件表裡有沒有 Svg」判斷能不能畫 SVG,但在測試環境裡,終端機的元件表也有 Svg,結果終端機上的進度條直接消失。它改成看畫面類型是不是 terminal 才過。

同一個 mod 在 Desktop app 的 Claude Code 分頁也會畫出來,而且大部分排版不用改。會壞的只有用字元畫的進度條:終端機是等寬字型,每個 █ 剛好佔一格;Desktop 是比例字型,同樣一排字元會變寬,蓋到後面的數字。這一段我是看到自己面板在 Desktop 上壞掉才加的。

讓它每次都自動載入

試用時用 --plugin-dir。確定要常駐,就加進 ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_PLUGIN_DIRS": "/Users/你/my-dash-work/my-dash"
  }
}

多個 mod 用冒號隔開。Desktop app 沒辦法加 --plugin-dir 參數,也是靠這個環境變數。之後每次改 mod:

  • 終端機裡開著的 session 會盯著 mod 資料夾,存檔就重新載入。
  • Desktop app 開著的 session 不會。要嘛開新的 session,要嘛在同一個 env 加 "CLAUDE_CODE_PLUGIN_DIR_WATCH": "1"。

進階:我的面板怎麼長出來的

不讀這節不影響使用。這裡是一天下來踩到的坑,給想往下做的人和 AI 參考。

踩到的坑

中文對不齊。 第一版用 padEnd 補空白對齊欄位,中文一個字佔兩格,整欄歪掉。改成每一欄放進固定寬度的 Box,讓排版引擎算寬度。

面板寬度不要自己算。 我一開始用事件裡的 viewport.columns 決定寬度,結果那是整個對話區的寬度,不是面板的。拿掉寬度設定、讓 flex 自己貼合,面板就會跟著你拖的寬度走。

validate 會擋的三種寫法。 同一個事件掛兩個沒有篩選條件的 hook 會被拒,要併成一個;用到 $ 的函式要寫在檔案最外層;用 atom 存的狀態要在型別檔裡宣告,不然會報 is not declared。

一個變數名讓整個面板消失。 機器卡的 hosts.map(h => …) 用了 h 當參數名,剛好遮住 JSX 編譯後用的 h。只要有機器快照,整個面板就直接報錯、什麼都不畫。測試沒餵快照所以全過,是在真終端機上才發現。

Desktop 的進度條。 前面第六段講過:比例字型讓 ━ 溢出,改用 SVG。判斷畫在哪裡用事件的 e.surface,terminal 以外才換。

三個 session 改同一支檔。 那天我同時開了三個 session 在調面板,其中一個把卡框統一改成灰色,另一個在它的版本上繼續改,第三個又改回彩色。mod 只有一支 register.tsx,後存檔的會蓋掉前面的。改 mod 最好固定在一個 session 做,改完 commit。

Claude Code 自己升級了。 mods 的 API 標著 early access,版本之間可能會變。我在 ~/.claude.json 設了 autoUpdates: false,當天還是從 2.1.288 升到 2.1.289。最後在 settings.json 的 env 加 DISABLE_AUTOUPDATER=1 才停住,要升級時手動 claude update。

常見問題

Claude Code mods 要什麼版本才能用?
官方文件寫的是 v2.1.287 起、預設開啟。先跑 claude --version 確認版本,太舊就 claude update。Desktop app 用的是 app 內建的引擎,跟著 app 自己更新。
不會寫 TypeScript 也能做 mod 嗎?
可以。mod 本身是 TypeScript,但 Claude Code 內建寫 mod 的說明,直接用中文描述你要的面板,它會寫好、跑 claude plugin validate 檢查,再告訴你怎麼載入。這篇六段 prompt 都是在乾淨的 session 實際跑過的,每段 1 分半到 4 分鐘。
做好的 mod 要怎麼讓 Claude Code 每次都自動載入?
臨時試用用 claude --plugin-dir <資料夾>。要常駐,在 ~/.claude/settings.json 的 env 裡加 CLAUDE_CODE_PLUGIN_DIRS,值是 mod 資料夾的絕對路徑,Desktop app 開的 session 也吃這個設定。終端機裡開著的 session 會盯著 mod 資料夾,存檔就重新載入;Desktop app 開著的 session 不會,要開新的,或在同一個 env 加 CLAUDE_CODE_PLUGIN_DIR_WATCH=1。
mod 安全嗎?
mod 跟 Claude Code 同權限,沒有沙箱,讀得到環境變數和你的對話。裝別人的 mod 前先跑 claude plugin validate,它會列出這個 mod 掛了哪些事件、用了哪些 API、讀寫哪些環境變數。

接著讀

  • 2026-08-31
    [Dev Workflow] AI 味不在破折號,在結構:一篇論文教我怎麼檢查自己的文章

    StoryScope 完全不看文風,只看敘事結構,93.2% macro-F1 就分得出人寫的與 AI 寫的。我拿它的五個問題掃自己已發布的文章,同一個教訓被抓到講了四次。

  • 2026-08-21
    [AI Agent] 從 41 分鐘到 73 秒:一張小工單的病理解剖

    派給 Codex CLI 的小工單常常一跑就是 40 分鐘起跳。這篇拆開近兩週 41 個執行紀錄,量出「牆鐘時間≈工具呼叫次數×14.3 秒」的公式,揪出 41 分鐘裡機器真正做事只有 4.4 分鐘,再用四刀把同型工單壓到 73 秒。

  • 2026-07-29
    [Dev Workflow] Skill 裡的檢查完全寫對了,但它一次都沒跑過

    一篇技術文五關全過,唯一的人類讀者一句話就命中:同一個句型在稿子裡出現了五次。查下去發現該抓的規則白紙黑字寫在 skill 裡、內容也對,但它標著「人工掃」——沒有指令、沒有 exit code、擋不住任何東西,所以從來沒運作過。門檻怎麼用五篇舊文校準、兩次真實攔截、以及一個機械檢查永遠抓不到的變體。

  • 2026-07-17
    [Dev Workflow] 幫 AI agent 的 skill 減肥:193 個塞爆 2% 預算,砍到剩 7 個

    AI Workflow 系列第 15 篇。某天早上我讀 codex 紀錄,滑到一行:skill 描述被剪短,才塞得進 2% 的 context 預算。我共用的 root 累到 193 個 skill,全載進去撐爆上限,每條描述都被截斷——我天天在用的,被剪掉是為了替我從不碰的一百多個騰位子。這篇講怎麼用 per-agent allowlist(不是刪)砍到 7 個、薄殼配深引擎壓低每個 skill 的載入成本,再用一個閘門加稽核加可逆退場區守住,不讓它肥回去。

不想錯過新文章?

訂閱我確保不漏接!

隨時一鍵退訂。