はじめに:AIエージェントが増えすぎた結果起きたこと
最近、CursorやClaude Code、ClineといったAIエージェントツールをローカル開発でフル活用しています。
私の運用では「1プロジェクトにつき1つのClaude Codeを起動する」というスタイルをとっているため、複数のプロジェクトやレイヤー(フロント、API、インフラなど)を並行して進めていると、無数のAIセッションが同時に動くことになります。
最初は「ターミナルで指示するだけでコード書いてくれる!最高!」と感動していたのですが、息をするように大量のAIを同時稼働させるようになった結果、ある悩みが……。
そう、「AIエージェント多すぎて迷子になる問題」です。
バックエンドのAPI改修をClaude Codeに任せつつ、フロントエンドのコンポーネントをCursorで実装し、裏で別のインフラ設定を走らせる。
そんなことをやっていると、ターミナルのウィンドウが散乱します。コーヒーを淹れて戻ってくると、「あ、30分前からファイルの上書き許可(Y/n)で止まってるじゃん……」という悲劇が頻発。
ターミナルを何度も切り替えないと状況が分からず、 AIの力を引き出すためのはずが、ターミナルの管理に時間を使っている ことに気づきました。
既存ツールとの決定的な違い(Terminal vs Project)
この話をすると、「TmuxやZellijみたいなターミナルマルチプレクサを使えば?」「WarpやGhostty等の次世代ターミナルがあるじゃん」「LumberghやCliDeck、Cockpitでセッション管理すればいい」と言われることがあります。
もちろん、それらはどれも優れたツールです。しかし、競合というより「解決している課題」が全く異なります。
既存のツールは 「Terminal」 や 「AI Session」 を管理しています。
しかし、私が欲しかったのは 「Project全体の状態把握」 でした。
知りたいのは、Terminalの黒い画面そのものではありません。
「今どのProjectが動いているか」「どのAgentが止まっているか」「自分待ちなのか」「Review中なのか」「次に自分が何をするべきか」という情報です。
画面の主役はTerminalではなく、Projectであるべきなのです(Project First)。
管理したいのはAIではなく、人間の「認知負荷」
私はこの問題を解決するために、SwiftUIでネイティブなmacOSアプリ「AI Control Center」を自作しました。
このアプリの根底にあるのはHuman Firstの思想です。
AIエージェントが増えるほど、人間が全体を把握するコストは急激に上がります。開発のボトルネックはもはや「コーディング」ではなく、「状況把握」と「コンテキストスイッチ」へと移行しました。
だからこそ、「今、自分の番か?(Waiting User)」がたった5秒で分かること。それだけで計り知れない価値があると考えました。
最大の発明:AIを抽象化する「Status Contract」
このツールを実現するにあたり、一番最初に諦めたのが「ターミナルの標準出力(stdout)を監視・パースする(Terminal Parsing)」というアプローチです。
エージェントごとにUIも出力も違い、アップデートで簡単に壊れるからです。
そこで発想を転換し、 「AIを共通の状態モデルで抽象化する」 ことにしました。
AI Control Centerは、Claude Code専用のビューワーではありません。
Claude Code、Cursor Agent、Gemini CLI、Aider、そして将来登場するであろう未知のAgentを、すべて共通の 「Status Contract」 で扱うことを目指しています。
具体的には、各プロジェクトのルートに .ai/agent-status.json を配置するというルールを設けました。
{
"schema_version": "1.0",
"agent": "claude-code",
"status": "waiting_user",
"workflow_phase": "deploying",
"progress": 0.8,
"task": "Permission required: write to /etc/hosts",
"branch": "main",
"started_at": "2026-07-28T09:00:00Z",
"updated_at": "2026-07-28T10:05:33Z"
}
ダッシュボード側はAgentを直接解析するのではなく、このContract(JSON)だけを読みます。
これがFile-Based Status Architectureです。
長期的には、Agentが増えてもダッシュボード側は変更不要になります。新しいAgentは、このStatus Contractを実装するアダプターを用意するだけで済みます。
実は、私が作っている本当の価値はMacアプリではなく、この「AIエージェント間の共通ステータス仕様(Status Contract)」そのものなのかもしれません。
これが安定すれば、AI開発ツール間をつなぐ強力な基盤になり得ると確信しています。
採用した技術スタックとMVP機能
現在実装しているMVP(最小限の機能)は以下のような構成です。
- リアルタイム状態検知:思考中、実行中、ユーザー待ちなどの状況を可視化
- 通知機能:承認待ちになった瞬間にmacOSネイティブ通知でお知らせ
- ターミナルジャンプ:リストをダブルクリックで対象ターミナル(Terminal.app, iTerm2等)へ即座に移動
技術的には、以下のモダンな構成を採用しています。
-
Swift 6 & SwiftUI:Combineは使わず、
@ObservableとActorモデル(@MainActor)を活用。 - FSEvents (FSEventStream):低レイヤAPIでJSONの更新を検知。
-
AsyncStreamブリッジ:C言語ベースのコールバックを
async/awaitに安全にブリッジし、超低負荷で監視。
今後の展望:Dashboardではなく「Mission Control」へ
このプロジェクトが目指すのは、単なる便利ツールではなく、Mac全体で動くAI開発の司令塔、つまり 「AI Development Operating System(AI開発用OS)」 です。
ゆくゆくは、状態だけでなく開発の「Workflow」も管理します。
Spec → Plan → Coding → Testing → Review → Done という流れをプロジェクト単位で可視化し、アプリ上から直接AIのチャットを覗き見たり、ワンクリックで承認(Approve)を出せるようにする予定です。
おわりに
今回は、無数のAIエージェントを束ねるための思想と、共通仕様としての「Status Contract」について紹介しました。
次回以降のシリーズでは、 「Swift 6でC言語のFSEventsをAsyncStreamに安全にブリッジする実装」 や、 「通知とターミナルジャンプをAppleScriptで強引かつエレガントに解決した話」 など、よりディープな技術的トピックを書いていこうと思います。