画像プロトコル検出ロジックの改善 #8586

Open
opened 2026-02-16 18:10:20 -05:00 by yindo · 1 comment
Owner

Originally created by @apollo880 on GitHub (Feb 5, 2026).

Originally assigned to: @kommander on GitHub.

概要

現在の画像プロトコル検出ロジックは限定的で、いくつかのターミナルで正しく検出できない問題がある。

現在の実装

function detectGraphicsSupport() {
  const termProgram = process.env["TERM_PROGRAM"] ?? "";
  const lcTerminal = process.env["LC_TERMINAL"] ?? "";
  const term = process.env["TERM"] ?? "";
  
  if (termProgram === "ghostty" || term.includes("ghostty")) {
    return { protocol: "kitty" };
  }
  if (termProgram === "iTerm.app" || lcTerminal === "iTerm2") {
    return { protocol: "iterm2" };
  }
  if (term.toLowerCase().includes("kitty") || process.env["OTUI_PREFER_KITTY_GRAPHICS"]) {
    return { protocol: "kitty" };
  }
  return { protocol: "none" };
}

問題点

  1. WezTerm 未検出 - TERM_PROGRAM="WezTerm" をチェックしていない
  2. Windows Terminal 未検出 - WT_SESSION 環境変数をチェックしていない
  3. VS Code Terminal 未検出 - TERM_PROGRAM="vscode" をチェックしていない
  4. Kitty 検出の脆弱性 - KITTY_WINDOW_ID または KITTY_PID の方が確実
  5. 動的クエリ未実装 - 環境変数のみに依存

主要ターミナルの検出方法調査

検出方法一覧

ターミナル 検出方法 画像プロトコル 備考
iTerm2 TERM_PROGRAM="iTerm.app" or LC_TERMINAL="iTerm2" iterm2 tmux内では LC_TERMINAL で検出
Kitty KITTY_WINDOW_ID exists or KITTY_PID exists or TERM="xterm-kitty" kitty KITTY_WINDOW_ID が最も確実
WezTerm TERM_PROGRAM="WezTerm" iterm2/kitty WSL環境でも自動設定
Ghostty TERM_PROGRAM="ghostty" or GHOSTTY_RESOURCES_DIR exists or TERM="xterm-ghostty" kitty
Windows Terminal WT_SESSION exists iterm2 v1.22+ で画像対応。ただし非公式API
VS Code TERM_PROGRAM="vscode" iterm2 v1.80+ で画像対応
Terminal.app TERM_PROGRAM="Apple_Terminal" none 画像プロトコル非対応
GNOME Terminal VTE_VERSION exists (VTEベース) none 画像プロトコル非対応
Alacritty TERM="alacritty" none 画像プロトコル非対応。TERM_PROGRAM未設定の可能性

環境変数詳細

iTerm2

  • TERM_PROGRAM="iTerm.app" - 直接起動時
  • LC_TERMINAL="iTerm2" - tmux内でも検出可能
  • 動的クエリ: OSC 1337;Capabilities (Feature Reporting)

Kitty

  • KITTY_WINDOW_ID - ウィンドウID(最も確実)
  • KITTY_PID - プロセスID
  • KITTY_INSTALLATION_DIR - インストールディレクトリ
  • TERM="xterm-kitty" - TERM変数

WezTerm

  • TERM_PROGRAM="WezTerm"
  • TERM_PROGRAM_VERSION - バージョン
  • WSL環境では自動で WSLENV を設定

Ghostty

  • TERM_PROGRAM="ghostty"
  • GHOSTTY_RESOURCES_DIR - リソースディレクトリ
  • TERM="xterm-ghostty"

Windows Terminal

  • WT_SESSION - セッションGUID
  • WT_PROFILE_ID - プロファイルID
  • 注意: 非公式API、将来変更の可能性あり

VS Code

  • TERM_PROGRAM="vscode"
  • VSCODE_INJECTION=1 - シェル統合時
  • VSCODE_GIT_IPC_HANDLE - Git IPC

提案する実装

function detectGraphicsSupport() {
  const termProgram = process.env["TERM_PROGRAM"] ?? "";
  const lcTerminal = process.env["LC_TERMINAL"] ?? "";
  const term = process.env["TERM"] ?? "";
  
  // === 画像非対応ターミナルを先に除外 ===
  
  // macOS Terminal.app (画像非対応)
  if (termProgram === "Apple_Terminal") {
    return { protocol: "none" };
  }
  
  // Alacritty (画像非対応)
  if (term === "alacritty") {
    return { protocol: "none" };
  }
  
  // GNOME Terminal / VTE系 (画像非対応)
  if (process.env["VTE_VERSION"] && !termProgram) {
    return { protocol: "none" };
  }
  
  // === Kitty Graphics Protocol ===
  
  // Kitty (最も確実な検出)
  if (process.env["KITTY_WINDOW_ID"] || process.env["KITTY_PID"]) {
    return { protocol: "kitty" };
  }
  
  // Ghostty
  if (termProgram === "ghostty" || process.env["GHOSTTY_RESOURCES_DIR"]) {
    return { protocol: "kitty" };
  }
  
  // Kitty (TERM fallback)
  if (term === "xterm-kitty") {
    return { protocol: "kitty" };
  }
  
  // Ghostty (TERM fallback)
  if (term === "xterm-ghostty" || term.includes("ghostty")) {
    return { protocol: "kitty" };
  }
  
  // === iTerm2 Protocol ===
  
  // iTerm2 (tmux内でも検出可能)
  if (termProgram === "iTerm.app" || lcTerminal === "iTerm2") {
    return { protocol: "iterm2" };
  }
  
  // WezTerm
  if (termProgram === "WezTerm") {
    return { protocol: "iterm2" };
  }
  
  // Windows Terminal
  if (process.env["WT_SESSION"]) {
    return { protocol: "iterm2" };
  }
  
  // VS Code Terminal
  if (termProgram === "vscode") {
    return { protocol: "iterm2" };
  }
  
  // === ユーザー指定 ===
  
  if (process.env["CHARACODE_GRAPHICS_PROTOCOL"]) {
    const override = process.env["CHARACODE_GRAPHICS_PROTOCOL"].toLowerCase();
    if (override === "kitty" || override === "iterm2") {
      return { protocol: override };
    }
  }
  
  // 旧互換
  if (process.env["OTUI_PREFER_KITTY_GRAPHICS"]) {
    return { protocol: "kitty" };
  }
  
  return { protocol: "none" };
}

将来の改善: 動的クエリ

iTerm2 Feature Reporting

// Query: OSC 1337;Capabilities ST
// Response: OSC 1337;Capabilities=<features> ST
// 'F' = FILE (inline images対応)

詳細: https://iterm2.com/feature-reporting/

TERM_FEATURES 環境変数

一部ターミナルは capability string を公開:

TERM_FEATURES="TFCwMScBFSyHNoF"

参考リンク

Originally created by @apollo880 on GitHub (Feb 5, 2026). Originally assigned to: @kommander on GitHub. ## 概要 現在の画像プロトコル検出ロジックは限定的で、いくつかのターミナルで正しく検出できない問題がある。 ## 現在の実装 ```javascript function detectGraphicsSupport() { const termProgram = process.env["TERM_PROGRAM"] ?? ""; const lcTerminal = process.env["LC_TERMINAL"] ?? ""; const term = process.env["TERM"] ?? ""; if (termProgram === "ghostty" || term.includes("ghostty")) { return { protocol: "kitty" }; } if (termProgram === "iTerm.app" || lcTerminal === "iTerm2") { return { protocol: "iterm2" }; } if (term.toLowerCase().includes("kitty") || process.env["OTUI_PREFER_KITTY_GRAPHICS"]) { return { protocol: "kitty" }; } return { protocol: "none" }; } ``` ## 問題点 1. **WezTerm 未検出** - `TERM_PROGRAM="WezTerm"` をチェックしていない 2. **Windows Terminal 未検出** - `WT_SESSION` 環境変数をチェックしていない 3. **VS Code Terminal 未検出** - `TERM_PROGRAM="vscode"` をチェックしていない 4. **Kitty 検出の脆弱性** - `KITTY_WINDOW_ID` または `KITTY_PID` の方が確実 5. **動的クエリ未実装** - 環境変数のみに依存 --- ## 主要ターミナルの検出方法調査 ### 検出方法一覧 | ターミナル | 検出方法 | 画像プロトコル | 備考 | |-----------|---------|---------------|------| | **iTerm2** | `TERM_PROGRAM="iTerm.app"` or `LC_TERMINAL="iTerm2"` | iterm2 | tmux内では `LC_TERMINAL` で検出 | | **Kitty** | `KITTY_WINDOW_ID` exists or `KITTY_PID` exists or `TERM="xterm-kitty"` | kitty | `KITTY_WINDOW_ID` が最も確実 | | **WezTerm** | `TERM_PROGRAM="WezTerm"` | iterm2/kitty | WSL環境でも自動設定 | | **Ghostty** | `TERM_PROGRAM="ghostty"` or `GHOSTTY_RESOURCES_DIR` exists or `TERM="xterm-ghostty"` | kitty | | | **Windows Terminal** | `WT_SESSION` exists | iterm2 | v1.22+ で画像対応。ただし非公式API | | **VS Code** | `TERM_PROGRAM="vscode"` | iterm2 | v1.80+ で画像対応 | | **Terminal.app** | `TERM_PROGRAM="Apple_Terminal"` | none | 画像プロトコル非対応 | | **GNOME Terminal** | `VTE_VERSION` exists (VTEベース) | none | 画像プロトコル非対応 | | **Alacritty** | `TERM="alacritty"` | none | 画像プロトコル非対応。TERM_PROGRAM未設定の可能性 | ### 環境変数詳細 #### iTerm2 - `TERM_PROGRAM="iTerm.app"` - 直接起動時 - `LC_TERMINAL="iTerm2"` - tmux内でも検出可能 - 動的クエリ: `OSC 1337;Capabilities` (Feature Reporting) #### Kitty - `KITTY_WINDOW_ID` - ウィンドウID(最も確実) - `KITTY_PID` - プロセスID - `KITTY_INSTALLATION_DIR` - インストールディレクトリ - `TERM="xterm-kitty"` - TERM変数 #### WezTerm - `TERM_PROGRAM="WezTerm"` - `TERM_PROGRAM_VERSION` - バージョン - WSL環境では自動で `WSLENV` を設定 #### Ghostty - `TERM_PROGRAM="ghostty"` - `GHOSTTY_RESOURCES_DIR` - リソースディレクトリ - `TERM="xterm-ghostty"` #### Windows Terminal - `WT_SESSION` - セッションGUID - `WT_PROFILE_ID` - プロファイルID - **注意**: 非公式API、将来変更の可能性あり #### VS Code - `TERM_PROGRAM="vscode"` - `VSCODE_INJECTION=1` - シェル統合時 - `VSCODE_GIT_IPC_HANDLE` - Git IPC --- ## 提案する実装 ```javascript function detectGraphicsSupport() { const termProgram = process.env["TERM_PROGRAM"] ?? ""; const lcTerminal = process.env["LC_TERMINAL"] ?? ""; const term = process.env["TERM"] ?? ""; // === 画像非対応ターミナルを先に除外 === // macOS Terminal.app (画像非対応) if (termProgram === "Apple_Terminal") { return { protocol: "none" }; } // Alacritty (画像非対応) if (term === "alacritty") { return { protocol: "none" }; } // GNOME Terminal / VTE系 (画像非対応) if (process.env["VTE_VERSION"] && !termProgram) { return { protocol: "none" }; } // === Kitty Graphics Protocol === // Kitty (最も確実な検出) if (process.env["KITTY_WINDOW_ID"] || process.env["KITTY_PID"]) { return { protocol: "kitty" }; } // Ghostty if (termProgram === "ghostty" || process.env["GHOSTTY_RESOURCES_DIR"]) { return { protocol: "kitty" }; } // Kitty (TERM fallback) if (term === "xterm-kitty") { return { protocol: "kitty" }; } // Ghostty (TERM fallback) if (term === "xterm-ghostty" || term.includes("ghostty")) { return { protocol: "kitty" }; } // === iTerm2 Protocol === // iTerm2 (tmux内でも検出可能) if (termProgram === "iTerm.app" || lcTerminal === "iTerm2") { return { protocol: "iterm2" }; } // WezTerm if (termProgram === "WezTerm") { return { protocol: "iterm2" }; } // Windows Terminal if (process.env["WT_SESSION"]) { return { protocol: "iterm2" }; } // VS Code Terminal if (termProgram === "vscode") { return { protocol: "iterm2" }; } // === ユーザー指定 === if (process.env["CHARACODE_GRAPHICS_PROTOCOL"]) { const override = process.env["CHARACODE_GRAPHICS_PROTOCOL"].toLowerCase(); if (override === "kitty" || override === "iterm2") { return { protocol: override }; } } // 旧互換 if (process.env["OTUI_PREFER_KITTY_GRAPHICS"]) { return { protocol: "kitty" }; } return { protocol: "none" }; } ``` --- ## 将来の改善: 動的クエリ ### iTerm2 Feature Reporting ```javascript // Query: OSC 1337;Capabilities ST // Response: OSC 1337;Capabilities=<features> ST // 'F' = FILE (inline images対応) ``` 詳細: https://iterm2.com/feature-reporting/ ### TERM_FEATURES 環境変数 一部ターミナルは capability string を公開: ``` TERM_FEATURES="TFCwMScBFSyHNoF" ``` --- ## 参考リンク - [iTerm2 Feature Reporting](https://iterm2.com/feature-reporting/) - [Kitty Graphics Protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) - [Kitty Shell Integration](https://sw.kovidgoyal.net/kitty/shell-integration/) - [Ghostty Shell Integration](https://ghostty.org/docs/features/shell-integration) - [WezTerm TERM config](https://wezterm.org/config/lua/config/term.html) - [Windows Terminal WT_SESSION issue](https://github.com/microsoft/terminal/issues/13006) - [Alacritty TERM_PROGRAM issue](https://github.com/alacritty/alacritty/issues/4793) - [Are We Sixel Yet?](https://www.arewesixelyet.com/) - [Terminal Compatibility Matrix](https://tmuxai.dev/terminal-compatibility/)
yindo added the opentui label 2026-02-16 18:10:20 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Feb 5, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #5677: Support iTerm2 inline image protocol (passthrough escape sequences)

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Feb 5, 2026): This issue might be a duplicate of existing issues. Please check: - #5677: Support iTerm2 inline image protocol (passthrough escape sequences) Feel free to ignore if none of these address your specific case.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8586