Skip to content

feat(hooks): SessionStart hook でセッション ID 伝播 + CronCreate セッション問題解決 (#17 再作成) - #18

Merged
aloekun merged 1 commit into
masterfrom
feat/session-start-hook
Apr 3, 2026
Merged

feat(hooks): SessionStart hook でセッション ID 伝播 + CronCreate セッション問題解決 (#17 再作成)#18
aloekun merged 1 commit into
masterfrom
feat/session-start-hook

Conversation

@aloekun

@aloekun aloekun commented Apr 3, 2026

Copy link
Copy Markdown
Owner

PR #17 の CodeRabbit レビュー上限到達のため再作成。内容は同一。

Summary by CodeRabbit

リリースノート

  • 新機能

    • Claudeセッションの継続性を改善するため、セッションID追跡機能を追加しました。セッションを明示的に再開できるようになります。
  • その他

    • 開発パイプラインの一部ステップを一時的に無効化しました。
    • セッション初期化フックを追加し、セッション管理の基盤を強化しました。

@coderabbitai

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown
📝 Walkthrough

概要

セッション ID の管理とハンドシェイク機能を実装するために、SessionStart フックを導入し、プッシュパイプラインの複数ステップを無効化しました。hooks-post-pr-monitor に主セッション ID の取得と再開ロジックを追加し、hooks-session-start という新しい Rust バイナリでセッション ID の環境変数への書き込みとファイル保存を行うようにしました。

変更一覧

コホート / ファイル(s) 概要
セッション ID 管理設定
.claude/hooks-config.toml, .claude/settings.local.json.template, .gitignore
プッシュパイプラインの integration_testai_reviewcommit_refactor ステップをコメントアウトして無効化。SessionStart フック構成を設定テンプレートに追加し、セッション ID ファイルおよびビルドアーティファクトを .gitignore に登録。
SessionStart フック実装
.claude/hooks-session-start/Cargo.toml, .claude/hooks-session-start/src/main.rs
セッション ID を JSON 入力から読み取り、環境変数ファイルと .session-id ファイルに伝播する新しい Rust バイナリを実装。シェルクォーティングと重複排除ロジックを含むユニットテスト付き。
セッション監視の強化
.claude/hooks-post-pr-monitor/src/main.rs
get_main_session_id() 関数を追加して主セッション ID を取得し、run_claude_with_stdin() の署名を更新して --resume <id> または --continue モードを選択できるようにしました。フォールバック制御フローで --resume 失敗時に --continue へのリトライを実装。
ビルドスクリプト
package.json
build:hooks-session-start スクリプトを追加して hooks-session-start の Rust バイナリをコンパイル・コピーし、build:hooks ターゲットの冒頭に統合。
ドキュメント
docs/todo.md
hooks-post-pr-monitor の "CronCreate session" 問題に関する TODO エントリを追加し、セッション ID の明示的な再開の必要性を記録。

シーケンス図

sequenceDiagram
    participant User as ユーザー<br/>(pnpm push)
    participant SessionStart as SessionStart<br/>フック
    participant EnvFile as 環境ファイル
    participant SessionFile as .session-id<br/>ファイル
    participant PostMonitor as hooks-post-pr-monitor
    participant Claude as Claude CLI

    User->>SessionStart: セッション ID を含む<br/>JSON を stdin に渡す
    SessionStart->>EnvFile: CLAUDE_CODE_SESSION_ID<br/>をエクスポートして追記
    SessionStart->>SessionFile: セッション ID<br/>を書き込み (初回のみ)
    SessionStart->>PostMonitor: フック出力に<br/>セッション ID を含める

    PostMonitor->>PostMonitor: get_main_session_id()<br/>で ID を取得
    PostMonitor->>Claude: claude -p --resume <id><br/>で実行を試みる
    
    alt --resume 成功時
        Claude-->>PostMonitor: 成功応答
    else --resume 失敗時
        PostMonitor->>Claude: claude -p --continue<br/>でフォールバック
        Claude-->>PostMonitor: 応答
    end
Loading

推定コードレビュー工数

🎯 3 (Moderate) | ⏱️ ~25 minutes

関連する可能性のあるプルリクエスト

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは SessionStart フックでのセッション ID 伝播と CronCreate セッション問題解決の実装を正確に反映しており、変更セット全体の主要な目的を明確に要約しています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
docs/todo.md (1)

10-12: TODO 項目のステータス確認

この PR で SessionStart フックと --resume 方式が実装されているため、この TODO 項目は [x] に更新すべきではないでしょうか?

📝 提案される修正
-- [ ] **CronCreate がサブセッションに閉じ込められる**: `pnpm push` 実行時、`review:ai` (`claude -p "/pre-push-review"`) のサブセッションが「最新セッション」となり、後続の `hooks-post-pr-monitor --monitor-only` の `--continue` がサブセッションに接続してしまう。SessionStart hook でメインセッション ID を `.session-id` ファイルに記録し、`--resume <session_id>` で明示指定する方式に修正
+- [x] **CronCreate がサブセッションに閉じ込められる**: `pnpm push` 実行時、`review:ai` (`claude -p "/pre-push-review"`) のサブセッションが「最新セッション」となり、後続の `hooks-post-pr-monitor --monitor-only` の `--continue` がサブセッションに接続してしまう。SessionStart hook でメインセッション ID を `.session-id` ファイルに記録し、`--resume <session_id>` で明示指定する方式に修正
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/todo.md` around lines 10 - 12, Update the TODO checklist entry about
"CronCreate セッション問題" to mark it complete by changing the checkbox from `[ ]` to
`[x]` since SessionStart hook and the `--resume` mechanism (referenced as
SessionStart and `--resume <session_id>`) have been implemented; modify the line
under "CronCreate セッション問題 (PR `#16` 調査で発見)" that currently reads "- [ ]
**CronCreate がサブセッションに閉じ込められる**" to "- [x] **CronCreate がサブセッションに閉じ込められる**" and
optionally add a brief note that SessionStart writes the main session ID to
`.session-id` and `--resume` is used to explicitly reconnect.
.claude/hooks-session-start/src/main.rs (2)

72-73: ファイル書き込み失敗の無視

let _ = std::fs::write(...) は書き込み失敗を無視します。失敗した場合、hooks-post-pr-monitor はセッション ID を取得できず、--continue にフォールバックします。これは設計上許容されていますが、デバッグ用にログを出力することを検討してください。

🔍 デバッグ用ログの追加
     if should_write {
-        let _ = std::fs::write(&sid_path, &session_id);
+        if let Err(e) = std::fs::write(&sid_path, &session_id) {
+            eprintln!("[hooks-session-start] 警告: .session-id 書き込み失敗: {}", e);
+        }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/hooks-session-start/src/main.rs around lines 72 - 73, 現在の let _ =
std::fs::write(&sid_path, &session_id);
は書き込みエラーを無視しているため、書き込みに失敗した場合にエラーをログ出力するように変更してください — std::fs::write の戻り値
(Result) をマッチまたは ? で処理し、Err の場合には sid_path と session_id
を含めた分かりやすいメッセージをログ(既存のロガーがあればそれを使う、なければ eprintln!)しておきます。対象箇所は should_write
ブロック内の std::fs::write 呼び出しです。

27-33: パス解決のエッジケース

current_exe() が失敗した場合、unwrap_or_default() が空の PathBuf を返し、その parent()None を返すため、最終的に "./.session-id" になる可能性があります。これは .claude/.session-id ではなく、hooks-post-pr-monitor が読み取れない場所になります。

実際には current_exe() が失敗するのは稀ですが、より堅牢にするには明示的なエラーハンドリングを検討してください。

♻️ より堅牢なパス解決の提案
 fn session_id_file_path() -> std::path::PathBuf {
-    std::env::current_exe()
-        .unwrap_or_default()
-        .parent()
-        .unwrap_or(Path::new("."))
-        .join(".session-id")
+    std::env::current_exe()
+        .ok()
+        .and_then(|p| p.parent().map(|p| p.to_path_buf()))
+        .unwrap_or_else(|| Path::new(".claude").to_path_buf())
+        .join(".session-id")
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/hooks-session-start/src/main.rs around lines 27 - 33,
session_id_file_path currently calls std::env::current_exe().unwrap_or_default()
which can produce an empty PathBuf and cause the function to resolve to
"./.session-id"; change session_id_file_path to explicitly handle the Result
from std::env::current_exe() (e.g. match or if let), on Ok use the exe's parent
when present, and on Err try a robust fallback such as std::env::current_dir()
and/or a dedicated directory like ".claude" before joining ".session-id"; update
the logic around parent() to use that explicit fallback so the function reliably
returns the intended .claude/.session-id path even when current_exe() fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.claude/hooks-session-start/src/main.rs:
- Around line 72-73: 現在の let _ = std::fs::write(&sid_path, &session_id);
は書き込みエラーを無視しているため、書き込みに失敗した場合にエラーをログ出力するように変更してください — std::fs::write の戻り値
(Result) をマッチまたは ? で処理し、Err の場合には sid_path と session_id
を含めた分かりやすいメッセージをログ(既存のロガーがあればそれを使う、なければ eprintln!)しておきます。対象箇所は should_write
ブロック内の std::fs::write 呼び出しです。
- Around line 27-33: session_id_file_path currently calls
std::env::current_exe().unwrap_or_default() which can produce an empty PathBuf
and cause the function to resolve to "./.session-id"; change
session_id_file_path to explicitly handle the Result from
std::env::current_exe() (e.g. match or if let), on Ok use the exe's parent when
present, and on Err try a robust fallback such as std::env::current_dir() and/or
a dedicated directory like ".claude" before joining ".session-id"; update the
logic around parent() to use that explicit fallback so the function reliably
returns the intended .claude/.session-id path even when current_exe() fails.

In `@docs/todo.md`:
- Around line 10-12: Update the TODO checklist entry about "CronCreate セッション問題"
to mark it complete by changing the checkbox from `[ ]` to `[x]` since
SessionStart hook and the `--resume` mechanism (referenced as SessionStart and
`--resume <session_id>`) have been implemented; modify the line under
"CronCreate セッション問題 (PR `#16` 調査で発見)" that currently reads "- [ ] **CronCreate
がサブセッションに閉じ込められる**" to "- [x] **CronCreate がサブセッションに閉じ込められる**" and optionally
add a brief note that SessionStart writes the main session ID to `.session-id`
and `--resume` is used to explicitly reconnect.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 452156a2-b35d-4e37-b8cd-f0be1d84609f

📥 Commits

Reviewing files that changed from the base of the PR and between 5f2aa95 and d895815.

⛔ Files ignored due to path filters (1)
  • .claude/hooks-session-start/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • .claude/hooks-config.toml
  • .claude/hooks-post-pr-monitor/src/main.rs
  • .claude/hooks-session-start/Cargo.toml
  • .claude/hooks-session-start/src/main.rs
  • .claude/settings.local.json.template
  • .gitignore
  • docs/todo.md
  • package.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant