fix: マウスレポート有効化で TUI のホイールスクロールを確実に止める#73
Merged
Conversation
DECSET 1007 を無視する Apple Terminal.app などでホイールがリスト・ 埋め込みシェルへ漏れる問題を、マウスレポート(1000+SGR 1006)有効化と 入力フィルタで解消する。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bf63d4a to
a05d79d
Compare
📊 Test Coverage
🎉✨ パーフェクト!全ファイル Lines カバレッジ 100% を達成しました 🏆🐰 |
kkyosuke
added a commit
that referenced
this pull request
Jun 14, 2026
## 目的 #73 でマウスレポート(DECSET 1000 + SGR 1006)を有効化し、Apple Terminal.app でホスト端末のスクロールバックが動く問題は解消した。しかし**マウスレポート列がそのまま画面に大量表示される**新たな問題が残っていたため、これを解消する。 ``` ^[[<64;70;23M^[[<64;70;23M^[[<64;70;23M... ``` ## 原因 `console` は**キー1個ごとに raw モードを on/off** し、読み取りの合間は元の cooked / `ECHO` 有効モードに戻す。マウスレポート有効化後、ホイール連打で stdin に流れ込むレポート列が、その合間に**カーネルの端末エコーでそのまま画面へ出力**されていた(先頭の `^[` は ESC のエコー)。`term_reader` のフィルタはキー列の漏れは防げるが、読み取りの“間”に起きるカーネルエコーは防げない。 ## 変更内容 - `src/presentation/tui/echo.rs`(新規): TUI 表示中だけ端末エコー(`termios` の `ECHO`)を切る薄い RAII `EchoGuard`。unix のみ実装、非 unix は no-op。出力処理 `OPOST` は維持するため `\n`→`\r\n` のレンダリングは不変。 - `src/presentation/tui/screen.rs`: `AlternateScreenGuard` が `EchoGuard` を保持し、TUI ライフタイム全体でエコーを抑止(Drop で復帰)。 - `Cargo.toml`: unix 限定で `libc` 依存を追加(`[target.'cfg(unix)'.dependencies]`)。 - `scripts/coverage.sh`: 端末 I/O の薄いラッパとして `tui/echo.rs` をカバレッジ計測対象外に追加。 - ドキュメント更新: `document/design/01-welcome.md` / `issues/006-terminal.md`。 ## テスト・確認方法 - `cargo fmt --check` / `cargo clippy --all-targets -- -D warnings` / `cargo test`(669 passed)をパス。 - カバレッジ enforce(line/function 100%)通過。 - 手動確認推奨: Apple Terminal.app で usagi TUI 起動中にホイールを連打 → メニュー・リスト画面にマウスレポート列が**出力されない**こと、スクロールも起きないこと、終了後に端末のエコー/スクロール挙動が元へ戻ること。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: test <test@example.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kkyosuke
added a commit
that referenced
this pull request
Jun 21, 2026
## 目的 error-log PR #236(TUI のセッション失敗をエラーログに記録)のレビューで判明した「まだ捕捉できないエラー」を、usagi の issue ストア(`.usagi/issues/`)へ task として登録する。 ## 変更内容 新規 issue 4 件を追加(コードは変更しない): | # | 種別 | 優先度 | 内容 | |---|---|---|---| | #70 | fix(pty) | high | エージェント/シェルの異常終了(非ゼロ exit)を記録。起動成功**後**のランタイム失敗を拾う。「session が失敗した」の本命経路。 | | #71 | refactor(tui) | medium | エラー記録を単一シンクへ集約し、画面内ログとファイル永続化を 1 経路に。「画面に出る=ファイルに残る」へ。 | | #72 | feat(mcp) | medium | MCP 経由の `session_create` 失敗も記録。 | | #73 | fix(tui) | low | 監視スレッドの異常終了(mutex poison での `break`)・ワーカースレッドの panic を記録。 | いずれも #236 の続きで、現状「起動失敗は拾えるが起動後の失敗・MCP 経路・バックグラウンドスレッドの異常は拾えない」という穴を埋めるもの。 ## テスト・確認方法 - issue ファイルのみの追加(`.rs` 変更なし)。frontmatter は既存 issue(番号・status・priority・labels・dependson・related)に準拠。 - `index.json` は gitignore 済み(スキャンで再生成)のため対象外。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: test <test@example.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kkyosuke
added a commit
that referenced
this pull request
Jun 21, 2026
## 目的 issue #73。バックグラウンドスレッドで起きる致命的失敗が握り潰され、エラーログに残らない問題を修正する。監視スレッドやワーカーが静かに死ぬとセッション表示が事実上機能停止するのに、原因を後から追えなかった。 ## 変更内容 - **ワーカースレッドの panic 捕捉**: セッション作成・削除のワーカー本体を `catch_unwind` で包む(`complete_or_record_panic`)。panic すると `complete` を呼ばずスレッドが死に、タスク行が回り続け op-lock も poison したまま痕跡が残らなかった。panic ペイロードを `ErrorLog::record` で記録し、タスク行を失敗として確定するようにした。 - **監視スレッドの異常停止記録**: 埋め込みターミナル監視スレッドが共有状態の mutex poison で停止する際、停止理由を記録してから `break` する(以後 bell / phase バッジが静かに凍結するのを追跡可能にする)。 - **記録判断ロジックの集約**: panic ペイロードの復号・ログ行とタスク行メッセージの整形を、カバレッジ対象の `tasks.rs` に `panic_outcome` として寄せた(カバレッジ除外の `home/mod.rs` からはスレッド spawn と unwind 境界のみ)。 - 通知失敗・resize 失敗などの non-fatal な握り潰しは対象外(ノイズを増やさない)。 - `document/data/01-global.md` のエラーログ仕様にバックグラウンドスレッド異常終了の記録対象を追記。 ## テスト・確認方法 - `tasks.rs` に `panic_outcome` のテストを追加(`&str` / `String` / 不透明ペイロードの 3 系統、create / remove 双方の文言)。 - `cargo fmt` / `cargo clippy --all-targets -- -D warnings` / `cargo test` 通過。 - カバレッジ 100%(line / function)維持を `scripts/coverage.sh` で確認。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: test <test@example.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kkyosuke
added a commit
that referenced
this pull request
Jun 21, 2026
## 目的 エラーログ拡充(#70-#73)の実装が `main` にマージ済みなのに、対応する issue の `status` が `todo` / `in-progress` のまま残っていたため、実態に合わせて `done` へ更新する。 ## 変更内容 以下 4 issue の `status` を `done` に更新(`updated_at` も更新)。 | issue | 内容 | 実装コミット | |---|---|---| | #70 | fix(pty): エージェント/シェルの異常終了をエラーログに記録 | `#239` | | #71 | refactor(tui): エラー記録を単一シンクへ集約・永続化 | `#244` | | #72 | feat(mcp): MCP 経由のセッション作成失敗をエラーログに記録 | `#242` | | #73 | fix(tui): 監視/ワーカースレッド異常の panic をエラーログに記録 | `#243` | ファイルは `.usagi/issues/` 配下の各 `.md` のフロントマターのみ変更。コード・ドキュメントの変更はなし。 ## テスト・確認方法 - pre-push フック(`cargo clippy --all-targets -- -D warnings` / `cargo test`)が通過。 - コード変更を含まないため挙動への影響なし。 Co-authored-by: test <test@example.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目的
#72 で代替スクロールモード(DECSET 1007)を無効化したが、Apple Terminal.app など 1007 を無視する端末ではマウスホイールが依然として↑↓矢印に合成され、usagi のリスト移動や埋め込みシェルへの転送として「スクロールが効いてしまう」問題が残っていた。これを端末非依存に解消する。
原因
DECSET 1007 は xterm 拡張で、Apple Terminal.app などは解釈しない。そのため代替スクリーン中もホイールが矢印キーに変換され、リスト・埋め込みシェルへ漏れていた。
変更内容
src/presentation/tui/screen.rsAlternateScreenGuardで代替スクリーン突入時にマウスレポート(DECSET 1000 + SGR 1006)を有効化 (\x1b[?1000h\x1b[?1006h)、Drop で解除。1007 の無効化も defensive に残置。src/presentation/tui/term_reader.rsconsoleがデコードできず後続バイトが文字キーとして漏れる問題に対し、next_non_mouse_keyが SGR (ESC[<…M|m) / X10 (ESC[M+3byte) 両形式をまとめて破棄し、次の実キーだけを返すフィルタを追加。terminal_pane.rs)は crossterm がEvent::Mouseを返しEvent::Key以外を元から破棄するため追加対応不要。同じガード変更で矢印転送の漏れも解消。document/design/01-welcome.md/document/03-commands/02-tui.md/issues/006-terminal.md。テスト・確認方法
cargo fmt/cargo clippy --all-targets -- -D warnings/cargo test(648 passed)をパス。🤖 Generated with Claude Code