Skip to content

feat: 1セッションから複数PRが出たときの表記を分ける(#12 +2 - #95

Merged
takecchi merged 3 commits into
mainfrom
codiva/1-pr
Aug 6, 2026
Merged

feat: 1セッションから複数PRが出たときの表記を分ける(#12 +2#95
takecchi merged 3 commits into
mainfrom
codiva/1-pr

Conversation

@takecchi

@takecchi takecchi commented Aug 6, 2026

Copy link
Copy Markdown
Owner

背景

セッションが自分で別ブランチを切って gh pr create すると、1 セッションに複数の PR が紐づきます。しかし一覧の PR セルはセッションブランチ(codiva/<slug>)の PR しか出せず、2 本目以降はどこにも表示されませんでした。

変更内容

検知(core/pr-detect.ts 新規・純粋)

  • gh pr create を実行した tool_use の結果に出る PR URL を拾う(sdk-parse が tool_use id を控えて tool_result と突き合わせる)。
  • ログ全体から URL を拾わないのは誤検出を避けるため — gh pr list の出力や、gh pr view / WebFetch で覗いただけの他人の PR まで「このセッションの PR」になってしまう。
  • MCP の create_pull_request 系ツールもツール名で拾う。
  • 参照の追加・除去は変化が無ければ同じ配列参照を返すstate.json を無駄に書き直さない / 再描画を増やさない)。

状態・永続化

  • SessionState.extraPrs(識別のみ・永続)と prCreateToolIds(結果待ちの対応付け・transient)を追加。
  • state.json に保存・復元(壊れた要素は 1 件ずつ落とす)。reducer はブランチの PR と重複したら畳む。

表示

画面 表記
一覧 ✓ #12 +2(代表 + 残り件数)。PR 列は複数 PR の行があるときだけ 10 → 14 桁に広げる
詳細 PR 3 件: ✓ #12 · #13 · #14(複数 PR のときだけ 1 行。1 本ならログの縦幅を 1 行も譲らない)
  • 代表はセッションブランチの PRprStatus(グリフ)を持つ唯一の PR で、クリック / p で開く先でもあるため、見えている番号と開く先とグリフの意味を一致させた。
  • セッションが自分で作った PR は codiva が追跡・操作しない(別ブランチのものを勝手に ready 化・マージしない)ので番号のみ・グリフなし。状態を知らないのに緑や赤で嘘をつかない。
  • gh の追加呼び出しはゼロ(API クォータを増やさない)。
  • 描画とクリック当たり判定は必ず同じ列幅(core/list-hit.tsprCellWidth)を使う。
  • PrCell / prStatusBadgeui/pr-cell.tsx に共通化(一覧と詳細で同じグリフ・同じ色)。

ドキュメント

README.md(利用者向けの表記説明)/ docs/ARCHITECTURE.md(状態フィールド・設計判断)/ docs/TASKS.md(Phase 27)/ CLAUDE.md(コードの地図)。

テスト

  • src/core/pr-detect.spec.ts(新規・テーブルドリブン): コマンド判定 / URL 抽出(GHE ホスト・サブパス・重複・issues リンク)/ 参照同一性 / 上限 / 表示ヘルパ。
  • src/core/sdk-parse.spec.ts: 実フィクスチャと同じメッセージ形で tool_use → tool_result の対応、gh pr list を数えないこと、ブランチ PR と判明したら畳むこと。
  • src/core/persistence.spec.ts: 往復と壊れた JSON の扱い。
  • src/core/list-hit.spec.ts: 列幅の切替。
  • tests/app.test.tsx: 一覧に ✓ #42 +2 が出て #43 は出ないこと、詳細に全件が並ぶこと、1 本のときは詳細に PR 行を出さないこと。

動作確認

  • npm run lint / npm run typecheck / npm test(2,232 件)/ npm run build
  • 実 TTY + Claude 認証での手動確認(非対話セッションでは実行できないため未実施)。確認観点: 複数 PR を出したセッションの行が #12 +2 になり、PR セルのクリックで代表の PR が開く / 詳細ビューに全件が並ぶ / 再起動しても +n が残る。

🤖 Generated with Claude Code

セッションが自分で別ブランチを切って `gh pr create` すると 1 セッションに複数の PR が
紐づくが、一覧はセッションブランチの PR しか出せず 2 本目以降はどこにも出なかった。

- `core/pr-detect.ts`(純粋・新規): `gh pr create` の tool_use 判定、結果からの PR URL
  抽出、参照の追加・除去(変化が無ければ同じ配列参照を返す = state.json を無駄に
  書き直さない)、表示ヘルパ(primaryPr / otherPrs / prCount / hasMultiplePrs / allPrs)
- `core/sdk-parse.ts`: tool_use id を控えて tool_result と突き合わせる。ログ全体から URL を
  拾うと `gh pr list` の出力や他人の PR まで数えるため、作成コマンドの結果だけを走査する
- `SessionState.extraPrs` を追加して永続化(壊れた要素は 1 件ずつ落とす)。reducer は
  ブランチの PR と重複したら畳む
- 一覧: `#12 +2`(代表 + 件数)。PR 列は複数 PR の行があるときだけ 10 → 14 桁に広げ、
  描画とクリック当たり判定で同じ幅を使う
- 詳細: 複数 PR のときだけ `PR 3 件: ✓ #12 · #13 · #14` の 1 行。PrCell / prStatusBadge は
  `ui/pr-cell.tsx` に共通化
- 代表はセッションブランチの PR(グリフとクリック先を一致させる)。自分で作った PR は
  codiva が追跡・操作しないので番号のみ。gh の追加呼び出しはゼロ
@takecchi
takecchi marked this pull request as ready for review August 6, 2026 14:28
- 行が 2 行に折り返すと rowLineAtPoint(1 セッション = 1 行が前提)が壊れ、以降の行の
  クリックが全部ズレる。広い PR 列を使う間はブランチ列の閾値を 4 桁ぶん厳しくし、
  PR セル・経過時間を truncate-end に、PR セルの Box を flexShrink={0}(描いた幅と
  当たり判定の幅を必ず一致させる)。80 桁での 1 行維持は回帰テストで固定
- `gh pr create … || gh pr list …` のような読み取り系との混在コマンドを検知対象から外す
  (一覧に出た PR を全部このセッションの PR として数えてしまう)
- `gh pr create` が「既に PR がある」と既存 URL を返すケースで、ブランチの PR が extraPrs に
  二重に積まれるのを検知側で弾く(reducer の畳み込みは pr が変わったときしか走らない)
- addPrRefs が上限到達後も新配列を返していて state.json の再保存が走るのを止める
- 並列 `gh pr create` の保留 id 上限を 4 → 8。順不同・サブエージェント経由のテストを追加
- toPrRef で http(s) 以外の URL を弾く(openUrl に渡るため多層防御)
- 詳細ビューの PR 行を入れ子 Text にして狭い端末でも見出し・番号が切れないように
- 未使用の prCount を削除、正規表現の /g 共有インスタンスをやめる、doc の型記載を修正
@takecchi
takecchi merged commit ad25e5e into main Aug 6, 2026
1 check passed
@takecchi
takecchi deleted the codiva/1-pr branch August 6, 2026 17:08
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