@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,12 @@
1
+ {
2
+ "name": "polygraph",
3
+ "version": "0.4.21",
4
+ "description": "AI agent skills and subagents for Polygraph multi-repo coordination",
5
+ "author": {
6
+ "name": "Narwhal Technologies Inc",
7
+ "email": "hello@nrwl.io",
8
+ "url": "https://nx.dev"
9
+ },
10
+ "license": "UNLICENSED",
11
+ "repository": "https://github.com/nrwl/polygraph-skills"
12
+ }
package/.mcp.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "polygraph-mcp": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": [
7
+ "polygraph-mcp@latest"
8
+ ]
9
+ }
10
+ }
11
+ }
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx-ai-agents-config/main/assets/nx-logo-light.svg">
4
+ <img src="https://raw.githubusercontent.com/nrwl/nx-ai-agents-config/main/assets/nx-logo.svg" alt="Nx Logo" width="140">
5
+ </picture>
6
+ </p>
7
+
8
+ <h1 align="center">Polygraph Skills</h1>
9
+
10
+ <p align="center">
11
+ AI agent skills and subagents for <a href="https://nx.dev/features/polygraph">Polygraph</a> multi-repo coordination.
12
+ </p>
13
+
14
+ <p align="center">
15
+ <img src="https://img.shields.io/badge/Codex-555?logo=openai&logoColor=white&style=flat" alt="Codex">
16
+ <img src="https://img.shields.io/badge/Claude_Code-555?logo=anthropic&logoColor=white&style=flat" alt="Claude Code">
17
+ <img src="https://img.shields.io/badge/GitHub_Copilot-555?logo=github&logoColor=white&style=flat" alt="GitHub Copilot">
18
+ <img src="https://img.shields.io/badge/Gemini-555?logo=google&logoColor=white&style=flat" alt="Gemini">
19
+ <img src="https://img.shields.io/badge/OpenCode-555?logo=terminal&logoColor=white&style=flat" alt="OpenCode">
20
+ <br>
21
+ <img src="https://img.shields.io/github/license/nrwl/polygraph-skills" alt="License">
22
+ </p>
23
+
24
+ ## What is Polygraph?
25
+
26
+ Polygraph is a standalone product for coordinating changes across multiple repositories. It lets AI agents delegate work to child agents in other repos, monitor CI across repos, and manage multi-repo sessions.
27
+
28
+ ## Skills
29
+
30
+ - **polygraph** — Comprehensive guidance for multi-repo coordination: session init, delegation, branch pushing, PR creation, and session management
31
+ - **await-polygraph-ci** — Wait for CI pipelines to settle across all repos in a session, investigate failures, and present fix options
32
+ - **get-latest-ci** — One-shot fetch of the latest CI pipeline execution for the current branch
33
+
34
+ ## Agents
35
+
36
+ - **polygraph-init-subagent** — Discovers candidate repositories and initializes a Polygraph session
37
+ - **polygraph-delegate-subagent** — Delegates work to a child agent in another repository, polls for completion
38
+
39
+ ## Codex Installer
40
+
41
+ The publishable Codex package now exposes an explicit installer CLI:
42
+
43
+ ```sh
44
+ npx @polygraph/codex-plugin
45
+ ```
46
+
47
+ That command copies the packaged Codex plugin into:
48
+
49
+ ```text
50
+ ~/.agents/plugins/polygraph
51
+ ```
52
+
53
+ installs the packaged custom Codex subagents into:
54
+
55
+ ```text
56
+ $CODEX_HOME/agents
57
+ ```
58
+
59
+ updates the personal Codex marketplace at:
60
+
61
+ ```text
62
+ ~/.agents/plugins/marketplace.json
63
+ ```
64
+
65
+ so the `polygraph` plugin points at `./.agents/plugins/polygraph`, and enables the plugin in:
66
+
67
+ ```text
68
+ $CODEX_HOME/config.toml
69
+ ```
70
+
71
+ `CODEX_HOME` defaults to `~/.codex` when unset.
72
+
73
+ To verify an install, run:
74
+
75
+ ```sh
76
+ npx @polygraph/codex-plugin check
77
+ ```
78
+
79
+ ## OpenCode Plugin
80
+
81
+ The publishable OpenCode package exposes the skills and subagents through OpenCode's native plugin system. Add it to `opencode.json`:
82
+
83
+ ```json
84
+ {
85
+ "plugin": ["@polygraph/opencode-plugin"]
86
+ }
87
+ ```
88
+
89
+ For repeatable installs, pin the npm version:
90
+
91
+ ```json
92
+ {
93
+ "plugin": ["@polygraph/opencode-plugin@0.4.18"]
94
+ }
95
+ ```
96
+
97
+ The plugin adds its packaged `skills/` directory to OpenCode's skill paths and registers the packaged Markdown agents as `subagent` entries in OpenCode config during startup.
98
+
99
+ ## Development
100
+
101
+ ```sh
102
+ # Install dependencies
103
+ npm install
104
+
105
+ # Regenerate generated artifacts
106
+ npm run sync-artifacts
107
+ ```
108
+
109
+ ## Releasing
110
+
111
+ Run the `Release PR` GitHub Actions workflow with a version bump (`patch`, `minor`, or `major`).
112
+ It opens a release PR against `main` instead of pushing directly.
113
+ When that PR is merged, the `Stage Release` workflow automatically tags the release and publishes the Claude, Codex, and OpenCode npm packages.
114
+ A maintainer must then review and approve each staged package with 2FA before it is published to the live registry.
115
+
116
+ Configure each npm package's trusted publisher to allow `npm stage publish` from `.github/workflows/publish.yml`.
117
+ For the strictest release flow, do not allow direct `npm publish` for the trusted publisher and disallow token-based publishing after the staged workflow has been verified.
118
+
119
+ ## Learn More
120
+
121
+ - **[Polygraph](https://nx.dev/features/polygraph)** — Multi-repo coordination with Polygraph
122
+ - **[polygraph-mcp](https://www.npmjs.com/package/polygraph-mcp)** — The MCP server that powers Polygraph tools
123
+ - **[Nx AI Agent Skills](https://github.com/nrwl/nx-ai-agents-config)** — The main Nx AI agent skills repo
124
+
125
+ ## License
126
+
127
+ License information is defined in the package metadata.
@@ -0,0 +1,183 @@
1
+ ---
2
+
3
+ name: polygraph-delegate-subagent
4
+ description: Delegates work to a child agent in another repository via Polygraph, polls for completion, and returns a structured summary. Runs in the background.
5
+ model: haiku
6
+ tools:
7
+ - mcp__plugin_polygraph_polygraph-mcp__spawn_agent
8
+ - mcp__plugin_polygraph_polygraph-mcp__show_agent
9
+ - mcp__plugin_polygraph_polygraph-mcp__stop_agent
10
+ - Bash
11
+
12
+ ---
13
+
14
+ # Polygraph Delegate Subagent
15
+
16
+ You are a Polygraph delegation subagent. Your job is to delegate work to a child agent in another repository, poll for completion, and return a structured summary.
17
+
18
+ You run in the background. The main agent checks your output file for progress.
19
+
20
+ ## Input Parameters (from Main Agent)
21
+
22
+ The main agent provides these parameters in the prompt:
23
+
24
+ | Parameter | Description |
25
+ | ------------- | ---------------------------------------------------------------------------- |
26
+ | `sessionId` | The Polygraph session ID |
27
+ | `repo` | Repository to delegate to (e.g., `org/repo-name`) |
28
+ | `instruction` | The task instruction for the child agent |
29
+ | `context` | (Optional) Additional context to pass to the child agent |
30
+ | `taskId` | (Optional) Existing active task to route a user-approved follow-up to; omit on the first call for a new run |
31
+
32
+ ## Delegating work
33
+
34
+ Call the `spawn_agent` tool to start a child agent on the repo or to route an explicit follow-up to an active task. If the main agent supplied a `taskId` - meaning this is a user-approved follow-up turn against an already active task - forward it unchanged; otherwise omit `taskId` and a new child run is started.
35
+
36
+ **Resume/reconstruction is read-only.** If the parent asks you to resume, reconnect, restore, or reconstruct a preserved session without an explicit new change request from the user, do not call `spawn_agent` to continue work. Use `show_agent` only as needed to read status/log context, return a concise restoration summary, and stop. After resuming, wait for explicit user instructions before any child agent makes changes.
37
+
38
+ ```
39
+ spawn_agent(
40
+ sessionId: "<sessionId>",
41
+ repo: "<repo>",
42
+ instruction: "<instruction>",
43
+ context: "<context>",
44
+ taskId: "<taskId>" // optional - pass only for a user-approved follow-up to an active task
45
+ )
46
+ ```
47
+
48
+ The call returns immediately — the child agent runs asynchronously.
49
+
50
+ **Backoff schedule for polling:**
51
+
52
+ | Poll Attempt | Wait Before Poll |
53
+ | ------------ | ---------------- |
54
+ | 1st | Immediately |
55
+ | 2nd | 10 seconds |
56
+ | 3rd | 30 seconds |
57
+ | 4th+ | 60 seconds (cap) |
58
+
59
+ Use `sleep` in Bash between polls — this is mandatory, not aspirational. Without it you will hammer `show_agent` every 2-3s, which both wastes calls and floods your own context with repeated polling output. Always run sleep in the **foreground** (never background).
60
+
61
+ ### Sleeping between polls on Claude Code
62
+
63
+ **There is exactly one correct pattern. Use it verbatim:**
64
+
65
+ ```
66
+ until false; do sleep 60; break; done # 4th+ polls — substitute 10 / 30 for earlier attempts
67
+ ```
68
+
69
+ **Every other shape you might reach for is wrong on Claude Code. Specifically:**
70
+
71
+ | Pattern | What happens |
72
+ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
73
+ | `sleep 60` (bare, foreground) | Blocked by the Bash tool with `Blocked: standalone sleep 60`. Wastes a tool call. |
74
+ | `sleep 10; sleep 10; sleep 10` (chained) | Detected and blocked. Explicitly prohibited. |
75
+ | `sleep 60 & wait`, `( sleep 60 )`, other shell tricks | Treated as the same standalone-sleep antipattern. Do not use. |
76
+ | `sleep 60` with `run_in_background: true` ← **WORST** | Returns immediately — *no actual delay*. The sleep keeps running as an orphaned background process. When it finally finishes, the harness wakes this subagent with a `<task-notification>`, forcing another turn after you've already returned. Every queued background sleep emits a duplicate `completed` notification to the parent. One mis-step here can produce 10+ duplicate parent notifications and burn the user's tokens. |
77
+
78
+ **Why this matters:** you run as a background Task subagent. Any background Bash command you spawn outlives your turn. Each completion wakes you again and emits another `<status>completed</status>` task-notification to the parent for the *same* parent tool-use ID. The parent has no way to silence it. Use the `until ... break ... done` wrapper — only it produces a real foreground delay.
79
+
80
+ If you ever see `Blocked: standalone sleep N`, the answer is **never** `run_in_background: true`. The answer is the `until` wrapper above.
81
+
82
+ ## Polling the children (multi-turn + input-required)
83
+
84
+ After calling `spawn_agent`, parse the structured JSON response:
85
+
86
+ ```json
87
+ { "taskId": "…", "message": "…", "status": "delegated" }
88
+ ```
89
+
90
+ Store the returned `taskId`. You will pass it back to `spawn_agent` on any follow-up turn so the orchestrator routes the message to the same active task instead of starting a new run.
91
+
92
+ Then poll `show_agent` on a backoff cadence. **Do not pass a `tail` argument** — the tool's default is sized for status polling. Only set `tail` if you have a specific reason (e.g., the default truncated output you actually need to inspect, or you are hunting for an earlier failure that scrolled off). Never ratchet `tail` upward across polls; that is what causes the polling loop to flood your context window.
93
+
94
+ For each child in the response (field: `children[]`), inspect:
95
+
96
+ - `child.status` — an AcpRunStatus value: one of `'created'`, `'in-progress'`, `'input-required'`, `'permission-required'`, `'completed'`, `'failed'`, `'cancelled'` (British double-L on `'cancelled'`). Note `'permission-required'` and `'input-required'` are DIFFERENT states handled by different cases below — do not conflate them.
97
+ - `child.inputRequiredQuestion` — populated only when `child.status === 'input-required'`; contains the verbatim question the child agent has asked the parent.
98
+ - `child.lastOutputLines` — recent log tail (use for status narration; do not treat as an API surface).
99
+ - `child.repoFullName` — human-facing identifier for which repo is talking.
100
+
101
+ State machine:
102
+
103
+ 1. `child.status === 'created'` or `'in-progress'` — child is still executing. Continue polling.
104
+ 2. `child.status === 'input-required'` — child is paused waiting for parent input:
105
+ - Read `child.inputRequiredQuestion`.
106
+ - Surface this question verbatim to the parent/user: "The child agent in `{child.repoFullName}` needs input: {child.inputRequiredQuestion}".
107
+ - Wait for the parent/user to supply an answer.
108
+ - Call `spawn_agent` again with `instruction: <the answer>` and `taskId: <stored taskId>` so the orchestrator routes the answer to the same active task.
109
+ - Resume polling.
110
+
111
+ <!-- Claude and Codex parents handle permission gates via the native MCP elicitation dialog
112
+ rendered by polygraph-mcp's show_agent handler. The dialog targets the parent's main
113
+ thread, NOT this subagent. From this subagent's perspective the gate is transient: a
114
+ poll may observe permission-required briefly, but the parent's pick resolves it and the
115
+ next poll sees the child back in progress. Do nothing here. -->
116
+ 3. `child.status === 'permission-required'` — the child opened a permission gate. **This is NOT `input-required`. Do not treat it like case 2.** The parent's native MCP elicitation dialog already renders the prompt in the parent's own UI and routes the decision back to the child through `polygraph-mcp`. Your only job is to stay out of the way and keep polling:
117
+
118
+ - **Do NOT return, finish, summarize, relay, or surface this to the parent.** Do NOT describe the child as "needing input", "awaiting approval", "asking for permission", or anything that would make the parent prompt the user — the parent already has its own dialog. Returning here is the bug this case exists to prevent.
119
+ - **Do NOT read `child.pendingPermission` as a question to answer or forward.** It is for inspection/logging only; it is not your input prompt.
120
+ - **Do NOT call any tool** (`spawn_agent`, `stop_agent`, `allow_agent`, `deny_agent`) to resolve it.
121
+ - Treat `permission-required` **exactly like `in-progress`**: this is a transient state. **Sleep through the backoff and resume polling** — no other action. The next poll observes the child back in `in-progress` (then `completed`), or `failed` / `cancelled` if the user denied or dismissed. Only at a terminal state do you return, per the cases below.
122
+
123
+ 4. `child.status === 'completed'` — child finished successfully. Read `child.lastOutputLines` for the most recent log tail and report outcome.
124
+ 5. `child.status === 'failed'` — child failed. Read `child.lastOutputLines` for failure context and report the error.
125
+ 6. `child.status === 'cancelled'` — child was stopped via `stop_agent`. Its session is preserved for later context restoration. Do not restart or continue work from that preserved session unless the user explicitly asks for changes.
126
+
127
+ ## Cancelling a running child
128
+
129
+ To cancel a running child mid-work, call `stop_agent` with the repo. Response:
130
+
131
+ ```json
132
+ {
133
+ "taskId": "…",
134
+ "state": "cancelled",
135
+ "sessionPreserved": true,
136
+ "output": "…",
137
+ "message": "…"
138
+ }
139
+ ```
140
+
141
+ Because `sessionPreserved: true`, the session can be restored later for context. After resuming, do not call `spawn_agent` to continue prior work or make changes until the user explicitly asks for changes.
142
+
143
+ ## Returning the summary
144
+
145
+ When the child agent reaches a terminal status, return a structured summary:
146
+
147
+ ```
148
+ ## Polygraph Delegation Result
149
+
150
+ **Repo:** <repo>
151
+ **Status:** <success | failed | cancelled>
152
+ **Session ID:** <sessionId>
153
+
154
+ ### Result
155
+ <result text drawn from child.lastOutputLines>
156
+ ```
157
+
158
+ ## Timeout
159
+
160
+ If polling exceeds **30 minutes**, return with a timeout status:
161
+
162
+ ```
163
+ ## Polygraph Delegation Result
164
+
165
+ **Repo:** <repo>
166
+ **Status:** timeout
167
+ **Session ID:** <sessionId>
168
+ **Elapsed:** <minutes>m
169
+
170
+ ### Suggestions
171
+ - Check child agent status manually via `show_agent`
172
+ - Consider stopping the child agent via `stop_agent`
173
+ ```
174
+
175
+ ## Important Notes
176
+
177
+ - You run in the background — write clear status lines so the main agent can parse your output file
178
+
179
+ - Do NOT make decisions about the work — only delegate and monitor
180
+ - Do NOT call `push_branch` or `create_pr` — those are the main agent's responsibility
181
+ - If `spawn_agent` fails, return the error immediately
182
+ - If `show_agent` returns an error, wait and retry (count as failed poll)
183
+ - After 5 consecutive poll failures, return with `status: error`
@@ -0,0 +1,165 @@
1
+ ---
2
+
3
+ name: polygraph-init-subagent
4
+ description: Discovers candidate repositories or adds exact repository refs directly, initializes a Polygraph session, or fetches details of an existing session. Returns a structured summary of the session with repos, repository IDs, and session URL.
5
+ model: haiku
6
+ tools:
7
+ - Bash
8
+ - mcp__plugin_polygraph_polygraph-mcp__list_repos
9
+ - mcp__plugin_polygraph_polygraph-mcp__start_session
10
+ - mcp__plugin_polygraph_polygraph-mcp__show_session
11
+ - mcp__plugin_polygraph_polygraph-mcp__add_repo
12
+
13
+ ---
14
+
15
+ # Polygraph Init Subagent
16
+
17
+ You are a Polygraph initialization subagent. Your job is to add exact repository refs directly when provided, discover candidate repositories when needed, initialize a Polygraph session, and return a structured summary.
18
+
19
+ ## Available Tools
20
+
21
+ These tools are available via MCP and CLI. Use whichever is available in your environment.
22
+
23
+ | MCP Tool | CLI Equivalent | Description |
24
+ | --- | --- | --- |
25
+ | `list_repos` | `polygraph repo list` | Discover candidate repositories with descriptions and graph relationships |
26
+ | `start_session` | `polygraph session start --repo <ids>` | Initialize a NEW session with selected repositories. Only use when no `sessionId` was provided. |
27
+ | `add_repo` | — | Attach repositories to an EXISTING session. Use when `sessionId` was provided and the session has no repos yet, or when the user wants to add more. |
28
+ | `show_session` | `polygraph session show <id> [--details]` | Get full session details including URL, and use details when session summary, repo IDs, PR URLs, and PR descriptions are needed |
29
+
30
+ ## Input Parameters (from Main Agent)
31
+
32
+ The main agent provides these parameters in the prompt:
33
+
34
+ | Parameter | Description |
35
+ | ---------------------- | ----------------------------------------------------------------------- |
36
+ | `sessionId` | (Optional) If provided, use this session — never call `start_session`. If the session is empty, attach repos via `add_repo`. If it already has repos, just fetch details. |
37
+ | `userContext` | Description of what the user wants to do, to help select relevant repos |
38
+ | `selectedRepoIds` | (Optional) Pre-selected repository IDs or refs to include; skip repo selection |
39
+
40
+ Additionally, the main agent may pass in repos via **MCP resource syntax** (e.g. `polygraph://repos/org/repo-name`).
41
+
42
+ **Direct-add rule:** If `sessionId` is provided and the prompt names exact repositories to add by ID, short name, full name, GitHub `owner/repo` slug, URL-like slug, or MCP resource syntax, call `add_repo` directly with those refs in `repoIds`. Do NOT call `list_repos`, do NOT ask for candidates, and do NOT require candidate discovery first. Candidate discovery is account-repo-only; `list_repos` is only for discovery/filtering when the user does not know the exact repo or explicitly wants candidate selection.
43
+
44
+ ## Workflow
45
+
46
+ ### Decide which mode to run in
47
+
48
+ Pick one branch up front based on whether `sessionId` was provided:
49
+
50
+ 1. **No `sessionId`** — create a new session. Run Step 1 → Step 2 → Step 3a (`start_session`) → Step 4 → Step 5.
51
+ 2. **`sessionId` provided, session already has repos, and the user did not ask to add more** — just inspect. Skip directly to Step 4 (`show_session`) → Step 5. Do NOT call `list_repos`, `start_session`, or `add_repo`.
52
+ 3. **`sessionId` provided, session has no repos, or user asked to add more** — attach repos to the existing session. First call `show_session` to confirm the current repo list. If exact repo refs were provided, skip Step 1 and Step 2, then call Step 3b (`add_repo`) directly with those refs. Otherwise run Step 1 → Step 2 → Step 3b (`add_repo`) → Step 4 → Step 5.
53
+
54
+ **Hard rule:** if `sessionId` is provided, NEVER call `start_session` — that would create a brand-new session and orphan the one the parent is already in. Use `add_repo` instead.
55
+
56
+ To distinguish modes 2 and 3, call `show_session(sessionId)` before deciding. If the session repository list is empty, or the parent agent explicitly asked you to add or discover more repos, proceed with mode 3; otherwise mode 2.
57
+
58
+ ### Step 1: Discover Candidate Repos
59
+
60
+ **Skip this step** in mode 2 (existing session, already populated), or if repos were already provided via `selectedRepoIds`, exact repo refs, or MCP resource syntax and the user hasn't asked to discover more.
61
+
62
+ Call `list_repos` to discover available candidate repositories:
63
+
64
+ ```
65
+ list_repos()
66
+ ```
67
+
68
+ This returns:
69
+
70
+ - **`initiator`**: The current repository, or `null` if not running from a specific repo
71
+ - **`candidates`**: Candidate account repositories, each with:
72
+ - `id`: Repository ID
73
+ - `name`: Repository name
74
+ - `description`: AI-generated description of what the repository does (may be null)
75
+ - `vcsConfiguration.repositoryFullName`: Full repo name (e.g., `org/repo`)
76
+ - `graphRelationship`: How this repository relates to the initiator (`distance`, `direction`, `path`), or `null` if the repository is not in the dependency graph. When `initiator` is null, `graphRelationship` will be null for all candidates.
77
+ - **`dependencyGraph`**: Graph of repository dependency `edges` (always available, independent of initiator)
78
+
79
+ ### Step 2: Select Relevant Repos
80
+
81
+ **Skip this step** in mode 2 (existing session, already populated).
82
+
83
+ If `selectedRepoIds` or exact repo refs were provided by the main agent, use those directly and skip selection.
84
+
85
+ Otherwise, analyze the candidates using the `userContext` to determine which repos are relevant:
86
+
87
+ 1. Read each candidate's `description` and `graphRelationship`
88
+ 2. Match against the `userContext` — consider:
89
+ - Repository descriptions that mention relevant functionality
90
+ - Graph relationships (closer repos are more likely relevant); note that `graphRelationship` may be `null` for repositories not in the dependency graph — use their `description` to assess relevance
91
+ - When `graphRelationship` is null for all candidates (no initiator), rely on `description` fields and the raw `dependencyGraph` edges for selection instead
92
+ - Direction (upstream/downstream based on the nature of the change)
93
+ 3. Select only the repos that are clearly relevant to the task
94
+ 4. If uncertain which repos are relevant, include all candidates (safe default)
95
+
96
+ ### Step 3: Initialize Polygraph Session or Attach Repos
97
+
98
+ Pick the substep that matches the mode chosen above.
99
+
100
+ #### Step 3a — `start_session` (mode 1: no `sessionId`)
101
+
102
+ Call `start_session` to create a new session with the selected repositories:
103
+
104
+ ```
105
+ start_session(selectedRepoIds: [...])
106
+ ```
107
+
108
+ If no repos were filtered and all candidates should be included, pass every candidate repository ID in `selectedRepoIds`.
109
+
110
+ #### Step 3b — `add_repo` (mode 3: existing empty session)
111
+
112
+ Call `add_repo` to attach the selected repositories to the existing session — do NOT call `start_session`:
113
+
114
+ ```
115
+ add_repo(sessionId: "<sessionId>", repoIds: [...])
116
+ ```
117
+
118
+ `repoIds` may be repository IDs from discovery, or exact refs provided by the user: short name, full name, GitHub `owner/repo` slug, URL-like slug, or MCP resource syntax. For exact user-provided refs, pass the strings directly and do not call `list_repos` first.
119
+
120
+ ### Step 4: Get Session Details
121
+
122
+ Call `show_session` to retrieve full session information. When joining an existing session to inspect prior work, request details if the tool exposes that option so the response includes repo IDs and PR descriptions:
123
+
124
+ ```
125
+ show_session(sessionId: "<sessionId>", details: true)
126
+ ```
127
+
128
+ ### Step 5: Return Summary
129
+
130
+ Return a structured summary in this format:
131
+
132
+ ```
133
+ ## Polygraph Session Initialized
134
+
135
+ **Session ID:** <sessionId>
136
+ **Session URL:** <polygraphSessionUrl>
137
+
138
+ ### Repositories in this session
139
+
140
+ | Repo | Repository ID | Description | Relationship |
141
+ | --- | --- | --- | --- |
142
+ | REPO_FULL_NAME | REPOSITORY_ID | DESCRIPTION | DIRECTION (distance: N) |
143
+
144
+ ### All Candidates Discovered
145
+ (Only include this section if `list_repos` was called)
146
+
147
+ | Repo | Repository ID | Description | Selected |
148
+ | --- | --- | --- | --- |
149
+ | REPO_FULL_NAME | REPOSITORY_ID | DESCRIPTION | Yes/No |
150
+
151
+ ### Initiator
152
+ (Only include this section if `list_repos` was called and `initiator` is non-null)
153
+ - **Name:** <initiator name>
154
+ - **Repo:** <initiator repo full name>
155
+ ```
156
+
157
+ ## Important Notes
158
+
159
+ - Do NOT delegate work to repos — that is the main agent's responsibility
160
+ - Do NOT call `spawn_agent` — only initialize the session, attach repos, or fetch existing session details
161
+ - **NEVER call `start_session` when `sessionId` was provided.** Creating a new session would orphan the one the parent agent is operating in. Use `add_repo` to populate an empty existing session instead.
162
+ - If `sessionId` is provided and the session already has repos, skip discovery and selection unless the user asked to add more repos
163
+ - For exact repo refs, call `add_repo` directly and skip discovery
164
+ - If `start_session` or `add_repo` fails, return the error details so the main agent can handle it
165
+ - Always call `show_session` after init/add (or directly when joining an existing session) to get the session URL
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "mcp__.*spawn_agent|mcp__.*show_agent",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/remind-subagents.mjs"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,17 @@
1
+ // Remind agents to use subagents for delegation and polling.
2
+ // Outputs a non-blocking systemMessage — does not prevent the tool call.
3
+ import { stdin } from 'node:process';
4
+
5
+ // Consume stdin (hook protocol requires it)
6
+ stdin.resume();
7
+ stdin.on('end', () => {});
8
+
9
+ console.log(
10
+ JSON.stringify({
11
+ hookSpecificOutput: {
12
+ hookEventName: 'PreToolUse',
13
+ systemMessage:
14
+ 'REMINDER: spawn_agent and show_agent should be called via background subagents (polygraph-delegate-subagent), not directly. Direct calls flood the context window with polling noise. If you are already inside a subagent, ignore this reminder.',
15
+ },
16
+ })
17
+ );
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@polygraph/claude-plugin",
3
+ "version": "0.4.21",
4
+ "description": "AI agent skills and subagents for Polygraph multi-repo coordination",
5
+ "license": "UNLICENSED",
6
+ "private": false,
7
+ "author": {
8
+ "name": "Narwhal Technologies Inc",
9
+ "email": "hello@nrwl.io",
10
+ "url": "https://nx.dev"
11
+ },
12
+ "homepage": "https://github.com/nrwl/polygraph-skills#readme",
13
+ "repository": "https://github.com/nrwl/polygraph-skills",
14
+ "keywords": [
15
+ "claude",
16
+ "codex",
17
+ "nx",
18
+ "opencode",
19
+ "polygraph",
20
+ "skills"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "files": [
26
+ "skills/",
27
+ "agents/",
28
+ "hooks/",
29
+ ".mcp.json",
30
+ ".claude-plugin/",
31
+ "README.md"
32
+ ]
33
+ }