昨天比較了三種包法,最後選了 Claude Code plugin,也大致看過了每個資料夾的用途。今天把這條產線的 plugin 實際做出來,先自己載入、跑一次驗證結果,再說明怎麼交給別人。
⚠️ 跟昨天一樣,本文對照的是 2026 年 10 月、Claude Code v2.1.286 的格式。安裝與發布的指令最容易隨版本變動,實際操作請以官方文件為準。
plugin 放在範例專案的 plugin/,同一個 repo 根目錄再放一份 marketplace,後面分享時會用到:
auto-manual-gen/
├── .claude-plugin/
│ └── marketplace.json
└── plugin/
├── .claude-plugin/plugin.json
├── skills/
│ ├── manifest-authoring/SKILL.md # 知識:動詞、schema、工作迴圈、錯誤碼
│ ├── doc-writing/SKILL.md # 知識:正文骨架、STYLE 預設值
│ ├── bootstrap-context/ # 知識:怎麼替新專案建 UI-MAP / QUIRKS
│ │ ├── SKILL.md
│ │ └── templates/ UI-MAP.md QUIRKS.md
│ ├── add-chapter/SKILL.md # 進入點:/manual:add-chapter
│ └── audit/SKILL.md # 進入點:/manual:audit
├── agents/
│ ├── explorer.md # 探勘畫面,不能改檔案
│ └── writer.md # 寫正文
├── hooks/hooks.json # manifest 或正文被改就自動 validate
├── scripts/validate-on-edit.mjs
└── bin/auto-manual # 轉接到專案裡的 CLI
每個元件裝的,都是 Day 16 到 Day 19 已經做過的東西:
| 元件 | 內容 | 來自 |
|---|---|---|
manifest-authoring |
探勘 → 寫 → validate → run 的迴圈、動詞表、exit code 與 error.code 的處理方式 |
Day 16–17 |
doc-writing |
正文骨架、截圖與 legend 的引用、人工保護區、STYLE.md 的通用部分 |
Day 18–19 |
bootstrap-context |
用 probe 起草 TESTID.md、UI-MAP.md、QUIRKS.md 交給人審 |
Day 16 |
add-chapter |
新增一章,跑通就停下來給人 review | Day 17 的 prompt |
audit |
UI 改版後檢查整本手冊,只回報、不修改 | Day 27 的 CI 情境 |
explorer / writer |
探勘與寫正文的 subagent | Day 16–18 |
plugin 不需要自己一個檔案一個檔案手寫,交給 AI agent 建就好。材料其實都已經在 repo 裡了:agent/ 裡的上下文、Day 17 下過的 prompt、CLI 的 README,再加上昨天規劃好的元件清單,請 agent 照著上面那張表建出來,最後用 claude plugin validate 檢查通過就行。
如果想先有個骨架再填內容,Claude Code 也內建了產生骨架的指令:
claude plugin init manual --with skills agents hooks
它會產生 plugin.json 與 skill、subagent、hook 各一份範例檔。要注意的是,骨架會建在 ~/.claude/skills/manual/,也就是只給自己用的位置,下一次開 Claude Code 就會自動載入。要跟著產品一起發布的話,再把它搬進 repo 的 plugin/。
各個檔案的內容就不一一說明了,用途昨天都介紹過,完整內容可以直接到範例專案的 plugin/ 看。
--plugin-dir 載入plugin 不用正式安裝就能測。在範例專案的根目錄,用 --plugin-dir 把它載入這一次的 session:
npm install # plugin 不帶 CLI,要用專案自己裝的那一份
claude --plugin-dir ./plugin
進到 Claude Code 之後,/manual:add-chapter、/manual:audit 就能用了。改了 plugin 的檔案,執行 /reload-plugins 重新載入,不用重開。
格式則交給 claude plugin validate ./plugin 檢查。放進 CI 的話加上 --strict,讓警告也視為失敗 (例如少了 author 或 description)。
載入之後,也可以看一下這個 plugin 會佔用多少 token。plugin details 一樣可以搭配 --plugin-dir,不用安裝:
claude --plugin-dir ./plugin plugin details manual
輸出的後半段是 token 成本:
Projected token cost
Always-on: ~471 tok added to every session
Per-component (rounded)
component always-on on-invoke
add-chapter ~20 ~400
audit ~30 ~410
bootstrap-context ~100 ~950
doc-writing ~90 ~1.2k
manifest-authoring ~110 ~2.5k
explorer ~70 ~380
writer ~70 ~310
add-chapter 與 audit 的 always-on 特別低:這兩個是只給人用斜線指令觸發的進入點,frontmatter 設了 disable-model-invocation: true,模型不需要判斷什麼時候該用它,所以幾乎不佔 context,只剩一點固定成本。知識型 skill 的 description 則是每一輪都在,所以只寫「什麼時候該用」就好,長的內容放進內文。
用 plugin 重做 Day 17 那一章。先移走 manifest/50-camera-add.yaml 與兩個語言的正文,免得 agent 直接抄到答案,再執行:
/manual:add-chapter 如何新增一台攝影機
validate 與 run 都通過後,agent 停下來交出 diff。這份 manifest 跟 Day 17 審過的版本差了不少,可以分成三類。
agent 多做、而且有根據的:
camera-add-04,捲到清單底部拍新增的那一台與總數。Day 17 的版本停在 toast,讀者看不到新增的結果。rtsp://10.0.4.100/live,直接截圖就會露出內網位址,所以先填文件專用的 192.0.2.10 再拍。這點連 Day 17 的人工審查都沒發現。Gate West。App 會從名稱推導 id,中文字會被濾掉、變成通用的 camera;填英文,兩個語言才會是同一個 camera-row_gate-west。而且這些理由,agent 都寫進了 manifest 的註解:
# 名稱用英數字,兩種語言推導出的 id 都是 gate-west(中文名稱會變成通用的 camera)
- { action: fill, testid: camera-dialog-name, text: { zh-Hant: Gate West, en: Gate West } }
# RTSP 欄空白時 placeholder 會露出內網 IP,先填文件專用位址(192.0.2.0/24)再截圖;帳號密碼不填
- { action: fill, testid: camera-dialog-source, text: rtsp://192.0.2.10/live }
review 的人對一下原始碼就能確認,不用自己重新探勘一次。
agent 不可能知道、要人決定的:
video: true 與 tour: true 不見了。要不要錄影片、做導覽,是產品的決定,不在任何一份上下文裡。Gate West。技術上合理,但讀者看了會不會覺得奇怪,只有人能判斷。真的有問題的:camera-add-04 的 2 號圓標,蓋住了「共 16 台」的「共」。

後兩類有個共通點:validate 與 run 都通過了,問題還在。一個是產品決定,一個是畫面上的瑕疵,都不是決定性的機制檢查得出來的。這也是 add-chapter 跑通就停下來的原因:包成 plugin 之後,agent 的草稿變得更完整,但 Day 16 選的第二種信任程度,人審 diff 這一步還是省不掉。
跟 Day 27 的 CLI 一樣,plugin 不一定要公開上架。更常見的情況是:在公司裡做好了,想交給同事,或讓別的產品也能用。
最快的做法,是把整個 plugin/ 資料夾複製到產品 repo 的 .claude/skills/manual/,跟程式碼一起 commit:
my-electron-app/
└── .claude/
└── skills/
└── manual/ # 整個 plugin 資料夾,含 .claude-plugin/plugin.json
帶有 .claude-plugin/plugin.json 的資料夾放在這裡,會被當成 plugin 載入,而不只是一個 skill。同事 clone 下來、在 repo 根目錄開 Claude Code 並信任這個資料夾之後,就會看到 manual@skills-dir (scope: project),hook 與 subagent 都在,不需要 marketplace,也不需要安裝。
缺點跟昨天的第一種包法一樣:每個 repo 一份,更新要靠人。
如果只是想讓別人先試試看,只要把 plugin/ 資料夾傳給對方,用 claude --plugin-dir ./plugin 載入就好。
有兩個以上的產品在用,或是會持續更新,就值得做成 marketplace。marketplace 其實就是一份目錄,最簡單的做法是直接放在同一個 repo 的 .claude-plugin/marketplace.json:
{
"name": "auto-manual-gen",
"description": "auto-manual-gen 的 Claude Code plugin",
"owner": { "name": "CK642509" },
"plugins": [
{ "name": "manual", "source": "./plugin", "description": "用 auto-manual-gen 產生與維護使用手冊" }
]
}
source 的相對路徑是從 marketplace 的根目錄算起,也就是 .claude-plugin/ 所在的那一層,而不是從 .claude-plugin/ 裡面算起。
給別人之前,先用 claude plugin validate . 驗 marketplace,再把 repo 當成本機 marketplace 裝一次,確認別人拿到的跟 --plugin-dir 看到的一樣:
claude plugin marketplace add ./ --scope local
claude plugin install manual@auto-manual-gen --scope local
測完用 claude plugin uninstall manual@auto-manual-gen --scope local 與 claude plugin marketplace remove auto-manual-gen 移除。
確認沒問題後,推到公司的私有 repo,同事這樣安裝 (以範例專案的 repo 名稱示範):
/plugin marketplace add CK642509/auto-manual-gen
/plugin install manual@auto-manual-gen
能 clone 這個 repo 的人才能安裝。Claude Code 會用使用者電腦上既有的 git 認證 (SSH key 或 gh auth login 存下的憑證) 去 clone,不會跳出密碼提示,所以同事要先設定好。GitLab 或公司內部的 git server 也可以,marketplace add 改給完整的 URL 就好。
更新的部分要注意兩件事:
claude plugin update manual@auto-manual-gen,或在 /plugin 的 Marketplaces 分頁打開 auto-update。version 就要記得升。plugin.json 裡一旦寫了 version,使用者就會停在那個版本,發布者忘了升版號,使用者就永遠拿不到更新。不想管版號的話,也可以乾脆不寫,使用者就會跟著 git commit 更新。只是少了 version,claude plugin validate 會提出警告,CI 用的 --strict 也就過不了。| 做法 | 適合 | 更新 |
|---|---|---|
| 放進產品 repo | 只有一個產品在用 | 手動複製新版 |
| 私有 repo 的 marketplace | 多個產品、會持續更新 | claude plugin update |
--plugin-dir |
試用 | 重新給一份 |
如果公司有統一管理 Claude Code 的設定 (managed settings),管理員也可以直接替所有人註冊 marketplace、啟用 plugin,連信任資料夾這一步都省了。
至於公開上架,做法跟方法二完全一樣,只是 repo 設成公開,推上 GitHub 就算上架了,不需要另外送審。
Anthropic 也有官方的 plugin 目錄,上架後 claude.ai 與 Cowork 的使用者都看得到。不過這兩個環境不會安裝帶有
bin/的 plugin,這條產線又需要 shell 來跑 CLI,所以不適用。
今天把這條產線的 plugin 做了出來,並實際驗證過了,這個系列也差不多可以收尾了!