Note: このIssueは 2026-03-09 にレビュー結果(Stage 1, Stage 3)を反映して更新されました。
詳細: dev-reports/issue/386/issue-review/
概要
Gemini CLIの応答完了後、ステータスがスピナー(processing)のまま ready に遷移しない。
GEMINI_PROMPT_PATTERN が実際のGeminiプロンプト形式にマッチしないことが原因。
現象
- Worktree:
commandmate-marketing-main(CLIツール: gemini)
- Geminiが応答完了してプロンプト入力待ち状態にもかかわらず、UIのステータスがスピナー(
isProcessing: true)のまま
- API応答:
sessionStatusByCli.gemini = { isRunning: true, isWaitingForResponse: false, isProcessing: true }
原因
現在の GEMINI_PROMPT_PATTERN
// src/lib/cli-patterns.ts:132
export const GEMINI_PROMPT_PATTERN = /^[>❯]\s*$/m;
行頭が > または ❯ で、その後が空白のみの行にマッチする。
実際のGeminiプロンプト出力
> Type your message or @path/to/file
- 先頭にスペースがある(
>)
> の後にプレースホルダーテキストがある(Type your message or @path/to/file)
status-detector.ts での検出失敗フロー
- ステップ1(プロンプト検出):
detectPrompt() → 対話的プロンプトではないためスキップ
- ステップ2(thinking検出):
detectThinking() → thinkingインジケーターなしでスキップ
- ステップ3(入力プロンプト検出):
getCliToolPatterns("gemini").promptPattern(= GEMINI_PROMPT_PATTERN)を介して promptPattern.test(lastLines) が呼ばれる → マッチしない(先頭スペース+テキスト付きのため)
- ステップ4(時間ベース):
lastOutputTimestamp 未提供のためスキップ
- ステップ5(デフォルト):
status: 'running' → スピナー表示
修正方針
GEMINI_PROMPT_PATTERN を実際のGeminiプロンプト形式にもマッチするよう拡張する。
// 現在
export const GEMINI_PROMPT_PATTERN = /^[>❯]\s*$/m;
// 修正案: 先頭スペース許容、プレースホルダーテキスト許容
export const GEMINI_PROMPT_PATTERN = /^\s*[>❯]\s*(Type your message.*)?$/m;
リテラル文字列依存に関する考察
修正案は Type your message というリテラル文字列に依存しており、Gemini CLIのバージョンアップでプレースホルダーテキストが変更された場合(例: Ask a question 等)に再度マッチしなくなるリスクがある。
より堅牢な代替案として /^\s*[>❯]\s*(.*)$/m(> or ❯ の後は任意テキスト許容)も検討したが、他のCLIツールのレスポンス行でたまたま > で始まる行を誤検出するリスクとのトレードオフがある。
現案を採用する理由: 現時点でのGemini CLIプロンプトの実態に即した最小変更であり、誤検出リスクを避けつつ既知の問題を確実に解消できる。将来プレースホルダーが変更された場合は、その時点で再度パターンを更新する方針とする。
修正対象
src/lib/cli-patterns.ts: GEMINI_PROMPT_PATTERN(132行目)の修正
src/lib/cli-patterns.ts: getCliToolPatterns('gemini') の skipPatterns(311行目)内のインラインパターン /^[>❯]\s*$/ を GEMINI_PROMPT_PATTERN への参照に変更し、DRY原則に適合させる(新しいプロンプト形式もフィルタ対象に含める)
src/lib/cli-tools/gemini.ts: handleTrustDialog 内(128行目)のハードコードパターン /^[>❯]\s*$/m を GEMINI_PROMPT_PATTERN への参照に変更し、新しいプロンプト形式(先頭スペース+テキスト付き)でもGeminiプロンプトを正しく検出できるようにする
- テストファイル: パターン修正に対応するテスト追加(具体的なテストケースは受入条件を参照)
変更不要の箇所
src/lib/cli-patterns.ts: claude用 skipPatterns(272行目)の /^[>❯]\s*$/ はClaude専用のため変更不要。GeminiのGEMINI_PROMPT_PATTERNの修正による影響はない
src/lib/response-poller.ts: 759行目の userPromptPattern = /^[>❯]\s+\S/ および879行目の /^[>❯]\s+(\S.*)$/m はユーザーが入力したプロンプト行(> メッセージ)を検出するためのパターンであり、Geminiの待機プロンプト( > Type your message...)とは用途が異なる。先頭スペース付きの待機プロンプトはこれらのパターンにマッチしないため、現時点では影響なし(調査済み)
受入条件
具体的なテストケース
以下のテストケースを tests/unit/lib/cli-patterns.test.ts に追加すること:
- 旧形式マッチ:
> のみの行が GEMINI_PROMPT_PATTERN にマッチする
- 旧形式マッチ(❯):
❯ のみの行が GEMINI_PROMPT_PATTERN にマッチする
- 新形式マッチ:
> Type your message or @path/to/file が GEMINI_PROMPT_PATTERN にマッチする
- 誤検出防止: レスポンス本文中の
> quoted text(先頭スペースなし、引用テキスト)が GEMINI_PROMPT_PATTERN に誤マッチしないこと
- skipPatterns検証:
getCliToolPatterns("gemini").skipPatterns が新形式にもマッチすること
レビュー履歴
Stage 1 (2026-03-09)
- 修正方針の明確化、リテラル文字列依存に関する考察を追加
- skipPatterns修正をDRY原則の観点で追加
Stage 3 (2026-03-09) - 影響範囲レビュー
- I1: gemini.ts handleTrustDialog内のハードコードパターンを修正対象に追加
- I2: response-poller.tsのパターンは影響なしであることを「変更不要の箇所」として明記
- I3: 具体的なテストケース5件を受入条件に追加
- I4: claude用skipPatterns(272行目)は変更不要であることを明記
概要
Gemini CLIの応答完了後、ステータスがスピナー(processing)のまま
readyに遷移しない。GEMINI_PROMPT_PATTERNが実際のGeminiプロンプト形式にマッチしないことが原因。現象
commandmate-marketing-main(CLIツール: gemini)isProcessing: true)のままsessionStatusByCli.gemini = { isRunning: true, isWaitingForResponse: false, isProcessing: true }原因
現在の
GEMINI_PROMPT_PATTERN行頭が
>または❯で、その後が空白のみの行にマッチする。実際のGeminiプロンプト出力
>)>の後にプレースホルダーテキストがある(Type your message or @path/to/file)status-detector.ts での検出失敗フロー
detectPrompt()→ 対話的プロンプトではないためスキップdetectThinking()→ thinkingインジケーターなしでスキップgetCliToolPatterns("gemini").promptPattern(=GEMINI_PROMPT_PATTERN)を介してpromptPattern.test(lastLines)が呼ばれる → マッチしない(先頭スペース+テキスト付きのため)lastOutputTimestamp未提供のためスキップstatus: 'running'→ スピナー表示修正方針
GEMINI_PROMPT_PATTERNを実際のGeminiプロンプト形式にもマッチするよう拡張する。リテラル文字列依存に関する考察
修正案は
Type your messageというリテラル文字列に依存しており、Gemini CLIのバージョンアップでプレースホルダーテキストが変更された場合(例:Ask a question等)に再度マッチしなくなるリスクがある。より堅牢な代替案として
/^\s*[>❯]\s*(.*)$/m(>or❯の後は任意テキスト許容)も検討したが、他のCLIツールのレスポンス行でたまたま>で始まる行を誤検出するリスクとのトレードオフがある。現案を採用する理由: 現時点でのGemini CLIプロンプトの実態に即した最小変更であり、誤検出リスクを避けつつ既知の問題を確実に解消できる。将来プレースホルダーが変更された場合は、その時点で再度パターンを更新する方針とする。
修正対象
src/lib/cli-patterns.ts:GEMINI_PROMPT_PATTERN(132行目)の修正src/lib/cli-patterns.ts:getCliToolPatterns('gemini')のskipPatterns(311行目)内のインラインパターン/^[>❯]\s*$/をGEMINI_PROMPT_PATTERNへの参照に変更し、DRY原則に適合させる(新しいプロンプト形式もフィルタ対象に含める)src/lib/cli-tools/gemini.ts:handleTrustDialog内(128行目)のハードコードパターン/^[>❯]\s*$/mをGEMINI_PROMPT_PATTERNへの参照に変更し、新しいプロンプト形式(先頭スペース+テキスト付き)でもGeminiプロンプトを正しく検出できるようにする変更不要の箇所
src/lib/cli-patterns.ts: claude用skipPatterns(272行目)の/^[>❯]\s*$/はClaude専用のため変更不要。GeminiのGEMINI_PROMPT_PATTERNの修正による影響はないsrc/lib/response-poller.ts: 759行目のuserPromptPattern = /^[>❯]\s+\S/および879行目の/^[>❯]\s+(\S.*)$/mはユーザーが入力したプロンプト行(> メッセージ)を検出するためのパターンであり、Geminiの待機プロンプト(> Type your message...)とは用途が異なる。先頭スペース付きの待機プロンプトはこれらのパターンにマッチしないため、現時点では影響なし(調査済み)受入条件
readyに遷移する(スピナーが消える)>のみの行)も引き続きマッチする> Type your message or @path/to/file)もマッチするgetCliToolPatterns("gemini").skipPatternsが新しいプロンプト形式にもマッチすることgemini.tsのhandleTrustDialog内のパターンも新形式にマッチすること具体的なテストケース
以下のテストケースを
tests/unit/lib/cli-patterns.test.tsに追加すること:>のみの行がGEMINI_PROMPT_PATTERNにマッチする❯のみの行がGEMINI_PROMPT_PATTERNにマッチする> Type your message or @path/to/fileがGEMINI_PROMPT_PATTERNにマッチする> quoted text(先頭スペースなし、引用テキスト)がGEMINI_PROMPT_PATTERNに誤マッチしないことgetCliToolPatterns("gemini").skipPatternsが新形式にもマッチすることレビュー履歴
Stage 1 (2026-03-09)
Stage 3 (2026-03-09) - 影響範囲レビュー