skills/completion-report/SKILL.md
--- name: completion-report description: Render a browsable HTML completion report at the tail of any autonomous coding run (Ralph, planner-worker, agentic-e2e-flow) or on demand for any git range. Shows per-story / per-PR cards with CI status, file-change stats, unified diffs, and a per-file rollback command. Inspired by ruizrica/agent-pi's completion-report extension. Fires automatically before Pushover when invoked from Ralph or planner-worker (the ping links to the report). Manual trigger vi
npx skillsauth add RonanCodes/ronan-skills skills/completion-reportInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
End-of-run artifact that answers four questions in one browser tab:
It's a single self-contained HTML file. No backend, no build step. Open it with open and read it in the browser. The HTML is also valid for emailing or sharing.
The shape is lifted from ruizrica/agent-pi's completion-report extension (see [ai-research:agent-pi]). The novelty for our flow is making it the tail call of every autonomous coding run, so the Pushover ping carries the report path as a deep link.
Automatic (the load-bearing case):
/ro:ralph run against a real backlog (NOT --plan-only, NOT one-shot --mode single exploration). Fires BEFORE /ro:pushover so the ping message can include the report path./ro:planner-worker run against a real backlog (NOT --plan-only). Same Pushover-precedes ordering./agentic-e2e-flow run that reached the ralph-or-planner-worker phase.The autonomous skills call this skill explicitly. Don't invoke it from inside an autonomous-loop body — only at the tail.
Manual:
/ro:completion-report.Do NOT fire:
git status / gh pr list — those are cheap and don't need rendering).Per repo, gitignored:
<repo-root>/.completion-reports/<YYYY-MM-DDTHH-MM>-<slug>.html
On first invocation in a repo, append .completion-reports/ to .gitignore (idempotent — check first). The slug comes from --title (kebab-cased) or, in autonomous mode, the PRD name (--prd <name>).
After writing, print the absolute path. If --open (default unless the parent skill passes --no-open), launch with open (macOS). The user wants open, not afplay-style direct playback, per memory feedback_open_audio_files.md — same principle applies here: GUI surface, not raw process.
The skill needs a commit range and a PR set. Pick whichever the caller supplied; otherwise auto-detect.
Priority order:
--prs n1,n2,n3 — explicit PR set. Resolves range from each PR's baseRefOid..headRefOid. Best when the caller (Ralph / planner-worker) already knows which PRs it shipped.--range <a>..<b> — explicit git range. Use as-is; no PR cards (only commit cards).--since <duration> (e.g. 4h, 1d) — git log --since=<duration> --pretty=%H. No PR cards unless gh pr list --state merged --search "closed:>=<computed-date>" returns matches.--prd <name> — read .ralph/<name>.progress.txt, extract every PR: #<n> line, treat as --prs.git merge-base HEAD origin/main..HEAD, PR set = gh pr list --author @me --state merged --search "closed:>=$(date -u -v-1d +%Y-%m-%d)" if gh available, otherwise empty.If the resolved range is empty (zero commits), exit early with a one-line summary: no commits in range, nothing to report. Do NOT write an empty HTML file.
┌────────────────────────────────────────────────────────────────┐
│ <title> │
│ <repo> @ <branch> · started <ts> · finished <ts> · <duration> │
│ <N> PRs · <M> commits · <added>+/<removed>- lines · <files> │
│ │
│ Risk panel — flags only show if triggered: │
│ ⚠ schema migration touched (drizzle/, migrations/) │
│ ⚠ env or secret changes (.env*, wrangler.toml secrets) │
│ ⚠ deletions > 100 lines in one PR │
│ ⚠ lockfile-only PRs │
└────────────────────────────────────────────────────────────────┘
┌─ PR #61 · ✅ merged · ✅ CI green · planner ────────────────────┐
│ Title: "feat(onboarding): add email-verification step" │
│ Author: claude (Ralph) · Squash: 8240af6 │
│ Files: 6 changed · +142 / -8 │
│ Summary: <if available from PRD/progress.txt> │
│ │
│ Files (click to expand diff): │
│ ▸ src/auth/verify.ts +88 / -0 [revert this file]│
│ ▸ src/auth/verify.test.ts +42 / -0 [revert this file]│
│ ▸ db/schema.ts +6 / -2 [revert this file]│
│ ... │
│ │
│ Rollback this PR: git revert -m 1 8240af6 │
└─────────────────────────────────────────────────────────────────┘
(repeat per PR / per orphan commit)
Each [revert this file] button is a one-liner clipboard copy:
git checkout <sha-before-pr>~1 -- <file>
The HTML uses <details>/<summary> for collapsible diffs, no JS framework. Syntax highlighting via inline <pre> with CSS classes (highlight.js loaded from a vendored copy in the skill's assets/).
| Source | Use |
|---|---|
| git log <range> | commit list, commit messages, timestamps |
| git diff <range> per file | unified diff bodies |
| git diff --stat <range> | per-file change stats |
| gh pr view <n> --json title,number,state,mergeable,statusCheckRollup,author,baseRefOid,headRefOid,mergedAt,body | PR card data |
| gh pr diff <n> | optional fallback when range diff is messy |
| .ralph/<prd>.progress.txt | story timestamps, duration, learnings (when --prd supplied) |
| .ralph/<prd>.session.md | session-level duration |
Surface a top-of-page warning when ANY of these match a PR or commit in range. The risks are deterministic — no LLM judgement, just file-path and stat checks:
**/migrations/**, **/drizzle/**.sql, **/prisma/migrations/**, or commit message starting with 🗄️/migration: per the repo's emoji map..env*, wrangler.toml with a [[secrets]] block change, **/secrets.toml, or commit message containing secret/token/key:.package-lock.json, pnpm-lock.yaml, bun.lockb, yarn.lock, or Cargo.lock.✨ feat: and no path matches **/*.test.* / **/*.spec.* / tests/**.These are warnings, not blockers — the user reads the report after the run, the gate is the merger / reviewer.
/ro:pushoverThe autonomous-skill callers (Ralph, planner-worker, agentic-e2e-flow) drive this ordering:
/ro:completion-report with --prd <name> (or --prs <list>) and --no-open (we don't want to pop a browser on a remote / SSH session)./ro:pushover with a --url file://<absolute-path> so the ping deep-links to the report.Pushover message anatomy stays the same (state + concrete metric + next step) — the URL is supplementary, not a replacement for the message text.
If the report isn't useful (zero commits, range empty), the caller skips both the report and the URL but STILL sends the Pushover ping with state.
# After a heavy hand-rolled session, no flags — defaults to "since I branched from origin/main"
/ro:completion-report
# Specific PR set (e.g. cherry-picked, or PRs you reviewed today)
/ro:completion-report --prs 61,62,64 --title "auth slice — 3 PRs"
# A named PRD, after Ralph
/ro:completion-report --prd phase-2-onboarding-2026-05-06
# Custom git range, custom title
/ro:completion-report --range origin/main..HEAD --title "feature-x review"
# Don't open the browser (useful in scripts and over SSH)
/ro:completion-report --no-open
The skill is a single bash + heredoc that:
.completion-reports/ is gitignored (idempotent).cat <<'EOF' > <path> heredoc that interpolates pre-computed sections. No template engine.--no-open.Three scripts under scripts/:
scripts/generate.sh — main entrypoint, orchestrates the steps above.scripts/risk-checks.sh — runs each risk-panel trigger against the resolved range, prints triggered ones as key:value lines.scripts/diff-to-html.sh — wraps git diff per file into a syntax-highlighted <pre> block. Uses pygmentize if available; falls back to plain <pre>.Bash, not Node — keeps the skill dependency-free for any repo.
feedback_artifact_format_mix.md) but defer until a real "I want to paste this into a PR description" moment surfaces. HTML wins for diffs + collapsible sections; markdown wins for inline pasting. If both end up needed, expose a --format html|md flag and reuse the same risk + range resolution.git log --graph and adding Mermaid drags in a renderer dependency. The HTML report is a list of changes, not a diagram of them.assets/highlight.min.js; do NOT load from a CDN. Bandwidth and offline-on-plane reasons.ruizrica/agent-pi's completion-report extension. See ai-research:agent-pi and the article ai-research:agent-pi-medium-ruiz./ro:ralph, /ro:planner-worker, /ro:pushover, /ro:close-session.development
--- name: worktree description: Coordinate multiple agents on one repo via a worktree-lock pool, so two agents never clobber each other's working tree. Acquire the first free slot (main, then beta/gamma… worktrees, created on demand), work there on your own branch, release when you've pushed. Use before modifying any repo that might be in use by another agent (factory, dataforce, etc.), or whenever you're told a repo is being worked on. Backed by `ro worktree`. category: development argument-hin
testing
--- name: ship description: Ship a feature branch the local-CI-first way — run the full local gate, push, open a PR, squash-merge, then deploy, without waiting on GitHub Actions. Use when a branch is ready for main and you want it merged and deployed now. Reads CI policy from `ro ci` (default skips remote CI because GitHub Actions billing keeps hitting limits). Sibling to /ro:gh-ship (waits on GitHub checks) and /ro:cf-ship (the deploy half). Triggers on "ship it", "ship this", "merge and deploy
testing
--- name: setup-logging description: Set up (or audit) the observability stack in a TanStack Start + Cloudflare Workers app so it is "diagnosable by default" — structured logging (logtape) with a request context carrying trace_id + userId + tenant/orgId, a trace_id propagated FE→BE→logs→Sentry→PostHog, Cloudflare Workers observability enabled, and Sentry + PostHog wired. Two modes: `setup` (wire it into an app) and `audit` (check an existing app + report gaps). Use when scaffolding a new app, wh
development
Manage credentials INSIDE the active ~/.claude/.env file — read which token/account to use for a given app (Simplicity vs Dataforce vs Ronan-personal), add or update a secret WITHOUT it passing through the chat (an interactive Terminal window prompts for it), and track secrets that were exposed in a transcript so they get rotated. Sibling to /ro:context (which switches WHICH env file is active). Use when the user wants to add an API key/token/secret, asks "which credential do I use for X", needs the env organized/labelled, or a secret was pasted into the chat and should be rotated.