Skip to content

fix(hooks): post-pr-monitor の4件の既知問題を修正 - #16

Merged
aloekun merged 1 commit into
masterfrom
fix/post-pr-monitor-issues
Apr 3, 2026
Merged

fix(hooks): post-pr-monitor の4件の既知問題を修正#16
aloekun merged 1 commit into
masterfrom
fix/post-pr-monitor-issues

Conversation

@aloekun

@aloekun aloekun commented Apr 3, 2026

Copy link
Copy Markdown
Owner

Summary\


PR #13 で報告された hooks-post-pr-monitor の既知問題4件をすべて修正。
\

修正内容\

\

Test plan\

\

  • cargo test (21テスト全通過、parse_pr_number_from_url + convert_body_to_file のテスト追加)\
  • E2E: pnpm pr-create でテスト PR 作成 → PR番号が正しく取得されることを確認\
  • E2E: pnpm push → --monitor-only で jj bookmark 経由の PR 検出を確認\
  • E2E: claude -p --continue で CronCreate が既存セッションに作成されることを確認

Summary by CodeRabbit

リリースノート

  • 機能改善

    • PR検出の信頼性を向上させました。複数の検出方式でPRを確実に見つけられるようになりました。
    • 複数行のPRボディ説明文に対応しました。
    • タイムアウト処理を改善し、より長い処理に対応しました。
  • ドキュメント

    • 既知の問題と解決内容をドキュメントに追加しました。

@coderabbitai

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

.claude/hooks-post-pr-monitor/src/main.rs で PR 監視ツールを改善し、タイムアウトを 120 秒から 300 秒に延長、Windows 固有の実装を削除、新しいプロセス実行フロー(claude -p --continue への直接実行)、PR 発見メカニズムの拡張(gh pr view および jj ブックマーク列挙フォールバック)、マルチライン --body 値への対応(一時ファイル変換)を追加。docs/todo.md にて既知の問題として文書化。

Changes

Cohort / File(s) Summary
プロセス実行とタイムアウト処理
.claude/hooks-post-pr-monitor/src/main.rs
Windows 固有の run_cmd 実装を削除、run_claude_with_stdin への新フロー(stdin 経由でプロンプト供給、stdout/stderr の同時ドレイン)に変更。デフォルトステップタイムアウトを 120 秒から 300 秒に増加。成功/失敗ログに経過時間を含める。
PR 発見メカニズムの拡張
.claude/hooks-post-pr-monitor/src/main.rs
get_pr_info()gh pr view 後、jj ブックマーク列挙と gh pr list --head <bookmark> のフォールバックを追加。PR 番号取得の堅牢性向上。
PR 作成と URL 解析
.claude/hooks-post-pr-monitor/src/main.rs
parse_pr_number_from_url() を追加し gh pr create stdout から PR URL を抽出。失敗時は get_pr_info() へフォールバック。ユニットテスト含む。
マルチライン本文対応
.claude/hooks-post-pr-monitor/src/main.rs
convert_body_to_file()TempFile ガードを追加。--body 内の改行または \n リテラル検出時、一時マークダウンファイルに書き込み、引数を --body-file <path> に置換。drop 時にクリーンアップ。ユニットテスト含む。
ドキュメント
docs/todo.md
新規ドキュメントにて「hooks-post-pr-monitor Known Issues (PR \#13)」セクション追加。4 つの既知問題を完了済みアイテムとして列挙。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 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 プルリクエストのタイトルは、主な変更内容である4件の既知問題の修正を正確に反映しており、実装内容と完全に一致しています。
Docstring Coverage ✅ Passed Docstring coverage is 95.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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/hooks-post-pr-monitor/src/main.rs:
- Around line 191-199: The current logic only tries the first jj bookmark (uses
split(',').next()) so you miss PR heads on later bookmarks; update the code
paths around get_jj_bookmark() and the similar block at lines 223-241 to iterate
over all comma-separated local_bookmarks, trying each entry with
run_gh_quiet("pr", "list", "--head", <bookmark>, ...) until you successfully
parse a pr_number; return a PrInfo with the first successful pr_number and repo,
or None if none match. Ensure you reference and reuse the same
parsing/validation logic used now (the s.parse::<u64>().ok() flow) for each
bookmark.
- Around line 420-459: convert_body_to_file currently writes to a fixed temp
filename "gh-pr-body.md" and returns an Option<PathBuf>, which causes cross-run
collisions and leaked files on early returns; change it to create a unique
temporary file per call (use tempfile::NamedTempFile or create a
random/UUID-based filename in std::env::temp_dir()) and keep the NamedTempFile
handle alive until the caller is done so the OS file is removed on drop—i.e.,
update the function signature to return (Vec<String>, Option<NamedTempFile>) or
otherwise return the owned temp-file handle (not just PathBuf), write the
resolved body into that unique temp file, push its displayed path into result as
before, and ensure the file is always cleaned up by relying on the NamedTempFile
drop rather than manual cleanup that can be skipped on early returns.
- Around line 373-377: The code currently ignores errors from writing the prompt
to the child's stdin (the write_all call inside the child.stdin.take() block),
which hides real failures; update that block to check the Result from
stdin.write_all(prompt.as_bytes()) and propagate a proper Err (e.g., return
Err(...)) on failure instead of discarding it so callers can see the actual
write error; ensure any error type matches the surrounding function's Result (or
convert it) and keep dropping stdin after handling the result to still send EOF.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 48221473-740f-4c15-b0fb-73ca2883b9dc

📥 Commits

Reviewing files that changed from the base of the PR and between 60dbe5e and 93208db.

📒 Files selected for processing (3)
  • .claude/hooks-config.toml
  • .claude/hooks-post-pr-monitor/src/main.rs
  • docs/todo.md

Comment thread .claude/hooks-post-pr-monitor/src/main.rs Outdated
Comment thread .claude/hooks-post-pr-monitor/src/main.rs Outdated
Comment thread .claude/hooks-post-pr-monitor/src/main.rs Outdated
@aloekun
aloekun force-pushed the fix/post-pr-monitor-issues branch from 93208db to be23ce7 Compare April 3, 2026 12:00

@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 (2)
.claude/hooks-post-pr-monitor/src/main.rs (2)

441-476: 複数の --body 引数がある場合、最初の変換のみが保持されます。

現在の実装では、引数リストに複数の --body がある場合(稀なケースですが)、temp_guard が上書きされ、最初に作成された一時ファイルが即座に削除されます。

gh CLI の仕様上、複数の --body が渡されることは通常ないため、実用上は問題ありませんが、ログに一貫性がなくなる可能性があります。

♻️ 複数 body 対応(必要に応じて)
-fn convert_body_to_file(args: &[String]) -> (Vec<String>, Option<TempFile>) {
+fn convert_body_to_file(args: &[String]) -> (Vec<String>, Vec<TempFile>) {
     let mut result = Vec::with_capacity(args.len());
     let mut i = 0;
-    let mut temp_guard: Option<TempFile> = None;
+    let mut temp_guards: Vec<TempFile> = Vec::new();
 
     while i < args.len() {
         if args[i] == "--body" && i + 1 < args.len() {
             let body = &args[i + 1];
             if body.contains('\n') || body.contains("\\n") {
                 // ... (ファイル作成ロジック)
                 match std::fs::write(&path, &resolved) {
                     Ok(()) => {
                         // ...
-                        temp_guard = Some(TempFile(path));
+                        temp_guards.push(TempFile(path));
                     }
                     // ...
                 }
             }
         }
         // ...
     }
 
-    (result, temp_guard)
+    (result, temp_guards)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/hooks-post-pr-monitor/src/main.rs around lines 441 - 476, The loop
currently overwrites temp_guard when multiple "--body" args are converted,
causing earlier temp files (TempFile) to be dropped immediately; change
temp_guard from an Option<TempFile> to a collection (e.g., Vec<TempFile>) and
push each created TempFile instead of assigning to temp_guard so all temporary
files remain alive until function end, update any drop/cleanup logic to iterate
that collection, and adjust where result pushes the corresponding "--body-file"
paths to still match each converted body.

384-385: unwrap()expect() に置き換えることを推奨します。

Stdio::piped() を設定しているため take()None を返すことは通常ありませんが、デバッグ時のエラーメッセージの明確化のため expect() の使用を検討してください。

♻️ 提案
-    let stdout_handle = drain_pipe(child.stdout.take().unwrap());
-    let stderr_handle = drain_pipe(child.stderr.take().unwrap());
+    let stdout_handle = drain_pipe(child.stdout.take().expect("stdout should be piped"));
+    let stderr_handle = drain_pipe(child.stderr.take().expect("stderr should be piped"));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/hooks-post-pr-monitor/src/main.rs around lines 384 - 385,
child.stdout.take().unwrap() と child.stderr.take().unwrap()
がパニック時のデバッグ情報不足を招くため、unwrap() を具体的な期待理由を付けた expect() に置き換えてください(例:
child.stdout.take().expect("child.stdout should be piped as Stdio::piped()")
と同様に child.stderr も)。対象箇所は drain_pipe(child.stdout.take().unwrap()) と
drain_pipe(child.stderr.take().unwrap())、および関連する drain_pipe 呼び出しで、None
の場合に分かりやすいエラーメッセージを返すように修正してください。
🤖 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-post-pr-monitor/src/main.rs:
- Around line 441-476: The loop currently overwrites temp_guard when multiple
"--body" args are converted, causing earlier temp files (TempFile) to be dropped
immediately; change temp_guard from an Option<TempFile> to a collection (e.g.,
Vec<TempFile>) and push each created TempFile instead of assigning to temp_guard
so all temporary files remain alive until function end, update any drop/cleanup
logic to iterate that collection, and adjust where result pushes the
corresponding "--body-file" paths to still match each converted body.
- Around line 384-385: child.stdout.take().unwrap() と
child.stderr.take().unwrap() がパニック時のデバッグ情報不足を招くため、unwrap() を具体的な期待理由を付けた
expect() に置き換えてください(例: child.stdout.take().expect("child.stdout should be piped
as Stdio::piped()") と同様に child.stderr も)。対象箇所は
drain_pipe(child.stdout.take().unwrap()) と
drain_pipe(child.stderr.take().unwrap())、および関連する drain_pipe 呼び出しで、None
の場合に分かりやすいエラーメッセージを返すように修正してください。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6418468f-f5df-4c70-98fd-2cfc5b7c7f92

📥 Commits

Reviewing files that changed from the base of the PR and between 93208db and be23ce7.

📒 Files selected for processing (2)
  • .claude/hooks-post-pr-monitor/src/main.rs
  • docs/todo.md
✅ Files skipped from review due to trivial changes (1)
  • docs/todo.md

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