OpenSource-Hub

firstmate

フレームワーク

kunchenguid/firstmate

単一のエントリーポイントでマルチエージェントの連携を管理するエージェントディストリビューション。

概要

firstmate は、1つのメインコーディングエージェントが一連の自律型コラボレーターを統一的にオーケストレーションできるようにするエージェントディストリビューションです。独立した git worktree、tmux セッションの可視化、再起動後も永続化される状態管理を提供し、Claude Code、Grok、Pi などのさまざまなターミナルエージェントをサポートします。

README プレビュー

firstmate\n\n  \n  \n  \n\n\nTalk to one agent. Ship with a crew.\n\n\n  \n\n\n## What it is\n\nYou can run one coding agent easily.\nBut the moment you want three project tasks done in parallel - fixes, investigations, plans, audits - you become a tab-juggler: babysitting sessions, copy-pasting context between repos, forgetting which terminal had the failing test.\n\nfirstmate flips the model.\nYou talk to a single agent - the first mate - and it runs the crew for you: spawning autonomous agents in a visible session backend, giving each a clean git worktree, supervising them to completion, and handing you finished PRs, approved local merges, or standalone investigation reports.\nFor larger fleets, you can opt in to persistent secondmates: second mates that are still ordinary direct reports, but run from their own isolated firstmate homes on this machine or another SSH-reachable host.\n\nfirstmate is not a model, not a harness, not a skill, not an MCP server, and not a CLI.\nfirstmate is an agent distro for running a crew of agents.\nAn agent distro is a portable directory of instructions, skills, tooling, policies, and state conventions that turns a general-purpose agent into a specialized one.\nThere is no app to install: the cloned repo is the distro - `AGENTS.md`, bundled firstmate skills, and helper scripts that any terminal coding agent can follow.\nLaunching a supported harness inside it instantiates your first mate - and makes you the captain.\n\n## Features\n\n- **One liaison** - you talk only to the first mate; it dispatches, supervises, escalates only real decisions, and reports plain outcomes.\n- **A visible crew** - every crewmate works in its own tmux window, experimental herdr/zellij tab, cmux workspace, or Orca terminal you can watch or type into; the first mate reconciles.\n- **Disposable worktrees** - each task runs in a clean [treehouse](https://github.com/kunchenguid/treehouse) git worktree, or an Orca-managed worktree when `backend=orca`, so par

FAQ (5)

トラブル対応
2人目の Linux または macOS ユーザーが fm-teardown を実行した際に 'herdr session presentation lock could not be resolved' を修正する方法

この障害は、Firstmate がマシン全体で共有されるディレクトリ /tmp/firstmate-herdr-presentation を使用し、そのディレクトリが現在の UID に所有され、モード 700 であることを要求し、さらに presentation が無効になっている場合でも fm-teardown.sh がこのロックを解決しようとするために発生します。--force ではこれを回避できません。直ちに実施できる回避策: Herdr presentation セッションがアクティブでないときに、ディレクトリの所有者に rm -rf /tmp/firstmate-herdr-presentation でディレクトリを削除してもらい、その直後にブロックされているユーザーとして bin/fm-teardown.sh <task> を再実行してください。その後、再度ディレクトリを削除する必要がある場合があります。あるいは、sudo chown <blocked-user>:<blocked-group> /tmp/firstmate-herdr-presentation で一度だけ所有権を譲渡する方法もあります。共有ホストでの衝突の再発を防ぐには、プライマリ側で config/backend を tmux に設定してリモートホームがそれを継承するようにするか、/tmp/firstmate-herdr-presentation-$UID や $XDG_RUNTIME_DIR/firstmate-herdr-presentation のようなアカウントごとの名前空間を適用またはパッチしてください。この問題は Firstmate 8b10b61e と Herdr 0.7.4 で観測されました。関連する修正は PR #2730、#2530、#5804 で追跡されています。

参照 Issue #4716
トラブル対応
断続的に発生する fm-watcher-lock の stale-steal 失敗、「expected exactly one stale-lock stealer, got 0」および「reap race hook never fired」を修正するにはどうすればよいですか?

これらはテストフィクスチャの競合(race)であり、ロック実装のバグではありません。tests/fm-watcher-lock.test.sh にパッチを適用してください:

1. test_lock_stale_steal_single_winner_under_concurrency では、40回のワンショット fm_lock_try_acquire 呼び出しによって勝者が生まれることに依存しないでください。負荷下では、すべてのノンブロッキング競合者がビジー状態の .steal ミューテックスを検出して終了する可能性があります。39個のノンブロッキング競合者に加えて、1つの fm_lock_acquire_wait 競合者を使用してください。待機する競合者にFIFOを通じて勝利を報告させ、FIFOの勝者が正確に1つであることをアサートしてください。

2. test_lock_steal_reap_cannot_remove_successor では、OSがそのPIDを再利用する可能性があるため、フィクスチャプロセスをkillしてそのPIDをロック内に残さないでください。専用のプロセスを作成し、それが終了していることを確認し、その確認済みの終了PIDをロックフィクスチャに書き込んで、reapパスが確実に実行されるようにしてください。

ロック実装自体を変更する必要はありません。この安定化は PR "test: stabilize watcher lock race fixtures" によってカバーされています。下流での証明は ironerumi/firstmate#69 で入手できます。

参照 Issue #6455
トラブル対応
なぜ fm-send.sh --help は usage を表示する代わりに "target '--help' is not resolvable" で失敗するのですか?

bin/fm-send.sh には -h|--help のハンドラーがありません。FM_HOME チェックが最初に実行され(231行目付近)、オプション解析(486行目付近)は --resolve-key / --fire-and-forget のみを処理するため、--help はターゲット解決に渡され、fm---help を使用するよう促す誤解を招くメッセージとともに失敗します。修正方法: PR #6402 を含むバージョンに更新してください。この PR では、FM_HOME チェックとターゲット解決の前に、スクリプトのヘッダーにある Usage: ブロックを表示して終了コード 0 で終了する早期の -h|--help 分岐が追加されています。影響を受けるバージョンでの回避策: ヘッダーコメントから使用方法の契約を直接読み取ってください(例: sed -n '1,40p' bin/fm-send.sh)。ヘッダーは steering、--resolve-key、および pending-reply の各契約について文書化された情報源であるためです。

参照 Issue #6398
トラブル対応
ターゲットセッションが無効または非アクティブな場合に、Herdr composer probe が Bash パイプラインをハングさせる問題を修正するにはどうすればよいですか?

issue #6915 の修正(fix(bin): keep herdr composer probes observable-only without autostarting server)を含むビルドにアップグレードしてください。このハングは、fm_backend_composer_state が fm_backend_herdr_target_ready を呼び出し、それが herdr server を起動するために発生します。バックグラウンドヘルパーがパイプディスクリプタ 10 を継承するため、... | head -20 のようなコマンドは EOF を受け取ることができません。

bin/backends/herdr.sh にコード修正を適用してください:
1. fm_backend_composer_state で、レディネス/自動起動チェックを受動的な observable/ステータスチェックに置き換えてください。
2. セッションが非アクティブであるか、存在しないか、またはターゲットが wPW:p2 のような裸のペイン ID である場合は、fm_backend_herdr_server_ensure を呼び出さずに即座に unknown を返してください。
3. 多層防御として、バックグラウンドサーバープロセスを継承されたディスクリプタから切り離してください。例:
( exec herdr server --session "$session" ) </dev/null >/dev/null 2>&1 10>&- &

即時の回避策としては、セッションが既に実行されているターゲットのみをプローブし、信頼できないターゲットに対してはプローブのパイプを避け、timeout でラップし、次のコマンドで不正なサーバーを削除してください:
pkill -f 'herdr server --session nonexistent-session'

参照 Issue #6915
トラブル対応
Claude Code のバックグラウンドセッションで /clear を実行した後に発生する "another live firstmate session holds the lock" エラーの修正方法

Claude Code バックグラウンドセッション(claude --bg-pty-host)は、/clear の後に自身のフリートロックを外部所有と誤検出し、読み取り専用状態になって、すべてのフリート変更操作(drain、spawn、steer、merge)がブロックされる場合があります。

原因: /clear は新しい CLAUDE_CODE_SESSION_ID を発行しますが、プロセスの pid(CLAUDE_PID)は変更されません。そのため、state/.lock の 1 行目がモデルループの pid ではなく、古い非祖先 pid(例: ターミナルフロントエンドの pid)を保持している場合、所有権チェックが失敗します。

即時の回避策: 古いロックを削除して再取得します:
rm state/.lock && bin/fm-lock.sh
再取得後、1 行目はモデルループの pid となり、セッションは正常に動作します。

恒久的な修正: bin/fm-lock.sh の confirm_own_lock にパッチを適用し、信頼された同一セッション ID パス経由で所有権が確認され、かつ CLAUDE_PID が記録されている稼働中の pid と異なる場合に、1 行目を CLAUDE_PID(セッションのアンカー)に書き換えるようにします。これにより、セッション ID が変更されても祖先メンバーシップチェックが通過するため、/clear をまたいでもロックが有効に保たれます。オプションとして、同じ CLAUDE_PID から発生した source: "clear" を持つ SessionStart フックイベントも同一セッションとして扱うようにします。

予防策: 古い非祖先 pid はフロントエンドプロセスが存続している限り無期限に残存するため、state/.lock の 1 行目が常に、生成元のフロントエンド pid ではなくセッション自身の CLAUDE_PID に更新されるようにしてください。

参照 Issue #6820