Skip to content

Repository files navigation

Agent Deck

CI License: MIT Release

複数のAI CLIエージェント(Claude Code / Antigravity / Codex / Gemini など)を、 それぞれ独立したターミナルで並列に立ち上げて監視するデスクトップアプリです。

  • Electron + node-pty(本物のPTY)+ xterm.js
  • クロスプラットフォーム設計(macOS / Windows / Linux)
  • シェル自動判定(mac/Linux → $SHELL、Windows → PowerShell)

機能

  1. 並列ターミナル — エージェントをグリッドに並べて同時操作・監視
  2. 起動コマンド自動入力 — 起動時に claude / agy 等を自動実行
  3. Git worktree 隔離 — セッションごとに新規ブランチ+作業ツリーで起動し競合防止
  4. 内蔵 diff レビュー — 各ペインの diff で起動時点からの変更を色分け表示。変更行内の語句レベル強調シンタックスハイライト(拡張子判定・依存ゼロの自前トークナイザ)・複数ファイル diff のファイル単位ジャンプ(チップ+↑↓+スクロール追従)
  5. 入力待ち検知 + 通知 — 出力停止をターミナル末尾の内容で分類し、プロンプト/確認質問なら約3秒で「要対応」点灯、作業中表示(スピナー・esc to interrupt)は抑制、判断材料なしは12秒。非アクティブ時はOS通知
  6. マルチリポジトリ管理 — サイドバーにリポを登録し、リポ単位で branch / diff-stat / worktree を表示。選択リポのセッションだけにステージを絞るフォーカスフィルタ、ダブルクリック即起動、PC全体で起動できる ⌂Home 常設エントリ
  7. diff からのマージ / PR — worktree 隔離セッションの成果を、diff ドロワーからローカルマージ(「merge ↩ base」=git merge --no-ff)または GitHub PR 作成(「PR 作成」=push → gh pr create)で取り込み
  8. ステージ操作 — グリッド切替(auto/fit/1/2/3・永続化)。fit は8ペインを標準ウィンドウで2列×4行に収め、通常モードで高さを超えた場合もスクロール可能。900px以下/200%拡大時は3カラムを縦にreflowし、端末行を潰さずスクロールで到達可能。ペインのドラッグ並べ替え、起動中デッキの保存&**再起動後に「↻ 前回のデッキを復元」**で再 spawn。Deck v2 は worktree の親リポジトリ・起動時base/branchも保持し、mainプロセスが現在のGit common-dir・worktree・両branch・merge-baseを再検証してからrepo分類・diff・merge・PRを再有効化
  9. エージェント・プリセット管理 — Agent 横の ⚙ からカスタムプリセット(表示名+起動コマンド)を追加・編集・削除。Aider 等の任意 CLI をコード変更なしで登録でき、select と Quick launch チップに反映(localStorage 永続)。さらにプリセットごとに**起動後コマンド(init)**を設定でき、エージェント起動が落ち着いてから /effort ultracode のようなスラッシュコマンドを自動入力(ビルトインの claude / agy にも設定可・毎回の手入力を省略)
  10. キーボード操作 — ペイン移動(1–9)・前後循環([ ])・クイック起動(Enter)・終了(W)・コマンドパレット(K・fuzzy 検索でセッションへジャンプ)。修飾キーは macOS が 、Windows / Linux が Ctrl+Shift(素の Ctrl はシェル/readline のキーのため、ターミナルアプリの慣習に準拠)
  11. スケジュール起動(⏰) — 「リポジトリ × エージェント × 時刻」を登録すると指定時刻にセッションを自動起動。繰り返し(一回のみ / 毎日 / 曜日指定)、worktree 隔離(発火ごとに日時付きブランチで一意化)、有効/無効トグル・次回発火表示・起動時の OS 通知に対応。Agent 横の ⏰ かリポジトリ行の ⏰ から登録(userData/schedules.json に永続化、スケジューラは main プロセス常駐で 30 秒間隔の壁時計照合 — スリープ復帰でも取りこぼし/二重発火なし)
  12. 多言語対応(5言語) — UI を 日本語 / English / 简体中文 / 繁體中文 / 한국어で切り替え(サイドバー下部のセレクタ)。初回は OS のロケールに追従(zh-Hans-HK のような明示スクリプト付きロケールも正しく解決)。文字列は依存ゼロの lib/i18n.js 辞書({key: {ja, en, zhHans, zhHant, ko}})で一元管理し、5言語の充足と {param} 一致を CI が検査

ダウンロード

最新版は Releases から取得してください。 バージョンタグを切ると CI が各 OS の成果物を自動ビルドして添付します(RELEASE.md)。

OS ファイル 初回起動
macOS (Apple Silicon -arm64 / Intel -x64) .dmg Gatekeeper 警告 → 右クリック → 開く(または xattr -dr com.apple.quarantine
Windows (x64) .exe(インストーラ) SmartScreen → 詳細情報 → 実行
Linux (x64) .AppImage / .deb AppImage は chmod +x で実行(要 libfuse2)/deb は apt install ./…deb

⚠️ 現在配布中のビルドは未署名です(GitHub Releases が正本)。上記の初回起動手順で開けます。 リリース CI は署名用 secrets が設定されていれば macOS を署名+公証しますが、v0.4.0-beta.10 時点では未設定のため未署名で出荷しています。Windows も未署名です。 App Store 配布は予定していません(サンドボックスとシェル起動が非互換のため非対応)。 アップデート: 起動時と 6 時間ごとに Releases を確認し、パッケージ版ではアプリ内でダウンロード+インストールします(Squirrel.Mac / NSIS / AppImage)。ダウンロードは通知をクリックしてから始まります(自動ダウンロードはしません)。未署名の macOS ビルドは Squirrel.Mac が自己インストールを拒否するため、ブラウザでのダウンロード導線にフォールバックします。


セットアップ(開発)

npm install
npm run rebuild   # node-pty を Electron 向けに再ビルド
npm start

npm start で「NODE_MODULE_VERSION mismatch」が出たら npm run rebuild。 mac は Xcode CLT(xcode-select --install)、Windows はビルドツールが必要な場合あり。

テスト

純粋ロジックは lib/ に切り出し、Node 標準テストランナーで検証します(依存ゼロ・電子/PTY不要)。

npm test       # = node --test  (test/*.test.js を実行)

CI(GitHub Actions)は ubuntu / macOS / windows のマトリクスで node --test に加え、 実ランナー上で Electron をヘッドレス起動するスモーク(npm run smoke — 起動 / preload / IPC / node-pty を検証。Linux は xvfb 経由)を実行します。

ビルド・配布(macOS / arm64 + x64)

electron-builder.dmg を生成します(node-pty は asar 外に展開して同梱)。 現在のリリースは未署名で、GitHub Releases を正本に配布します。

npm run pack:unsigned   # 未署名 .dmg ← 現在のリリース手順

Apple Developer ID による署名+公証(npm run dist)はリリース CI が対応済みです。 MAC_CSC_LINK / MAC_CSC_KEY_PASSWORD / APPLE_ID / APPLE_APP_SPECIFIC_PASSWORD / APPLE_TEAM_ID の 5 secrets が揃っていれば署名+公証(アプリ内自動更新が有効)、 未設定なら未署名ビルドへ graceful fallback します。証明書の準備手順と GitHub Releases 公開フローは RELEASE.md を参照してください。

アプリは起動時と 6 時間ごとに Releases feed を確認し、新版があれば右下のトースト+OS 通知(バージョンごとに一度)でお知らせします。パッケージ版では通知からアプリ内でダウンロード+インストールまで完結します(autoDownload は無効なので、ダウンロードはユーザーのクリック後に始まります)。未署名 macOS ビルドや更新メタデータの無い旧リリースでは、ブラウザでダウンロードページを開くフォールバックに切り替わります。

プライバシー / ネットワーク

  • テレメトリ・解析・クラッシュレポートは一切送信しません。 収集も送信もしていません。
  • アプリが自発的に行う外部通信はアップデート確認のみです(起動時と 6 時間ごとに api.github.com / github.com へ HTTPS アクセス。ダウンロードを選んだ場合は成果物の取得)。 AGENTDECK_UPDATE_FEED 環境変数で向き先を変更でき、到達不能でもアプリは通常どおり動作します。
  • リポジトリ登録・スケジュール(userData/ 配下の JSON)と UI 設定(localStorage)は すべてローカル保存です。ターミナルの内容が外部に送られることはありません。
  • エージェント CLI(claude / codex 等)自身の通信は各 CLI のポリシーに従います。

使い方

  1. Agent を選ぶ(Startup command 自動入力・編集可)
  2. Working directory を指定(git リポジトリならステータス表示)
  3. 必要なら Isolate in git worktree をオン+ブランチ名入力
  4. ▶ Launch agent → ペイン追加 & コマンド自動実行
  5. diff で変更レビュー、kill で終了

Antigravity(agy)

起動コマンドは agyantigravity プリセットに設定済み)。agy --model <model> で モデル指定、agy -p "..." でヘッドレス。インストール先: mac/Linux ~/.local/bin/agy、 Windows C:\Users\<Username>\AppData\Local\agy\bin


リポジトリ構成

willink-oss/agentdeck(i-Willink の OSS 組織)で公開しています。

同梱物

パス 役割
.github/workflows/ci.yml OSマトリクスで npm test + ヘッドレス起動スモーク(npm run smoke
.github/pull_request_template.md PR テンプレート
.github/ISSUE_TEMPLATE/ bug / feature テンプレート
LICENSE MIT(i-Willink)
CONTRIBUTING.md 開発・テスト・PR 規約

.gitignorenode_modules/.agentdeck-worktrees/ 相当は除外済みです。


構成

agentdeck/
├── main.js              # Electron main:PTY・git worktree/diff/merge・リポ登録・スケジューラ・IPC
├── preload.js           # contextBridge 経由の IPC
├── lib/                 # DOM/Electron 非依存の純粋ロジック(テスト対象)
│   ├── git-utils.js     #   defaultShell / sanitizeBranch / worktreeFolderName
│   ├── diff.js          #   classifyLine / diffToSegments
│   ├── attention.js     #   shouldFlagAttention
│   ├── repos.js         #   normalizePath / addRepo / findRepo / effectiveRepos / findEff
│   ├── gitstat.js       #   parseNumstat / parseWorktreeList / formatStat
│   ├── layout.js        #   normalizeLayoutMode / gridTemplateFor / gridAutoRowsFor
│   ├── workspace.js     #   Deck v2(レイアウト+repo/worktree metadata)の保存/復元
│   ├── fuzzy.js         #   score(⌘K パレットの部分列マッチ)
│   ├── version.js       #   compare / isNewer(アップデートチェック)
│   ├── presets.js       #   ビルトイン定義 + validate / keyFor / merge(プリセット管理)
│   ├── schedule.js      #   validate / nextFireAt / shouldFire / markFired(スケジュール起動)
│   ├── i18n.js          #   t(key) / 辞書(ja / en / zh-Hans / zh-Hant / ko)
│   ├── worktree-identity.js # main 専用: 保存 worktree の再検証(12 の拒否パス)
│   └── session-merge.js #   main 専用: merge/PR の事前条件 + コンフリクト時 abort
├── renderer/            # UI(順序ロードの classic script 群 — global lexical scope を共有)
│   ├── index.html       #   script の並び順がロード順(boot を含む 07 → 08 の順を維持)
│   ├── 00-state.js      #   共有状態・定数・DOM refs・lib バインディング
│   ├── 01-launch-form.js#   起動フォーム(preset select / quick chips)
│   ├── 02-repos.js      #   リポジトリパネル(サイドバー・ポーリング・フィルタ)
│   ├── 03-deck.js       #   レイアウト切替・ペイン並べ替え・デッキ保存/復元
│   ├── 04-sessions.js   #   セッション起動/kill・attention 検知・PTY ルーティング
│   ├── 05-diff.js       #   diff ドロワー(merge / PR)
│   ├── 06-keys-palette.js #  ⌘ショートカット・リネーム・⌘K パレット
│   ├── 07-overlays-boot.js # プリセット管理・右クリックメニュー・update toast・boot
│   ├── 08-schedules.js  #   スケジュール起動(⏰ モーダル・schedule:fire ハンドラ)
│   └── styles.css       #   配色は PULSE(@willink-labs/pulse)の別名定義のみ
├── e2e/
│   └── smoke.cjs        # CI 用ヘッドレス起動スモーク(3 OS・起動/preload/IPC/node-pty)
└── test/                # node --test 用ユニットテスト

デザインシステム

配色は PULSE(i-Willink のデザインシステム)に従う。@willink-labs/pulse の dark ビルドを renderer/index.html で読み込み、styles.css は自前の色を一切持たず PULSE ロールの別名を定義するだけ。トークン契約側で色が変われば、Flutter アプリ・Web と同時にここへ届く。

割り切りが 2 つある。どちらも「デザインシステムは端末の外枠を統べるが、中身の意味は統べない」という線引き:

  • ANSI 16 色は PULSE 化しないrenderer/00-state.jsTERM_THEME)。端末が赤を出すのは「エラー」、緑は「成功」という契約で、利用者は長年の慣れで読む。背景・前景・カーソル・選択色だけが PULSE に追従する。
  • diff ビューアの syntax 配色は PULSE に該当ロールが無いため、最も近いアクセントを借りている(--syntax-kw / --syntax-num)。

既知の割り切り

  • kill では worktree とブランチを残す(作業保全優先。不要分は git worktree prune)。
  • diff は git diff <base>(追跡ファイル)+ untracked 一覧。
  • 入力待ち検知はヒューリスティック(出力停止+末尾分類)。プロンプト/質問は素早く、不明なケースは保守的に点灯するが、誤検知は依然あり得る。
  • merge はローカル git merge --no-ff のみ(コミット済み履歴が対象。未コミット分はセッション内で commit してから)。コンフリクト時は git merge --abort で原状復帰。
  • PR 作成は origin リモート+認証済み gh CLI が前提(push → gh pr create)。worktree 隔離セッションのみ対象。
  • デッキ復元は各セッションの起動設定を再 spawn するもの(ライブ端末出力・スクロールバックは復元しない)。worktree セッションは既存ディレクトリでシェルを開き直すが、保存情報と現在のGit状態が一致しない場合は安全な通常shellへ降格し、merge / PRを無効化する。
  • スケジュール起動はアプリ起動中のみ発火する(OS のタスクスケジューラには登録しない)。非起動中に過ぎた回はスキップされるが、「一回のみ」は起動時に直近 5 分以内なら猶予発火する。精度は ±30 秒。
  • シングルウィンドウ構成のため、ウィンドウを閉じると実行中の全セッションが終了する。実行中セッションがある場合は閉じる前に確認する(macOS の「閉じてもアプリは生存」慣習との差で黙って失わないように)。

次の一手(任意)

  • SSHから同じライブセッションへ再接続する用途には、direct PTYに加えて任意のtmuxバックエンド(GUI終了=detach、明示終了=terminate)を追加する
  • tmux実装後、同じbackend契約の上にZellij 0.44系のpane制御/read-only watchを追加する
  • 配布を絞るなら Tauri + portable-pty(Rust)へ移植

コントリビュート / ライセンス

Issue / PR を歓迎します。1 PR = 1 トピック、npm test がグリーンであることをご確認ください。

About

Parallel AI agent terminal orchestrator (Claude Code / Antigravity / any CLI agent) with git-worktree isolation and built-in diff review.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages