Claude Codeのプランファイルをesa.ioに自動投稿するCLIツールです。
Claude CodeのSessionEndフックから呼び出すことで、$CLAUDE_CODE_TMPDIR/plans/配下に生成されたプランファイル(Markdown)をesa.ioに自動投稿します。プランファイルはgitignore対象のため、ブランチ削除と共に失われてしまいますが、本ツールを使うことでナレッジとして蓄積できます。
- 自動投稿: SessionEndフックからの自動実行
- プランファイル検索:
$CLAUDE_CODE_TMPDIR/plans/から最新の.mdファイルを検索 - タイトル抽出: Markdownの最初の
# 見出しをタイトルとして抽出(なければファイル名を使用) - タイトルサニタイズ: esa.ioで特殊な意味を持つ文字(
# / \ | [ ] < > ( ) :)を_に置換 - 日付カテゴリ: 設定したカテゴリに
/yyyy/mm/ddを自動付与 - Gitリポジトリタグ: リポジトリ名を自動タグ付け
- dry-runモード: 投稿内容をプレビュー(実際には投稿しない)
- タイムスタンプ比較: esa側の
updated_atとローカルファイルの更新日時を比較し、ローカルが古ければ更新をスキップ - セキュア設計: TLS 1.2+、プロキシ無効、リダイレクト禁止、レスポンスサイズ制限
go install github.com/syou6162/plan2esa@latestまたは、ソースからビルド:
git clone https://github.com/syou6162/plan2esa.git
cd plan2esa
go build -o plan2esa .設定ファイルのパス解決順序:
-configフラグで明示指定された場合はそのパス$XDG_CONFIG_HOME/plan2esa/config.yaml~/.config/plan2esa/config.yaml
設定ファイルの例(~/.config/plan2esa/config.yaml):
esa:
team_name: "your-team-name" # あなたのesa.ioチーム名
post:
category: "Claude Code/plans" # カテゴリ(実際の投稿時は末尾に /yyyy/mm/dd が自動付与される)esa.ioのアクセストークンは環境変数で指定します:
export ESA_ACCESS_TOKEN="your_esa_access_token_here"plan2esaデフォルトの設定ファイルパス(~/.config/plan2esa/config.yaml)を使用し、$CLAUDE_CODE_TMPDIR/plans/配下の最新プランファイルをesa.ioに投稿します。
plan2esa -config /path/to/config.yaml実際に投稿せず、投稿内容をプレビューします:
plan2esa -dry-rundry-runモードでは環境変数ESA_ACCESS_TOKENが不要です。
Claude Codeの設定ファイル(~/.claude/settings.json)にSessionEndフックを追加します:
{
"hooks": {
"SessionEnd": {
"command": "plan2esa",
"blocking": false
}
}
}これにより、Claude Codeのセッション終了時に自動的にプランファイルがesa.ioに投稿されます。
cchookを使うと、より高度なフック管理ができます:
{
"hooks": {
"SessionEnd": {
"command": "cchook -event SessionEnd",
"blocking": false
}
}
}cchookの設定ファイル(~/.config/cchook/config.yaml):
hooks:
SessionEnd:
- command: plan2esa
description: "プランファイルをesa.ioに投稿"$CLAUDE_CODE_TMPDIR/plans/ディレクトリのパスを取得- 環境変数が未設定またはディレクトリが不在の場合は何もせず正常終了
- 最新の
.mdファイルを検索(更新日時順)- ファイルがない場合は何もせず正常終了
- プランファイルが見つかった場合のみ、設定ファイルを読み込み
- dry-runの場合:タイトル・本文・カテゴリを表示して終了(既存記事がある場合はタイムスタンプ比較結果も表示)
- 通常モード:
ESA_ACCESS_TOKENを取得してesa.io APIに投稿- 既存記事が見つかった場合:esa側の
updated_atとローカルファイルの更新日時を比較し、ローカルが古ければ更新をスキップ - ローカルが新しい/同一の場合:既存記事を上書き更新
- 既存記事がない場合:新規作成
- 既存記事が見つかった場合:esa側の
- Markdownの最初の
# 見出しを抽出 - サニタイズ(特殊文字を
_に置換、制御文字を除去、255バイト上限) TrimSpaceを適用- 空文字になった場合はファイル名(
.md拡張子を除く)を使用
最初の# 見出し行が本文から除去されます(タイトルとの重複を避けるため)。
設定ファイルで指定したカテゴリに、実行日の日付(/yyyy/mm/dd)が自動付与されます。
例:設定がClaude Code/plansの場合、2026年2月10日に実行するとClaude Code/plans/2026/02/10となります。
Gitリポジトリ名が自動的にタグとして付与されます(git config --get remote.origin.urlから抽出)。Gitリポジトリでない場合やremote.origin.urlが未設定の場合はタグなし(エラーにはしない)。
go mod downloadgo test -v ./...カバレッジ付き:
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.outgo build -o plan2esa .pre-commitフックを使用して、コミット前に自動的にフォーマット・検証・テストを実行します:
# pre-commitのインストール(初回のみ)
brew install pre-commit # macOS
# または
pip install pre-commit
# フックのインストール
pre-commit install
# 手動実行
pre-commit run --all-filesMIT License - 詳細はLICENSEを参照してください。