{"id":"2330de19-f8a9-4a5d-a220-cf0deea5bc5b","shortId":"t7Rv5W","kind":"skill","title":"pr-reply","tagline":"Draft friendly, concise replies to pull request review comments. Use when user pastes a PR comment, asks to \"reply to a PR comment\", \"/pr-reply\", \"answer this reviewer\", or wants help responding to review feedback. Don't use for posting comments to GitHub, creating new PRs, or re","description":"# PR Reply\n\nDraft replies to reviewer comments grounded in the project's source of truth (specs, ADRs, CHANGELOG, code, prior PRs). Output is text only — the user posts to GitHub themselves.\n\n## Pre-loaded context\n\n- Branch: !`git rev-parse --abbrev-ref HEAD`\n- Recent log: !`git log --oneline -15`\n- Spec dir: !`ls docs/specs/ docs/adrs/ 2>/dev/null`\n\n## Inputs\n\nAccept any of:\n\n1. **Quoted comment + file reference** (most common, fastest)\n   ```\n   @src/foo.ts\n   > Why are we wrapping JSON.stringify here?\n   ```\n\n2. **GitHub permalink to a review comment** — fetch with `gh`:\n   ```bash\n   # https://github.com/<owner>/<repo>/pull/<n>#discussion_r<id>\n   gh api /repos/<owner>/<repo>/pulls/comments/<id>\n   ```\n   Returns body, path, line, diff_hunk, user, in_reply_to_id. Use those fields to skip the \"ask for file/line\" step.\n\n3. **PR number** — fetch all review comments to triage in bulk:\n   ```bash\n   gh api /repos/<owner>/<repo>/pulls/<n>/comments --jq \\\n     '.[] | {id, path, line, user: .user.login, body, in_reply_to_id}'\n   ```\n   When user says \"reply to all open comments on PR #289\", iterate.\n\n4. **Code block pasted inline** — treat the same as quoted text; extract the file path from a leading `@path` or fenced header.\n\nAlways confirm file + line before drafting if not derivable from input.\n\n## Workflow\n\n0. **Resolve input** — if a permalink or PR number is given, fetch via `gh` (see Inputs). Extract: comment body, file path, line, prior replies.\n\n1. **Locate sources of truth** in this order, stopping when sufficient:\n   - `docs/specs/*.md` — architecture decisions, design rationale\n   - `docs/adrs/*.md` — legacy ADR location (if no specs/)\n   - `CHANGELOG.md` — historical context for \"why does X exist\"\n   - `git log -- <file>` — when the line was introduced and why\n   - `gh pr list --search` — prior debate on the same topic\n   - The code itself\n\n2. **Classify the comment** — picks the response shape:\n\n   | Type | Shape |\n   |---|---|\n   | Already-decided | Acknowledge + link to spec/decision + offer to revisit on concrete pain |\n   | Valid in-scope | Acknowledge + plan the change inline |\n   | Valid out-of-scope | Acknowledge + commit to follow-up + scope out of current PR |\n   | Misconception | Correct gently with one fact + restate decision |\n   | Praise / nit | One-liner |\n\n3. **Draft response** following the rules below.\n\n4. **Iterate on request** — user often asks shorter, friendlier, or rephrased.\n\n## Tone Rules\n\n- **English only.** Even if user writes in another language.\n- **Sound like a human.** No em dashes (`—`). Use commas, periods, parentheses, \"but\", \"so\", \"and\" instead. Em dashes read as AI-generated.\n- **Friendly but not sycophantic.** \"Good question\", \"Good catch\", \"Good call\". Pick one, don't stack.\n- **Concise.** 1–3 sentences typical, 1 paragraph max. Sacrifice grammar for brevity.\n- **Specific.** Reference file/decision/PR number when pointing at sources.\n- **No conditional fluff.** \"I think maybe we could possibly...\" → cut.\n- **Emoji.** Default off. Add 🙌 / ✅ only if the repo's existing PR comments use them.\n- **End with engagement** when appropriate: \"Happy to revisit if...\", \"Want me to address it in this PR or follow-up?\"\n\n## Response Templates\n\n**Already-decided:**\n> {Acknowledgment}. We landed on this in {spec/PR link}, {one-line reason}. Happy to revisit if there's a concrete pain point.\n\n**Out-of-scope:**\n> {Acknowledgment}. {One-line answer}. Out of scope for this PR, but happy to address it in a follow-up.\n\n**Misconception:**\n> {Acknowledgment}. Quick clarification: {correct fact}. {Restate intent if needed}.\n\n**In-scope fix:**\n> {Acknowledgment}. I'll {specific action}. {One-line rationale if non-obvious}.\n\n## Rules\n\n- NEVER fabricate decisions, spec sections, or PR numbers — only cite what you've verified\n- NEVER post to GitHub — output is text for the user to paste\n- ALWAYS verify cited line numbers / PR numbers exist before referencing\n- When pointing at specs, link with the actual filename (`docs/specs/<file>.md`), not a hallucinated path\n- If multiple comments are pasted at once, draft replies separately, one per comment\n\n## Examples\n\n**Already-decided (string-only contract debate):**\n\n> We landed on this in a [previous discussion](pr-link). String-only simplifies the library but pushes parsing, defaults, and type assertions to every call site. We'd also lose compile-time enforcement (`setDarkMode(\"yes\")` would compile), and migration logic would scatter across MFEs instead of staying in the getter. Happy to revisit if there's a concrete pain point.\n\n**Out-of-scope (postbuild shim):**\n\n> Good catch! The shim isn't browser-storage-specific. It was added earlier for `utils/` to support consumers on older Jest versions that don't follow `exports`. Out of scope for this PR, but happy to revisit in a follow-up.\n\n**Misconception (browser quota):**\n\n> Good call, conservative start is easier to expand than retract. Quick clarification: 4KB isn't the browser cap (browsers allow ~5-10MB per origin), it's our soft ceiling against the 50KB per-MFE budget. Principle still applies though, so I'll drop the default to 2KB.\n\n**In-scope fix (missing CHANGELOG):**\n\n> Good catch! Looks like the previous bumps landed without updating the CHANGELOG. I'll backfill the missing entries in this PR to avoid pushing the gap further.\n\n## Error Handling\n\n- No PR comment provided — ask for the quoted text + file/line\n- Spec/decision referenced doesn't exist — say so and re-classify the comment\n- Reviewer's question reveals a real bug — flag to user, suggest fixing in-scope rather than just replying\n\n## See Also\n\n- [code-review](../code-review/SKILL.md) — review a PR (opposite direction)\n- [create-pull-request](../create-pull-request/SKILL.md) — create the PR being commented on","tags":["reply","agent","skills","helderberto","agent-skills","ai-tools","antigravity","claude-code","cursor","developer-tools","gemini-cli","markdown"],"capabilities":["skill","source-helderberto","skill-pr-reply","topic-agent-skills","topic-ai-tools","topic-antigravity","topic-claude-code","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-markdown","topic-plugin","topic-sdlc","topic-skills","topic-tracer-bullet"],"categories":["agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/helderberto/agent-skills/pr-reply","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add helderberto/agent-skills","source_repo":"https://github.com/helderberto/agent-skills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (5,797 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:09:14.038Z","embedding":null,"createdAt":"2026-05-18T13:14:54.316Z","updatedAt":"2026-05-18T19:09:14.038Z","lastSeenAt":"2026-05-18T19:09:14.038Z","tsv":"'-10':801 '-15':100 '/code-review/skill.md':911 '/comments':183 '/create-pull-request/skill.md':921 '/dev/null':107 '/pr-reply':27 '/pull':139 '/pulls':182 '/pulls/comments':145 '/repos':144,181 '0':241 '1':112,265,448,452 '2':106,127,320 '289':205 '2kb':828 '3':167,381,449 '4':207,388 '4kb':792 '5':800 '50kb':812 'abbrev':92 'abbrev-ref':91 'accept':109 'acknowledg':333,347,357,517,543,565,578 'across':710 'action':582 'actual':635 'ad':746 'add':480 'address':503,557 'adr':67,285 'ai':430 'ai-gener':429 'allow':799 'alreadi':331,515,658 'already-decid':330,514,657 'also':695,907 'alway':229,618 'anoth':408 'answer':28,547 'api':143,180 'appli':819 'appropri':495 'architectur':278 'ask':20,163,394,868 'assert':688 'avoid':857 'backfil':849 'bash':137,178 'block':209 'bodi':147,190,259 'branch':86 'breviti':458 'browser':741,778,796,798 'browser-storage-specif':740 'budget':816 'bug':893 'bulk':177 'bump':841 'call':441,691,781 'cap':797 'catch':439,735,836 'ceil':809 'chang':350 'changelog':68,834,846 'changelog.md':290 'cite':601,620 'clarif':567,791 'classifi':321,884 'code':69,208,318,909 'code-review':908 'comma':418 'comment':12,19,26,43,57,114,133,173,202,258,323,488,645,655,866,886,926 'commit':358 'common':118 'compil':698,704 'compile-tim':697 'concis':6,447 'concret':341,536,725 'condit':468 'confirm':230 'conserv':782 'consum':752 'context':85,292 'contract':663 'correct':369,568 'could':474 'creat':46,918,922 'create-pull-request':917 'current':366 'cut':476 'd':694 'dash':416,426 'debat':312,664 'decid':332,516,659 'decis':279,375,594 'default':478,685,826 'deriv':237 'design':280 'diff':150 'dir':102 'direct':916 'discuss':140,672 'docs/adrs':105,282 'docs/specs':104,276,637 'doesn':876 'draft':4,53,234,382,650 'drop':824 'earlier':747 'easier':785 'em':415,425 'emoji':477 'end':491 'enforc':700 'engag':493 'english':401 'entri':852 'error':862 'even':403 'everi':690 'exampl':656 'exist':297,486,625,878 'expand':787 'export':761 'extract':218,257 'fabric':593 'fact':373,569 'fastest':119 'feedback':37 'fenc':227 'fetch':134,170,252 'field':159 'file':115,220,231,260 'file/decision/pr':461 'file/line':165,873 'filenam':636 'fix':577,832,898 'flag':894 'fluff':469 'follow':361,384,510,562,760,775 'follow-up':360,509,561,774 'friend':5,432 'friendlier':396 'gap':860 'generat':431 'gentl':370 'getter':717 'gh':136,142,179,254,307 'git':87,97,298 'github':45,80,128,609 'github.com':138 'given':251 'good':436,438,440,734,780,835 'grammar':456 'ground':58 'hallucin':641 'handl':863 'happi':496,529,555,718,769 'head':94 'header':228 'help':33 'histor':291 'human':413 'hunk':151 'id':156,185,194 'in-scop':344,574,829,899 'inlin':211,351 'input':108,239,243,256 'instead':424,712 'intent':571 'introduc':304 'isn':738,793 'iter':206,389 'jest':755 'jq':184 'json.stringify':125 'land':519,666,842 'languag':409 'lead':224 'legaci':284 'librari':681 'like':411,838 'line':149,187,232,262,302,527,546,585,621 'liner':380 'link':334,524,632,675 'list':309 'll':580,823,848 'load':84 'locat':266,286 'log':96,98,299 'logic':707 'look':837 'lose':696 'ls':103 'max':454 'mayb':472 'mb':802 'md':277,283,638 'mfe':815 'mfes':711 'migrat':706 'misconcept':368,564,777 'miss':833,851 'multipl':644 'need':573 'never':592,606 'new':47 'nit':377 'non':589 'non-obvi':588 'number':169,249,462,599,622,624 'obvious':590 'offer':337 'often':393 'older':754 'one':372,379,443,526,545,584,653 'one-lin':378,525,544,583 'onelin':99 'open':201 'opposit':915 'order':272 'origin':804 'out-of-scop':353,539,728 'output':72,610 'pain':342,537,726 'paragraph':453 'parenthes':420 'pars':90,684 'past':16,210,617,647 'path':148,186,221,225,261,642 'per':654,803,814 'per-mf':813 'period':419 'permalink':129,246 'pick':324,442 'plan':348 'point':464,538,629,727 'possibl':475 'post':42,78,607 'postbuild':732 'pr':2,18,25,51,168,204,248,308,367,487,507,553,598,623,674,767,855,865,914,924 'pr-link':673 'pr-repli':1 'prais':376 'pre':83 'pre-load':82 'previous':671,840 'principl':817 'prior':70,263,311 'project':61 'provid':867 'prs':48,71 'pull':9,919 'push':683,858 'question':437,889 'quick':566,790 'quot':113,216,871 'quota':779 'r':141 'rather':902 'rational':281,586 're':50,883 're-classifi':882 'read':427 'real':892 'reason':528 'recent':95 'ref':93 'refer':116,460 'referenc':627,875 'rephras':398 'repli':3,7,22,52,54,154,192,198,264,651,905 'repo':484 'request':10,391,920 'resolv':242 'respond':34 'respons':326,383,512 'restat':374,570 'retract':789 'return':146 'rev':89 'rev-pars':88 'reveal':890 'review':11,30,36,56,132,172,887,910,912 'revisit':339,498,531,720,771 'rule':386,400,591 'sacrific':455 'say':197,879 'scatter':709 'scope':346,356,363,542,550,576,731,764,831,901 'search':310 'section':596 'see':255,906 'sentenc':450 'separ':652 'setdarkmod':701 'shape':327,329 'shim':733,737 'shorter':395 'simplifi':679 'site':692 'skill' 'skill-pr-reply' 'skip':161 'soft':808 'sound':410 'sourc':63,267,466 'source-helderberto' 'spec':66,101,289,595,631 'spec/decision':336,874 'spec/pr':523 'specif':459,581,743 'src/foo.ts':120 'stack':446 'start':783 'stay':714 'step':166 'still':818 'stop':273 'storag':742 'string':661,677 'string-on':660,676 'suffici':275 'suggest':897 'support':751 'sycophant':435 'templat':513 'text':74,217,612,872 'think':471 'though':820 'time':699 'tone':399 'topic':316 'topic-agent-skills' 'topic-ai-tools' 'topic-antigravity' 'topic-claude-code' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-markdown' 'topic-plugin' 'topic-sdlc' 'topic-skills' 'topic-tracer-bullet' 'treat':212 'triag':175 'truth':65,269 'type':328,687 'typic':451 'updat':844 'use':13,40,157,417,489 'user':15,77,152,188,196,392,405,615,896 'user.login':189 'util':749 'valid':343,352 've':604 'verifi':605,619 'version':756 'via':253 'want':32,500 'without':843 'workflow':240 'would':703,708 'wrap':124 'write':406 'x':296 'yes':702","prices":[{"id":"e49887b8-31f9-4941-9c73-c7339acb907a","listingId":"2330de19-f8a9-4a5d-a220-cf0deea5bc5b","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"helderberto","category":"agent-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:14:54.316Z"}],"sources":[{"listingId":"2330de19-f8a9-4a5d-a220-cf0deea5bc5b","source":"github","sourceId":"helderberto/agent-skills/pr-reply","sourceUrl":"https://github.com/helderberto/agent-skills/tree/main/skills/pr-reply","isPrimary":false,"firstSeenAt":"2026-05-18T13:14:54.316Z","lastSeenAt":"2026-05-18T19:09:14.038Z"}],"details":{"listingId":"2330de19-f8a9-4a5d-a220-cf0deea5bc5b","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"helderberto","slug":"pr-reply","github":{"repo":"helderberto/agent-skills","stars":8,"topics":["agent-skills","ai","ai-tools","antigravity","claude-code","cursor","developer-tools","gemini-cli","markdown","plugin","sdlc","skills","tracer-bullet"],"license":"mit","html_url":"https://github.com/helderberto/agent-skills","pushed_at":"2026-05-14T11:37:47Z","description":"My personal SDLC toolbelt for AI coding agents — PRD to ship.","skill_md_sha":"6cf95dcf6ab68f977cd2d45722e12dd2e6720b78","skill_md_path":"skills/pr-reply/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/helderberto/agent-skills/tree/main/skills/pr-reply"},"layout":"multi","source":"github","category":"agent-skills","frontmatter":{"name":"pr-reply","description":"Draft friendly, concise replies to pull request review comments. Use when user pastes a PR comment, asks to \"reply to a PR comment\", \"/pr-reply\", \"answer this reviewer\", or wants help responding to review feedback. Don't use for posting comments to GitHub, creating new PRs, or reviewing PRs."},"skills_sh_url":"https://skills.sh/helderberto/agent-skills/pr-reply"},"updatedAt":"2026-05-18T19:09:14.038Z"}}