pm-report
Use this skill when the user asks for a "status report", "what changed", "what's stuck", "what shipped", "velocity report", "what's next to pick up", "review prs", "open prs", "ready to merge", "is this project on track", "project health", "are projects at risk", "which projects are off track", or any project status summary that should be persisted as a document or sent as email. **Eight profiles** — movement (default — what changed), stuck (what's blocked), throughput (velocity vs prior), next-up (what's ready), exec (one-pager standup), prs (open-PR review), full (legacy daily/weekly behavior), **project-health** (per-project on-track / at-risk / off-track classification with milestone burndown — for project-tier health questions like "is this project on track" or "which projects are at risk"). Produces Markdown plus HTML and/or PDF; optional handoff to resend-cli for delivery.
What this skill does
# PM Report
Generate an actionable, profile-driven status report for the active project. Each profile renders only the sections that answer one operator question — no more "show everything by default." Output formats: Markdown (always), HTML, PDF, or both.
If the user asks for a *briefing* in the conversation (no document, no email) — that is `pm-status`'s job, not this skill. Reports here are intended to be persisted and shared.
## When to use this skill
Trigger phrases grouped by the profile they imply:
- **movement** (default): "what changed", "what shipped", "what got done today/this week", "daily movement"
- **stuck**: "what's stuck", "what's blocked", "what's dragging", "anything stalled"
- **throughput**: "velocity report", "are we on track", "pace this week", "throughput vs last week"
- **next-up**: "what's next", "what's ready to pick up", "what should I grab next"
- **exec**: "standup", "status report", "daily report", "weekly report", "one-pager"
- **prs**: "review prs", "open prs", "what prs need attention", "ready to merge", "waiting on me to review"
- **full**: "everything", "full report", legacy `--kind daily|weekly` without `--profile`
Also fires on the `/pm-report` slash command.
## Profiles
Each profile is a composition of lenses (pure functions in `hooks/lib/report-lenses.js`) plus a bundled template.
- **movement** *(default)* — Answers "what changed in the window?" Renders completions, started/reopened, created, and updated-only buckets plus a per-team movement rollup and per-assignee accountability. Use when the operator wants a record of what moved.
When composing narrative for the **movement** profile, each per-team block carries a derived `taxonomy` (the type-relevant labels that team used in the window) and, when the `other` bucket is non-zero, the labels behind it. Use these to read a team's movement in its own terms — e.g. note when a team's large `other` count is because it files most work under a non-canonical label like `Improvement`. Add at most one interpretive line per notable team; never restate or duplicate the deterministic per-team block.
- **stuck** — Answers "where are we blocked?" Renders newly-stale issues (crossed the threshold inside the window), drifting WIP, unassigned-with-priority, blocked-labeled, and awaiting-info-from-operator buckets, plus a WIP-aging distribution. Use when the operator wants an unblock-list.
- **throughput** — Answers "are we moving faster or slower?" Renders completion-rate compare, cycle-time compare, per-team and per-assignee deltas vs the prior equal-length window, and end-of-window WIP aging. Use when the operator wants a velocity readout.
- **next-up** — Answers "what's ready to pick up?" Renders ready-to-work issues (priority + assignee + template-validated title) plus watchouts (close-to-ready with missing signals) and a compact "stuck on the operator's desk" tail. Use when the operator is planning the next slice of work.
- **exec** — One-pager standup. Renders single-line headlines for movement, stuck, and throughput plus top-N changes / top-N stuck. Use when the operator wants something to paste into a stakeholder update or email.
### `prs`
Reports across **open pull requests** rather than issues. Buckets PRs by funnel stage (draft, no_reviewers, awaiting_review, changes_requested, checks_failing, conflicts, approved_pending, ready_to_merge), shows what's waiting on you (to review / push / merge), flags stale and orphan PRs, and **cross-references the issue `stuck` lens** to surface PRs whose merge would directly unstick blocked work. Requires `pull-prs` (or `prs-sync` verb) to populate the `prs.json` cache first. Needs the `gh` CLI installed and authenticated.
- **full** — Legacy "render everything" behavior. Maps to `daily.md` (kind=daily) or `weekly.md` (kind=weekly). Preserved for back-compat with scheduled reports and existing scripts.
## Profile resolution
The skill picks a profile using this decision tree (first match wins):
1. **Explicit flag** — `--profile <name>` is always honored.
2. **Legacy kind** — `--kind daily|weekly` with no `--profile` resolves to `full` (the legacy templates).
3. **Natural-language match** against the operator message:
| Phrase | Profile |
|---|---|
| "stuck" / "blocked" / "dragging" | `stuck` |
| "shipped" / "what got done" / "what changed" | `movement` |
| "velocity" / "pace" / "on track" / "throughput" | `throughput` |
| "ready" / "what's next" / "pick up" | `next-up` |
| "standup" / "status report" / "daily report" / "weekly report" | `exec` |
| "everything" / "full" | `full` |
4. **Fallback** — `movement`.
If the operator message is ambiguous and the cache is empty (cold start), ask once: "Movement (what changed), Stuck (what needs unblocking), or Throughput (velocity)?"
### Legacy single-slug inputs (still supported)
For back-compat, the original per-slug invocation still works: `--slug <slug> --kind daily|weekly` (without `--profile`) reads the slug's cache + snapshots and renders the legacy daily / weekly templates via the `full` profile. Prefer the profile + scope form for new reports.
## Workflow
### Step 1: Resolve the profile
Apply the decision tree above. If the user passes `--profile`, use it. Otherwise pattern-match the message and fall back to `movement`.
### Step 2: Resolve the scope
One of `workspace:<slug>` (default), `team:<KEY>[+subteams]`, `project:<slug>[+deps[:upstream|downstream]]`, `repo:<org/repo>`, or `all`. Ask if not specified: "Scope this report to workspace / team / project / repo / all?"
### Step 3: Resolve the window
`today` (since UTC midnight), `week` (last 7 days), `month` (last 30 days), or `custom <YYYY-MM-DD> <YYYY-MM-DD>`. Ask if not specified.
### Step 4: Render + run the matching pm-script
Each profile has a bundled `pm-script` that refreshes the cache deterministically (`pull-movement`, `pull-stuck`, `pull-throughput`, `pull-next-up`, `pull-exec`). Render the first ~20 lines of the substituted script and ask "Run this?" before executing — unless the caller passes `--auto-pull` (CI / cron). Skip this step entirely if `pm-status` already synced the workspace this session and the profile doesn't need extra snapshots.
### Step 5: Invoke the generator
```bash
node "$CLAUDE_PLUGIN_ROOT/skills/pm-report/scripts/generate-report.js" \
--profile <movement|stuck|throughput|next-up|exec|full> \
--scope "<scope-expression>" \
--from "<YYYY-MM-DD>" --to "<YYYY-MM-DD>" \
--format both \
--out "$HOME/.claude/project-manager/reports/<slug>"
```
Key flags:
- `--profile <name>` — movement | stuck | throughput | next-up | exec | full
- `--kind daily|weekly` — back-compat (without `--profile`, maps to `full`)
- `--scope <expr>` — scope grammar (workspace/team/project/repo/all)
- `--from`, `--to` — explicit window endpoints (overrides `--date`)
- `--operator <login>` — needed by the `needs_info_self` reason in the stuck lens
- `--auto-pull` — skip the "Run this?" gate (CI / cron)
- `--format pdf|html|both|md` — default `both` (always also writes `.md`)
- `--out <dir>` — default `~/.claude/project-manager/reports/<slug>`
- `--template <path>` — override the bundled template
- `--date <YYYY-MM-DD>` — override "today" for testing / backfilling
The script prints JSON describing what it wrote:
```json
{ "ok": true, "profile": "movement", "files": ["...md", "...html", "...pdf"], "comparedTo": { "...": "..." }, "lensesUsed": ["movement","accountability","inProgress"] }
```
### Step 6: Show paths + offer delivery
Read the JSON output and tell the operator where each file landed and what it compared against (so they can spot when a snapshot was missing). Then offer delivery via the `resend-cli` skill — only ask if the project has a `.resend.md` configured or the user mentioned sending. If emailing, hand off the HTML file as the body; do not attach the PDF unless the user asks.
### First-time PDF setup (one-time)
PDF rendering uses `md-to-pdf` (Puppeteer + Chromium). OnRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.