はじめに
VS Code 拡張「Input Assistant for AI Agents」の 2.0 を公開しました。
もともとは、Windows + WSL の VS Code ターミナルで Claude Code を使うと、日本語 IME の変換中に文字が崩れる、という自分の不便から作り始めた拡張です。入力は専用のパネルで書いて、書き終わったら AI に送る。それだけの道具でした。
使い続けるうちに、Claude Code だけでなく Codex CLI や Gemini CLI も同じ VS Code の中で並べて動かすようになりました。すると、入力の問題は「日本語が崩れる」だけではなくなってきました。
- どのターミナルに送ったのか分からなくなる
- 複数行のプロンプトが途中で実行されてしまう
- 送ったあと、返事が来たのか、承認待ちで止まっているのかが分からない
2.0 は、この 3 つを片付けるために作り直した版です。名前から「Claude Code」を外したのも、対象を AI コーディングエージェント全般に広げたからです。拡張 ID と設定キーは変えていないので、既存の利用者はそのまま更新されます。
この記事では、2.0 で何を変えたのか、なぜそうしたのか、そして正直に言ってまだ弱いところを書きます。最初のユーザーである自分が欲しかった機能を順番に足していった結果なので、同じような使い方をしている方の参考になれば幸いです。
1.x までの送信先は「概念」だった
1.x の入力タブには、「Claude Code」「OpenAI Codex」「Gemini Code Assist」「VS Code Chat」という送信先のカードが並んでいました。カードを選ぶと、拡張がそれらしいターミナルを探して送る仕組みです。
この方式には、使い込むほど目立つ問題がありました。
一つ目は、同じ種類のターミナルが複数あるときに、どれに送るかを選べないことです。Claude Code を 2 つ立ち上げて別々の作業をさせると、狙っていないほうに送ってしまうことがありました。
二つ目は、ターミナル名だけで判定していたことです。たとえば名前が node のターミナルは Claude Code とみなす、というヒューリスティックでした。当然、誤検出があります。
三つ目は、複数行の扱いです。クリップボード経由で貼り付けると、シェルによっては最後の行以外が 1 行ずつ即実行されてしまいます。1.14 系では確認ダイアログを出して緩和しましたが、根本的な解決にはなっていませんでした。
要するに、送信先が「実際に開いているターミナル」ではなく「Claude Code という概念」だったのが原因です。
2.0 の一つ目の柱、実在するターミナルへ送る
2.0 では、送信先の一覧を今実際に開いているターミナルそのものにしました。入力タブの送信ボタンの上に、開いているターミナルが並びます。
各ターミナルがどのエージェントかは、次の順で判定しています。
- ターミナルのシェル情報
- シェル統合で取れる、実行中のコマンド行
- ターミナル名(最後の手段)
Claude Code、Codex、Gemini CLI、Grok Build、Copilot CLI、そしてただのターミナルを見分けます。サイドバー版の拡張と VS Code Chat は、その下に並びます。
判定が確定したエージェントのターミナルには、ブラケットペーストで送ります。ブラケットペーストは、貼り付けた文字列を開始と終了の制御シーケンスで囲み、アプリケーション側に「これは 1 回の貼り付けです」と伝える仕組みです。これで複数行のプロンプトが 1 つの入力として届くようになりました。クリップボードを経由しないので、送信のたびに手元のクリップボードが上書きされることもなくなりました。
推測でしか判定できなかったターミナルには、従来どおりクリップボード経由で送ります。確信がないものに Enter まで自動で送るのは危ないからです。
実機で触っていて一つ困ったのが、開いているのは 1 つなのに、一覧に 2〜3 件出る現象でした。原因は、他の拡張が内部用に作った「ユーザーには見せない」ターミナルでした。VS Code の API では、ユーザーから隠す設定で作られたターミナルも取得できてしまいます。2.0 ではこれを除外しています。念のため、ターミナルが開いた・閉じたこと、隠しかどうかを出力パネルに記録するようにしました。まだ余分に出る環境があっても、原因を追えるようにするためです。
二つ目の柱、hook でつながる
送る側が正確になると、次に欲しくなるのは送ったあとの様子でした。
Claude Code には hook という仕組みがあり、セッションの開始、プロンプトの送信、応答の終了、承認の要求などのタイミングで、任意のコマンドを実行できます。Codex や Gemini CLI などにも、似た仕組みがあります。
2.0 では、エージェントタブの「接続」でツールごとにトグルを ON にすると、次の処理をします。
- 同梱の小さなスクリプト
bridge.jsを~/.input-assistant/bridge/に置く - そのツールの hook 設定に、自分用のエントリを 1 つだけ追加する
- hook が呼ばれるたびに、
~/.input-assistant/events/にイベントを 1 行ずつ追記する - 拡張はそのファイルを読んで、画面に反映する
登録先は次のとおりです。
| ツール | 登録先 |
|---|---|
| Claude Code | ~/.claude/settings.json |
| Codex | ~/.codex/hooks.json |
| Gemini CLI | ~/.gemini/settings.json |
| Grok Build | ~/.grok/hooks/input-assistant.json |
| Copilot CLI | ~/.copilot/settings.json |
設計で一番気を使ったのは、ユーザーがすでに書いている他の hook には一切触らないことです。hook の設定ファイルは、人によっては大事な自動化が詰まっている場所です。拡張が勝手に書き換えて壊してしまったら、信頼を失います。拡張をアンインストールすると、自分が追加したエントリだけを消します。
イベントが届くようになると、できることが一気に増えました。
左サイドバーのカードが、生きているセッションの一覧になりました。このウィンドウのものも、別ウィンドウのものも出ます。カードには次の情報が並びます。
- 入力待ち、応答中、承認待ち、エラー終了の状態
- 最後に送った内容と返答の 1 行
- 所要時間
- コンテキストの使用量ゲージ
- 承認待ちの件数(アクティビティバーのバッジにも出ます)
別ウィンドウのセッションには「ここで再開」があり、新しいターミナルで resume できます。
履歴にも返答の抜粋が付くようになり、「続きを送る」で同じ送信先に追いの指示を出せます。
プロンプトの本文をイベントファイルに残したくない人向けに、状態と ID だけを保存する設定 cc-input-jp.agents.storePromptText も用意しました。
正直に書くと、hook の入出力の形式はツールごとに違い、しかも各ツールの更新で変わる可能性があります。5 つのツールに対応したことは、そのまま 5 つの保守対象が増えたことでもあります。ここは今後も追いかけ続ける必要があります。
三つ目の柱、組み立て式入力
入力欄そのものも変えました。
1.x では、テンプレートやファイルパスを選ぶと、入力欄の本文に文字列として挿入していました。これだと、本文を書き直すたびに挿入した部分と混ざって、どこまでが自分の文章か分からなくなります。
2.0 では、入力欄の上にチップ行を置きました。チップにできるのは次のものです。
- Guardrails のオン・オフ
- 添付するファイル
- テンプレート
- エージェントの返答からの引用
- 英訳して送るのトグル
送信の瞬間に、これらを決まった順番で組み立てます。
[Guardrails(前置き)]
[引用]
[テンプレート]
[本文]
@path/to/file
[Guardrails(後置き)]
Guardrails は一番外側に付きます。組み立てた結果は「プレビュー」で、実際に送る文字列のまま確認できます。
ファイルは、行頭か空白の直後で @ を打つとパレットがファイルの種類で開き、選ぶとチップになります。Claude Code の @ 参照に慣れている人なら、違和感なく使えると思います。
本文とチップは、プロジェクトごとの下書きとして自動で保存します。Reload Window をしても消えません。長い指示を書いている途中で VS Code を再読み込みして書き直し、という事故が、自分では一番多かったので入れました。
英訳して送るは、本文と引用とテンプレートだけを翻訳して送る機能です。ファイルパスと Guardrails は訳しません。翻訳に失敗したら送信しないようにしました。訳されていない日本語が英語のつもりで届くよりは、止まったほうがいいと判断したためです。履歴には原文と訳文の両方を残します。
画面の整理
機能が増えた分、画面は整理しました。
1.x では最大 8 タブまで増えていたのを、入力、ライブラリ、エージェント、設定の 4 タブにまとめました。ライブラリ・エージェント・設定の 3 つは、左に一覧、右に内容という同じ構造にそろえています。サイドバーの幅に応じて、一覧、アイコンのレール、セレクトの 3 段階に畳みます。
履歴、お気に入り、テンプレート、Skills、ワークスペースのファイルは、Ctrl+K のパレットでまとめて検索できます。
まだ弱いところ
使ってみて気づいた限界も書いておきます。
- ターミナルの判定は完全ではありません。 シェル統合が効いていない環境では名前頼りになり、その場合は安全側に倒してクリップボード経由になります
-
ブラケットペーストに対応していないシェルもあります。 貼り付けた文字列の前後に
00~や01~が見える場合は、cc-input-jp.send.forceClipboardを ON にしてください - hook の形式は各ツールの都合で変わりえます。 動かなくなったら接続を一度オフにして、Issue で教えてもらえると助かります
- 使用量の表示は非公式のエンドポイントを使っています。 Claude Code 本体が使っているものですが、仕様が変われば表示が止まる可能性があります
- VS Code 1.118 以降が必要になりました。 それより古い VS Code には、Marketplace から 1.14 系が配られ続けます
移行について
1.x の送信先まわりの設定のうち、実在のターミナル一覧に置き換わって意味がなくなったものは、起動時に自動で削除します。「ターミナルを優先しない」設定にしていた人には、代わりにサイドバー版を一覧に出すよう読み替えます。履歴、お気に入り、テンプレート、プロジェクトはそのまま引き継がれます。
おわりに
2.0 は、自分が毎日 Claude Code と Codex を並べて使う中で「これがないと困る」と感じたものを、一つずつ埋めていった結果です。入力を書く場所、送る先、返事を待つ間の様子を、VS Code の中の 1 か所で見られるようになりました。