每次開 Claude Code 自動打開右側的 Diff 和 Files 面板(Source Control 用 ◨ 手動開)

Daniel 的 Claude Code mod 清單,讓每台電腦都裝到同一套 mod。
mods/。清單本體是 .claude-plugin/marketplace.json。需要 Claude Code 2.1.287 以上。
| mod | 來源 | 做什麼 | 指令 |
|---|---|---|---|
| cache-glance | 自己做的 | 輸入框上方常駐一行快取狀態:還有多久過期、過期後重寫要多少錢 | 無 |
| task-progress | 自己做的 | 給 Claude 一個回報工具,多步驟工作時把任務清單和進度寫進 cmux 左側欄(只在 cmux 裡啟動;搭配下方的 cmux 側欄) | 無 |
| auto-panes | 自己做的 | 每次開 Claude Code 等 1.5 秒自動打開右側的 Diff(/diff)和 Files(/filetree)。Source Control 不自動開:它的 /git 打開時會搶走鍵盤,第一個打的字會進 commit 欄,所以用 ◨ 手動開 | 無 |
| image-view | jarrodwatts/claude-image-view | 貼上的圖片在輸入框上方顯示縮圖(需要支援圖片的終端機) | 無 |
| filetree | data-goblin/claude-code-filetree | 右側欄的檔案樹,標出 Claude 正在讀寫的檔案(需要全螢幕模式) | /filetree |
| cache-tax | karanb192/cache-tax | 快取保溫;閒置過久後的第一則訊息會擋下一次並顯示重寫價格 | /keepwarm、/cache-tax |
| next-steps | anthropics/claude-plugins-community(Thariq Shihipar) | 每次回覆後在輸入框上方給最多三個下一步建議;對話框是空的時按 1、2、3 填進去,再按 Enter 送出,0 關掉,Tab 採用第一個。不會自己送出 | 無 |
| source-control | manuel-will/cc-source-control | VS Code 風格的原始碼控制:commit 歷史分支圖、暫存、commit、同步(介面只有英文、德文) | /git |
別人的 mod 都在 2026-10-08 讀過程式碼:image-view、filetree 不連網;cache-tax 不連網,但開了 /keepwarm 會定時送請求、吃額度;source-control 只執行 git、沒有破壞性操作,背景每 10 分鐘 git fetch 一次(設定 fetchIntervalMinutes 為 0 可關閉),從它的面板 commit 時不會跑專案的 git hooks;next-steps 只讀指令清單、填對話框,不連網、不執行程式,但每輪回覆後會送一次分身請求問建議,對話越長這次請求越貴(讀一次整段快取,跟一次保溫差不多)。
filetree 和 source-control 共用右側面板,用 source-control 那列 Commit 按鈕右邊的 ◨ 切換。
cmux/task-cards.js 是 cmux 的自訂左側欄(cmux 的 Custom Sidebars beta 功能),不是 Claude Code 的 mod。它照 cmux 內建的 workspaces 範本改,每個工作區一張卡片,把「最後一則訊息」換成 task-progress 寫進來的任務清單:
task-progress 把清單寫在工作區的「描述」、摘要寫在「進度」。換回 cmux 預設側欄時,這兩項也會顯示在工作區下面。
安裝:在 ~/.config/cmux/sidebars/ 放一個捷徑,再到 cmux 側欄切換鈕上按右鍵,選 task-cards。
mkdir -p ~/.config/cmux/sidebars
# 主力電腦(清單在 ~/claude-mods)
ln -s ~/claude-mods/cmux/task-cards.js ~/.config/cmux/sidebars/
# 其他電腦(清單是從 GitHub 加的,放在 Claude Code 的下載資料夾)
ln -s ~/.claude/plugins/marketplaces/claude-mods/cmux/task-cards.js ~/.config/cmux/sidebars/
cmux sidebar validate task-cards
repo 是私有的,第一次要先讓那台電腦能讀 GitHub:
gh auth login
gh auth setup-git
加入清單,再裝想要的 mod:
claude plugin marketplace add Toriwuuu/claude-mods
claude plugin install cache-glance@claude-mods
claude plugin install image-view@claude-mods
claude plugin install filetree@claude-mods
claude plugin install cache-tax@claude-mods
claude plugin install source-control@claude-mods
claude plugin install task-progress@claude-mods
claude plugin install auto-panes@claude-mods
claude plugin install next-steps@claude-mods
裝好後重開 Claude Code。要用 task-cards 側欄的話,照上面「cmux 側欄」那段放捷徑。
在主力電腦改完並 push 之後,另一台執行:
claude plugin marketplace update claude-mods
claude plugin update cache-glance@claude-mods
然後重開 Claude Code。
注意:Claude Code 是看 plugin.json 裡的 version 判斷有沒有新版。改了自己的 mod,要把版本號往上加(例如 0.1.0 → 0.1.1),另一台才會更新。
主力電腦的清單直接指向本機資料夾:
claude plugin marketplace add ~/claude-mods
這樣改了 mods/ 裡的檔案,在 Claude Code 裡執行 /reload-plugins 就會生效,不用先 push。確認沒問題再 commit、push。
改完可以先跑檢查:
claude plugin validate mods/cache-glance
claude plugin test mods/cache-glance
不要直接換 sha。先讀過新版本的程式碼,確認沒問題再把 marketplace.json 裡的 sha 換成新的 commit。
hooks/register.ts 42 lines1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4// The side panes to open at the start of every session, in the order their tabs
5// should read: the built-in diff panel, then filetree. Source control stays a
6// click on its ◨ button: its `/git` opens the panel holding the keyboard, so
7// what the person typed first would land in its commit field.
8export const PANES = ['diff', 'filetree'] as const
9
10// Long enough for the other mods to finish their own session start first.
11export const START_DELAY_MS = 1_500
12
13const launched = atom({ plugin: 'auto-panes', key: 'launched' } as const, false)
14
15// `/diff` toggles: once the diff panel is up, running it again would close it.
16let isDiffOpen = false
17
18const isDiffPane = (id: string, title: string | undefined) => /diff/i.test(id) || /diff/i.test(title ?? '')
19
20async function launch($: EngineInterface) {
21 for (const command of PANES) {
22 if (command === 'diff' && isDiffOpen) continue
23 await $.command.run({ command }).catch(() => undefined)
24 }
25}
26
27export const register: Register = on => {
28 on('ui.open', async ($, e, next) => {
29 if (isDiffPane(e.id, e.title)) isDiffOpen = true
30 return next(e)
31 })
32
33 on('session.start', async ($, e, next) => {
34 const result = await next(e)
35 // Once per session: a reload of the mod would otherwise toggle the diff panel shut.
36 if (await read($, launched)) return result
37 await update($, launched, () => true)
38 $.clock.after(START_DELAY_MS, () => void launch($))
39 return result
40 })
41}
42types/index.d.ts 12 lines1/** Whether this session's side panes were already opened. */
2export type Launch = { launched: boolean }
3
4declare module 'claude-code' {
5 interface PluginState {
6 'auto-panes': {
7 /** Set once per session, so a reload of the mod doesn't open (or toggle) the panes again. */
8 launched: Launch['launched']
9 }
10 }
11}
12