@polygraph/cursor-plugin 0.4.51

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,129 @@
1
+ ---
2
+ name: pack-and-copy
3
+ description: Validate a publisher package change against consumer repos by building + packing the publisher and installing the tarballs into each consumer, so consumer CI can run against the unmerged change. USE WHEN a publisher repo (e.g. a design system, shared library, SDK) has a pending change that needs to be tested in downstream repos before its version is merged and published. TRIGGER when user says "pack and copy", "pre-release test in consumers", "test this package change in <consumer>", "install the unreleased version into the apps", or "validate this change against <consumer repo>".
4
+
5
+ ---
6
+
7
+ # Pack and Copy
8
+
9
+ Validate a publisher package change against its consumer repos **before** the publisher's version bump is merged and published. The flow is:
10
+
11
+ 1. Build the publisher package(s) — repo-specific, not automatable.
12
+ 2. Run `polygraph _pack-and-copy` (or the `pack_and_copy` MCP tool) to pack them and install the tarballs into each consumer, rewriting `package.json` to a `file:` dependency.
13
+ 3. Commit the consumer changes, including `.polygraph-packages/*.tgz`, to a branch, open a PR, and let consumer CI validate the change.
14
+
15
+ This skill covers **steps 1 and 2**. PR creation / CI monitoring is left to the `polygraph` and `await-polygraph-ci` skills.
16
+
17
+ ## Available Tools
18
+
19
+ Pack-and-copy functionality is available via both an MCP tool and a CLI command. Use whichever is available in your current environment.
20
+
21
+ | MCP Tool | CLI Equivalent | Description |
22
+ | --- | --- | --- |
23
+ | `pack_and_copy` | `polygraph _pack-and-copy` | Pack publisher packages and install tarballs into consumer repos for pre-release validation. |
24
+
25
+ Session discovery / inspection tools (`show_session`, `list_repos`, etc.) come from the `polygraph` skill — see that skill's tool table for the full mapping.
26
+
27
+ ## Prerequisites
28
+
29
+ - An active Polygraph session that includes the publisher repo and one or more consumer repos. If you don't have a session yet, run the `polygraph` skill first to create one.
30
+ - The publisher repo's built artifacts are **packable** — i.e. running `npm pack` in the package directory produces a tarball that, when installed, Just Works. If the publisher needs to be built first, you'll need to do that explicitly.
31
+
32
+ ## Phase 1: Identify Publishers and Consumers
33
+
34
+ Determine which packages are being changed in the publisher, and which consumer repos need to validate the change.
35
+
36
+ **If the user specified them**, skip to Phase 2.
37
+
38
+ **Otherwise**, inspect the session and the publisher's change:
39
+
40
+ 1. Call `show_session(sessionId)` to enumerate the repos in the session and their local paths.
41
+ 2. The **publisher** is usually the current repo (where the change is being made). Look at its `package.json` files to find the packages being shipped — the one being changed, or all packages in a monorepo package tree.
42
+ 3. The **consumers** are the other repos in the session. Only repos that actually depend on one of the publisher's packages are relevant — the command will auto-skip the rest, but listing them up front keeps the user informed.
43
+
44
+ Before proceeding, print a short table:
45
+
46
+ | Publisher package | Publisher path | Consumer repo | Consumer path |
47
+ | ----------------- | ----------------------- | ------------- | ----------------- |
48
+ | @org/tokens | /path/to/ds/packages/tokens | web-app | /path/to/web-app |
49
+ | @org/button | /path/to/ds/packages/button | web-app | /path/to/web-app |
50
+
51
+ and confirm with the user using `AskUserQuestion` if anything is ambiguous.
52
+
53
+ ## Phase 2: Build the Publisher Packages
54
+
55
+ **This step is not automatable.** Build commands vary per repo and per package. Ask the user how to build, or inspect the repo for conventions.
56
+
57
+ Common hints to surface to the user:
58
+
59
+ - A root-level `package.json` with a `build` script that builds all packages (e.g. `npm run build`, `nx run-many -t build`, `pnpm -r build`).
60
+ - Per-package `build` scripts (check each publisher's `package.json`).
61
+ - A `prepack` script — if one exists, `npm pack` will run it automatically and you don't need a separate build step.
62
+
63
+ Run the build. Verify the `dist/` or equivalent output exists in each publisher package directory before proceeding.
64
+
65
+ **If the build fails**, surface the error to the user and stop. Do not attempt to pack a broken package.
66
+
67
+ ## Phase 3: Pack and Copy
68
+
69
+ Run `polygraph _pack-and-copy` (or the `pack_and_copy` MCP tool), passing a `--pair` for every (publisher, consumer) combination the user wants to test. The command is deterministic: it computes a unique pre-release version, runs `npm pack` in each publisher, copies the tarballs into each consumer's `.polygraph-packages/` directory, rewrites the consumer's `package.json` deps to point at the tarballs via `file:`, and POSTs a summary of published and consumed packages to the Polygraph session so the UI reflects what was packed where.
70
+
71
+ CLI form:
72
+
73
+ ```bash
74
+ polygraph _pack-and-copy \
75
+ --session <session-id> \
76
+ --pair <publisher-path>=<consumer-path> \
77
+ [--pair <publisher-path>=<consumer-path> ...] \
78
+ --json
79
+ ```
80
+
81
+ MCP tool form — call `pack_and_copy` with:
82
+
83
+ - `sessionId` (string, required): the Polygraph session ID
84
+ - `pairs` (array, required): one `{ publisherPath, consumerPath }` object per (publisher, consumer) combination
85
+ - `runScripts` (boolean, optional): enable npm lifecycle scripts during `npm pack` (off by default)
86
+
87
+ **Notes:**
88
+
89
+ - `<publisher-path>` / `publisherPath` is the directory containing the publisher package's `package.json` (not necessarily the repo root — for monorepos, this is `packages/<name>/`).
90
+ - `<consumer-path>` / `consumerPath` is the consumer repo's root (where its `package.json` lives).
91
+ - If a consumer doesn't declare a dependency on a publisher's package, that pair is silently skipped for that consumer — the tarball is still produced but not installed there.
92
+ - The command creates a new unique version on each run, but package managers can still keep stale `file:` dependency contents in `node_modules`. Use a forced install on reruns if the consumer still sees old package contents.
93
+ - Consumers' `.polygraph-packages/*.tgz` files **must be tracked and committed** with the consumer branch. Fresh CI clones need those tarballs to install the `file:` dependencies.
94
+
95
+ Parse the JSON output to get the `published` and `consumed` summaries. Print them back to the user:
96
+
97
+ ```
98
+ Packed:
99
+ - @org/tokens 1.4.2 -> 1.4.3-pg.<session>.<timestamp>
100
+ - @org/button 2.1.0 -> 2.1.1-pg.<session>.<timestamp>
101
+
102
+ Installed into:
103
+ - web-app: @org/tokens, @org/button
104
+ - docs: @org/tokens
105
+ ```
106
+
107
+ ## Phase 4: Install in Consumers and Commit
108
+
109
+ For each consumer that received a tarball:
110
+
111
+ 1. Run the consumer's package manager install command, e.g. `npm install`, `pnpm install`, or `yarn install`, so the lockfile and `node_modules/` reflect the new `file:` dep. On reruns in the same worktree, use `npm install --force`, `pnpm install --force`, or `yarn install --force` if the consumer still sees old package contents.
112
+ 2. Commit the `package.json`, lockfile, and `.polygraph-packages/*.tgz` changes on a dedicated branch.
113
+
114
+ 3. Push the branch and open a draft PR with a description that explains this is validating an unmerged publisher change.
115
+
116
+ 4. Once CI results come in (see the `await-polygraph-ci` skill), report back. Do **not** merge any consumer PR opened via this flow — these PRs are for validation only and should be closed once the publisher's real version lands.
117
+
118
+ ## Common Pitfalls
119
+
120
+ - **Forgetting to build**: `npm pack` packs whatever the package's `files` field points at. If `dist/` is stale or missing, the tarball will be broken. Always rebuild before packing unless a `prepack` script does it.
121
+ - **Stale `file:` installs**: package managers may keep old extracted contents for local tarball dependencies after reruns. Use `install --force` if a consumer still sees old package contents.
122
+ - **Peer dependency mismatches**: if the publisher bumps a peer dep, consumers that don't satisfy it may fail to install. Surface this to the user.
123
+ - **Lockfile churn**: installing after a `file:` swap will change the lockfile. That's expected and should be committed alongside the `package.json` and tarball changes.
124
+ - **Multiple publishers in one repo**: pass one `--pair` per publisher package, using the same consumer path. They'll all be bundled into the same `.polygraph-packages/` dir.
125
+
126
+ ## Related Skills
127
+
128
+ - `polygraph` — session setup, branch push, PR creation.
129
+ - `await-polygraph-ci` — monitor consumer CI after the PRs are opened.
@@ -0,0 +1,294 @@
1
+ ---
2
+ name: polygraph
3
+ description: Guidance for working with Polygraph sessions, shared/resumable agent context, repository graph visibility, linked PR/CI state, and cross-repo expansion when needed. Use when starting, joining, resuming, inspecting, or sharing a Polygraph session; handing off progress; discovering related repositories; coordinating changes/branches/PRs across repos; delegating tasks to child agents in different repos; checking CI status and logs; fetching missing git history in a shallow session clone; or tracing a commit or line of code back to the session that produced it. TRIGGER when user mentions "polygraph", resuming or sharing a session, "other repos", "other repositories", "who uses this", "what uses this", "cross-repo", "multi-repo", "consuming this API/endpoint", "dependent repositories", asks about what other repos are doing with shared code/APIs/endpoints, or asks about a "commit sha", "session behind this commit", "which session changed this line", "find session by sha", "git blame", "shallow clone", "missing commit", "bad object", "unshallow", "fetch history".
4
+
5
+ ---
6
+
7
+ # Working with Polygraph
8
+
9
+ **IMPORTANT:** Polygraph keeps local clones only for *other* repositories in the session. NEVER `cd` into those clones or access their files directly — work in other repositories ALWAYS happens through the Polygraph MCP `spawn_agent` tool. Before delegating anything, read [`reference/delegation.md`](reference/delegation.md).
10
+
11
+ Polygraph connects repos and the agent work happening across them. Its central artifact is the session, which groups the repos, branches, PRs, and CI status for one piece of work and can be shared and resumed: use it to coordinate changes across multiple repos or in a single repoto share the session URL with collaborators, hand off progress via the session description, resume prior work, and watch CI across the session's PRs.
12
+
13
+ **Polygraph operates on the current repo in place.** Starting a session never clones or modifies the repository you are in — you keep working in your real working directory, and `push_branch` pushes your local commits from that checkout. Only *other* repos are worked on in separate Polygraph-managed clones via `spawn_agent`. Resuming is the one qualified case: a `resume_session` with the explicit `reset` consent force-switches branches inside the session's materialized repositories, and can force-move the current working tree when it is itself one of them. Repositories outside the session folder are never modified. Full contract under "Explore an Existing Session".
14
+
15
+ ## Available Tools
16
+
17
+ Polygraph functionality is available via both MCP tools and CLI commands. Use whichever is available in your current environment.
18
+
19
+ | MCP Tool | CLI Equivalent | Description |
20
+ | --- | --- | --- |
21
+ | `list_repos` | `polygraph repo list` | Discover candidate repositories. Candidate entries do not include repository descriptions; use `semanticQuery` for natural-language discovery. |
22
+ | `start_session` | `polygraph session start --repo <ids>` | Initialize a Polygraph session with selected repositories |
23
+ | `resume_session` | `polygraph session resume --session <id> --json` | Join an existing session from this conversation: a tracked adoption that performs the full reconstruct. On divergence it stays local by default; `reset` is an explicit, destructive opt-in. Divergence and post-join behavior are under "Explore an Existing Session". |
24
+ | `spawn_agent` | — | Start a child task, or send a follow-up to an active task, in another repository; returns a delegation id. A repeat call for the same (repo, role) is delivered to that task as a follow-up; otherwise a new child starts. See `reference/delegation.md`. |
25
+ | `show_agent` | — | Poll by repo or delegation id; unwaited reads return the child's result. Waited calls are for the poller subagent, not the main conversation. See `reference/delegation.md`. |
26
+ | `stop_agent` | — | Cancel an in-progress child by delegation id; its session is preserved for later read-only context restoration. |
27
+ | `push_branch` | — | Push a local git branch to the remote repository. For the repo you are in, this pushes from your current checkout. Requires a session description. |
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` | `polygraph session update --session <id> [--title] [--description]` | Update the session title and/or description (at least one required); metadata only, independent of 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 session (pass exact refs directly, skipping `list_repos`). See "Add Repositories to a Session". |
35
+ | `archive_session` | `polygraph session archive <id>` | Archive a session, hiding it from active lists (it can still be resumed) |
36
+ | `get_ci_logs` | — | Retrieve full plain-text log for a specific CI job |
37
+ | `git_fetch` | `polygraph git fetch` | Fetch git history for a shallow session clone when git fails with "bad object" or missing-commit errors. See "Fetching Git History for Shallow Clones". |
38
+ | `login` | `polygraph auth login [--token]` | Authenticate with Polygraph (use `--token` for headless/CI) |
39
+ | `logout` | `polygraph auth logout` | Log out of Polygraph |
40
+ | `list_sessions` | `polygraph session list` | List sessions. By default only active sessions created by the current git user; pass `recommendedFilters: false` for all sessions. |
41
+ | `search_sessions` | `polygraph session search` | Find sessions by free-text `query` OR by commit `sha` — pass exactly one. See "Finding the Session Behind a Commit or Line". |
42
+ | `list_accounts` | `polygraph account list` | List available organizations |
43
+ | `select_account` | `polygraph account select` | Select the organization that future commands run against |
44
+ | `whoami` | `polygraph whoami` | Show current auth status and org |
45
+
46
+ ## CLI Statefulness
47
+
48
+ 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.
49
+
50
+ ## Setup
51
+
52
+ Before using Polygraph tools, ensure the CLI is authenticated and an organization is selected.
53
+
54
+ ### Check Authentication
55
+
56
+ Use `polygraph whoami` (or the `whoami` MCP tool) before session work to check if the user is currently logged in and which organization is active.
57
+
58
+ - If the user **is logged in** and an org is selected → proceed to the workflow.
59
+ - If auth is **missing, expired, or no org is selected** → stop session work. Do not keep trying session creation, repository discovery, delegation, or CI checks.
60
+ - Facilitate user reauth through the browser-based login flow, such as `polygraph auth login` (or the `login` MCP tool). In interactive desktop clients, browser reauth is usually user-driven; surface the need clearly and wait for the user to complete it.
61
+ - After login, an organization must be selected. Use `polygraph account select` (or MCP equivalent) when needed.
62
+ - Re-run `polygraph whoami` (or `whoami`) after reauth and org selection. Continue only after it confirms a valid login and selected organization.
63
+
64
+ ### Select Organization
65
+
66
+ After logging in (or if logged in but no org is selected), use `polygraph account select` (or MCP equivalent) to choose the organization that future commands will run against.
67
+
68
+ ## Workflow Overview
69
+
70
+ The delegate/monitor/stop steps apply only when working across repos. A single-repo session skips them and still benefits from shared progress, resume, and CI visibility.
71
+
72
+ 2. **Initialize or join Polygraph session** - If you already have a session ID, call `show_session` to fetch details. If the user asks to add exact repo refs, call `add_repo` directly and skip candidate discovery. Otherwise, discover candidate repos, select relevant repositories, and create a new session via `list_repos` and `start_session`.
73
+ 3. **Delegate work to each repo** - Use `spawn_agent` to start child agents in other repositories (returns immediately with a delegation id). With the default role, delegate only to *other* repos — never to the repo you are in; work on it directly. Delegating into the repo you are in is allowed only with an explicit non-default `role`. Parallel delegation across repos is encouraged. Read [`reference/delegation.md`](reference/delegation.md) before delegating.
74
+
75
+ 4. **Monitor child agents** - Let the background poller subagent do the waiting. When it exits, read that child's answer with a single unwaited `show_agent(sessionId, id)` — `result.text` is the child's final message.
76
+ 5. **Stop child agents** (if needed) - Use `stop_agent` with the delegation id to cancel an in-progress child agent. The agent's session is preserved for later read-only context restoration; after a resume, wait for explicit user instructions before making changes.
77
+ 6. **Push branches** - Use `push_branch` after making commits. A required `description` must follow the Session Description Policy.
78
+ 7. **Create draft PRs** - Use `create_pr` to create linked draft PRs. Always pass `description` following the Session Description Policy.
79
+ 8. **Associate existing PRs** (optional) - Use `associate_pr` to link PRs created outside Polygraph.
80
+ 9. **Query PR status** - Use `show_session` to check progress.
81
+ 10. **Mark PRs ready** - Use `mark_pr_ready` when work is complete.
82
+ 11. **Archive session** - Use `archive_session` to archive the session when the user requests it.
83
+
84
+ ## Step-by-Step Guide
85
+
86
+ ### Initialize or Join Polygraph Session
87
+
88
+ There are three cases. Pick exactly one before calling any tool. The case labels are internal routing shorthand — never mention them in anything you show the user.
89
+
90
+ **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 or you are provided one by a reminder hook), 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`.**
91
+
92
+ **Hard rule: before doing ad-hoc work in another repository, or reading a session's context untracked, ask whether an existing session already covers this work. If one might and its session ID is not in scope, ask the user for it — never fall back to an ad-hoc clone. To WORK in a session's context, join it via `resume_session` — a tracked adoption. To only read or summarize, `show_session` remains the read path.**
93
+
94
+ **Case A — Existing session, already has repos.** Call `show_session` directly with the known session ID. Skip the init subagent entirely, show the session details (format below), and proceed.
95
+
96
+ **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`.
97
+
98
+ **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.
99
+
100
+ In case B, direct exact repo refs go straight to `add_repo`; use `list_repos` only when discovery/filtering is needed. In case C, discover candidate repos using `list_repos`, select relevant repositories, and call `start_session`. In case A, just call `show_session`.
101
+
102
+ **Session ID handling:**
103
+
104
+ - For a new session (case C), `start_session` auto-generates a unique session ID. You do NOT need to pass one.
105
+ - For cases A and B, the session ID already exists; reuse it everywhere
106
+ - The parent conversation is responsible for detecting an existing session ID from current context, the startup banner, or a user-provided session URL/ID, then passing it explicitly to `polygraph-init-subagent`. The init subagent cannot infer parent session context by itself.
107
+ - For a fresh Codex Desktop conversation started with `/polygraph:session-start`, no `sessionId` is expected; launch `polygraph-init-subagent` without `sessionId` so it creates a new session.
108
+
109
+ The subagent will:
110
+
111
+ 1. Use exact repo refs directly when provided for an existing session; otherwise call `list_repos` to discover available repositories
112
+ 2. Select relevant repos based on the user context (or include all if uncertain)
113
+ 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.
114
+ 4. Call `show_session` to retrieve session details
115
+ 5. Return a summary with session URL and repo info
116
+
117
+ **When the init subagent has just created a brand-new session,** render the session welcome card instead of the session-details block below. Prefer the `session_intro` MCP tool (or the hidden `polygraph session intro -s <sessionId>` via the CLI) — call it with the session ID; it returns the card as markdown. 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.
118
+
119
+ **For an existing session — after `show_session` returns or the init subagent's summary arrives — show the session details:**
120
+
121
+ **Session:** POLYGRAPH_SESSION_URL
122
+
123
+ **Repositories in this session:**
124
+
125
+ - REPO_FULL_NAME
126
+
127
+ - REPO_FULL_NAME: from the session repository entries
128
+ - POLYGRAPH_SESSION_URL: from `polygraphSessionUrl`
129
+
130
+ ### Explore an Existing Session
131
+
132
+ Use this workflow when the user gives a Polygraph session ID and asks to understand, resume, inspect, or investigate prior work.
133
+
134
+ **Resume is not a work command.** If the user's intent is to resume, reconnect, or reconstruct a prior Polygraph session, join it via `resume_session`, summarize the restored context it returns, then stop. Do not edit files, push branches, add repos, delegate new work, or continue previous changes until the user explicitly asks for changes. Recording the join in the session's history is not making changes to the work. Treat "resume" as context restoration followed by waiting for user instructions.
135
+
136
+ 1. Fetch session context by intent:
137
+ - To continue work in the session from this conversation, join it via `resume_session` (CLI: `polygraph session resume --session <id> --json`) — a tracked adoption that performs the full reconstruct; the restored session context comes back in the tool result. On a divergent session the join stays on the local conversation by default and returns the divergence evidence; adopting the selected path requires the explicit `reset` consent, a destructive opt-in that force-switches branches in the session's materialized repositories (discarding uncommitted tracked changes there, untracked files survive) and deletes this machine's local session logs.
138
+ - To only read, inspect, or summarize without joining, prefer `show_session` with `details: true`; otherwise run `polygraph session show --details <session-id>`. This is the read-only path and records nothing.
139
+ 2. Treat the detailed output as authoritative context. It should include:
140
+ - `<summary>` — the session summary.
141
+ - `<repositories>` — relevant repos, including each repo's `<id>` and `<name>`.
142
+ - `<pullRequests>` — relevant PRs, including `<url>`, `<repoId>`, `<repoName>`, branch metadata, and `<description>`.
143
+ 3. Parse the XML-style blocks and XML-unescape text inside `<summary>` and `<description>`.
144
+ 4. Build a repo/PR map:
145
+ - repo id
146
+ - repo full name
147
+ - PR URL
148
+ - branch
149
+ - base branch
150
+ - title
151
+ - status
152
+ - PR description
153
+ 5. If the request was resume/reconnect/reconstruct only, report the restored session context and wait for the user's next instruction.
154
+ 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.
155
+ 7. If the repo to investigate is already part of the session, delegate directly to that repo (unless it is the repo you are in — investigate that one directly).
156
+ 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.
157
+ 9. After `add_repo`, call `show_session` again to verify the repo was added, then delegate to that repo.
158
+ 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.
159
+
160
+ When delegating investigation from a PR, include the PR context in the child instruction:
161
+
162
+ ```
163
+ Session: <session-id>
164
+ Repo: <repoName>
165
+ Repo ID: <repoId>
166
+ PR: <url>
167
+ Branch: <branch>
168
+ Base branch: <baseBranch>
169
+ Description:
170
+ <description>
171
+
172
+ Inspect the PR commits/diff and investigate the requested behavior. Report findings with file paths and concrete evidence.
173
+ ```
174
+
175
+ ### Finding the Session Behind a Commit or Line
176
+
177
+ Use this workflow when the user asks which Polygraph session produced, is behind, or changed a particular commit — or a particular line of code.
178
+ **Read [`reference/session-by-commit.md`](reference/session-by-commit.md) before running any lookup.** That reference file holds clear, reliable steps for answering questions related to this.
179
+
180
+ ## Delegating to other repos
181
+
182
+ Working across more than one repo, or delegating any task? Read [`reference/delegation.md`](reference/delegation.md) first — required. Delegation is the only way to act on other repos, and the reference holds the contract that keeps it cheap and trackable: skipping it leads to re-pasting briefs, polling in the main conversation, and touching other repos' clones directly — each of which burns tokens or breaks session tracking.
183
+
184
+ <!-- Claude and Codex parents handle permission gates via the native MCP elicitation dialog
185
+ rendered by polygraph-mcp's show_agent handler. The dialog targets the parent harness's
186
+ own UI, NOT this agent. From the agent's vantage point the gate is transient: a
187
+ `show_agent` poll may briefly see `permission-required` between the child opening the
188
+ gate and the user picking in the dialog. The agent must NOT resolve it itself. -->
189
+ ## Handling permission requests
190
+
191
+ 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.
192
+
193
+ **Critical: do NOT call `allow_agent` or `deny_agent` yourself.** If `show_agent` 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).
194
+
195
+ 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.
196
+
197
+ 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.
198
+
199
+ ## Publishing and Session Management
200
+
201
+ ### Publish Changes (Push Branches, Create PRs, Mark Ready)
202
+
203
+ Publishing covers the branch-to-PR flow: `push_branch` (push local commits; must precede PR creation), `create_pr` (linked draft PRs, including fork PRs via `targetRepository`), `mark_pr_ready` (transition drafts to OPEN), and `associate_pr` (link PRs created outside Polygraph).
204
+
205
+ **Whenever you push a branch, create or associate a PR, or mark PRs ready, read [`reference/publish-changes.md`](reference/publish-changes.md) first.** That reference file holds the full flow.
206
+
207
+ ### Session Description Policy
208
+
209
+ `description` is user-facing Polygraph session context. It is required for `push_branch`, `create_pr`, and `associate_pr`, and is the primary input to `update_session` (`mark_pr_ready` does not take a description).
210
+
211
+ **Whenever you write or update a session description, read [`reference/session-description.md`](reference/session-description.md) first.** That reference file holds the full policy.
212
+
213
+ Use `update_session` directly when the user asks to summarize progress, update the session description, or capture the current state.
214
+ Be liberal about updating the session description when you make changes that affect the scope of the session, how logic flows between repos, or anything else important for posterity. Avoid updating it for small implementation details that are not relevant outside of this session. An up-to-date session description matters for maintainability.
215
+
216
+ ### Linked References
217
+
218
+ Use `link_reference` to link an external reference to the current Polygraph session.
219
+
220
+ **Parameters:**
221
+
222
+ - `sessionId` (required): The Polygraph session receiving the linked reference
223
+ - `reference` (required): Reference metadata with `type`, `url`, and `label`
224
+ - `reference.sessionId` (session references only): The referenced Polygraph session ID when `reference.type` is `session`
225
+
226
+ 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.
227
+
228
+ The canonical MCP parameters are `{ sessionId, reference }`. There is no unlink command; `show_session` returns a session's existing links as `session.linkedReferences`.
229
+
230
+ ### Add Repositories to a Session
231
+
232
+ Use `add_repo` to add repositories to an existing Polygraph session after it has already started.
233
+
234
+ **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 is only for cases where the user does not know the exact repo.
235
+
236
+ **Not limited to your organization:** repos outside the org — including public open-source repos — can be added by GitHub `owner/repo` slug or URL. Only `list_repos` discovery is org-scoped, so a repo missing from `list_repos` can still be added directly.
237
+
238
+ ### Archive Session
239
+
240
+ **IMPORTANT: Only call this tool when the user explicitly asks to archive or close the session.** Do not archive sessions automatically as part of the workflow.
241
+
242
+ Use `archive_session` (CLI: `polygraph session archive <id>`) to archive the session. Archiving only hides the session from active lists — it can still be resumed and interacted with afterwards. It is idempotent — archiving an already-archived session returns success. Pass the optional `clean` flag to also remove the local clones Polygraph created for delegated repos.
243
+
244
+ **When to call:** all work is finished, PRs are created and marked ready, and the user explicitly confirms they are done with the session.
245
+
246
+ ## Other Capabilities
247
+
248
+ ### Retrieving CI Job Logs
249
+
250
+ `get_ci_logs` retrieves the full plain-text log for a specific CI job — the drill-in tool for investigating a failed job. **ONLY use it when NO CIPE (CI Pipeline Execution) exists for the PR** (`ciStatus[prId].cipeUrl` is null); when a CIPE exists, use the Nx MCP `ci_information` tool instead, and do NOT fetch or poll the `cipeUrl` over HTTP.
251
+
252
+ When you need to fetch and read a failed job's log, read [`reference/ci-job-logs.md`](reference/ci-job-logs.md) for the parameters, return shape, and the full flow (identify the job from `externalCIRuns`, call `get_ci_logs`, then `Read` the saved log file).
253
+
254
+ ### Fetching Git History for Shallow Clones
255
+
256
+ Session repos are shallow (`--depth 1`) clones. When git fails on missing history (`bad object` from `git revert`, `git log`, `git blame`, etc.), call `git_fetch({ sessionId, repo })` and retry. Read [`reference/shallow-clone-history.md`](reference/shallow-clone-history.md) for the CLI form, the `depth`/`refs` options, and the redundant-call behavior.
257
+
258
+ ### Print Polygraph Session Details
259
+
260
+ When asked to print polygraph session details, use `show_session` or `polygraph session show --details <session-id>` and display in the following format.
261
+
262
+ **Session:** POLYGRAPH_SESSION_URL
263
+
264
+ | Repo | PR | PR Status | CI Status | Self-Healing | CI Link |
265
+ | -------------- | ------------------ | --------- | --------- | ------------------- | ---------------- |
266
+ | REPO_FULL_NAME | [PR_TITLE](PR_URL) | PR_STATUS | CI_STATUS | SELF_HEALING_STATUS | [View](CIPE_URL) |
267
+
268
+ If the session has a description timeline, also display:
269
+
270
+ **Description:** SESSION_DESCRIPTION
271
+
272
+ (Omit the Description line if `description` is empty.)
273
+
274
+ - REPO_FULL_NAME: from the session repository entries (match repository to PR via `repoId`)
275
+ - PR_URL, PR_TITLE, PR_STATUS: from `pullRequests[]`
276
+ - CI_STATUS: from `ciStatus[prId].status`
277
+ - SELF_HEALING_STATUS: from `ciStatus[prId].selfHealingStatus` (omit or show `-` if null)
278
+ - CIPE_URL: from `ciStatus[prId].cipeUrl` (null if no CIPE — omit the CI Link cell) — a human-facing Nx Cloud link: render it for the user, never fetch, curl, or poll it. CIPE data is only reachable via the Nx MCP `ci_information` tool.
279
+ - POLYGRAPH_SESSION_URL: from `polygraphSessionUrl`
280
+ - SESSION_DESCRIPTION: from the latest/current item in `description`
281
+
282
+ ## Best Practices
283
+
284
+ 1. **Delegate asynchronously** — Use `spawn_agent` which returns immediately with a delegation id, then poll with `show_agent`.
285
+
286
+ 1. **Read each result once** — when a poller exits, read that child with a single unwaited `show_agent(sessionId, id)`; `result.text` is the child's final message. Only reach for an explicit `tail` if that is not enough.
287
+ 1. **Poll child status before proceeding** — Always verify child agents have reached a terminal `child.status` (`'completed'`, `'failed'`, or `'cancelled'`) before pushing branches or creating PRs
288
+ 1. **Link PRs in descriptions** - Reference related PRs in each PR body
289
+ 1. **Keep PRs as drafts** until all repos are ready
290
+ 1. **Always pass `description`** when calling `create_pr`, `associate_pr`, or `update_session` — it is required and must follow the Session Description Policy
291
+ 1. **Test integration** before marking PRs ready
292
+ 1. **Coordinate merge order** if there are deployment dependencies
293
+
294
+ 1. **Use `stop_agent` to clean up** — Stop child agents that are stuck or no longer needed (pass the delegation id). 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.
@@ -0,0 +1,38 @@
1
+ # Retrieving CI Job Logs
2
+
3
+ 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.
4
+
5
+ **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 the Nx MCP `ci_information` tool — do NOT call `get_ci_logs`, and do NOT fetch or poll the `cipeUrl` over HTTP (it is a browser link for the user, not an API). This tool is specifically for PRs where only external CI runs exist (e.g., GitHub Actions runs without an Nx Cloud CIPE).
6
+
7
+ **Parameters:**
8
+
9
+ - `sessionId` (required): The Polygraph session ID
10
+ - `repoId` (required): Repository ID (MongoDB ObjectId hex string, from the session repository entry)
11
+ - `jobId` (required): GitHub Actions job ID (from `ciStatus[prId].externalCIRuns[].jobs[].jobId` in the `show_session` response)
12
+
13
+ **Returns:**
14
+
15
+ - On success: `{ success: true, jobId: number, logFile: string, sizeBytes: number }`
16
+ - On failure: `{ success: false, error: string }`
17
+
18
+ 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.
19
+
20
+ ```
21
+ get_ci_logs(
22
+ sessionId: "<session-id>",
23
+ repoId: "<repo-id>",
24
+ jobId: 12345678
25
+ )
26
+ // Returns: { success: true, jobId: 12345678, logFile: "/tmp/ci-logs/job-12345678.log", sizeBytes: 152340 }
27
+ // Then: Read(logFile) to examine the log
28
+ ```
29
+
30
+ **Typical flow:**
31
+
32
+ 1. Use `show_session` to see PR CI status
33
+ 2. Check `ciStatus[prId].cipeUrl` — if a CIPE exists, use `ci_information` for logs and skip this tool
34
+ 3. If NO CIPE exists, check `ciStatus[prId].externalCIRuns` — examine runs and jobs directly from the session data
35
+ 4. For a failed job, call `get_ci_logs(sessionId, repoId, jobId)` to save the log to a file
36
+ 5. Use `Read(logFile)` to examine the log content — use `offset`/`limit` for large files
37
+
38
+ **Important:** Logs can be large (100KB+). Only fetch logs for failed or relevant jobs, and read only the sections you need.
@@ -0,0 +1,109 @@
1
+ # Delegation Reference
2
+
3
+ Delegation is the only way to act on a repository other than the one you are in. Polygraph keeps local clones of the other repos in the session, but they are not yours to touch: never `cd` into them, read their files, or run git in them. Everything happens through `spawn_agent` and `show_agent`.
4
+
5
+ The flow is **pointer-based**. `spawn_agent` hands you a delegation id. A cheap background subagent watches that id and tells you when it stops moving. You then read the answer yourself, once. Nothing re-pastes the brief, and no log lines pass through a middleman.
6
+
7
+ ## The delegation id
8
+
9
+ `spawn_agent` returns a short id (e.g. `frontend-1`) that names one child run. It is the handle for everything afterwards — polling, reading the result, following up, stopping. The id pins the repo AND the role, so once you have it you never re-specify either.
10
+
11
+ Keep every id you are given. Losing one means falling back to `repo` + `role` lookups, which are ambiguous the moment a repo hosts more than one agent.
12
+
13
+ ## Spawning
14
+
15
+ Call `spawn_agent` directly from the main conversation. This is a fast, non-blocking call that returns an id — it is not polling and does not belong in a subagent.
16
+
17
+ ```
18
+ spawn_agent(
19
+ sessionId: "<sessionId>",
20
+ repo: "<org/repo-name>",
21
+ instruction: "<the task instruction>",
22
+ role: "<optional role>",
23
+ context: "<optional context>",
24
+ agent: "<optional: claude | codex | opencode>",
25
+ model: "<optional model override>"
26
+ )
27
+ ```
28
+
29
+ `agent` picks the child's harness and `model` overrides its default model; include either only when the user named one.
30
+
31
+ Write the instruction as if to a competent engineer who cannot see your conversation: state the goal, the constraints, and what "done" looks like. The child has its own repo and its own context; it inherits nothing from yours.
32
+
33
+ Delegate to several repos in parallel by calling `spawn_agent` once per repo before waiting on any of them.
34
+
35
+ **Own-repo rule.** With the default role, `repo` must be a repository other than the one you are working in — never delegate into your own repo with the default role; work on it directly (ordinary local subagents are fine for that). Delegating into your own repo IS allowed with an explicit non-default `role`, because each (repo, role) pair is a separate agent slot and the child then runs alongside your own default-role work without colliding with it.
36
+
37
+ ## Waiting
38
+
39
+ For each id, launch one background poller subagent whose entire job is to block until that child stops moving. Give it the `sessionId` and the `id`, and nothing else.
40
+
41
+ - **Claude Code** — a background `Task` with `subagent_type: "polygraph:polygraph-delegate-subagent"`, `run_in_background: true`, and description `Delegate to <repo>`. Fall back to the bare agent name only if the namespaced form is not found.
42
+ - **OpenCode** — invoke `@polygraph-delegate-subagent`.
43
+ - **Codex** — launch `agent_type: "polygraph-delegate-subagent"` via Codex's own `spawn_agent`, and collect it with `wait_agent`.
44
+
45
+ The poller has exactly one tool and cannot read logs. It exits with a few lines naming the repo, the id, and the final status. That message is a doorbell, not a report — it tells you the child is worth reading, and nothing about what the child did.
46
+
47
+ **Routine polling never happens in the main conversation.** A waited `show_agent` loop run inline floods your context with status noise and is the single largest avoidable cost in a multi-repo session. That is what the poller exists to absorb.
48
+
49
+ ## Reading the result
50
+
51
+ When a poller exits, read the child's answer yourself with a single **unwaited** `show_agent` — no `waitForTransitionMs`, no `tail`:
52
+
53
+ ```
54
+ show_agent(sessionId: "<sessionId>", id: "<id>")
55
+ ```
56
+
57
+ `result.text` is the child's final message: what it did, what it found, what it wants you to know. This is the payload. Read it once, in the main conversation, and act on it.
58
+
59
+ One-off unwaited reads like this are cheap and expected inline. It is the *waiting* that belongs in a subagent, not the reading.
60
+
61
+ ## When the result is not enough
62
+
63
+ Only if `result.text` is missing, truncated, or the child failed in a way you cannot explain from it:
64
+
65
+ - Pass an explicit `tail` to `show_agent` to pull recent log lines.
66
+ - Page further back with the `page` param: `tail: 5, page: 2` returns the 5 lines before the newest 5, `page: 3` the window before that.
67
+ - If the user wants to watch the run live, point them at `polygraph agent attach <repo>` (plus `--role <role>` for a non-default agent) — an interactive terminal view for humans, not a command for you to run.
68
+
69
+ These are deliberate, targeted follow-ups. None of them belongs in a polling loop, and none of them is a reason to go looking at transcript files, `~/.polygraph/sessions`, or anything a harness saved to disk because a tool result was too large. `show_agent` is the supported interface.
70
+
71
+ ## Follow-ups
72
+
73
+ To send a child more work, call `spawn_agent` again with the SAME `repo` and the SAME `role`. If that (repo, role) still has a live task — working, or paused waiting on you — the orchestrator delivers your instruction to it as a follow-up instead of starting a second run. A (repo, role) pair therefore has at most one active child at a time.
74
+
75
+ A follow-up returns a **new** delegation id, linked to the previous one by a `continues` reference. The new id is the live handle: poll it, read it, follow up on it. The old id still addresses the earlier turn if you need to look back at it.
76
+
77
+ After a follow-up, launch a fresh poller subagent for the new id. The old poller has already exited; it does not resume.
78
+
79
+ ## Input-required
80
+
81
+ When a child needs an answer from you, it stops and the poller exits with status `input-required` and "needs attention."
82
+
83
+ Read the child with an unwaited `show_agent` as usual. `inputRequiredQuestion` carries the child's verbatim question. Surface it to the user as the child asked it — do not paraphrase or answer on the user's behalf — then send the answer back as an ordinary follow-up `spawn_agent` for the same (repo, role). Poll the new id it returns.
84
+
85
+ `permission-required` is a different state and is not yours to resolve here; see "Handling permission requests" in the skill.
86
+
87
+ ## Roles
88
+
89
+ A repository in a session can host several child agents at once, distinguished by **role**:
90
+
91
+ - **Omit by default.** Set a `role` only when the user very explicitly asked for a named one, or when a skill the user invoked prescribes one (e.g. `adversarial-review` uses `reviewer`). Never invent one.
92
+ - **Purpose.** Roles let independent streams of work run concurrently in one repo — a default agent implementing a feature while a `reviewer` or `ci-investigator` runs alongside. Each (repo, role) pair has at most one active child.
93
+ - **Default role.** An omitted `role` means the default role: `spawn_agent` without `role` starts or follows up with that repo's default-role agent.
94
+ - **Ids pin the role.** A delegation id already identifies one (repo, role) pair, so `show_agent` and `stop_agent` by id need no `role` argument. Pass `role` only when addressing an agent by `repo` instead of by id.
95
+ - **Logs.** Only default-role agents upload logs to the cloud and appear in the multiplexed stream (`polygraph session logs`). A non-default agent's transcript stays on this machine — the user can watch it with `polygraph agent attach <repo> --role <role>`.
96
+
97
+ ## Stopping
98
+
99
+ Cancel a running child by id:
100
+
101
+ ```
102
+ stop_agent(sessionId: "<sessionId>", id: "<id>")
103
+ ```
104
+
105
+ The response reports `sessionPreserved: true`: the stopped agent's session is kept so its context can be restored later. Restoring is read-only. After a resume, do not continue the prior work or make further changes until the user explicitly asks for them.
106
+
107
+ ## Before publishing
108
+
109
+ Every delegation must reach a terminal status — `completed`, `failed`, or `cancelled` — before you push branches or open PRs. A poller exiting on `input-required` is not terminal; it means the child is still waiting on you.