port-daddy について
Port Daddy は、共有状態を扱う同一リポジトリ内の複数の AI エージェント向け調整デーモンです。決定的なポート割り当て、セッションとノート、ファイル宣言、メッセージング、クラッシュ後の作業回収を提供します。
主な機能
- 01サービス ID に基づく決定的なポート割り当て
- 02エージェントのセッションと不変ノートの追跡
- 03ファイル宣言による編集競合の通知
- 04Pub/Sub とタプルスペースによる調整
- 05クラッシュしたエージェントの作業を回収キューに登録
- 06エージェントフリートとバックグラウンドタスクの支援
活用シーン
- 01複数エージェントによる開発サーバーのポート競合を回避
- 02同一リポジトリでの複数エージェントの編集を調整
- 03クラッシュしたエージェントの作業を引き継ぐ
- 04メッセージとタプルで依存関係の状態を共有
MCP 対応
Port Daddy は、エージェントのセッション、ポート、ノート、ロック、メッセージング、共有タプルを管理する MCP ツールを提供します。クライアントはカテゴリ別に追加ツールを検索できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill port-daddyインストール後、Claude Code で/port-daddyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
architecture.html.claude-plugin/plugin.jsonassets/.portdaddyrc.starterpd-fleet.starter.ymlsession-note.template.mdexamples/01-bootstrap-new-session.md02-two-agents-same-file.md03-salvage-dead-agent.md04-fleet-from-zero.md05-tuple-swarm-handoff.md06-debug-daemon-down.md07-deterministic-port-collision.mdINDEX.mdschemas/INDEX.mdmcp-tool-catalog.mdnote-shape.mdpd-fleet.schema.jsonpd-fleet.schema.mdpheromone-signal.mdsalvage-entry.mdsemantic-identity.mdtuple-shape.mdscripts/agent-handshake.shfleet-validate.shpreflight.shsalvage-triage.shsession-resume.sh詳細
Port Daddy v3.8.2 — 実際に機能するエージェント連携
対象外
- 本番環境へのデプロイのオーケストレーション、ロールアウトポリシー、CI のリリースゲート。
- Docker、Kubernetes、サービスメッシュ、クラウドネットワークの検出に関する問題。
- ポート調整、サルベージ、共有状態のワークフローが存在しない、単一エージェントによるローカル作業。
今まさに直面している問題
あなたは AI エージェントです。これから開発サーバーを起動しようとしています。どのポートを使いますか?3000?使用中です。3001?別のエージェントが確保しました。適当なポートを選びます。すると、今度は誰もあなたのサーバーを見つけられません。
その一方で、別のエージェントがあなたと同じファイルを編集しています。お互いそのことを知りません。両方ともコミットし、どちらか一方の作業が失われます。
さらに別のエージェントは20分前にクラッシュしました。マイグレーションの途中でした。その作業は宙に浮いています。誰も気づいていません。
Port Daddy はこれらすべてを1つのデーモンで解決します。
判断ツリー — 適切なプリミティブを選ぶ
上から順に読んでください。最初に該当するリーフが答えです。デーモンの起動確認を飛ばすと、その後の判断はすべて意味がありません。
flowchart TD
A[I want to do something coordination-shaped] --> Up{pd status<br/>== running?}
Up -- no --> Down[examples/06-debug-daemon-down.md]
Up -- yes --> Scope{Scope?}
Scope -- single agent, no shared state --> Out[Out of scope: just code.<br/>NOT for this skill.]
Scope -- this agent, this session --> Life[Lifecycle path]
Scope -- two+ agents, same repo --> Coord[Coordination path]
Scope -- background cadence / fleet --> Fleet[Fleet path]
Scope -- many agents, same harbor --> Swarm[Swarm path]
Life --> L1{What do I need?}
L1 -- "session boundary" --> L1a[pd begin / pd done<br/>schemas/note-shape.md]
L1 -- "deterministic port" --> L1b[pd claim {project}:{stack}:{ctx}<br/>schemas/semantic-identity.md<br/>examples/07-port-collision.md]
L1 -- "audit trail" --> L1c[pd note --type ...<br/>assets/session-note.template.md]
L1 -- "what happened?" --> L1d[pd sitrep / catch_me_up MCP]
Coord --> C1{Failure mode I'm preventing?}
C1 -- "two agents edit same file" --> C1a[pd session files claim<br/>examples/02-two-agents-same-file.md]
C1 -- "must be exclusive" --> C1b[pd with-lock<br/>or pd lock + pd unlock]
C1 -- "agent-to-agent signal" --> C1c[pd pub + pd watch]
C1 -- "DM a specific agent" --> C1d[pd inbox send<br/>or talk_to_agent MCP]
C1 -- "agent died, finish their work" --> C1e[pd salvage claim<br/>schemas/salvage-entry.md<br/>examples/03-salvage]
Fleet --> F1{Fleet exists?}
F1 -- "no" --> F1a[pd fleet init + edit pd-fleet.yml<br/>assets/pd-fleet.starter.yml<br/>examples/04-fleet-from-zero.md]
F1 -- "yes, broken" --> F1b[scripts/fleet-validate.sh<br/>schemas/pd-fleet.schema.md]
F1 -- "yes, want it daemon-managed" --> F1c[POST /fleet/register<br/>survives terminal close]
F1 -- "yes, want to chain agents" --> F1d[on_success: publish channel<br/>+ declare in channels:]
Swarm --> S1{Shape of the data?}
S1 -- "typed records, multi-reader" --> S1a[pd tuple out + pd tuple rd<br/>schemas/tuple-shape.md]
S1 -- "exactly-once work" --> S1b[pd tuple in<br/>work-stealing<br/>examples/05-tuple-swarm-handoff.md]
S1 -- "ambient gradient / heat" --> S1c[pd pheromone spray<br/>schemas/pheromone-signal.md]
S1 -- "broadcast, ephemeral" --> S1d[pd pub on a harbor channel]
5つの質問を順番に確認します:
- デーモンは起動しているか? —
pd status。起動していなければ、連携機能は一切使えません。まずこれを解決してください。 - スコープは? — 単一セッション、2エージェント、フリート(ケイデンス)、それともスウォーム(多数のエージェントが同じハーバーにいる状態)ですか?それぞれ異なるプリミティブを使います。混在させるのは見せかけにすぎません。
- どの障害モードを防ごうとしているか? — サイレント上書き、ポート競合、停止したエージェントによる作業の喪失、シグナルの見落としですか?障害モードに応じてプリミティブを選びます。
- 永続的か、一時的か? — ノート(永久)と TTL のないタプル(削除されるまで)は永続的です。フェロモンと pub/sub は一時的です。誤った方を選ぶと、監査記録が汚染されるか、シグナルが失われます。
- 複数回読み取るか、一度だけ取得するか? —
tuple rdとpubはファンアウトです。tuple inとlockは勝者が必ず1つだけになります。ここを誤ると、作業が失われるか、重複して実行されます。
障害モードの切り分け
すでに問題が起きている場合は、ここから確認してください。
| 症状 | 考えられる原因 | 最初の診断 | 修正/手順書 |
|---|---|---|---|
pd <anything> → Connection refused | デーモンが起動していない | pd status | examples/06-debug-daemon-down.md |
pd status がいつまでも応答しない | デーモンがイベントループで停止している | lsof ~/.port-daddy/daemon.sock を実行し、daemon.log を確認 | kill -9 $(cat ~/.port-daddy/daemon.pid) を実行してから pd start |
pd claim が「間違った」ポートを返す | 設計上、ID によって決まるため、正しい動作です | pd find <identity> で確認 | ポートではなく、別の ID コンテキストを使う |
pd begin がセッションはすでにアクティブだと表示する | この PID に対する古いセッションがある | pd whoami | pd done を実行してから再度 begin するか、既存のセッションを続行する |
pd session files claim が競合を表示する | 別のエージェントがすでにそのファイルを確保している | pd swarm_awareness を実行するか、警告を読む | examples/02-two-agents-same-file.md |
| フリートエージェントがコミット時に起動しない | fleet.name != basename(projectDir)(最も一般的) | scripts/fleet-validate.sh | fleet.name を修正し、pd fleet up を再実行する |
| フリートエージェントは起動するが何もしない | prompt が曖昧すぎる、または allowedTools が必要な操作をブロックしている | pd spawned で短時間実行されたことを確認し、ログを確認する | プロンプトを具体化し、許可リストを広げる |
pd salvage に大量のバックログが表示される | かなり前にクラッシュしたエージェントの古いエントリー | pd salvage --project <p> | scripts/salvage-triage.sh で切り分け、明らかに停止済みのエントリーを破棄する |
pd tuple rd が何も返さない | ハーバーまたはパターンの形式が間違っている | pd tuple scan --harbor <h> | 文法については schemas/tuple-shape.md を参照 |
pd note の書き込みは成功するが、pd notes は空を返す | ノートは暗号化されているが、キーが変更されている | ls -la ~/.port-daddy/master.key を実行し、権限が 0600 であることを確認 | バックアップからキーを復元してください。復元できない場合、ノートは読み取れません |
| フェロモンの読み取り値が常にほぼゼロ | 減衰が散布の頻度を上回っている | pd pheromone show --table <t> --id <i> | より頻繁に散布するか、--strength を大きくしてください。フェロモンはデータベースではありません |
2つのエージェントが同じタプルに対してどちらも tuple in に成功する | バグです — 報告してください | .spark/feedback/$(date +%F)-tuple-double-take.md | デーモンはアトミックに取得する必要があります。これはリグレッションです |
L3 インデックス — 詳細なナレッジの所在
このファイルは L1/L2 のエントリです。詳細なリファレンスをここに直接貼り付けず、必要に応じて読み込んでください。
| 必要な情報 | 読むファイル |
|---|---|
| エンドツーエンドの実例 | examples/INDEX.md(8 つのシナリオ:ブートストラップ、競合、サルベージ、フリート、スウォーム、デーモン停止、ポート競合) |
| 正式な契約/データ形式 | schemas/INDEX.md(semantic-identity、pd-fleet スキーマ、タプル、ノート、フェロモン、サルベージ、MCP ツール) |
| すぐに実行できるヘルパー | scripts/(preflight、session-resume、salvage-triage、fleet-validate、agent-handshake) |
| コピーして編集するテンプレート | assets/(pd-fleet.starter.yml、.portdaddyrc.starter、session-note.template.md) |
| HTTP API 全体(93 以上のエンドポイント) | references/api-reference.md |
| JavaScript SDK | references/sdk-reference.md |
| 高度なマルチエージェントパターン | references/multi-agent-patterns.md |
プロジェクトごとの .portdaddyrc 設定 | references/portdaddyrc-spec.md |
クイックスタート(最初に実行)
# 1. Start your session — ALWAYS do this first
pd begin "Building auth module"
# 2. Claim a port — deterministic, never conflicts
PORT=$(pd claim myapp:api:main -q)
# 3. Leave breadcrumbs for other agents
pd note "JWT validation working, moving to refresh tokens"
# 4. Check who else is working here
pd salvage --project myapp # Any dead agents to rescue?
# 5. End cleanly
pd done
重要な理由
Port Daddy がない場合:
- 2 つのエージェントが開発サーバーを実行するたびにポートが競合します
- エージェントが何をしたか、何を決定したかの記録がありません
- クラッシュしたエージェントの作業が取り残され、誰にも見つけられません
- エージェント同士が互いに通知する手段がありません
- ファイル編集の競合により、作業が気付かれないまま失われます
Port Daddy がある場合:
- 決定論的なポート — 同じ ID には常に同じポートが割り当てられます
- 不変のノート — あらゆる判断の完全な監査証跡が残ります
- サルベージキュー — 停止したエージェントの作業が保存され、引き継ぎ可能になります
- Pub/Sub とファイルクレーム — エージェント同士が互いの作業を妨げずに連携できます
- バックグラウンドフリート — QA、ドキュメント、テストがすべてのコミットで自動実行されます
- バイナリー IPC — Unix ソケット経由のサブマイクロ秒ハートビートとフェロモン送信
- フェロモントレイル — 競合検出のための、時間とともに減衰する環境中の数値シグナル
- タプル空間 — スウォーム連携のための共有型付きメモリー
- セマンティックトライ — SQL の LIKE スキャンに代わる O(k) の ID 検索
知っておくべきこと
- タスクに一時ポートが 1 つ必要なだけで、共有セッション状態も必要ない場合、フリートやフェロモントレイルを立ち上げるのは連携ではなく見せかけです。
- クリティカルセクションへの厳密な排他制御が必要な場合は、ロックを使用してください。アドバイザリーなファイルクレームは交渉用であり、安全性を保証するものではありません。
- 障害がコンテナーのイングレス、DNS、本番サービスディスカバリーにある場合、Port Daddy は適切なレイヤーではありません。
MCP ツール一覧
まずはこちらから(概要レベルのツール。一度の呼び出しで多くのことを実行します):
| ツール | 説明 |
|---|---|
begin_session | エージェントとして登録し、セッションを一括で開始します |
end_session_full | セッションを終了し、登録を一括で解除します |
whoami | 自分はどのエージェントか、どのセッションか、どのファイルを所有しているかを確認します |
catch_me_up | 離れていた間の出来事を確認します。最近のアクティビティ、メモ、停止したエージェントを表示します |
swarm_awareness | ほかに作業しているエージェントを確認します。すべてのエージェント、セッション、ファイルの申告を表示します |
file_heat | エージェント間で競合しているファイルを確認します。フェロモンベースの競合マップを表示します |
talk_to_agent | 名前を指定して、特定のフリートエージェントにダイレクトメッセージを送信します |
claim_port | サービス ID に対応する決定論的なポートを取得します |
add_note | 不変の記録を残します(メモは削除できません) |
acquire_lock | クリティカルセクション用の分散ロックを取得します |
spawn_agent | タスクを指定して、バックグラウンド AI エージェントを起動します |
fleet_init | git フックと pd-fleet.yml を使って、バックグラウンドエージェントフリートを設定します |
pd_discover | カテゴリ別に追加のツールを検索します |
タプル空間ツール(共有スウォームメモリ):
| ツール | 説明 |
|---|---|
tuple_out | 型付きタプルを共有空間に書き込みます(ハーバー単位) |
tuple_read | パターンに一致するタプルを読み取ります(非破壊的) |
tuple_take | パターンに一致するタプルをアトミックに読み取り、削除します |
tuple_scan | ハーバーまたはグローバル空間のすべてのタプルを一覧表示します |
tuple_count | パターンに一致するタプルの数をカウントします |
カテゴリ別にツールを検索:
カテゴリ名を指定して pd_discover を呼び出します:magic、session-lifecycle、ports、sessions、notes、locks、messaging、agents、inbox、webhooks、integration、dns、briefing、tunnels、projects、changelog、activity、system、tuples、pheromone
インテグレーションシグナル: サービスの依存関係を調整するには、integration ready と integration needs を使用します。サービスの準備ができたら、その旨を通知して、ほかのエージェントが作業を進められるようにします。
中核となる概念
セマンティック ID:project:stack:context
各サービスにはセマンティック名が付与されます。この名前がそのままポートになります。決定論的なハッシュにより、同じ ID は常に同じポートに割り当てられます。ID はメモリ内の Adaptive Radix Tree にインデックス化され、O(k) の検索(k はキーの長さ)を実現します。これにより、SQL LIKE によるスキャンを置き換えます。
pd claim myapp:api:main # Always gets port 3142 (or whatever hash gives)
pd claim myapp:api:feature-auth # Different port, same project
pd find 'myapp:*' # Prefix search — resolves through the trie, not SQL
pd find 'myapp:*:main' # Wildcard — all stacks with context "main"
セッションとメモ
セッションは各エージェントの作業内容を記録します。メモは不変です。一度書き込むと、編集も削除もできません。これにより、エージェントと人間が信頼できる監査証跡が作成されます。メモは AES-256-GCM で保存時に暗号化されます(マスターキーは ~/.port-daddy/master.key に保存され、初回起動時に自動生成されます)。
pd begin --identity myapp:api --purpose "Building auth"
pd note "Found SQL injection in token validation"
pd note "Patched. Tests green."
pd done
サルベージ(停止したエージェントの復旧)
エージェントがクラッシュすると、そのセッションはサルベージキューに入ります。別のエージェントが作業を引き継ぎ、続行できます。
pd salvage --project myapp # See dead agents' context
pd salvage claim dead-agent-42 # Pick up their work
重要: セッションの開始時には、必ず pd salvage を確認してください。最初からやり直すのではなく、クラッシュしたエージェントの作業を引き継いで続行できる場合があります。
ファイルの申告(助言的)
pd session files claim src/auth/*.ts
# Another agent tries the same file:
pd session files claim src/auth/login.ts
# → CONFLICT: claimed by agent 'myapp:api'
申告は助言的なもので、警告はしますがロックはしません。ハードロックはデッドロックを引き起こします。助言的な申告は対話を促します。
Pub/Sub メッセージング
エージェント同士は、チャネルを通じてシグナルを送信します。
# Agent A finishes database setup
pd pub myapp:events "database-ready"
# Agent B was watching
pd watch myapp:events --exec "npm run migrate"
分散ロック
排他制御が本当に必要な操作の場合:
pd with-lock deployment -- npm run deploy
# Or manually:
pd lock db-migration --ttl 300
pd unlock db-migration
バイナリ IPC プロトコル(v3.8.2)
MessagePack エンコーディングを使用し、Unix ドメインソケット経由で高頻度のエージェント通信を行います。IPC チャネルは HTTP API と並行して動作します。低レイテンシの通信(ハートビート、フェロモン散布、pub/sub のパブリッシュ)が必要なエージェントは、デーモンの実行中に IPC を自動的に使用します。
主な特性:
- 7 バイトのヘッダー:[type:1][conv_id:4][payload_len:2] + MessagePack ペイロード
- HTTP JSON と比較して帯域幅を 70~80%削減
- fire-and-forget 操作で約 3us のレイテンシ(HTTP では約 200us)
- 13 種類の FIPA performative:INFORM、REQUEST、QUERY_REF、REFUSE、FAILURE、NOT_UNDERSTOOD、SUBSCRIBE、UNSUBSCRIBE など
- fire-and-forget:ハートビート、フェロモン散布、pub/sub のパブリッシュ(conv_id=0)
- リクエスト/レスポンス:claim、lock、session(相関用の conv_id)
- pub/sub サブスクリプション:切断時にデッドマンによるクリーンアップを実施
- 自動再接続:ソケット切断時に、サブスクリプションを再登録してクライアントが再接続
- SDK の高速パス:
heartbeat()、pheromoneSpray()、publish()は、利用可能な場合に IPC を自動使用
ソケットの場所: ~/.port-daddy/daemon.ipc
セキュリティ強化:
- レート制限:接続ごとに毎秒 500 フレーム
- 接続数上限:最大 256(上限超過時は REFUSE)
- プロトコル違反は 3 回まで(不正なフレームを受信すると切断)
- 書き込みキューと drain イベントによるバックプレッシャー
- IPC 切断時にロックを解放
IPC を直接使用する必要はありません。SDK と CLI はホットパス操作で IPC を透過的に使用します。
Fleet:バックグラウンドエージェント(v3.8.0)
エージェントを YAML で宣言します。Git コミット、cron スケジュール、または pub/sub メッセージをトリガーに実行されます。クラッシュ時は、サーキットブレーカー付きで自動的に再起動します。
pd fleet init # Creates pd-fleet.yml + git hook
pd fleet up # Starts the fleet
git commit -m "fix auth" # QA, docs, cartographer fire automatically
pd fleet status # What is the fleet doing?
pd fleet down # Stop the fleet
スターターフリートには、QA(バグの調査)、Documentarian(ドキュメントの同期)、Cartographer(ロードマップの追跡)、Spark(アイデアの創出)、Spider(機能間のつながりの発見)が含まれます。
# pd-fleet.yml
fleet:
name: myapp
harbor: "{project}:fleet"
agents:
qa:
trigger: git:committed # React to pub/sub events
respawn: true # Auto-restart on crash
max_respawns: 3 # Circuit breaker
backend: claude-cli
allowedTools: "Read,Grep,Glob,Bash(npm test*)"
prompt: "Review the last commit for bugs..."
gardener:
schedule: "*/10 * * * *" # Or run on a cron schedule
backend: custom
prompt: "git status --porcelain"
on_success: publish git:status # Chain agents via channels
channels:
git:committed:
description: "Fired after a successful commit"
consumers: [qa]
主な機能:
- あらゆる LLM バックエンドで動作:
claude-cli、ollama、gemini、aider、custom - テンプレート変数(
{project})は YAML コンテキストから解決されます on_success: publish <channel>により pub/sub 経由でエージェントを連携(DAG トポロジーは起動時に検証)pd fleet upの実行時にフリートの Harbor を自動作成 — すべてのエージェントがセマンティック名前空間を共有- 各エージェントは PD の調整機能をすべて利用:登録、セッション、ハートビート、クラッシュ時のサルベージ
respawn: trueとmax_respawnsサーキットブレーカーによる自動再起動
Tuple Space:共有スウォームメモリー(v3.8.0)
エージェントは型付きタプルを共有スペースに書き込みます。他のエージェントはパターンで検索できます。Linda(Gelernter、1985)に基づいています。フリートを分離するため Harbor ごとにスコープ化されます。TTL による自動期限切れに対応しています。
# Spider writes a connection it discovered
pd tuple out '["connection", "trie+pubsub=routing", "spider", 0.9]' --harbor myapp:fleet
# Spark reads all connections with confidence > 0.7
pd tuple rd '["connection", "*", "*", ">0.7"]' --harbor myapp:fleet
# Take (remove) a processed task from the space
pd tuple in '["task", "build-auth", "pending"]'
# Scan all tuples in a harbor
pd tuple scan --harbor myapp:fleet
# Count tuples
pd tuple count --harbor myapp:fleet
パターンマッチング:完全一致、* ワイルドカード、数値比較の >N/<N、セマンティック ID プレフィックスの myapp:*。
HTTP API:
POST /tuples— タプルを書き込みます(本文:{ tuple, harbor?, writtenBy?, ttl? })GET /tuples— パターンで読み取ります(クエリ:pattern、harbor、limit)DELETE /tuples— パターンに一致するタプルを取得します(破壊的読み取り)GET /tuples/scan— Harbor 内のすべてのタプルを一覧表示しますGET /tuples/count— タプルの数を取得します
Pheromone Trails:環境信号(v3.8.0)
エージェントはエンティティに数値信号(0~1)を散布します。読み取り時に信号が指数関数的に減衰するため、ポーリングせずに周囲の状況を把握できます。
# Spray a signal onto a service
pd pheromone spray --table services --id myapp:api --key urgency --strength 0.8
# Sniff pheromone values (applies read-time decay)
pd pheromone sniff --table services --id myapp:api
# View file heat map (which files are most contested)
pd pheromone files
# List all non-zero pheromone trails
pd pheromone list
ユースケース:ファイル競合の検出、エージェントの評判スコアリング、ホットパスの特定、しきい値の適応。
HTTP API:
POST /pheromone/spray— フェロモン値を設定します(本文:{ table, id, key, strength })GET /pheromone/:table/:id— フェロモン値を読み取ります(読み取り時に減衰を適用)GET /pheromone— 0 以外のフェロモンをすべて一覧表示しますGET /pheromone/files— セッションのファイル claim からファイルヒートマップを取得します(クエリ:path、depth)
Arbiter:実行時不変条件の強制(v3.8.0)
Arbiter は、TLA+ 仕様から形式的に導出された 6 つの不変条件に照らして、すべての状態遷移を監視します。
- PID の横取り — プロセスが他のプロセスのポートを取得することはできません
- 機能の昇格 — エージェントが宣言された機能を超えることはできません
- ノートの単調性 — ノートは追記のみで、削除されることはありません
- エスクローの正値性 — 暗号化されたノートのエスクロー残高は常に正の値を保ちます
- ロック所有者の有効性 — ロックを解除できるのは所有者だけです
- ハートビートの鮮度 — 古くなったエージェントは回収されます
厳格モードでは、重大な違反が発生すると、緊急救出処理が実行されます。
pd arbiter status # Check rules and violation count
pd arbiter violations # List recorded violations
実行時ファイルの場所(v3.8.2)
すべての実行時ファイルは ~/.port-daddy/(/tmp/ ではありません)に配置されます。これにより、シンボリックリンク攻撃を防ぎ、/tmp/ のクリーンアップ後もファイルが保持され、権限がユーザー専用(ディレクトリは 0700)になります。
| ファイル | 用途 |
|---|---|
~/.port-daddy/daemon.sock | HTTP Unix ソケット(CLI、SDK、MCP) |
~/.port-daddy/daemon.ipc | バイナリ IPC ソケット(エージェントのホットパス) |
~/.port-daddy/daemon.pid | PID ファイル |
~/.port-daddy/daemon.port | TCP ポートファイル(ダッシュボードの検出用) |
~/.port-daddy/master.key | ノート暗号化用 AES-256-GCM マスターキー |
環境変数 PORT_DADDY_SOCK、PORT_DADDY_IPC、PORT_DADDY_PORT_FILE で上書きできます。
CLI クイックリファレンス
| コマンド | 用途 |
|---|---|
| セッションのライフサイクル | |
pd begin / pd done | セッションの開始/終了(エージェント登録を含む) |
pd whoami | 現在のエージェントとセッションのコンテキスト |
pd note / pd notes | 不変のノートを書き込む/読み取る |
| ポート管理 | |
pd claim / pd release | 決定論的なポートを取得/解放する |
pd find | ワイルドカードによるサービス検索(トライ木で高速化) |
| 調整 | |
pd lock / pd unlock | 分散ロック |
pd with-lock | ロックを取得してコマンドを実行し、自動で解放する |
pd pub / pd watch | パブ/サブメッセージング |
pd session files claim | アドバイザリーファイルの取得 |
| フリートとエージェント | |
pd fleet init | pd-fleet.yml と git フックを作成する |
pd fleet up/down/status | フリートを起動/停止/確認する |
pd spawn / pd spawned | バックグラウンドエージェントを起動/一覧表示する |
pd spawn kill | 起動したエージェントを終了する |
pd salvage | 停止したエージェントを復旧する |
| スウォームメモリ | |
pd tuple out/rd/in | タプルを書き込む/読み取る/取得する |
pd tuple scan/count | タプルを一覧表示/カウントする |
pd pheromone spray | エンティティに環境シグナルを設定する |
pd pheromone sniff | フェロモン値を読み取る(減衰を含む) |
pd pheromone list | 0 以外のフェロモンをすべて一覧表示する |
pd pheromone files | ファイルのヒートマップ |
| システム | |
pd status | デーモンの健全性 |
pd version | バージョンとコードハッシュ |
pd arbiter status | 不変条件の強制状況 |
pd arbiter violations | 記録された違反を一覧表示する |
pd dev start/stop/status | 分離された開発用デーモン(ポート 9877) |
判断マトリクス:状況に応じたツールの選択
| 問題 | 解決策 |
|---|---|
| 開発サーバーのポート競合 | pd claim myapp:api -q |
| 他のエージェントとの調整が必要 | pd begin + pd session files claim |
| エージェント間のシグナリング | pd pub + pd watch |
| 特定のエージェントへのダイレクトメッセージ | talk_to_agent MCP ツールまたは pd inbox send |
| バックグラウンドの自動化 | pd fleet init + pd fleet up |
| エージェント間で知識を共有する | pd tuple out / pd tuple rd |
| リソースの「活発さ」を追跡する | pd pheromone spray / sniff |
| ファイルの競合状況を一目で確認する | file_heat MCP ツールまたは pd pheromone files |
| クラッシュしたエージェントが作業を残した | pd salvage |
| 排他的な操作(デプロイ、マイグレーション) | pd with-lock |
| 離席中に起きたことを確認する | catch_me_up MCP ツール |
| 現在作業中の他のエージェントを確認する | swarm_awareness MCP ツール |
| 不変条件違反を確認する | pd arbiter status |
よくある問題
Port Daddy デーモンが起動していない
症状: どの pd コマンドでも Connection refused が表示される
対処法: pd start または pd install(launchd サービスとしてインストールされ、ログイン時に自動起動します)
ポートがすでに確保されています
症状: ポートは割り当てられますが、「間違った」ポートです
これは正しい動作です。 同じ ID なら、常に同じポートになります。別のポートが必要な場合は、myapp:api:main ではなく myapp:api:feature-x のように、異なる ID コンテキストを使用してください。
セッションがすでにアクティブです
症状: pd begin がセッションが存在すると表示します
対処方法: pd whoami を呼び出して現在のセッションを確認してください。古いセッションで pd done を実行するか、そのまま続けてください。
ファイルの確保が競合しています
症状: 別のエージェントが必要なファイルを確保しました
対処方法: これはシステムが正常に動作している状態です。pd swarm_awareness を確認して、誰が何を所有しているかを確認してください。pd pub で調整するか、別のファイルで作業してください。
IPC 接続エラー
症状: ログに IPC 関連のエラーが表示されます
対処方法: SDK は自動的に HTTP にフォールバックします。IPC は最適化のためのものであり、必須ではありません。~/.port-daddy/daemon.ipc が存在し、正しい権限が設定されていることを確認してください(ユーザーのみがアクセスできる権限で、デーモンによって作成されている必要があります)。
品質ゲート
PD を介した作業を「完了」と宣言する前に、以下を確認してください。
- エージェントが ID を登録している(
pd whoamiが ID を返す)。 - ファイルの確保対象が、実際に編集したファイルと一致している。
- 基本的なマイルストーンごとに、
progressノートが少なくとも 1 件ある。 - 作業が途中で終了する場合は、
handoffノートがある(引き継ぎやすい状態になっている)。 pd doneを呼び出している。セッションを開いたままにすることは、ドッグフーディングで最もよくある違反です。