| name | pm-improve |
| description | Distinct from `pm-review` (which *scores* whether an issue has the right structural shape), this skill *adds* project-specific context to an existing Linear or GitHub issue — relevant files, recent commits, owning modules, best-practice references, prior-art / related issues, and clarifying questions the author should answer before work starts. Use it when you want to give an issue more material to work from, not when you want to grade it. Trigger phrases "improve this issue", "enrich issue <ID>", "add context to this issue", "what's missing from this issue", "any relevant code for this issue", "research this issue", "qna this issue", "/pm-improve". Also use proactively after `pm-review` flags structural gaps that hint at missing context. Produces a draft enrichment; with `--apply`, posts it as a comment on the issue. Safe to re-run as repo state drifts — the marker mechanic replaces rather than stacks. |
| version | 0.44.4 |
PM Improve
Enrich an issue with the context that makes it actionable — repo references, prior-art links, best-practice pointers, and clarifying questions. Distinct from pm-review (which is structural) and pm-issues (which is lifecycle). This skill answers: "if a teammate picked this up tomorrow, what would they need to know that's not in the body?"
The enrichment is suggestive, not authoritative. It's a draft set of additions for the operator to evaluate — they decide what's worth pasting into the issue body or posting as a comment.
When to run this
- After
pm-review returned a "needs more information" verdict and the gap is context (not "fill the acceptance criteria").
- When grooming an issue before assigning it to someone unfamiliar with the area.
- When the issue was filed by a stakeholder who lacks repo-level context (PM, designer, support engineer).
- Not for issues that are already detailed and clear — running this on a well-written issue produces noise.
Safe to re-run
pm-improve is deliberately non-idempotent — re-running it after time has passed surfaces new commits, new related issues, and new clarifying questions as the repo and tracker evolve. That's a feature, not a bug: an issue that sat in the backlog for a month genuinely has more context around it now than it did when filed.
To prevent comment stacking, the --apply path embeds a marker (<!-- pm-improve: … -->) and detects prior pm-improve comments on the issue — the operator chooses whether to replace the old enrichment or add a new one. The marker is matched by prefix (not version), so upgrades don't break recognition.
Four enrichment streams
The skill produces up to four blocks. Each is optional — if a stream returns nothing useful, omit it (do not pad).
1. Repo context
Find the files, modules, and recent changes most likely relevant to this issue.
Heuristics that have worked in practice:
- Title/body keywords → file matches. Run
grep -r -l for the most specific nouns in the title against the repo. Filter out vendored / build directories. Aim for 3-7 file hits, not 50.
- Recent commits.
git log --since="3 months ago" -i --grep="<keyword>" --oneline for each of the top keywords. Cap at 5 commits per keyword.
- Owners. If
CODEOWNERS exists and any matched file falls under a codeowner block, surface the owner(s).
- Related symbol definitions. For bugs especially, if a function/class name appears in the body, locate where it's defined.
Output as a tight list — file paths with one-line "why" annotations:
**Repo context**
- `src/auth/middleware.ts:42` — session-validation logic, mentioned in body
- `src/auth/__tests__/middleware.test.ts` — existing tests near the affected area
- Recent change: 8a1f3d2 (3 weeks ago) "fix: handle expired JWT in refresh path"
- CODEOWNERS: @auth-team
If the repo isn't accessible or grep returns nothing, omit the block entirely — do not write "No repo context found."
2. Best-practice / domain references
If the issue touches a topic with established best practices, point at the canonical reference. Only when it's actually useful — citing a Wikipedia page on "what is a bug" is not useful.
Selection rule: would a senior engineer in this area actually paste this link in code review? If not, skip it.
When the project has registered SME repos via the repo-sme plugin, prefer those — they're already curated:
ls ~/.claude/repo-sme/repos/ 2>/dev/null
If a registered SME repo plausibly applies (e.g., issue is about Obsidian plugin API, and obsidian-api is registered), suggest the operator delegate the question to the SME agent rather than padding the issue with links:
**Suggested next step:** Run `repo-sme query obsidian-api "<question>"` for grounded API context before posting links.
3. Related issues / prior art
Search the tracker for issues that share keywords with this one. The goal is to surface dupes, prerequisites, and follow-ups — not the top-10 most-recent issues:
linear issue query --json --search "<top 2-3 keywords>" --team <team_key> --limit 10 --no-pager
gh issue list --repo <org/repo> --search "<keywords>" --state all --limit 10 --json number,title,state,url
Filter aggressively. For each candidate, decide: is this a duplicate, a parent, a child, a peer, or unrelated? Drop "unrelated". Cap the surfaced list at 5 entries.
**Related issues**
- ENG-31 (closed): "JWT refresh fails on Safari" — likely related; same auth surface
- ENG-58 (open): "session middleware refactor" — possible prerequisite, check ordering
4. Clarifying questions (Q&A)
The hardest stream, and the most valuable. Generate questions whose answers would unblock implementation. Each question must be specific enough that the operator can answer it in one sentence.
Bad questions to avoid:
- "What are the acceptance criteria?" — that's the operator's job, not yours to ask.
- "How should this work?" — too open.
- "Have you considered ...?" — leading, condescending.
Good questions:
- "Should expired refresh tokens trigger a full re-login, or fall through to the session-renewal endpoint? Existing middleware at
src/auth/middleware.ts:42 does the latter."
- "Is this scoped to the web client only, or should the iOS app also be updated? The mobile auth flow is separate."
Cap at 3-5 questions. If you can't generate genuinely useful ones, omit the block.
Stuck-aware enrichment
When enriching an issue, check whether the issue ID appears in the stuck lens output (via pm-cache.js lens --slug <slug> --lens stuck). If yes, prepend the enrichment prompt with:
"This issue is flagged stuck for: <reasons>. Propose the specific unblock action the assignee needs to take, in addition to any general enrichment."
This makes enrichment unblock-aware. The lens result's byIssue map (now plain object from the lens verb) lets you look up <issue_id> → reasons array (e.g., ['stale', 'no_update']).
Workflow
Step 1: Fetch and parse the issue
Same fetch logic as pm-review. Cache the body, labels, and title.
Step 2: Classify the tag
Use pm-templates' classifier. The tag biases which enrichment streams matter:
- bug → repo context (files near the failure) and related issues (likely dupes) are usually most valuable
- feature → best-practice references and clarifying questions
- task / chore → minimal enrichment usually — most context is in the title
- spike → clarifying questions about scope and time-box
Step 3: Run the four streams in parallel
Each stream is independent. If any one fails (network error, missing CODEOWNERS), continue with the others — log the failure but don't block the rest.
Step 4: Apply project conventions and compose the draft
Conventions pass first. If <repo>/.claude/pm/conventions.md exists, consult its ## Issue enrichment section (and any tag-specific guidance) before composing. Examples of what conventions might dictate:
- "Every bug must link to the failing test path." → inject into the Repo context stream
- "Don't link external docs unless they're from a registered SME repo." → trim the Best-practice references stream
- "Always include the parent issue ID for sub-issues." → inject into Related issues
Apply convention rules as additional content for the relevant stream — do not invent a "Conventions" block in the draft (that's the reviewer's shape, not enrichment's).
Then compose.
Combine non-empty streams into a single markdown block, header ## Context (added by pm-improve):
## Context (added by pm-improve)
**Repo context**
- `src/auth/middleware.ts:42` — session-validation logic, mentioned in body
- Recent change: 8a1f3d2 "fix: handle expired JWT in refresh path"
**Related issues**
- ENG-31 (closed): "JWT refresh fails on Safari" — likely related; same auth surface
**Open questions**
1. Should expired refresh tokens trigger full re-login, or fall through to renewal endpoint?
2. Is this web-only, or should mobile clients also update?
Step 5: Show and optionally apply
Print the draft to the terminal. Then ask the operator: "Post this as a comment on <ID>?" — only post on explicit yes.
The --apply flag skips the confirmation and posts directly:
linear issue comment create <ID> --body-file "$DRAFT_FILE"
gh issue comment <NUMBER> --repo <org/repo> --body-file "$DRAFT_FILE"
Like pm-review, every posted comment carries a two-layer header at the top:
> *Generated by `pm-improve` to surface project-specific context. Edits welcome — this is a draft set of additions, not authoritative.*
<!-- pm-improve: v<plugin-version> -->
## Context (added by pm-improve)
... (the four enrichment streams) ...
The blockquote is the human-facing provenance. Readers months later can tell at a glance that this comment is machine-drafted enrichment, not a teammate weighing in.
The HTML marker is the machine-readable idempotency handle. Match by prefix, not exact version. When re-improving, grep for <!-- pm-improve: (ignoring the version). Any prior pm-improve comment — from any version — counts as "we've been here before." The version in the marker is provenance for humans reading the comment later, not the match key. If you tied the match to the exact version, every plugin upgrade would silently stack new comments alongside old ones.
When a prior marker is found, ask: replace the prior enrichment comment, or stack a new one.
What this skill does NOT do
- It does not edit the issue body. Enrichment goes as a comment so the operator can decide what's worth promoting into the body.
- It does not implement, plan, or estimate. It surfaces context; humans plan.
- It does not run code or tests. Read-only against the repo.
- It does not score the issue. That's
pm-review's shape.
Pipelining with pm-review
The intended loop:
/pm-review <ID> # what's structurally missing?
/pm-improve <ID> # here's the context that might fill the gaps
/pm-review <ID> # confirm the operator's edits closed the gaps
pm-improve is not idempotent — repo state and tracker state drift, so re-running it after time has passed will surface new commits and new related issues. That's a feature; the comment marker lets the operator decide whether the prior comment should be replaced.