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年9月23日 06:47
检测到的 SKILL.md 语言
英语
星标
523
分支
93

安装方式

默认使用会先检查来源的 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, live status, and // current Herdr workspace/tab/pane (or explicit not-hosted/unavailable state) ``` ### 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 and freshly resolved Herdr location | 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 list location instead of guessing For a Herdr-hosted session, `list` displays readable workspace and tab labels plus stable opaque IDs and a diagnostic pane ID. The workspace/tab values come from a fresh bounded Herdr snapshot for that list request, joined by the Pi session identity that remains stable when Herdr changes the workspace-qualified pane ID, so use them instead of inferring location from cwd or session name. `not under Herdr` means the session did not register a Herdr pane. `Herdr location unavailable` means it did register one, but the current snapshot failed or no longer contained that pane. Use `herdrLocation.paneId`, not the launch-time `herdrPaneId`, when current diagnostic pane metadata is needed. Do not use pane IDs as intercom addressing handles; target the session name or intercom session ID. If no connected session is Herdr-hosted, `list` does not call Herdr or add location lines. ### 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",
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看