Claude Code、Gemini CLI、Codex。全部同時に走らせてる。
べつにカッコつけてるわけじゃない。片方がリファクタリング、もう片方がテスト書いて、3つ目がデプロイ設定いじってる——これが今いちばん速い開発の仕方だと思ってる。少なくとも自分の場合は。
走らせるのは簡単。管理が地獄。
ターミナルウィンドウを4つ開いて、Alt+Tabをひたすら押して、「どれが入力待ちだっけ?」「どれがまだ考え中?」「あれ、5分前に終わってたのに気づかなかった」——こういうのがずっと続いてた。プロンプトを見逃す。エージェントの思考中に割り込む。そもそもどのターミナルで何やってたか忘れる。(余談だけど、tmux使えばいいじゃんって思う人いると思う。試した。見た目は並ぶけど、状態が分からない問題は解決しない。結局同じだった。)
3ヶ月くらいこの状態が続いて、ある日「もう無理だ」ってなった。
で、作った。PATAPIMっていうターミナルIDE。名前はダサい、分かってる。
まず結論:9つのターミナルを同時に見れるグリッドレイアウト
ふつうのIDEは、コードエディタがメインで、下にちっちゃいターミナルパネルがある。ビルドコマンド叩くだけならそれでいい。
でもClaude Codeとか使ってたら、ターミナルがメインの作業場になってる。サブパネルじゃない。もう主役。で、複数エージェントを並列で動かすなら、全部同時に見えないと話にならない。
PATAPIMは最大9ターミナルをグリッドで並べる。左サイドバーにプロジェクト、タスク、ファイルツリー。メインエリアは全部ターミナル。
いちばん苦労した部分:エージェントが今なにしてるか分からない問題
「複数エージェント並列で動かせばいい」って簡単に言う人いるけど、やったことある?
どれが終わったかどうやって分かる? どれが入力待ちか? 全部のターミナルを一個ずつスクロールして確認する?
これが技術的にいちばん難しかった。エージェントが今なにしてるか、人間がターミナル覗かなくても分かるようにしたい。
結局やったのは泥臭いパターンマッチング。エージェントごとに出力の癖がある:
- ブレイルスピナー(
⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏)やアスタリスクスピナー → 作業中 -
❯プロンプトが出てスピナーなし → 入力待ち -
Plan:みたいなテキスト → プランモード -
Cost: $→ コスト更新
検出は200msのスロットルで走る。9ターミナルが同時にガンガン出力してもパフォーマンスが死なない程度に、でも体感でちゃんとリアルタイムに感じる程度に。この数値、地味に調整が大変だった。最初は16msでやろうとして、CPUが爆発した。
で、各ターミナルの枠が状態に応じて色が変わる:
赤 → エージェントが作業中。触るな。
緑 → 入力待ち。ここに行け。
シアン → プランモード。レビューして承認。
これ入れてから、作業の仕方が変わった。9個のターミナルをチラッと見るだけで「あ、3番と7番が入力待ちだな」って分かる。信号機みたいなやつ。地味だけど、これがなかったらたぶんこのツール自体作ってない。
音声入力はローカルで動く(動くまでが長かった)
スタンディングデスクで作業してるんだけど、たまにタイピングじゃなくて話しかけたい時がある。あと手首の問題を昔からずっと抱えてて、音声入力は自分にとっておもちゃじゃなくて必需品。
最初はWeb Speech APIで済ませようとした。ブラウザのやつ。「これでいいだろ」って思ってたら、マイクの音声が全部Googleのサーバーに飛んでることに気づいて、「いや、それはダメだろ…」ってなった。開発中のコードの内容、全部送ってるわけだから。
で、Whisperをローカルで動かすことにした。@huggingface/transformersのONNXモデル。これがまた大変で、Electronのメインプロセスでモデル読み込んだらUIが5秒フリーズした笑。結局ワーカーに逃がして解決したけど、ONNXのランタイム周りで3日くらい沼にハマった。
今はちゃんと動いてる。音声データは一切外に出ない。モデルサイズはハードウェアに応じてtiny、base、smallを自動選択。無料枠で30分、Proで無制限。
スマホからリモートアクセス
これは完全に自分用に作った機能なんだけど、意外と他の人も欲しがった。
コーヒー入れに行ったり、アーキテクチャ考えながらウロウロしてる時に、「エージェント終わったかな?」「プラン承認しなきゃ」みたいなのがある。PATAPIMはLAN上にWebSocketサーバーを立てて、スマホでQRコード読むだけでブラウザからターミナル操作できる。
VPNなし、クラウドサービスなし、ポートフォワーディングなし。ローカルネットワーク上の直接接続。
最初はSSHでいけると思ってたんだけど、SSHだと状態検出の色付きボーダーが見えない。それじゃ意味ない。WebSocket + xterm.jsを丸ごとブラウザに飛ばすことで、PCと同じUIがスマホに出る。ただしスマホのキーボードとxterm.jsの相性が最悪で、日本語入力に至ってはまだ微妙。ここは正直まだ課題。
毎日使ってる。ソファからプラン承認。ブエノスアイレスの夏は暑いから、エアコンのある部屋に逃げてスマホでコード確認、みたいな使い方。
組み込みのMCPブラウザ
これはちょっとヤバい機能かもしれない。
説明がむずいんだけど、要はPATAPIMの中にChromeが丸ごと入ってて、それがMCPサーバーとして動く。Claude Codeがそのブラウザを操作できる。Webサイト開いて、クリックして、フォーム埋めて、内容読む。全部。
ヘッドレスじゃなくて本物のChrome。stdio JSON-RPCでMCPサーバーとして通信して、HTTPブリッジで画面に出てる。Claude側から見たらただのMCPツール。(MCPが何か分からない人は、Anthropicのドキュメント見てほしい。ここで説明すると長くなる。)
この前、Claudeに「近くの食料品店を探して」って頼んだら、勝手にGoogleマップ開いて検索して、結果をまとめてきた。自分で使っといてなんだけど、ちょっと怖かった笑。あとWebアプリのテストでログインフォームを操作させたら、自分が2週間気づかなかったバグを見つけてくれたことがある。ブラウザ操作系は可能性が広い反面、ElectronのBrowserViewのセキュリティサンドボックスとの戦いがかなりあった。このへんの技術的な話はまた別記事で書くかも。
技術スタック
気になる人向け:
- Electron 28 —— はい、Electron。分かってる笑。「Tauriにしろ」って言われそうだけど、xterm.jsはJSのターミナルエミュレーションのゴールドスタンダードだし(VS Codeも使ってる)、PTY管理にネイティブOS統合が必要だった。組み込みブラウザのBrowserViewもElectronの機能。メモリは9ターミナル全部開いて150〜200MBくらい。
- xterm.js 5.3 —— ターミナル描画
- node-pty 1.0 —— PTYプロセス管理
- ws 8.16 —— WebSocketでリモートアクセス
- esbuild —— バンドル
- @huggingface/transformers 3.8.1 —— ローカルWhisper推論、ONNXモデル
起動時にトランスポートを自動検出する。Electron内ならIPC、ブラウザ(リモートモード)ならWebSocket。同じコードベースで2つのトランスポート。ここの切り替えロジック、最初はif (window.electron)みたいな雑な判定だったんだけど、リモートからElectron APIを叩こうとしてクラッシュする事故が何回かあって、ちゃんと環境検出モジュールを書き直した。
今後
macOS版が一番リクエスト多い。「macOS出たら使う」って言われまくってる。コアはElectronだからクロスプラットフォームのはずなんだけど、Appleの署名と公証がとにかくめんどくさい。node-ptyのmacOSビルドも罠が多い。もうすぐ出せると思う、たぶん。その次Linux。
あと日本語UI対応を今やってる。この記事書いてるのもその一環。日本のエンジニアに使ってもらいたい。
使ってみる
無料で使える。9ターミナル、3プロジェクト、30分の音声入力。クレジットカード不要。Proは$7/月、または$30で買い切り。
今のところWindowsだけ。macOSはもうちょい待って。
まあそんな感じ。ブエノスアイレスで一人でゴリゴリ作ってる。もともとAlt+Tabの地獄から自分を救うために作り始めたんだけど、気づいたら3ヶ月経ってた。ゲーム開発(VR)から転向してきた人間がElectronでターミナルIDE作るとは思ってなかった。
バグ、要望、「ここ使いにくい」、なんでもいいから教えてほしい。日本語で大丈夫。