feat(rust-term,rust-app): OSC 52 クリップボード書き込みに対応(第21波)#158
Merged
Conversation
claude はドラッグ選択時に OSC 52 (ESC ] 52 ; c ; <base64> BEL/ST) で システムクリップボードへの書き込みを端末に要求するが、LaboLabo はこれを 一切処理しておらず、素のドラッグでコピーできなかった(Ghostty はこれを 処理するため可能)。 labolabo-term にバックエンド非依存の逐次スキャナ (osc52.rs) を追加し、 セッションのワーカースレッドで PTY 生バイト列を alacritty/ghostty 双方の バックエンドと並行してスキャン、OSC 52 の set 要求のみ抽出して TermSession::take_clipboard_set() で一度だけ取り出せるようにした。 read 要求 (Pd == "?") には一切応答しない(クリップボード漏えい防止)。 labolabo-app 側は既存の redraw bridge (Wakeup 経路) で take_clipboard_set() を確認し、あれば cx.write_to_clipboard() で システムクリップボードへ書き込む。
sasagar
marked this pull request as ready for review
July 18, 2026 13:51
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.
Summary
ESC ] 52 ; c ; <base64> BEL/ST(OSC 52)でシステムクリップボードへの書き込みを端末に要求するが、LaboLabo はこれを一切処理していなかった(Ghostty はこれを処理するため素のドラッグでコピーできる)。本 PR で LaboLabo にも同等の対応を追加する。labolabo-termにバックエンド非依存の逐次スキャナ (src/osc52.rs) を追加。セッションのワーカースレッドで PTY 生バイト列を alacritty/ghostty 双方のバックエンドのfeedと並行してスキャンし、OSC 52 の set 要求のみを抽出する(TermSession::take_clipboard_set()で一度だけ取り出せる one-shot セマンティクス)。read 要求 (Pd == "?") には一切応答しない(クリップボード内容の漏えい防止)。labolabo-appは既存の redraw bridge(Wakeup経路)でtake_clipboard_set()を確認し、値があればcx.write_to_clipboard()でシステムクリップボードへ書き込む。なぜバックエンド非依存のスキャナか
libghostty-vtのTerminalは OSC 52 のペイロードを取り出す公開 API を持たない(on_title_changed/on_pty_write/on_device_attributesのみ。低レベルのghostty_osc_*パーサもCLIPBOARD_CONTENTSのデータ抽出手段を提供しない)。alacritty_terminalは内部で解釈するがEventListener::Event::ClipboardStore経由のみで、現状どちらのバックエンドもこの経路を配線していない。そのため PTY 生バイト列を直接スキャンする方式とした(詳細はosc52.rsのモジュールコメント)。テスト
osc52.rs単体テスト 15 件(一括到着/1バイトずつ分割/BEL・ST 両終端/他 OSC との混在/?読み取り要求の無視/不正 base64/上限超過(1 MiB)/複数シーケンスの順序保証/日本語 UTF-8 ペイロード 等)tests/backend_common.rsに統合テスト 7 件追加(title のテストと同一の idiom)。cargo test -p labolabo-term(alacritty backend)とcargo test -p labolabo-term --no-default-features --features backend-ghostty-vt(ghostty-vt backend、GHOSTTY_SOURCE_DIR経由)の両方で green。cargo test --workspace/cargo test -p labolabo-app(444 件) /cargo clippy --workspace --all-targets -- -D warnings/cargo fmt --checkすべて green。未検証点
gpui::Context::write_to_clipboardを呼ぶだけのロジックであり、labolabo-term側の統合テスト(PTY 経由でtake_clipboard_set()が期待通り値を返すこと)までで検証を止めている。実際に claude の TUI 上でドラッグ選択してシステムクリップボードに反映されることは、この PR のレビュー/マージ後に実機で確認する必要がある。Test plan
cargo test -p labolabo-term(osc52 単体 15件 + backend_common 統合7件 含む、alacritty backend)cargo test -p labolabo-term --no-default-features --features backend-ghostty-vtcargo test --workspacecargo test -p labolabo-appcargo clippy --workspace --all-targets -- -D warningscargo fmt --check