開発
Claude Codeとの会話を自動記録する仕組み - Windows環境での実装計画
背景
Claude Codeでの会話はセッション終了とともに消えてしまう。過去の会話を検索・参照できるよう、自動的にMarkdownファイルとして保存する仕組みを作りたい。
参考にした記事では、macOS環境でLaunchAgentを使ってObsidianに同期している。これをWindows環境に適応し、mdx-playgroundプロジェクト内に保存する形で実装する。
結論
以下の構成で実現できる:
mdx-playground/
└── claude-code-sync/
├── watch-claude-sync.sh # 監視スクリプト(1分ごと:ファイル更新のみ)
├── commit-daily.sh # コミットスクリプト(1日1回:commit & push)
├── 2026年1月13日.md # 会話ログ(日付ごと)
└── ...
- 監視スクリプト: 1分ごとにセッションファイルを監視し、Markdownに追記(コミットしない)
- コミットスクリプト: 1日1回(23:59)にまとめてcommit & push
- 常駐化: Windowsタスクスケジューラで2つのタスクを登録
- 保存先:
claude-code-sync/ディレクトリにMarkdownファイル
実装計画
Phase 1: ディレクトリ構造の準備
mkdir -p claude-code-sync
Phase 2: 監視スクリプトの作成
claude-code-sync/watch-claude-sync.sh を作成する。
主な機能
- セッションファイルの監視(1分間隔)
~/.claude/projects/*/配下の全プロジェクトのjsonlファイルを監視- 最終更新から60分以内のファイルを対象
- 会話の抽出・整形
jqを使ってjsonlをパースtype: "user"とtype: "assistant"のメッセージを抽出- システムメッセージやコマンド出力はフィルタリング
- 日付ごとのファイル分割
YYYY年M月D日.md形式で保存- タイムスタンプを確認し、その日の会話のみ抽出
- 追記モード
- 上書きではなく差分追記
- 最後に処理した行番号を記録し、新しい行のみ処理
スクリプト骨格
#!/bin/bash
# Watch Claude Code sessions and sync to markdown
# コミットは別スクリプト(commit-daily.sh)で1日1回行う
SYNC_DIR="$(dirname "$0")" # スクリプトと同じディレクトリに保存
CLAUDE_PROJECTS="/c/Users/numbe/.claude/projects"
STATE_FILE="$SYNC_DIR/.sync-state"
# 日本語日付フォーマット
get_today() {
date +"%Y年%-m月%-d日"
}
# セッションファイルを検索(全プロジェクト)
find_sessions() {
find "$CLAUDE_PROJECTS" -name "*.jsonl" -type f -mmin -60 \
! -path "*/subagents/*" 2>/dev/null
}
# jsonlから会話を抽出
extract_conversations() {
local session_file="$1"
local today_start=$(date -u -d "today 00:00:00 +0900" +%Y-%m-%dT%H:%M:%S 2>/dev/null)
jq -r --arg today "$today_start" '
select(.type == "user" or .type == "assistant") |
select((.timestamp // "9999") >= $today) |
# フィルタリングとフォーマット処理
...
' "$session_file"
}
# メインループ(ファイル更新のみ、コミットしない)
while true; do
for session in $(find_sessions); do
extract_conversations "$session"
done
sleep 60
done
Phase 3: コミットスクリプトの作成
claude-code-sync/commit-daily.sh を作成する。1日1回実行し、まとめてcommit & pushする。
#!/bin/bash
# Daily commit and push for Claude Code sync
# タスクスケジューラで毎日23:59に実行
SYNC_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SYNC_DIR" || exit 1
# 今日の日付
TODAY=$(date +"%Y年%-m月%-d日")
# 変更があればコミット&プッシュ
if git status --porcelain | grep -q .; then
git add -A
git commit -m "Claude: ${TODAY}"
git push origin master
echo "Committed and pushed: ${TODAY}"
else
echo "No changes to commit"
fi
Phase 4: フィルタリングルール
以下のメッセージは除外する:
| パターン | 理由 |
|---|---|
<system-reminder> | システムの自動挿入メッセージ |
<local-command-*> | ローカルコマンドの出力 |
<command-name> | スラッシュコマンドの内部表現 |
<task-notification> | タスク通知 |
tool_use / tool_result | ツール実行の詳細 |
Phase 5: 出力フォーマット
# 2026年1月13日 Claudeとの会話
## セッション: mdx-playground (10:30)
**ユーザー**: Claude Codeとの会話を自動的に記録したい
**Claude**: はい、実現できます。以下の仕組みで...
---
## セッション: tax-assistant (14:15)
**ユーザー**: 確定申告の準備について
**Claude**: 確定申告の準備として...
Phase 6: タスクスケジューラで常駐化
2つのタスクを登録する。
タスク1: 監視スクリプト(ログイン時に起動)
$action = New-ScheduledTaskAction -Execute "C:\Program Files\Git\bin\bash.exe" `
-Argument "-c 'C:/Users/numbe/Git_repo/mdx-playground/claude-code-sync/watch-claude-sync.sh'"
$trigger = New-ScheduledTaskTrigger -AtLogon
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries -StartWhenAvailable
Register-ScheduledTask -TaskName "ClaudeCodeSync" -Action $action `
-Trigger $trigger -Settings $settings -RunLevel Highest
タスク2: コミットスクリプト(毎日23:59に実行)
$action = New-ScheduledTaskAction -Execute "C:\Program Files\Git\bin\bash.exe" `
-Argument "-c 'C:/Users/numbe/Git_repo/mdx-playground/claude-code-sync/commit-daily.sh'"
$trigger = New-ScheduledTaskTrigger -Daily -At "23:59"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries -StartWhenAvailable
Register-ScheduledTask -TaskName "ClaudeCodeSyncCommit" -Action $action `
-Trigger $trigger -Settings $settings -RunLevel Highest
手動での起動・停止
# 監視スクリプト
Start-ScheduledTask -TaskName "ClaudeCodeSync"
Stop-ScheduledTask -TaskName "ClaudeCodeSync"
Get-ScheduledTask -TaskName "ClaudeCodeSync"
# コミットスクリプト(手動実行したい場合)
Start-ScheduledTask -TaskName "ClaudeCodeSyncCommit"
Phase 7: 動作確認
- 監視スクリプトを手動実行してエラーがないか確認
- 会話が正しく抽出されるか確認
- 日付フィルタリングが正しく動作するか確認
- コミットスクリプトを手動実行してcommit & pushを確認
- タスクスケジューラからの起動を確認
技術的な注意点
Windows環境での違い
| macOS | Windows (Git Bash) |
|---|---|
date -v-9H | date -d "-9 hours" |
~/.claude/ | /c/Users/numbe/.claude/ |
| LaunchAgent | タスクスケジューラ |
セッションファイルの構造
{"type":"user","message":{"role":"user","content":"..."},"timestamp":"2026-01-13T01:30:00.000Z"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"..."}]},"timestamp":"..."}
type: "user", "assistant", "system" などmessage.content: ユーザー入力は文字列、Claude応答は配列timestamp: UTC形式
コミット戦略
| 項目 | 設定 |
|---|---|
| ファイル更新 | 1分ごと(リアルタイム) |
| コミット | 1日1回(23:59) |
| プッシュ | コミットと同時 |
| 履歴 | 1日1コミットできれいに保つ |
メリット:
- git履歴が汚れない(1日1コミット)
- 会話はリアルタイムで保存される
- pushも1日1回で済む
今後の拡張案
- プロジェクトごとのディレクトリ分け
- 要約の自動生成
- 検索機能の追加
- Web UIでの閲覧
まとめ
Claude Codeのセッションファイルを監視し、会話を自動的にMarkdownとして保存する仕組みを実装する。監視は1分ごとにファイル更新のみ行い、コミット&プッシュは1日1回にまとめることで履歴をきれいに保つ。Windows環境ではタスクスケジューラとGit Bashを組み合わせて実現する。これにより、過去の会話を検索・参照でき、学んだことがナレッジベースに蓄積される。