讓 Claude Code 擁有跨 session 記憶的技能,用純 Markdown 檔案實現——對 Obsidian vault 友善。
需要 Python 3(僅用標準庫)。任何可寫目錄都能當儲存區;作者本人用 iCloud 同步的 Obsidian vault。也附帶舊版 Apple Notes 的遷移工具(僅限 macOS)。
Claude Code 的 session 是無狀態的。每次 session 結束,所有 context 都消失。下一次 session 從零開始——不記得做過什麼、進行到哪、做了什麼決策。
這個 skill 在每次 session 結束前,自動把結構化的 Markdown 交接檔(shard)寫入檔案系統儲存區,下次 session 開始時透過 SessionStart hook 讀回來。等於 AI 自動幫你寫交接便條。
v2.0 儲存後端切換 — 後端已從 Apple Notes 改為純 Markdown 檔案。v1.x 用戶請看 從 Apple Notes 遷移。
Session 結束
↓
┌───────────────────────────────────────────────┐
│ [私有] {root}/Active/{AgentID}.md │ ← 單一 agent 的工作狀態
│ [共有] {root}/Shared/{AgentID}.md │ ← 跨 agent 同步(每 agent 一片)
└───────────────────────────────────────────────┘
↓ 舊內容歸檔
┌───────────────────────────────────────────────┐
│ [歸檔] {root}/Archive/{YYYY}/….md │ ← 每次 session 一個檔案
└───────────────────────────────────────────────┘
↓ 定期整合
┌───────────────────────────────────────────────┐
│ [長期] MEMORY.md / episodic 記憶檔 │ ← 提煉後的知識
└───────────────────────────────────────────────┘
每個檔案都帶 YAML frontmatter(schema_version / kind / agent / updated_at),由內附腳本生成並驗證。格式壞掉會大聲報錯,不會被靜默弄爛。
| 層級 | 儲存位置 | 生命週期 |
|---|---|---|
| 活躍層 | 私有 + 共有 shard | 每次 session 覆寫 |
| 歸檔層 | Archive/{YYYY}/ 檔案 |
滾動保留最近 5 條 |
| 長期層 | MEMORY.md / episodic 檔案 | 永久,提煉後的模式 |
如果你在多台機器跑 Claude Code(例如筆電做互動開發 + 伺服器跑無人值守任務),每個 agent 寫自己的私有 shard 和自己的共有 shard(Shared/{AgentID}.md)——永遠不碰別的 agent 的檔案。session 開始時,各 agent 的 hook 會合併所有 Shared/*.md。
也支援單 agent 模式——直接跳過共有 shard 就好。
npx skills add fredchu/claude-session-handoff任何可寫目錄都行。兩種常見選擇:
~/.agents/handoff— 純本地、零依賴- iCloud/Syncthing 上的 Obsidian vault 資料夾 — 跨機器同步,還能在 Obsidian 裡瀏覽
mkdir -p ~/.agents/handoff複製範例 hook 腳本,設定你的 agent 名稱和 root:
cp hooks/session-start.sh ~/.claude/hooks/session-start.sh
chmod +x ~/.claude/hooks/session-start.sh
# 編輯腳本裡的 AGENT_ID 和 HANDOFF_ROOT加入 .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/session-start.sh"
}
]
}
]
}
}chmod 只適用於 Unix。
需要 Python 3.9+,可從 PATH 呼叫或透過 py launcher 使用。
在檔案總管中,把 hooks/session-start.ps1 複製到 %USERPROFILE%\.claude\hooks\session-start.ps1,再編輯複本裡的 $AgentId 和 $HandoffRoot。
加入 .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:/Users/<you>/.claude/hooks/session-start.ps1\""
}
]
}
]
}
}請把 <you> 換成你的 Windows 使用者名稱,這段 command 一律使用正斜線。Agent ID 可使用英文字母、數字、空格和連字號;避免 < > : " / \ | ? *、結尾的句點或空格,以及保留裝置名稱(CON、PRN、AUX、NUL、COM1–COM9、LPT1–LPT9)。
各平台的 hook 都會呼叫 handoff_cli.py session-start,印出私有 shard 加上所有 agent 的共有 shard(超過 --stale-days(預設 14 天)未更新的 shard 會標 ⚠️ stale)。
在使用者層級的 CLAUDE.md(~/.claude/CLAUDE.md)加入:
## Session Handoff Config
- Agent ID: Main
- Handoff root: ~/.agents/handoff
- Episodic dir: ~/.agents/memory/episodic
- Other Agents:(留空代表單 agent 模式)
- Private budget: 1500 chars
- Shared budget: 1000 chars
## Session Handoff Rules
- 用戶說「收工」「bye」「結束」「handoff」時 → 執行 `/session-handoff`
- 即使「還沒做什麼事」也不可跳過session 結束時說「收工」或「handoff」就好。Skill 會自動:
- 歸檔前一次的交接內容(每次 session 一個帶 frontmatter 的檔案)
- 寫入新的私有 + 共有 shard(透過
handoff_cli.py) - 整合(Archive 達 5 條時自動觸發,老條目提煉進 episodic 記憶)
- 提煉教訓寫入長期記憶
執行的 LLM 永遠不手寫 shard 檔案。所有寫入(Active / Shared / Archive)一律走 scripts/handoff_cli.py,由它負責 frontmatter 生成、schema 驗證、atomic write、路徑逃逸防護:
python3 scripts/handoff_cli.py write --root "$ROOT" --kind active --agent "Main" --body-file /tmp/private.md
python3 scripts/handoff_cli.py write --root "$ROOT" --kind shared --agent "Main" --body-file /tmp/shared.md
python3 scripts/handoff_cli.py archive --root "$ROOT" --agent "Main" --session-id "20260726-topic" --slug "topic" --body-file /tmp/old.md讀取直接讀檔即可。這個設計來自血淚教訓:v1.x(Apple Notes 時期)讓 LLM 現場即興寫入,長期累積出重複筆記和被弄爛的內容;確定性腳本從源頭解決。atomic write 也避免雲端同步上傳寫到一半的檔案。
本次 session 產出的資訊
↓
另一個 agent 也需要知道?
├── 是 → 共有 shard
└── 否 → 私有 shard
- 私有:進行中的 feature branch、環境特有問題、只跟這台機器有關的事
- 共有:跨 agent 的專案狀態、用戶決策、環境同步進度
shard 保持精簡,注入 session 時不浪費 token:
| Shard | 預算 |
|---|---|
| 私有 | 1500 字元 |
| 共有 | 1000 字元 |
| 注入總計 | ~2500 字元 |
- git 可 diff、可 grep、不被特定廠商綁死
- 任何同步層都能用(iCloud、Syncthing、git),還能在 Obsidian 裡瀏覽
- frontmatter 有 schema 驗證——壞掉會大聲報錯
- 沒有 AppleScript 的不穩定、沒有 HTML round-trip 摧殘(Apple Notes 曾把 CJK 粗體標題切碎成多段)
- 跨平台:儲存腳本是純標準庫 Python
Archive 建立會使用 hardlink(os.link),遇到 OneDrive placeholder 檔或非 NTFS volume 時可能失敗。若同步軟體正在鎖定目標,atomic replace(os.replace)可能拋出 PermissionError,因此 OneDrive 目前屬於條件式支援。Windows 建議在系統層級設定 PYTHONUTF8=1。2>> 診斷 log redirect 在 Windows PowerShell 5.1 和 PowerShell 7 使用的 encoding 不同;該 log 只供診斷。
repo 保留了舊版工具,做一次性匯出:
python3 scripts/export_notes_to_markdown.py --root ~/.agents/handoff --agent "Main" \
--folder "Claude 工作區"這會把現有的私有 / 共有 / Archive 筆記轉進 Markdown 儲存區。匯出後就完全不要再寫 Apple Notes——舊筆記變成凍結的歸檔。
MIT