Skip to main content

pi-intercom

Streamline session-to-session coordination with pi-intercom. Send messages, delegate tasks, and coordinate work across multiple pi sessions on the same machine. Use for planner-worker workflows, cross-session context sharing, and real-time collaboration between sessions.

설치로 이동

소스 정보

저장소
nicobailon/pi-intercom
최근 소스 활동
2026년 8월 30일 15:17
감지된 SKILL.md 언어
영어
스타
514
포크
88

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
pi-intercom
description
Streamline session-to-session coordination with pi-intercom. Send messages, delegate tasks, and coordinate work across multiple pi sessions on the same machine. Use for planner-worker workflows, cross-session context sharing, and real-time collaboration between sessions.
# Pi Intercom Skill Use this skill when you need to coordinate work across multiple pi sessions running on the same machine. Pi-intercom enables direct 1:1 messaging between sessions for delegation, context sharing, and collaborative workflows. When you are supervising `pi-subagents`, delegated child agents can escalate to you via `contact_supervisor` if `pi-subagents` supplied child bridge metadata. This skill covers how to handle those orchestrator-side escalations. ## When to Use - **Task delegation**: Split work between a planner session and worker sessions - **Context handoffs**: Send findings from a research session to an execution session - **Clarification loops**: Worker asks questions, planner answers, work continues - **Multi-session workflows**: Coordinate between specialized sessions (frontend/backend, research/implementation) - **Cross-codebase peer messages**: Message an explicit live peer in another project, or open a visible Herdr project pane when a long-lived conversation is needed ## Core Patterns ### Pattern 1: Planner-Worker Delegation The most common pattern. One session holds the big picture, others do hands-on work. **Setup** (in each session): ``` /alias planner # Terminal 1 /alias worker # Terminal 2 ``` **Planner delegates a task** (fire-and-forget): ```typescript intercom({ action: "send", to: "worker", message: "Task-3: Add retry logic to API client. Key files: src/api/client.ts. Ask if anything's unclear." }) ``` **Worker asks for clarification** (blocks until answer): ```typescript intercom({ action: "ask", to: "planner", message: "Should I use exponential backoff or fixed intervals?" }) // → Returns the planner's reply as the result ``` **Worker reports completion**: ```typescript intercom({ action: "ask", to: "planner", message: "Task-3 complete. Added exponential backoff (100ms → 1600ms, max 5 retries). Ready for task-4?" }) ``` ### Pattern 2: Quick Status Check Before sending, verify who's connected: ```typescript intercom({ action: "list" }) // → Shows all connected sessions with names, cwd, models, and live status (`idle`, `thinking`, `tool:<name>`) ``` ### Pattern 3: Reply Naturally When responding to an inbound ask, prefer `reply` instead of reconstructing raw IDs: ```typescript // In the turn triggered by the ask: intercom({ action: "reply", message: "Use exponential backoff starting at 100ms." }) // If replying later and there might be more than one pending ask: intercom({ action: "pending" }) intercom({ action: "reply", to: "planner", message: "Use exponential backoff starting at 100ms." }) ``` `reply` still preserves exact threading under the hood by sending the response with the original `replyTo` value. ### Pattern 4: Broadcast to Multiple Workers Send to multiple sessions in parallel: ```typescript const workers = ["worker-1", "worker-2", "worker-3"]; const task = "Check for null pointer exceptions in your assigned files"; // Fire-and-forget to all workers workers.forEach(w => intercom({ action: "send", to: w, message: task }) ); ``` ### Pattern 5: Send with Attachments Share code snippets, files, or context: ```typescript intercom({ action: "send", to: "worker", message: "Here's the fix for the auth issue:", attachments: [{ type: "snippet", name: "auth.ts", language: "typescript", content: `function validateUser(user: User | null) { if (!user) throw new Error("User required"); return user.email?.includes("@"); }` }] }) ``` ### Pattern 6: Cross-Codebase Peer Messages Use `to` alone to message any explicit live peer on the machine, even when it is in another codebase. Use `cwd` alone when there should be exactly one live peer in that repo. Use `to` plus `cwd` when the directory is a safety guard. ```typescript intercom({ action: "ask", cwd: "/path/to/other-repo", to: "workbench-agent", message: "Which module owns workbench source slices?" }) ``` Only open a Herdr project pane when you need a durable visible peer session in that repo. For bounded work, prefer `pi-subagents` with an explicit `cwd`; the child can use `contact_supervisor` for owner decisions and regular `intercom` for explicit peer coordination. ```typescript intercom({ action: "send", cwd: "/path/to/other-repo", openProjectPaneIfMissing: true, message: "Let's discuss the workbench API ergonomics in this repo." }) ``` If a live session already exists in that `cwd`, intercom reuses it. If multiple sessions are active there, pass `to` to select one by name or session ID. ### Pattern 7: Handle Subagent Escalations (Orchestrator Side) When `pi-subagents` spawns a delegated child and supplies child bridge metadata, that child can reach you through `contact_supervisor`. You receive a formatted message that includes run metadata: ``` **From subagent-worker-78f659a3-1** Subagent needs a supervisor decision. Run: 78f659a3 Agent: worker Child index: 0 Which API should I use? ``` **Reply using `reply`:** ```typescript // The reply hint in the incoming message will show the exact call: intercom({ action: "reply", message: "Use the stable v2 API." }) ``` This works because `reply` resolves the correct sender and message ID automatically. **Three types of escalations to expect:** | Type | What it means | How to respond | |------|---------------|----------------| | `need_decision` | Subagent is blocked and waiting for your answer. Uses the shared ask timeout: 10 minutes by default, configurable with `PI_INTERCOM_ASK_TIMEOUT_MS`. | Reply promptly with a clear decision. If you need more context, ask follow-up questions via `reply`. | | `interview_request` | Subagent needs multiple structured answers in one blocking exchange. Uses the shared ask timeout: 10 minutes by default, configurable with `PI_INTERCOM_ASK_TIMEOUT_MS`. | Reply with plain JSON or a fenced `json` block using the provided `{ "responses": [...] }` shape. | | `progress_update` | Subagent is sharing meaningful progress or a plan-changing discovery. Not blocking. | Read and acknowledge. No reply required unless you want to redirect. | **When a subagent asks:** ```typescript // In the turn triggered by the incoming ask: intercom({ action: "reply", message: "Use exponential backoff, max 3 retries." }) ``` **When a subagent sends an interview request:** Read the rendered questions in the incoming message and reply with the exact ids in JSON. `info` questions are context-only and do not need response entries: ```typescript intercom({ action: "reply", message: "```json\n{\n \"responses\": [\n { \"id\": \"api\", \"value\": \"Stable API\" },\n { \"id\": \"constraints\", \"value\": \"Keep the public error shape unchanged.\" }\n ]\n}\n```" }) ``` **If you receive multiple pending asks from different subagents:** ```typescript intercom({ action: "pending" }) // → Shows all unresolved inbound asks with sender, elapsed time, and preview intercom({ action: "reply", to: "subagent-worker-78f659a3-1", message: "Use the v2 API." }) ``` **Important:** Only sessions where `pi-subagents` supplied child bridge metadata get the `contact_supervisor` tool. Normal sessions use the regular `intercom` tool. If you see the formatted supervisor decision/progress update message, treat it as a `contact_supervisor` escalation. A subagent may use regular `intercom` for peer coordination, including peers in other directories, but owner decisions and new visible project panes should go through the supervisor. ## Key Differences | Action | Behavior | Use When | |--------|----------|----------| | `send` | Fire-and-forget; infers the sole pending ask as its reply | You don't need a response | | `ask` | Blocks until reply (10 min default, configurable with `PI_INTERCOM_ASK_TIMEOUT_MS`) | You need an answer to continue | | `reply` | Responds to the active or pending inbound ask | You were asked something and need to answer naturally | | `pending` | Lists unresolved inbound asks | You need to see who is waiting before replying | | `list` | Returns all sessions with live status | You need to discover targets or choose an idle peer | | `status` | Returns your connection state | Troubleshooting | ## Visible Peer Sessions For bounded cross-codebase work, prefer `pi-subagents` with an explicit `cwd`. Use `intercom({ action: "send", cwd: "/path", openProjectPaneIfMissing: true, ... })` only when a long-lived visible peer session is useful. If Herdr is unavailable, do not invent a terminal fallback inside this workflow. Ask the user before opening another visible surface manually. ## Important Constraints ### `ask` Limitations - **Connected targets only**: `ask` fails immediately when the target is not in the live intercom roster. Use `list` before asking when liveness is uncertain; use `send` for non-blocking mailbox delivery. - **Configurable timeout**: If no reply arrives before the shared ask timeout, the ask fails. The default is 10 minutes; set `PI_INTERCOM_ASK_TIMEOUT_MS` to a positive millisecond value to change it. - **One at a time**: Cannot have multiple pending asks from the same session - **Cannot self-target**: A session cannot ask itself, including through disconnected-mailbox remapping ```typescript // Check if already waiting before asking const result = await intercom({ action: "ask", to: "planner", message: "..." }); if (result.isError && result.content[0].text.includes("Already waiting")) { // Use send instead, or wait for current ask to complete } ``` ### `send` Behavior - **No timeout**: Message is delivered or fails immediately - **Sole pending ask inference**: If the destination has exactly one pending inbound ask, `send` attaches its `replyTo` and reports `Reply sent to <target> (inferred from pending ask)` - **Ambiguity stays unthreaded**: Zero or multiple matching asks leave the send as an ordinary message - **Confirmation dialogs**: If `confirmSend: true` in config, interactive sessions confirm ordinary and inferred sends - **Explicit replies skip confirmation**: A caller-supplied `replyTo` skips the dialog ## Best Practices ### Use `ask` for blocking workflows When the worker needs information to proceed: ```typescript // GOOD: Worker blocks until planner responds const reply = await intercom({ action: "ask", to: "planner", message: "API rate limit is 100/min. Should I implement client-side throttling or batching?" }); // Continue with the answer... ``` ### Use `send` for notifications When you just want to inform: ```typescript // GOOD: Fire-and-forget notification intercom({ action: "send", to: "reviewer", message: "PR #123 is ready for review. Key changes in auth.ts." }); // Continue immediately, don't wait ``` ### Name sessions meaningfully Use `/alias` so others can target you easily. It names the current session and is shown in intercom lists, send/reply results, overlays, and incoming headers: ``` /alias api-worker /alias frontend-dev /alias planner ``` ## Error Handling ### Common Errors and Solutions **"Already waiting for a reply"** ```typescript // You can only have one pending ask at a time // Option 1: Use send instead intercom({ action: "send", to: "planner", message: "..." }); // Option 2: Wait for current ask to complete first ``` **"Cannot message the current session"** ```typescript // You cannot target yourself // This usually means you confused session names - double-check the target ``` **"Session not found"** ```typescript const result = await intercom({ action: "send", to: "worker", message: "..." }); if (!result.delivered) { console.log("Failed:", result.reason); // → "Session not found" - check the name and list available sessions await intercom({ action: "list" }); } ``` Replies to recently disconnected explicitly named senders can be queued by the broker and delivered if that sender reconnects with the same name and directory. Runtime-only `subagent-chat-...` aliases are not reconnect identities. New `send` calls may target a known live or recently disconnected session; blocking `ask` calls require a live target. **Ask timeout** ```typescript // The ask will reject with a timeout error // Default: 10 minutes // Override: set PI_INTERCOM_ASK_TIMEOUT_MS to a positive millisecond value // For longer tasks, use send + follow-up ask pattern ``` ## Troubleshooting ### Session not appearing in list 1. Check intercom is enabled: `intercom({ action: "status" })` 2. Verify the target session has loaded pi-intercom 3. Ensure both sessions are on the same machine (intercom is same-machine only) ### Message not delivered ```typescript const result = await intercom({ action: "send", to: "worker", message: "..." }); if (!result.delivered) { console.log("Failed:", result.reason); // → "Session not found" or delivery failure reason } ``` ### Connection lost Sessions automatically reconnect if the broker restarts. If persistently disconnected: ```typescript intercom({ action: "status" }) // Check if broker is running and restart if needed ``` ## Common Workflows ### Research → Implementation Handoff ```typescript // Research session finds relevant code intercom({ action: "send", to: "impl-session", message: "Found the bug. The issue is in validateUser() - it doesn't check for null.", attachments: [{ type: "snippet", name: "validate.ts", language: "typescript", content: `// Line 45-52 - missing null check function validateUser(user: User) { return user.email?.includes("@"); // crashes if user is null }` }] }); ```
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기