@polygraph/claude-plugin 0.4.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,681 @@
1
+ ---
2
+ name: polygraph
3
+ description: Guidance for coordinating changes across multiple repositories using Polygraph. Use when working on a feature that affects another repository, coordinating changes/branches/PRs across repos, delegating tasks to child agents in different repos, discovering how code is consumed across repositories, or starting a multi-repo coordination session. TRIGGER when user mentions "polygraph", "other repos", "other repositories", "who uses this", "what uses this", "cross-repo", "multi-repo", "consuming this API/endpoint", "dependent repositories", or asks about what other repos are doing with shared code/APIs/endpoints.
4
+
5
+ allowed-tools:
6
+ - mcp__plugin_polygraph_polygraph-mcp
7
+
8
+ ---
9
+
10
+ # Multi-Repo Coordination with Polygraph
11
+
12
+ **IMPORTANT:** NEVER `cd` into cloned repositories or access their files directly. ALWAYS use the `spawn_agent` tool to perform work in other repositories.
13
+
14
+ This skill provides guidance for working on features that span multiple repositories using Polygraph for coordination.
15
+
16
+ ## Available Tools
17
+
18
+ Polygraph functionality is available via both MCP tools and CLI commands. Use whichever is available in your current environment.
19
+
20
+ | MCP Tool | CLI Equivalent | Description |
21
+ | --- | --- | --- |
22
+ | `list_repos` | `polygraph repo list` | Discover candidate repositories with descriptions and graph relationships |
23
+ | `start_session` | `polygraph session start --repo <ids>` | Initialize a Polygraph session with selected repositories |
24
+ | `spawn_agent` | — | Start a new child task or send an explicit follow-up to an active task in another repository. Input: `{ sessionId, repo, instruction, context?, taskId? }`. Output: `{ taskId, message, status: 'delegated' }`. Pass the `taskId` returned by a prior call to route a follow-up message to a specific active task; omit to start a new child run. A session resume or reconstruction is read-only context restoration; after resuming, do not use `spawn_agent` to continue changes unless the user explicitly asks for changes. |
25
+ | `show_agent` | — | Poll flat per-child status for the session. Output: `{ children: PolygraphChildStatusItem[] }` where each item exposes `repositoryId`, `repoFullName`, `status`, `lastOutputLines`, `durationMs`, `instruction`, `agentType?`, `inputRequiredQuestion?`. `status` is an AcpRunStatus: `'created' \| 'in-progress' \| 'input-required' \| 'completed' \| 'failed' \| 'cancelled'` (British double-L on `'cancelled'`). `inputRequiredQuestion` is populated only when `status === 'input-required'`. |
26
+ | `stop_agent` | — | Cancel an in-progress child. Output: `{ taskId, state: 'cancelled', sessionPreserved: true, output, message }`. Because `sessionPreserved: true`, the preserved agent session can be restored later for context, but resume must wait for explicit user instructions before making changes. |
27
+ | `push_branch` | — | Push a local git branch to the remote repository |
28
+ | `create_pr` | — | Create draft PRs with session metadata linking related PRs |
29
+ | `show_session` | `polygraph session show <id> [--details]` | Query status of the current session. Use details when session summary, repo IDs, PR URLs, and PR descriptions are needed. |
30
+ | `update_session_description` | `polygraph session update-description` | Set the current session description from a synthesized progress summary or user-provided text. This updates session metadata only; it does not require PR creation or mark-ready. |
31
+ | `link_reference` | — | Link an external reference to a session. |
32
+ | `mark_pr_ready` | — | Mark draft PRs as ready for review |
33
+ | `associate_pr` | — | Associate an existing PR with a session |
34
+ | `add_repo` | — | Add repositories to a running Polygraph session. For explicit refs, pass the refs directly and skip `list_repos`. |
35
+ | `complete_session` | `polygraph session archive <id>` | Mark a session complete |
36
+ | `get_ci_logs` | — | Retrieve full plain-text log for a specific CI job |
37
+ | — | `polygraph auth login [--token]` | Authenticate with Polygraph (use `--token` for headless/CI) |
38
+ | — | `polygraph session list` | List all sessions |
39
+ | — | `polygraph account list` / `polygraph account select` | Organization management |
40
+ | — | `polygraph whoami` | Show current auth status and org |
41
+
42
+ **Delegation rules:** `list_repos` and `start_session` MUST be called via the `polygraph-init-subagent` as described in step 0. Direct `add_repo` is allowed only when the user provides exact repo refs for an existing session. `spawn_agent` and `show_agent` MUST ALWAYS be called via background Task subagents (`run_in_background: true`) as described in the delegation sections below — NEVER call them directly in the main conversation.
43
+
44
+ ## CLI Statefulness
45
+
46
+ The Polygraph CLI (`polygraph`) is **stateful**. When you select an organization — via `polygraph account select` or the equivalent MCP tool — that selection is saved globally and all subsequent CLI commands and MCP tool calls operate against it. You do not need to pass the org on every command.
47
+
48
+ ## Setup
49
+
50
+ Before using Polygraph tools, ensure the CLI is authenticated and an organization is selected.
51
+
52
+ ### Check Authentication
53
+
54
+ Use `polygraph whoami` (or the `whoami` MCP tool) to check if the user is currently logged in and which organization is active.
55
+
56
+ - If the user **is logged in** and an org is selected → proceed to the workflow.
57
+ - If the user **is not logged in** → use `polygraph auth login` (or the `login` MCP tool) to authenticate. After login, an organization must be selected.
58
+
59
+ ### Select Organization
60
+
61
+ After logging in (or if logged in but no org is selected), use `polygraph account select` (or the equivalent MCP tool) to choose the organization that future commands will run against.
62
+
63
+ ## Workflow Overview
64
+
65
+ 0. **Initialize or join Polygraph session** - If you were spawned inside an existing session (the startup banner names a session ID), reuse it. Call `show_session` first; if it already has repos and the user did not ask to add more, you're done. If the user asks to add exact repo refs, call `add_repo` directly with those refs and skip candidate discovery. If the session has no repos and no exact refs were provided, launch the `polygraph-init-subagent` with that `sessionId` so it discovers candidates and uses `add_repo` (NOT `start_session`). Only when there is no session ID at all should the init subagent create a new session.
66
+ 1. **Delegate work to each repo** - Use the `polygraph-delegate-subagent` to start child agents in other repositories. Choose the Simple (fire-and-forget) or Multi-turn (interactive) pattern described below based on whether the child may need clarification.
67
+
68
+ 4. **Monitor child agents** - Use `show_agent` to poll progress and read the flat `children[]` array for each child's `status` and `lastOutputLines`.
69
+ 5. **Stop child agents** (if needed) - Use `stop_agent` to cancel an in-progress child agent. The underlying agent session is preserved for later read-only context restoration; after a resume, wait for explicit user instructions before making changes.
70
+ 6. **Push branches** - Use `push_branch` after making commits.
71
+ 7. **Update session description** (optional) - Use `update_session_description` to set the current session description from a progress summary or user-provided text that follows the Session Description Policy. This is independent of PR creation or mark-ready.
72
+ 8. **Create draft PRs** - Use `create_pr` to create linked draft PRs. Pass `description` only when you are already creating PRs and can provide session context that follows the Session Description Policy.
73
+ 9. **Associate existing PRs** (optional) - Use `associate_pr` to link PRs created outside Polygraph.
74
+ 10. **Query PR status** - Use `show_session` to check progress.
75
+ 11. **Mark PRs ready** - Use `mark_pr_ready` when work is complete.
76
+ 12. **Complete session** - Use `complete_session` to mark the session as completed when the user requests it.
77
+
78
+ ## Step-by-Step Guide
79
+
80
+ ### 0. Initialize or Join Polygraph Session
81
+
82
+ There are three cases. Pick exactly one before calling any tool.
83
+
84
+ **Hard rule: if a session ID is already in scope (e.g., the startup banner says "You're in Polygraph session …", or the user passed one), that session ID is authoritative for this entire conversation. NEVER call `start_session` — doing so creates a brand-new session and orphans the one the parent harness is pointed at. Reuse the existing session via `show_session` and, if needed, `add_repo`.**
85
+
86
+ **Case A — Existing session, already has repos.** Call `show_session` directly with the known session ID. Skip the init subagent entirely. Print the session details (format below) and proceed.
87
+
88
+ **Case B — Existing session, no repos yet (or user wants to add more).** If the user gives exact repo refs by ID, short name, full name, GitHub `owner/repo` slug, or URL-like slug, call `add_repo(sessionId, repoIds: [...])` directly with those refs. Do NOT call `list_repos`, do NOT ask for candidates, and do NOT launch the init subagent just to resolve those refs. If the user wants discovery/filtering instead, launch the `polygraph-init-subagent`, passing both the existing `sessionId` and `userContext`. The subagent will discover candidates, select relevant repositories, and call `add_repo` against the existing session — it will NOT call `start_session`.
89
+
90
+ **Case C — No session at all.** Launch the `polygraph-init-subagent` with only `userContext` (no `sessionId`). The subagent will discover candidates and call `start_session` to create a new session.
91
+
92
+ In case B, call `add_repo` yourself when exact repo refs were provided; otherwise the subagent handles discovery and attachment. In case C the subagent handles session creation. In case A you call `show_session` yourself.
93
+
94
+ **Session ID handling:**
95
+
96
+ - For a new session (case C), `start_session` auto-generates a unique session ID. You do NOT need to pass one.
97
+ - For cases A and B, the session ID already exists; reuse it everywhere — never let `start_session` run in this conversation.
98
+
99
+ **Launch the init subagent** (cases B and C — skip in case A):
100
+
101
+ ```
102
+ Task(
103
+ subagent_type: "polygraph-init-subagent",
104
+ description: "Init Polygraph session",
105
+ prompt: """
106
+ Parameters:
107
+ - sessionId: "<existing-session-id-or-omit-for-new-session>"
108
+ - userContext: "<description of what the user wants to do>"
109
+
110
+ If sessionId is provided, reuse that session and use add_repo to attach repositories — do NOT call start_session. If exact repo refs were provided, pass them directly to add_repo and do NOT call list_repos. If discovery is needed, discover candidates and select relevant repos. If sessionId is omitted, create a new session via start_session. Return a structured summary.
111
+ """
112
+ )
113
+ ```
114
+
115
+ Omit the `sessionId` line for case C. Include it (with the existing session ID) for case B.
116
+
117
+ The subagent will:
118
+
119
+ 1. Use exact repo refs directly when provided for an existing session; otherwise call `list_repos` to discover available repositories
120
+ 2. Select relevant repos based on the user context (or include all if uncertain)
121
+ 3. Either call `start_session` (case C, no `sessionId`) or call `add_repo` against the existing session (case B). It will never call `start_session` when a `sessionId` was provided.
122
+ 4. Call `show_session` to retrieve session details
123
+ 5. Return a summary with session URL and repo info
124
+
125
+ **Case C only — new session just created:** After the init subagent completes and creates the new session, render the session welcome card (skip the session-details block below for this case). Prefer the `session_intro` MCP tool — call it with the session ID; it returns the card as markdown. If that tool is unavailable, run `polygraph session intro -s <sessionId>` via the CLI instead. Either way, print the result to the user verbatim as markdown — do NOT wrap it in a code block or reformat it (the logo is pre-fenced; the rest is live markdown). It needs no other input, and you do not need to call `show_session` first. Then continue (ask the user what they want, or start the requested task).
126
+
127
+ **After receiving the subagent's summary (Case B) or after calling `show_session` for an existing session (Case A), print the session details:**
128
+
129
+ **Session:** POLYGRAPH_SESSION_URL
130
+
131
+ **Repositories in this session:**
132
+
133
+ - REPO_FULL_NAME
134
+
135
+ - REPO_FULL_NAME: from the session repository entries
136
+ - POLYGRAPH_SESSION_URL: from `polygraphSessionUrl`
137
+
138
+ ### Explore an Existing Session
139
+
140
+ Use this workflow when the user gives a Polygraph session ID and asks to understand, resume, inspect, or investigate prior work.
141
+
142
+ **Resume is not a work command.** If the user's intent is to resume, reconnect, or reconstruct a prior Polygraph session, fetch and summarize the restored context, then stop. Do not edit files, push branches, add repos, delegate new work, or continue previous changes until the user explicitly asks for changes. Treat "resume" as context restoration followed by waiting for user instructions.
143
+
144
+ 1. Fetch detailed session context:
145
+ - Prefer `show_session` with `details: true` when the MCP tool exposes that option.
146
+ - Otherwise run `polygraph session show --details <session-id>`.
147
+ 2. Treat the detailed output as authoritative context. It should include:
148
+ - `<summary>` — the session summary.
149
+ - `<repositories>` — relevant repos, including each repo's `<id>` and `<name>`.
150
+ - `<pullRequests>` — relevant PRs, including `<url>`, `<repoId>`, `<repoName>`, branch metadata, and `<description>`.
151
+ 3. Parse the XML-style blocks and XML-unescape text inside `<summary>` and `<description>`.
152
+ 4. Build a repo/PR map:
153
+ - repo id
154
+ - repo full name
155
+ - PR URL
156
+ - branch
157
+ - base branch
158
+ - title
159
+ - status
160
+ - PR description
161
+ 5. If the request was resume/reconnect/reconstruct only, report the restored session context and wait for the user's next instruction.
162
+ 6. If the user explicitly asked to inspect or investigate prior work, use the PR descriptions and session summary to decide whether more repo investigation is needed.
163
+ 7. If the repo to investigate is already part of the session, delegate directly to that repo.
164
+ 8. If the repo to investigate is not currently initialized in the session, and either the user provided an exact repo ref or the repo appears in `<repositories>`, call `add_repo` with that ref or repo `<id>` directly. Do not call `list_repos` just to resolve the repo.
165
+ 9. After `add_repo`, call `show_session` again to verify the repo was added, then delegate to that repo.
166
+ 10. Fall back to `list_repos` only when the desired repo is not an exact ref and is missing from `<repositories>`, or when the details output came from an older Polygraph version that did not include repo IDs.
167
+
168
+ When delegating investigation from a PR, include the PR context in the child instruction:
169
+
170
+ ```
171
+ Session: <session-id>
172
+ Repo: <repoName>
173
+ Repo ID: <repoId>
174
+ PR: <url>
175
+ Branch: <branch>
176
+ Base branch: <baseBranch>
177
+ Description:
178
+ <description>
179
+
180
+ Inspect the PR commits/diff and investigate the requested behavior. Report findings with file paths and concrete evidence.
181
+ ```
182
+
183
+ ## Simple tasks (fire-and-forget)
184
+
185
+ Use this pattern when the task is well-defined and the child is not expected to need clarification. It is a single-round delegation: kick it off, poll until terminal, then push branch + create PR.
186
+
187
+ **CRITICAL:** `spawn_agent` and `show_agent` MUST ALWAYS be called via background Task subagents (`run_in_background: true`), NEVER directly from the main conversation. Direct calls flood the context window with polling noise and degrade the user experience. This is a hard requirement, not a suggestion.
188
+
189
+ 1. Launch a background `Task` subagent per repo using `polygraph-delegate-subagent`. The subagent calls `spawn_agent`, then polls `show_agent` on backoff until terminal.
190
+
191
+ ```
192
+ Task(
193
+ subagent_type: "polygraph-delegate-subagent",
194
+ run_in_background: true,
195
+ description: "Delegate to <repo-name>",
196
+ prompt: """
197
+ Parameters:
198
+ - sessionId: "<session-id>"
199
+ - repo: "<org/repo-name>"
200
+ - instruction: "<the task instruction>"
201
+ - context: "<optional context>"
202
+
203
+ Delegate the work, poll for completion, and return a structured summary.
204
+ """
205
+ )
206
+ ```
207
+
208
+ 2. Delegate to multiple repos in parallel by launching multiple background Task subagents at the same time. Read the output files later to check progress.
209
+ 3. For each child, the subagent watches `child.status` in the flat `children[]` response and exits when it sees a terminal status — typically `'completed'` or `'failed'` (and `'cancelled'` if it was stopped).
210
+ 4. Once all background subagents report a terminal status, continue to `push_branch` + `create_pr`.
211
+
212
+ In rare cases where you need to check the raw child agent status directly (e.g., debugging a stuck subagent), you may call `show_agent` as a one-off tool call. Do NOT use this for regular polling — that MUST happen in background subagents.
213
+
214
+ Use Simple when the task is well-defined and the child will not need clarification.
215
+
216
+ ## Multi-turn tasks (interactive)
217
+
218
+ Use this pattern when the child may need clarification, the task is exploratory, or interactive collaboration is desired. The orchestrator exposes paused children via the `'input-required'` status.
219
+
220
+ 1. Call `spawn_agent` with the initial `instruction`. Parse the response:
221
+
222
+ ```json
223
+ { "taskId": "…", "message": "…", "status": "delegated" }
224
+ ```
225
+
226
+ Store the returned `taskId`. You will pass it back on any follow-up turn so the orchestrator routes the message to the same active task instead of starting a new run.
227
+
228
+ 2. Poll `show_agent`. The response shape is `{ children: PolygraphChildStatusItem[] }`. For each child, inspect:
229
+
230
+ - `child.status` — one of `'created'`, `'in-progress'`, `'input-required'`, `'completed'`, `'failed'`, `'cancelled'` (British double-L on `'cancelled'`).
231
+ - `child.inputRequiredQuestion` — populated only when `child.status === 'input-required'`.
232
+ - `child.lastOutputLines` — recent log tail.
233
+ - `child.repoFullName` — which repo is talking.
234
+
235
+ Drive the state machine:
236
+
237
+ - `child.status === 'in-progress'` or `'created'` — continue polling.
238
+ - `child.status === 'input-required'` — read `child.inputRequiredQuestion`, surface it to the user verbatim (e.g. "The child agent in `{child.repoFullName}` needs input: {child.inputRequiredQuestion}"), get the answer, then call `spawn_agent` again with `taskId: <stored taskId>` and `instruction: <answer>`. Continue polling.
239
+ - `child.status === 'completed'` — read `child.lastOutputLines`, proceed to `push_branch` + `create_pr`.
240
+ - `child.status === 'failed'` — read `child.lastOutputLines`, surface the failure.
241
+ - `child.status === 'cancelled'` — the child was stopped via `stop_agent`; see below.
242
+
243
+ 3. To abort mid-flight, call `stop_agent` with `{ sessionId, repo }`. The response is:
244
+
245
+ ```json
246
+ {
247
+ "taskId": "…",
248
+ "state": "cancelled",
249
+ "sessionPreserved": true,
250
+ "output": "…",
251
+ "message": "…"
252
+ }
253
+ ```
254
+
255
+ Because `sessionPreserved: true`, the preserved agent session can be restored later for context. After resuming, do not make changes or continue prior work until the user explicitly asks for changes.
256
+
257
+ Use Multi-turn when the child may need clarification, the task is exploratory, or interactive collaboration is desired. Otherwise use Simple.
258
+
259
+ <!-- Claude and Codex parents handle permission gates via the native MCP elicitation dialog
260
+ rendered by polygraph-mcp's show_agent handler. The dialog targets the parent harness's
261
+ own UI, NOT this agent. From the agent's vantage point the gate is transient: a
262
+ `show_agent` poll may briefly see `permission-required` between the child opening the
263
+ gate and the user picking in the dialog. The agent must NOT resolve it itself. -->
264
+ ## Handling permission requests
265
+
266
+ Your MCP client supports the native permission dialog. When a child agent requests permission, the dialog renders directly in your UI and the user picks — the decision routes back through `polygraph-mcp` automatically.
267
+
268
+ **Critical: do NOT call `allow_agent` or `deny_agent` yourself.** If `show_agent` (or `cloud_polygraph_child_status`) briefly reports a child in `permission-required` state with `pendingPermission` populated, that is a transient state the dialog is in the middle of resolving. Your job is to keep polling — the next poll will see the child back in `in-progress` (or `failed` / `cancelled` if the user denied or dismissed).
269
+
270
+ If you call `allow_agent` while the dialog is already open, you create a race: the user's pick lands first and the explicit allow fails with `Task <id> is in state 'completed', not 'permission-required'`. The child receives the user's choice; your call is wasted work.
271
+
272
+ The `allow_agent` and `deny_agent` tools exist for parents whose MCP clients do NOT advertise elicitation capability (opencode TUI today). They are not part of your flow.
273
+
274
+ ### 2. Push Branches
275
+
276
+ Once work is complete in a repository, push the branch using `push_branch`. This must be done before creating a PR.
277
+
278
+ **Parameters:**
279
+
280
+ - `sessionId` (required): The Polygraph session ID
281
+ - `repo` (required): Repository name or repository ID to push from
282
+ - `branch` (required): Branch name to push to remote
283
+
284
+ ```
285
+ push_branch(
286
+ sessionId: "<session-id>",
287
+ repo: "org/repo-name",
288
+ branch: "polygraph/ad5fa-add-user-preferences"
289
+ )
290
+ ```
291
+
292
+ ### Session Description Policy
293
+
294
+ `description` is user-facing Polygraph session context.
295
+
296
+ The same policy applies anywhere a Polygraph tool accepts `description`, including `create_pr`, `associate_pr`, and `update_session_description`.
297
+
298
+ If you pass `description`, use the canonical structured format:
299
+
300
+ ```text
301
+ Goal: <what the session is trying to accomplish>
302
+
303
+ Current Progress: <what has been completed so far, including PR/session state when relevant>
304
+
305
+ What Worked: <important decisions, approaches, or constraints that future agents should preserve>
306
+
307
+ Next Steps: <clear next implementation steps>
308
+ ```
309
+
310
+ - Do not use a one-line feature summary for final handoff or PR creation in a multi-repo session.
311
+ - Keep it concise but durable for a future resumed agent.
312
+ - Prefer high-level state over file-by-file changelogs.
313
+ - Mention unresolved decisions or risks when they matter.
314
+ - In `Next Steps`, include only next implementation steps. Do not list routine operational steps such as pushing branches, watching CI, or marking PRs ready.
315
+
316
+ > **Tip (optional):** The Polygraph UI renders fenced ` ```mermaid ` blocks in the session description as diagrams. If a small diagram would genuinely clarify the session state — for example, cross-repo relationships or a sequence of changes — you may include one. Plain text remains the norm; diagrams are never required.
317
+
318
+ ### 3. Create Draft PRs
319
+
320
+ Create PRs for all repositories at once using `create_pr`. PRs are created as drafts with session metadata that links related PRs across repos. Branches must be pushed first. For fork PR creation or registration, include `targetRepository` on the PR spec to identify the repository that should receive the PR.
321
+
322
+ **Parameters:**
323
+
324
+ - `sessionId` (required): The Polygraph session ID
325
+ - `prs` (required): Array of PR specifications, each containing:
326
+ - `owner` (required): GitHub repository owner
327
+ - `repo` (required): GitHub repository name
328
+ - `title` (required): PR title
329
+ - `body` (required): PR description (session metadata is appended automatically)
330
+ - `branch` (required): Branch name that was pushed
331
+ - `targetRepository` (optional): Target GitHub repository for fork PR creation or registration, as `owner/repo`. Omit for same-repository PRs.
332
+ - `description` (optional): Optional. If supplied, it must follow the Session Description Policy.
333
+
334
+ **PR title format (applies to parent and child agents):**
335
+
336
+ - PR titles become squash-merge commit messages in most repos. They MUST follow the target repo's commit convention (e.g., Conventional Commits: `<type>(<scope>): <subject>`).
337
+ - Do NOT add agent-identifier prefixes such as `[codex]`, `[claude]`, or `[opencode]` to PR titles. These prefixes violate commit-lint rules and pollute the git history.
338
+
339
+ ```
340
+ create_pr(
341
+ sessionId: "<session-id>",
342
+ prs: [
343
+ {
344
+ owner: "org",
345
+ repo: "frontend",
346
+ title: "feat: Add user preferences UI",
347
+ body: "Part of multi-repo user preferences feature",
348
+ branch: "polygraph/ad5fa-add-user-preferences"
349
+ },
350
+ {
351
+ owner: "org",
352
+ repo: "backend",
353
+ title: "feat: Add user preferences API",
354
+ body: "Part of multi-repo user preferences feature",
355
+ branch: "polygraph/ad5fa-add-user-preferences"
356
+ }
357
+ ]
358
+ )
359
+ ```
360
+
361
+ For fork PR creation or registration, keep `owner` and `repo` set to the source repository that owns the pushed branch and set `targetRepository` to the target repository:
362
+
363
+ ```
364
+ create_pr(
365
+ sessionId: "<session-id>",
366
+ prs: [
367
+ {
368
+ owner: "contributor",
369
+ repo: "frontend-fork",
370
+ targetRepository: "org/frontend",
371
+ title: "feat: Add user preferences UI",
372
+ body: "Part of multi-repo user preferences feature",
373
+ branch: "polygraph/ad5fa-add-user-preferences"
374
+ }
375
+ ]
376
+ )
377
+ ```
378
+
379
+ **After creating PRs**, always print the Polygraph session URL:
380
+
381
+ ```
382
+ **Polygraph session:** POLYGRAPH_SESSION_URL
383
+ ```
384
+
385
+ ### 4. Get Current Polygraph Session
386
+
387
+ Check the details of a session using `show_session` or `polygraph session show --details <session-id>`. Returns the full session state including repositories, PRs, CI status, and the Polygraph session URL.
388
+
389
+ **Parameters:**
390
+
391
+ - `sessionId` (required): The Polygraph session ID
392
+
393
+ **Returns:**
394
+
395
+ - `session.sessionId`: The session ID
396
+ - `session.polygraphSessionUrl`: URL to the Polygraph session UI
397
+ - `session.description`: DescriptionItem[] timeline describing the session.
398
+ - `session.agentSessionId`: The agent CLI session ID — captured automatically by the MCP server (null if no agent has run yet).
399
+ - `session.linkedReferences`: Array of references linked to this session
400
+ - Session repository entries: Array of connected repositories, each with:
401
+ - `id`: Repository ID
402
+ - `name`: Repository name
403
+ - `defaultBranch`: Default branch (e.g., `main`)
404
+ - `vcsConfiguration.repositoryFullName`: Full repo name (e.g., `org/repo`)
405
+ - `vcsConfiguration.provider`: VCS provider (e.g., `GITHUB`)
406
+ - description field: AI-generated description of what this repository does (may be null)
407
+ - `initiator`: Whether this repository initiated the session
408
+ - `session.dependencyGraph`: Graph of repository dependency `edges`
409
+ - `session.pullRequests[]`: Array of PRs, each with:
410
+ - `url`: PR URL
411
+ - `branch`: Branch name
412
+ - `baseBranch`: Target branch
413
+ - `title`: PR title
414
+ - `status`: One of `DRAFT`, `OPEN`, `MERGED`, `CLOSED`
415
+ - `repoId`: Associated repository ID
416
+ - `relatedPRs`: Array of related PR URLs across repos
417
+ - `session.ciStatus`: CI pipeline status keyed by PR ID, each containing:
418
+ - `status`: One of `SUCCEEDED`, `FAILED`, `IN_PROGRESS`, `NOT_STARTED` (null if no CIPE and no external CI)
419
+ - `cipeUrl`: URL to the CI pipeline execution details (null if no CIPE)
420
+ - `completedAt`: Epoch millis timestamp, set only when the CIPE has completed (null otherwise)
421
+ - `selfHealingStatus`: The self-healing fix status string from Nx Cloud's AI fix feature (null if no AI fix exists)
422
+ - `externalCIRuns`: Array of external CI runs (present when no CIPE but external CI data exists, e.g., GitHub Actions). Each run contains:
423
+ - `runId`: GitHub Actions run ID
424
+ - `name`: Workflow name
425
+ - `status`: Run status (`completed`, `in_progress`, `queued`)
426
+ - `conclusion`: Run conclusion (`success`, `failure`, `cancelled`, `timed_out`, or null)
427
+ - `url`: GitHub Actions run URL
428
+ - `jobs`: Array of jobs in the run, each with:
429
+ - `jobId`: Job ID (use with `get_ci_logs`)
430
+ - `name`: Job name
431
+ - `status`: Job status
432
+ - `conclusion`: Job conclusion (or null)
433
+
434
+ ```
435
+ show_session(sessionId: "<session-id>")
436
+ ```
437
+
438
+ ### Linked References
439
+
440
+ Use `link_reference` to link an external reference to the current Polygraph session.
441
+
442
+ **Parameters:**
443
+
444
+ - `sessionId` (required): The Polygraph session receiving the linked reference
445
+ - `reference` (required): Reference metadata with `type`, `url`, and `label`
446
+ - `reference.sessionId` (session references only): The referenced Polygraph session ID when `reference.type` is `session`
447
+
448
+ When an external resource is mentioned during a Polygraph session and appears relevant to the current work, the parent agent should record it with `link_reference({ sessionId, reference })`. This applies to relevant external resources such as pull requests, GitHub issues, other Polygraph sessions, and Linear issues.
449
+
450
+ Invoke the MCP tool with a single object containing `{ sessionId, reference }`. For example, to record a relevant pull request:
451
+
452
+ ```
453
+ link_reference({
454
+ sessionId: "<current-session-id>",
455
+ reference: {
456
+ type: "github_pr",
457
+ url: "https://github.com/nrwl/polygraph-skills/pull/123",
458
+ label: "Implementation PR"
459
+ }
460
+ })
461
+ ```
462
+
463
+ To record a relevant Polygraph session, use the same invocation shape and include `reference.sessionId`:
464
+
465
+ ```
466
+ link_reference({
467
+ sessionId: "<current-session-id>",
468
+ reference: {
469
+ type: "session",
470
+ url: "https://polygraph.example/s/<inspected-session-id>",
471
+ label: "Inspected Polygraph session",
472
+ sessionId: "<inspected-session-id>"
473
+ }
474
+ })
475
+ ```
476
+
477
+ The canonical MCP parameters are `{ sessionId, reference }`. There is no unlink command.
478
+
479
+ ### 5. Mark PRs Ready
480
+
481
+ Once all changes are verified and ready to merge, use `mark_pr_ready` to transition PRs from DRAFT to OPEN status.
482
+
483
+ **Parameters:**
484
+
485
+ - `sessionId` (required): The Polygraph session ID
486
+ - `prUrls` (required): Array of PR URLs to mark as ready for review
487
+
488
+ ```
489
+ mark_pr_ready(
490
+ sessionId: "<session-id>",
491
+ prUrls: [
492
+ "https://github.com/org/frontend/pull/123",
493
+ "https://github.com/org/backend/pull/456"
494
+ ]
495
+ )
496
+ ```
497
+
498
+ **After marking PRs as ready**, always print the Polygraph session URL so the user can easily access the session overview. Call `show_session` and display:
499
+
500
+ ```
501
+ **Polygraph session:** POLYGRAPH_SESSION_URL
502
+ ```
503
+
504
+ Where `POLYGRAPH_SESSION_URL` is from `polygraphSessionUrl` in the response.
505
+
506
+ ### 6. Associate Existing PRs
507
+
508
+ Use `associate_pr` to link pull requests that were created outside of Polygraph (e.g., manually or by CI) to the current session. This is useful when PRs already exist for the branches in the session and you want Polygraph to track them.
509
+
510
+ Provide either a `prUrl` to associate a specific PR, or a `branch` name plus `repo` to find and associate PRs for a source repository.
511
+
512
+ **Parameters:**
513
+
514
+ - `sessionId` (required): The Polygraph session ID
515
+ - `prUrl` (optional): URL of an existing pull request to associate
516
+ - `branch` (optional): Branch name to find and associate PRs for
517
+ - `repo` (optional): Source repository for branch-based association. Required when using `branch` in a multi-repo session.
518
+ - `description` (optional): Optional. If supplied, it must follow the Session Description Policy.
519
+
520
+ ```
521
+ associate_pr(
522
+ sessionId: "<session-id>",
523
+ prUrl: "https://github.com/org/repo/pull/123"
524
+ )
525
+ ```
526
+
527
+ Or by branch:
528
+
529
+ ```
530
+ associate_pr(
531
+ sessionId: "<session-id>",
532
+ repo: "org/repo",
533
+ branch: "feature/my-changes"
534
+ )
535
+ ```
536
+
537
+ **Returns** the list of PRs now associated with the session.
538
+
539
+ ### 7. Add Repositories to a Session
540
+
541
+ Use `add_repo` to add repositories to an existing Polygraph session after it has already started.
542
+
543
+ **Direct-add rule:** When the user provides exact repo refs by ID, short name, full name, GitHub `owner/repo` slug, or URL-like slug, pass those refs directly to `add_repo` and do not call `list_repos` first. Candidate discovery remains account-repo-only and is only for cases where the user does not know the exact repo or asks to choose/filter candidates.
544
+
545
+ **Parameters:**
546
+
547
+ - `sessionId` (required): The Polygraph session ID
548
+ - `repoIds` (required): Repository IDs or exact repository refs to add. Accepts IDs, short names, full names, GitHub `owner/repo` slugs, and URL-like slugs.
549
+
550
+ ```
551
+ add_repo(
552
+ sessionId: "<session-id>",
553
+ repoIds: ["nrwl/ocean"]
554
+ )
555
+ ```
556
+
557
+ ### 8. Complete Session
558
+
559
+ **IMPORTANT: Only call this tool when the user explicitly asks to complete or close the session.** Do not automatically complete sessions as part of the workflow.
560
+
561
+ **Warning:** Completing a session seals it from further modifications. Only complete a session when the user explicitly confirms they are done coordinating the session.
562
+
563
+ Use `complete_session` to mark the session as completed. Completing a session will:
564
+
565
+ - **Mark the session as completed** and sealed from further modifications (no new PRs, status changes, etc.)
566
+
567
+ This is idempotent — completing an already-completed session returns success.
568
+
569
+ **Parameters:**
570
+
571
+ - `sessionId` (required): The Polygraph session ID
572
+ - `clean` (optional): Remove local session worktrees after marking the session complete
573
+
574
+ **Returns:**
575
+
576
+ - `sessionId`: The session ID
577
+ - `completed`: Boolean indicating completion status
578
+
579
+ ```
580
+ complete_session(
581
+ sessionId: "<session-id>"
582
+ )
583
+ ```
584
+
585
+ **When to call:**
586
+
587
+ - After all cross-repo work is finished
588
+ - All PRs have been created and marked ready for review
589
+ - The user explicitly confirms they want to close all PRs and seal the session
590
+
591
+ ## Other Capabilities
592
+
593
+ ### Retrieving CI Job Logs
594
+
595
+ Use `get_ci_logs` to retrieve the full plain-text log for a specific CI job. This is the drill-in tool for investigating CI failures after identifying a failed job from the session's CI status.
596
+
597
+ **ONLY use this tool when NO CIPE (CI Pipeline Execution) exists for the PR.** When a CIPE exists (`ciStatus[prId].cipeUrl` is non-null), logs and failure data are available through the CIPE system (Nx Cloud) via `ci_information` — do NOT call `get_ci_logs`. This tool is specifically for PRs where only external CI runs exist (e.g., GitHub Actions runs without an Nx Cloud CIPE).
598
+
599
+ **Parameters:**
600
+
601
+ - `sessionId` (required): The Polygraph session ID
602
+ - `repoId` (required): Repository ID (MongoDB ObjectId hex string, from the session repository entry)
603
+ - `jobId` (required): GitHub Actions job ID (from `ciStatus[prId].externalCIRuns[].jobs[].jobId` in the `show_session` response)
604
+
605
+ **Returns:**
606
+
607
+ - On success: `{ success: true, jobId: number, logFile: string, sizeBytes: number }`
608
+ - On failure: `{ success: false, error: string }`
609
+
610
+ The tool saves the log to a local temp file and returns the path in `logFile`. Use the `Read` tool to examine the file contents. For large logs, use `offset` and `limit` parameters to read specific sections.
611
+
612
+ ```
613
+ get_ci_logs(
614
+ sessionId: "<session-id>",
615
+ repoId: "<repo-id>",
616
+ jobId: 12345678
617
+ )
618
+ // Returns: { success: true, jobId: 12345678, logFile: "/tmp/ci-logs/job-12345678.log", sizeBytes: 152340 }
619
+ // Then: Read(logFile) to examine the log
620
+ ```
621
+
622
+ **Typical flow:**
623
+
624
+ 1. Use `show_session` to see PR CI status
625
+ 2. Check `ciStatus[prId].cipeUrl` — if a CIPE exists, use `ci_information` for logs and skip this tool
626
+ 3. If NO CIPE exists, check `ciStatus[prId].externalCIRuns` — examine runs and jobs directly from the session data
627
+ 4. For a failed job, call `get_ci_logs(sessionId, repoId, jobId)` to save the log to a file
628
+ 5. Use `Read(logFile)` to examine the log content — use `offset`/`limit` for large files
629
+
630
+ **Important:** Logs can be large (100KB+). Only fetch logs for failed or relevant jobs, and read only the sections you need.
631
+
632
+ ### Update Session Description
633
+
634
+ Use this when the user asks to summarize progress, update the session description, capture the current state.
635
+
636
+ Before writing:
637
+ - Read the current session details.
638
+ - Consider the current conversation, child-agent results, PRs, pushed branches, validation, and unresolved decisions.
639
+ - If appending a new item, read the current/latest description first and write the full replacement description with the existing items plus the new item.
640
+ - If updating or replacing the existing last item, write the resulting state directly.
641
+
642
+ Write the description using the canonical structured format in the Session Description Policy. Then call `update_session_description` with the resulting summary.
643
+
644
+ ### Print Polygraph Session Details
645
+
646
+ When asked to print polygraph session details, use `show_session` or `polygraph session show --details <session-id>` and display in the following format.
647
+
648
+ **Session:** POLYGRAPH_SESSION_URL
649
+
650
+ | Repo | PR | PR Status | CI Status | Self-Healing | CI Link |
651
+ | -------------- | ------------------ | --------- | --------- | ------------------- | ---------------- |
652
+ | REPO_FULL_NAME | [PR_TITLE](PR_URL) | PR_STATUS | CI_STATUS | SELF_HEALING_STATUS | [View](CIPE_URL) |
653
+
654
+ If the session has a description timeline, also display:
655
+
656
+ **Description:** SESSION_DESCRIPTION
657
+
658
+ (Omit the Description line if `description` is empty.)
659
+
660
+ - REPO_FULL_NAME: from the session repository entries (match repository to PR via `repoId`)
661
+ - PR_URL, PR_TITLE, PR_STATUS: from `pullRequests[]`
662
+ - CI_STATUS: from `ciStatus[prId].status`
663
+ - SELF_HEALING_STATUS: from `ciStatus[prId].selfHealingStatus` (omit or show `-` if null)
664
+ - CIPE_URL: from `ciStatus[prId].cipeUrl`
665
+ - POLYGRAPH_SESSION_URL: from `polygraphSessionUrl`
666
+ - SESSION_DESCRIPTION: from the latest/current item in `description`
667
+
668
+ ## Best Practices
669
+
670
+ 1. **MUST delegate via background subagents** — You MUST use `Task(run_in_background: true)` for every `spawn_agent` and `show_agent` call. NEVER call these directly in the main conversation — it floods the context window with polling noise.
671
+
672
+ 1. **Poll child status before proceeding** — Always verify child agents have reached a terminal `child.status` (`'completed'`, `'failed'`, or `'cancelled'`) via `show_agent` before pushing branches or creating PRs
673
+ 1. **Link PRs in descriptions** - Reference related PRs in each PR body
674
+ 1. **Keep PRs as drafts** until all repos are ready
675
+ 1. **Test integration** before marking PRs ready
676
+ 1. **Coordinate merge order** if there are deployment dependencies
677
+
678
+ 1. **NEVER call `spawn_agent` or `show_agent` directly**. These MUST ALWAYS go through background Task subagents (`run_in_background: true`).
679
+
680
+ 1. **Use `stop_agent` to clean up** — Stop child agents that are stuck or no longer needed. The child's session is preserved (`sessionPreserved: true`) so the context can be restored later, but after resuming you must wait for explicit user instructions before making changes.
681
+ 1. **Only complete sessions when asked** — Only call `complete_session` when the user explicitly requests it. Completing a session seals it from further modifications. Do not automatically complete sessions.