🖥️

ターミナルを自作したら、1日のコミット数が500を超えて、生産性がバグった話

に公開
52
20

僕は長いこと、ターミナルの中で暮らしています。エディタは emacs、VS Code や GUI 系のツールはどうにも手に馴染まない。Web 上の開発環境も、あの「ちょっとした不便」が積もって結局使わなくなる。要するに、ターミナルに慣れ親しみすぎて、GUI のボタンがどこにあるのか探せない人間です。

そんな僕が、勢いで自分専用のターミナルを作ったら、GitHub のコミットが毎日 500 を超えるようになりました。一度きりの当たり日ではなく、来る日も来る日も、です。生産性がバグりました。

GitHub の contribution graph(草)。1日500コミットを超える日が並んでいる
毎日 500 コミット超え。草が真緑になった

先に言い訳をしておくと、「コミット数は生産性の指標じゃない」というツッコミはまったくその通りです。細かくコミットする癖もあります。でも、数字そのものより、その数字が出てしまうくらい "詰まらなくなった" という体感の変化の話として読んでもらえると嬉しいです。順を追って書きます。

課題:ターミナル暮らしが、限界に来ていた

やりたいことはシンプルで、emacs とターミナルで vibe coding したい。ただそれだけ。

ところが、AI エージェント(Claude Code)を本格的に回し始めると、この「シンプルな暮らし」が急に破綻します。理由ははっきりしていて、Claude Code は 1 タスク投げると数分〜十数分、返ってこない。その間ぼーっと待つのは馬鹿げているので、2 本目を開く。2 本目が考え込んでいる間に 3 本目を開く。気づけば人間のほうが「エージェントの待ち時間を埋める」係になっていました。

こうなると 1 枚のターミナルでは全然足りません。macOS 標準のターミナルは改行まわりで細かい問題があったので Ghostty に乗り換え、6 分割でしのいでいましたが、今度は別の壁にぶつかります。

Ghostty で 6 分割したターミナル。同じ見た目のペインが 6 枚並んでいる
乗り換えた Ghostty での 6 分割。並列にはできたが、どれが終わってどれが待ちなのか、パッと見では分からない

  • 状態がわからない。 これが一番きつかった。6 枚並べても、どのセッションが終わっていて、どれが入力待ちで、どれがまだ動いているのか、パッと見で判別できない。全部が同じ見た目のテキストなので、結局ひとつずつ覗きに行くことになる
  • どのペインで何を頼んだのか見失う。 6 枚が同じ顔をしているので、どのセッションでどのタスクを走らせていたのか分からなくなる。まして複数のアプリやパッケージ(リポジトリ)を並行で回していると、どのウィンドウで何を動かしていたのかすら分からない。極めつけは、狭い画面で AI に「A と B どっちにします?」と聞き返されたとき。ログが上に流れてしまって、そもそも自分が最初に何を命令したのかすら思い出せず、質問の意味が取れなくなる
  • 1 つ 1 つのペインが狭い。 並列にしたいのにスペースが足りない
  • サイズは変えられるけど、手動で静的。 ペインの大きさ自体は手で調整できます。でも「今まさに動いてるやつを大きく、待ってるやつを小さく」のように、状態に合わせて勝手に変わってはくれない。結局、複数ウィンドウを行き来する運用に逆戻り

要するに僕が本当に欲しかったのは、ペインを手で並べ替える自由ではなく、「今どれが自分を待っているか」がひと目で分かって、それに応じて画面が反応してくれることでした。当時はそれが言語化できておらず、ただ「厳しいなあ」と思いながら使っていました。

キッカケ:Claude Code の -p 問題と、xterm.js との出会い

もともと僕は MulmoClaude という別のツールを作っていました。Claude Code に GUI 的なアウトプット(ドキュメント・フォーム・図など)を出させたり、LLM Wiki を自動で生成させたりする、Claude Code を使い倒すためのツールです。

MulmoClaude の画面
キッカケになった MulmoClaude

その開発中に、ある問題にぶつかります。claude-p(非対話モード)でプログラムから叩くと、対話で使うときと課金体系が変わり、自動でたくさん回すほど API 課金がかさむのです。エージェントを本気で並列運用しようとすると、この従量課金が地味に効いてくる。しかも Anthropic が途中で方針を変えたこともあって、まともな回避策が見当たらない。正直、一度は「これはもう無理だな」と諦めていました。

ところが、偶然が重なります。日本で中島聡さん(元マイクロソフトで Windows 95 の開発に携わった、Singularity Society 代表)と話す機会があったとき、居合わせたあるユーザが「どうしてもこれをサポートしてほしい」と熱く語ってきたんです。その熱意に背中を押される形で、「じゃあ、別のやり方はないか」ともう一度、中島さんと議論することになりました。

でも正直、その場では「やっぱり打つ手はなさそうだ」と思っていました。ただ一つ引っかかったのが、議論の中で中島さんが話していた VS Code のシェルのこと。僕は普段 VS Code をほとんど使わないので、「へえ、あれはどうやってターミナルを動かしてるんだろう」と、妙に気になったんです。

その日はいったん解散。ホテルに戻ってから、その VS Code のシェルがどう実装されているのかを調べてみました。行き着いたのが xterm.js です。VS Code の統合ターミナルの中身は、これだったんですね。ブラウザ上で動くターミナルエミュレータで、サーバ側で PTY(擬似端末)を立てて WebSocket でブラウザに繋げば、ブラウザの中で本物のシェルがそのまま動く

最初は、ためしにターミナルをブラウザで動かしてみるだけのつもりでした。ところが、少し実験してみたら——あっさり動いてしまった。

ブラウザの中でターミナルが動くなら、レイアウトは HTML/CSS の世界。何分割でも、どんな大きさでも、好きに置ける。画面をいじりながら、ようやく長年の悩みが言語化できました。

ひょっとして、これを使えば あの窮屈さが、根本から解決するのでは?

興奮して中島さんに報告したら、その場で Slack のラリーが始まりました。ああでもない、こうでもないと投げ合っているうちに、気づいたらプロトタイプが完成していた。……こんなことなら、最初から二人でどこかのカフェにこもって一気に作ればよかったな、と思ったほどです。

道筋:レイアウトは「何度でも試せる」

ブラウザの上でターミナルが動く——これはつまり、中身はもう普通の Web 開発だということです。レイアウトの変更も、機能の追加も、Web アプリを書くのと同じ感覚で、すぐに・簡単にできる。ここが効きました。

  • まずは 6 分割
  • 次に 9 分割まで増やし、さらにタブで何ページも足せるようにする
  • zoom で狭いセルを一時的に拡大したり、1 つだけ大きく・他は小さく並べたり

CSS Grid と Flexbox なので、思いついたら数分で試せる。コードを書いては眺め、を延々と繰り返して、最終的に効いたのは「状態がひと目で分かる」ための仕掛けたちでした。

  • 各セッションのサイドに「AI のサマリー」と「自分のプロンプト」を並べる。 サマリーは AI が書いた要約なので「今どこまで進んだか」が分かり、プロンプト欄には自分が投げた指示がそのまま残るので「そもそも何を頼んだか」を見失わない
  • Claude Code の状態(idle / running / 入力待ち など)を分かりやすく表示する。 今どれが動いていて、どれが止まっているのかが、いちいち覗きに行かなくても分かる
  • ディレクトリ(リポジトリ)ごとに、色もレイアウトもカスタムできる。 自分で色味を割り当ててグループ分けしておけば、色を見た瞬間に「これはあのプロジェクトだ」と分かる。複数のリポを並行していても迷子にならない
  • waiting(入力待ち)になったら音で通知する。 音もカスタムできるので、僕はドラの音にしています。じゃーーーん!

サイドメニューに各セッションのサマリーとステータスを表示しながら、複数のセルで開発しているターミナル画面
サイドメニューにサマリーを表示しながら開発しているところ

これらに共通しているのは、「こっちから探しに行かなくて済むようにする」という一点です。並列で回していて一番消耗するのは、「今どれが自分を待っているのか」を探す時間なんです。6 枚のペインを順番に目でスキャンして、止まっているやつを見つけて、文脈を思い出す。この認知コストが、セッションが増えるほど指数的に効いてくる。サマリー、ステータス、色、音で「向こうから呼んでくれる」ようにした瞬間、その探す時間がゼロになりました。

そして地味に効いたのが、この「自分のプロンプトがそのまま残る」ほうでした。AI に途中で「A と B どっちにします?」と聞き返されても、狭いログを遡らずに「そういえば俺、これを頼んでたんだ」と一瞬で思い出せる。あの一番イライラする「自分の命令を思い出す」作業が、まるごと消えました。

さらに、GitHub へのショートカット、ウィンドウ切り替えに加えて、context(残りコンテキスト量)や branch といった開発に必要な情報・ボタンをカスタムで足せるようにしました。全部 JS なので、欲しくなったその場で追加できる。ターミナルが「使うもの」から「育てるもの」に変わりました。

もう一つ、裏方だけど地味に効いているのが tmux です。セッションの実体は裏で tmux に持たせているので、MulmoTerminal(ブラウザ側)を落としても、サーバを再起動しても、Claude Code のセッションは生きたまま。あとから繋ぎ直せば、何事もなかったように続きが動いています。

爆発:スマホに通知が来た瞬間、世界が変わった

決定打はここです。

中島さんが MulmoClaude で、面白い実験をしていました。Firebase 経由でローカル Mac の状態をミラーし、モバイルのブラウザで表示、さらに一部のプロンプトを Mac 側に送り返す、という仕組みです。手元の Mac で動いているものを、外から覗いて、外から少し操作できる。

これを見て、「これ、ターミナルでもいけるのでは?」と思って試したら——外出先でも、ブラウザからターミナルの進捗が見える。この時点ではまだ通知はありません。それでも、散歩の途中にふとスマホで画面を開いて状況を確認し、簡単な指示ならその場で送り返す。それだけでも、もう十分に便利でした。

スマホのブラウザで開いた MulmoTerminal。外出先からターミナルの進捗が見え、簡単な指示も送り返せる
外出先でも、スマホからターミナルを覗ける。簡単な指示ならその場で送り返す

ただ、これだと結局「自分から見に行く」必要がある。もっと良くできないか——そこで思い出したのが Web Push でした。「iPhone の Safari って昔はこれできなかったよな」と。調べたら、今はできる。iOS 16.4 以降、ホーム画面に追加した Web アプリなら、Service Worker 経由で Web Push が飛ぶようになっていたのです。

さっそく繋いでみたら——Claude Code の入力待ち・動作終了のタイミングで、スマホに通知が来る。

スマホのロック画面に届いた Claude Code の通知。「入力待ち」「タスク完了」が表示されている
スマホとスマートウォッチに「呼ばれる」。AI 時代のターミナルの完成形はこれだった

これが本当に効きました。PC から離れても状態が分かるし、PC の前にいてもスマホやスマートウォッチに通知が来る。普通のアプリなら「うざい」で終わる機能ですが、AI 時代のエージェント相手だと、この "呼ばれたら行く" がとんでもなく便利なんです。

働き方そのものが変わりました。「画面に張り付いて待つ」から「呼ばれたら応じる」へ。散歩中でも、飯を食っていても、6 本のエージェントのうち 1 本が詰まれば手元に通知が来て、数十秒で指示を返してまた放す。24 時間、どこにいても Claude Code の状態が分かる。ターミナルで 6 セッション、場合によっては複数のリポジトリを並行でガンガン進められる。必要な機能は JS でその場で足せるので、なおさら止まらない。廃人化です。

5〜6 の壁を、道具で超える

思えば、あの「6 分割」には意味がありました。プレーンなターミナルを並べていた頃、僕が同時に追えたのは、せいぜい 5〜6 エージェントが限界。6 枚が同じ顔で並ぶと、それ以上は誰が何をしているのか本当に分からなくなる。6 分割だったのは、選んだからではなく、そこが認知の天井だったからです。

ところが、状態をひと目で分かる仕掛け(AI のサマリー、自分のプロンプト、ステータス、色、通知)をターミナル側に持たせた瞬間、その天井が動きました。「今どれが自分を待っているか」を追う仕事を道具に肩代わりさせれば、5〜6 の壁は超えられる。実際、6 を超えて並べても破綻しなくなりました。

面白いのは、これが Anthropic の中の人の使い方とも重なること。Claude Code を率いる Boris Cherny 氏は、ターミナルで 5 セッション(各セッション別の git worktree)+ ブラウザで 5〜10 セッション、あわせて 10〜15 個ほどを同時に回していると X で公開しています(Anthropic 公式のドキュメントでも 複数セッションの並行実行 が推奨されています)。並列数の上限を決めるのは、人間の生の注意力ではなく、どれだけ道具が状態を肩代わりしてくれるか。そういうことなんだと思います。

500 コミットの正体

ここまで来て、冒頭の「1 日 500 コミット」の話に戻ります。

あれは、僕が超人になったわけでも、意味なくコミットを量産したわけでもありません。並列度 × 通知ドリブンの自然な帰結です。6 本のエージェントがそれぞれ小さな変更を積み、僕は詰まったところだけを次々にさばく。1 本あたりのコミットは普通でも、6 本ぶんが同時に流れれば、1 日の総量は簡単に跳ね上がる。しかもそれが、たまの当たり日ではなく毎日続く。ボトルネックが「僕が手を動かす速度」から「僕が判断を返す速度」に移った結果です。

気づけば、emacs を開かなくなっていた

ここで、自分でも意外だったことを白状します。

これだけ書いておいてなんですが、僕はもう、コーディングで emacs を使っていません。

長年 emacs とターミナルに慣れ親しんで、GUI のボタンひとつ満足に探せず、そのために専用ターミナルまで自作した人間が、です。理由は単純で、コードを書く・直す作業が、ほとんどエージェント(ハーネス)側で完結してしまうから。僕が手でファイルを開いて直す場面は、もうほとんどありません。

じゃあ今の僕は何をしているのか。せいぜい GitHub で PR の changes を眺めるくらいです。差分を見て、良ければ通す、おかしければ指示を返す。エディタで文字を打つ仕事は、いつのまにか「レビューする仕事」に置き換わっていました。自分の作業環境を守るために作ったターミナルが、結果的に自分からエディタを奪った。皮肉な話ですが、これが今のリアルです。

そして、ボトルネックは GitHub になった

そして、その「PR を眺めてさばく」作業そのものが、次のボトルネックになりました。

判断を返す速度すら追いついてくると、次に詰まる場所が変わります。もう、ボトルネックは人間でも AI でもありません。GitHub です。

エージェントは次々と PR を積んでくる。でも取り込みが追いつかない。CI が詰まる。マージ判定(レビュー、コンフリクト解決)が律速になる。複数のキューがどんどん溜まっていく。「書く速度」が律速だった時代はとっくに終わり、次は「さばく速度」、そして今は「取り込む速度」に律速が移りました。

半分冗談、半分本気で、こう思っています——人類は、次のステップに進んだのかもしれない。

これは MulmoTerminal として公開しています

……という個人的な悪あがきから始まったこのターミナル。でも、効果は自分ひとりには留まりませんでした。MulmoTerminal のおかげで、MulmoCast や MulmoClaude を含む「Mulmo ファミリー」全体の開発速度が、体感で 2 段ほど上がっています。

そのターミナルを、いま MulmoTerminal として OSS 公開しています。npx mulmoterminal@latest で起動して、ブラウザで開くだけです。Claude Code と OpenAI Codex の両方に対応しています。

使い方は日本語のマニュアルを用意してあります → MulmoTerminal ガイド(日本語)

  • MulmoTerminal — ローカルの AI コーディングエージェントを、ブラウザから並列で監督する
  • MulmoCast — コンテンツをマルチフォーマットのメディアに変換する
  • MulmoClaude — Claude Code を使い倒すためのツールキット

同じ「AI 時代にボトルネックが変わった」話は、コード品質の側面から 別記事 でも書いています。あわせてどうぞ。

最後に、種明かしを一つ。この記事自体、MulmoTerminal の中で書いています。 裏のセルでは Claude Code に別のプログラムを書かせながら、その片手間に、この原稿もまた Claude Code に書かせている。僕がやっているのは、方向を決めて手を入れることだけ——まさに、ここまで書いてきたとおりの状況です。

だから、ぜひ一度使ってみてほしい。そして、もし自分には合わなくても、まわりに「ターミナルの住民」がいたら教えてあげてください。中身は Web 技術なので、拡張も修正も簡単です。自分好みに好きなだけカスタムして、良いアイデアがあれば Issue を立ててもらえたら嬉しい。

この体験を、みんなにも味わってほしい。心から、そう願っています。

参考文献

  1. Anthropic. "Best practices for Claude Code." https://code.claude.com/docs/en/best-practices
  2. Vibe Coder Blog. "Multi-Claude: How Anthropic Engineers Run 5+ Agents in Parallel." https://blog.vibecoder.me/multi-claude-parallel-agents-anthropic-workflow
  3. WebKit. "Web Push for Web Apps on iOS and iPadOS." https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/
  4. xterm.js. https://xtermjs.org/
  5. Ghostty. https://ghostty.org/
52
20
シンギュラリティ・ソサエティ

Discussion

ログインするとコメントできます
52
20