claude-dev-env 1.93.1 → 1.94.0
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.
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/audit-contract.md +1 -1
- package/_shared/pr-loop/gh-payloads.md +3 -3
- package/_shared/pr-loop/post-audit-thread-contract.md +51 -0
- package/_shared/pr-loop/scripts/README.md +2 -2
- package/_shared/pr-loop/scripts/fix_hookspath.py +47 -12
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -69
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -374
- package/_shared/pr-loop/state-schema.md +3 -22
- package/bin/CLAUDE.md +1 -1
- package/bin/install.mjs +2 -7
- package/bin/install.test.mjs +10 -4
- package/hooks/blocking/CLAUDE.md +2 -0
- package/hooks/blocking/pii_commit_command.py +398 -0
- package/hooks/blocking/pii_payload_scan.py +133 -0
- package/hooks/blocking/pii_prevention_blocker.py +151 -449
- package/hooks/blocking/test_pii_prevention_blocker.py +299 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +42 -7
- package/hooks/hooks_constants/CLAUDE.md +2 -2
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -2
- package/hooks/hooks_constants/local_identity.py +65 -15
- package/hooks/hooks_constants/pii_prevention_constants.py +16 -0
- package/hooks/hooks_constants/pr_description_enforcer_constants.py +1 -1
- package/hooks/hooks_constants/test_local_identity.py +68 -0
- package/package.json +1 -1
- package/scripts/CLAUDE.md +10 -1
- package/scripts/Get-SessionAccount.ps1 +210 -0
- package/scripts/tests/CLAUDE.md +15 -1
- package/scripts/tests/Get-SessionAccount.Tests.ps1 +350 -0
- package/skills/CLAUDE.md +3 -25
- package/skills/anthropic-plan/SKILL.md +1 -13
- package/skills/autoconverge/CLAUDE.md +5 -2
- package/skills/autoconverge/SKILL.md +112 -387
- package/skills/autoconverge/reference/CLAUDE.md +4 -1
- package/skills/autoconverge/reference/closing-report.md +9 -2
- package/skills/autoconverge/reference/convergence.md +26 -22
- package/skills/autoconverge/reference/headless-safety.md +44 -0
- package/skills/autoconverge/reference/multi-pr.md +88 -0
- package/skills/autoconverge/reference/self-closing-loop.md +84 -0
- package/skills/autoconverge/reference/stop-conditions.md +21 -13
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +87 -27
- package/skills/autoconverge/workflow/converge.contract.test.mjs +40 -10
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +179 -47
- package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.mjs +284 -94
- package/skills/bugteam/CLAUDE.md +1 -1
- package/skills/bugteam/CONSTRAINTS.md +3 -3
- package/skills/bugteam/PROMPTS.md +8 -19
- package/skills/bugteam/SKILL.md +13 -14
- package/skills/bugteam/reference/CLAUDE.md +1 -1
- package/skills/bugteam/reference/audit-and-teammates.md +2 -2
- package/skills/bugteam/reference/copilot-gap-analysis.md +2 -0
- package/skills/bugteam/reference/github-pr-reviews.md +56 -38
- package/skills/bugteam/reference/team-setup.md +11 -11
- package/skills/bugteam/scripts/CLAUDE.md +6 -6
- package/skills/bugteam/scripts/README.md +20 -8
- package/skills/bugteam/scripts/bugteam_code_rules_gate.py +13 -1463
- package/skills/bugteam/scripts/bugteam_fix_hookspath.py +23 -358
- package/skills/bugteam/scripts/bugteam_preflight.py +13 -315
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +2 -3
- package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +34 -1053
- package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +30 -347
- package/skills/bugteam/scripts/test_bugteam_preflight.py +30 -305
- package/skills/copilot-finding-triage/SKILL.md +80 -28
- package/skills/copilot-finding-triage/reference/tier-rubric.md +70 -11
- package/skills/copilot-finding-triage/templates/notification.md +8 -3
- package/skills/everything-search/SKILL.md +1 -2
- package/skills/grokify/SKILL.md +58 -0
- package/skills/grokify/templates/handoff-template.md +92 -0
- package/skills/orchestrator/SKILL.md +12 -8
- package/skills/orchestrator-refresh/SKILL.md +3 -3
- package/skills/pr-converge/SKILL.md +132 -233
- package/skills/pr-converge/reference/convergence-gates.md +102 -66
- package/skills/pr-converge/reference/examples.md +37 -25
- package/skills/pr-converge/reference/fix-protocol.md +7 -7
- package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -4
- package/skills/pr-converge/reference/per-tick.md +64 -41
- package/skills/pr-converge/reference/state-schema.md +27 -2
- package/skills/pr-converge/scripts/CLAUDE.md +8 -0
- package/skills/pr-converge/scripts/README.md +4 -3
- package/skills/pr-converge/scripts/_pr_converge_path_setup.py +23 -0
- package/skills/pr-converge/scripts/check_convergence.py +189 -645
- package/skills/pr-converge/scripts/check_convergence_gates.py +235 -0
- package/skills/pr-converge/scripts/check_convergence_thread_gates.py +219 -0
- package/skills/pr-converge/scripts/conftest.py +8 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -0
- package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +26 -0
- package/skills/pr-converge/scripts/test_check_convergence.py +73 -228
- package/skills/pr-converge/scripts/test_check_convergence_contract.py +321 -0
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +68 -0
- package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +75 -0
- package/skills/privacy-hygiene/SKILL.md +4 -3
- package/skills/reviewer-gates/SKILL.md +26 -8
- package/skills/session-log/SKILL.md +11 -12
- package/skills/session-tidy/SKILL.md +40 -30
- package/skills/skill-builder/CLAUDE.md +13 -10
- package/skills/skill-builder/SKILL.md +31 -31
- package/skills/skill-builder/references/CLAUDE.md +10 -6
- package/skills/skill-builder/references/delegation-map.md +13 -4
- package/skills/skill-builder/references/description-field.md +113 -0
- package/skills/skill-builder/references/self-audit-checklist.md +21 -4
- package/skills/skill-builder/references/skill-modularity.md +113 -0
- package/skills/skill-builder/references/skill-types.md +4 -0
- package/skills/skill-builder/templates/CLAUDE.md +4 -4
- package/skills/skill-builder/templates/gap-analysis.md +25 -1
- package/skills/skill-builder/workflows/CLAUDE.md +6 -4
- package/skills/skill-builder/workflows/improve-skill.md +17 -16
- package/skills/skill-builder/workflows/new-skill.md +34 -10
- package/skills/skill-builder/workflows/polish-skill.md +59 -43
- package/skills/usage-pause/SKILL.md +10 -14
- package/skills/bdd-protocol/CLAUDE.md +0 -26
- package/skills/bdd-protocol/SKILL.md +0 -30
- package/skills/bdd-protocol/references/CLAUDE.md +0 -10
- package/skills/bdd-protocol/references/anti-patterns.md +0 -26
- package/skills/bdd-protocol/references/example-mapping.md +0 -23
- package/skills/bg-agent/CLAUDE.md +0 -17
- package/skills/bg-agent/SKILL.md +0 -69
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_code_rules_gate_constants.py +0 -55
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_fix_hookspath_constants.py +0 -26
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_preflight_constants.py +0 -35
- package/skills/caveman/CLAUDE.md +0 -15
- package/skills/caveman/SKILL.md +0 -38
- package/skills/code/CLAUDE.md +0 -17
- package/skills/code/SKILL.md +0 -178
- package/skills/deep-research/CLAUDE.md +0 -17
- package/skills/deep-research/SKILL.md +0 -80
- package/skills/findbugs/CLAUDE.md +0 -20
- package/skills/findbugs/SKILL.md +0 -241
- package/skills/fixbugs/CLAUDE.md +0 -19
- package/skills/fixbugs/SKILL.md +0 -142
- package/skills/gh-paginate/CLAUDE.md +0 -18
- package/skills/gh-paginate/SKILL.md +0 -84
- package/skills/gotcha/CLAUDE.md +0 -33
- package/skills/gotcha/SKILL.md +0 -73
- package/skills/implement/CLAUDE.md +0 -27
- package/skills/implement/SKILL.md +0 -66
- package/skills/implement/scripts/CLAUDE.md +0 -22
- package/skills/implement/scripts/append_note.py +0 -133
- package/skills/implement/scripts/implement_scripts_constants/CLAUDE.md +0 -22
- package/skills/implement/scripts/implement_scripts_constants/__init__.py +0 -0
- package/skills/implement/scripts/implement_scripts_constants/notes_constants.py +0 -12
- package/skills/implement/scripts/test_append_note.py +0 -191
- package/skills/log-audit/CLAUDE.md +0 -20
- package/skills/log-audit/SKILL.md +0 -66
- package/skills/log-audit/reference/CLAUDE.md +0 -9
- package/skills/log-audit/reference/charter.md +0 -52
- package/skills/log-audit/scripts/CLAUDE.md +0 -27
- package/skills/log-audit/scripts/cluster_recurrences.py +0 -261
- package/skills/log-audit/scripts/collect_log_window.py +0 -199
- package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +0 -12
- package/skills/log-audit/scripts/log_audit_constants/__init__.py +0 -0
- package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +0 -23
- package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +0 -24
- package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +0 -49
- package/skills/log-audit/scripts/mine_copilot_findings.py +0 -302
- package/skills/log-audit/scripts/test_cluster_recurrences.py +0 -160
- package/skills/log-audit/scripts/test_collect_log_window.py +0 -111
- package/skills/log-audit/scripts/test_mine_copilot_findings.py +0 -126
- package/skills/logifix/CLAUDE.md +0 -36
- package/skills/logifix/SKILL.md +0 -69
- package/skills/logifix/scripts/CLAUDE.md +0 -16
- package/skills/logifix/scripts/logifix.ps1 +0 -205
- package/skills/monitor-open-prs/CLAUDE.md +0 -34
- package/skills/monitor-open-prs/SKILL.md +0 -88
- package/skills/monitor-open-prs/scripts/CLAUDE.md +0 -17
- package/skills/monitor-open-prs/scripts/discover_open_prs.py +0 -69
- package/skills/monitor-open-prs/scripts/test_discover_open_prs.py +0 -149
- package/skills/monitor-open-prs/test_skill_contract.py +0 -27
- package/skills/post-audit-findings/SKILL.md +0 -80
- package/skills/pr-consistency-audit/CLAUDE.md +0 -34
- package/skills/pr-consistency-audit/SKILL.md +0 -116
- package/skills/pr-consistency-audit/reference/CLAUDE.md +0 -16
- package/skills/pr-consistency-audit/reference/detection-rules.md +0 -96
- package/skills/pr-consistency-audit/reference/illustrations.md +0 -78
- package/skills/pr-fix-protocol/SKILL.md +0 -65
- package/skills/pr-review-responder/CLAUDE.md +0 -35
- package/skills/pr-review-responder/EXAMPLES.md +0 -590
- package/skills/pr-review-responder/PRINCIPLES.md +0 -533
- package/skills/pr-review-responder/README.md +0 -168
- package/skills/pr-review-responder/SKILL.md +0 -203
- package/skills/pr-review-responder/TESTING.md +0 -350
- package/skills/pr-scope-resolve/SKILL.md +0 -45
- package/skills/pre-compact/CLAUDE.md +0 -24
- package/skills/pre-compact/SKILL.md +0 -134
- package/skills/qbug/CLAUDE.md +0 -40
- package/skills/qbug/SKILL.md +0 -387
- package/skills/qbug/test_qbug_skill_audit_schema.py +0 -152
- package/skills/qbug/test_qbug_skill_post_fix_audit.py +0 -103
- package/skills/refine/CLAUDE.md +0 -44
- package/skills/refine/SKILL.md +0 -262
- package/skills/refine/templates/CLAUDE.md +0 -17
- package/skills/refine/templates/implementation-notes-template.html +0 -56
- package/skills/refine/templates/plan-template.md +0 -60
- package/skills/research-mode/CLAUDE.md +0 -35
- package/skills/research-mode/SKILL.md +0 -53
- package/skills/structure-prompt/CLAUDE.md +0 -42
- package/skills/structure-prompt/SKILL.md +0 -44
- package/skills/structure-prompt/reference/CLAUDE.md +0 -28
- package/skills/structure-prompt/reference/adversarial-tuning.md +0 -62
- package/skills/structure-prompt/reference/block-classification.md +0 -27
- package/skills/structure-prompt/reference/canonical-case.md +0 -48
- package/skills/structure-prompt/reference/citation-depth.md +0 -70
- package/skills/structure-prompt/reference/cleanup.md +0 -33
- package/skills/structure-prompt/reference/constraints.md +0 -33
- package/skills/structure-prompt/reference/directives.md +0 -37
- package/skills/structure-prompt/reference/examples.md +0 -72
- package/skills/structure-prompt/reference/instantiation.md +0 -51
- package/skills/structure-prompt/reference/output-contract.md +0 -72
- package/skills/structure-prompt/reference/per-category.md +0 -23
- package/skills/structure-prompt/reference/persona.md +0 -38
- package/skills/structure-prompt/reference/research.md +0 -33
- package/skills/structure-prompt/reference/structure.md +0 -28
- package/skills/verified-build/CLAUDE.md +0 -33
- package/skills/verified-build/SKILL.md +0 -33
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pr-fix-protocol
|
|
3
|
-
description: >-
|
|
4
|
-
Applies reviewer findings to a PR as verified fixes and drives unresolved
|
|
5
|
-
review threads to zero. Invoked by PR-loop orchestrators (pr-converge,
|
|
6
|
-
autoconverge, bugteam, qbug, copilot-review) when a reviewer reports
|
|
7
|
-
findings; not for ad-hoc 'fix this bug' requests outside a PR loop.
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# PR Fix Protocol
|
|
11
|
-
|
|
12
|
-
**Core principle:** a finding is addressed only when the fix is pushed, the thread carries a reply, and the thread is resolved — as one unit of work. Anything less leaves a convergence gate stalled.
|
|
13
|
-
|
|
14
|
-
## How callers invoke this
|
|
15
|
-
|
|
16
|
-
- **Skill-capable contexts** (a lead session with the `Skill` tool): `Skill({skill: "pr-fix-protocol", args: "--skill <caller> --pr <URL> --worktree <path> [findings payload or 'sweep']"})`.
|
|
17
|
-
- **Fallback** (a subagent or teammate without the `Skill` tool): the caller's spawn prompt says "Read `~/.claude/skills/pr-fix-protocol/SKILL.md` and apply it with the parameters below."
|
|
18
|
-
|
|
19
|
-
The caller passes: its identity, the PR scope, the PR worktree path, this round's findings (or `sweep` for a thread sweep with no fresh findings), and its post-push obligations (which clean-SHA state fields to reset, which reviewers to re-trigger).
|
|
20
|
-
|
|
21
|
-
## Executor choice
|
|
22
|
-
|
|
23
|
-
- **Single-PR loops** (no shared `state.json`): the lead spawns `Agent(subagent_type: "clean-coder")` to write the fix. Full-stop if `Agent` is unavailable. A spawned clean-coder does not inherit the lead's working directory — name the PR worktree path in its prompt and direct it to edit, stage, and commit there.
|
|
24
|
-
- **Multi-PR orchestration** (shared `state.json`): a per-PR clean-coder teammate owns edits, replies, and state writes; the orchestrator never edits inline. The teammate obligations (reply before writing state, state fields, idle handoff) live in the calling skill's multi-PR reference.
|
|
25
|
-
|
|
26
|
-
Run every git command in the PR worktree — `git add`, `git commit`, and `git push` act on the repo of the current working directory, so a cross-repo PR's fix lands in the PR's repo only when the cwd is its worktree.
|
|
27
|
-
|
|
28
|
-
## The fix sequence
|
|
29
|
-
|
|
30
|
-
Follow the shared 13-step sequence in [`_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md) exactly: read each file:line, capture the pre-fix SHA and contents, TDD where the finding has behavior, apply narrowly, `py_compile`, post-fix self-audit, stage by explicit path, one commit, fast-forward push, then reply + resolve atomically per thread. Its Constraints section (narrow scope, no `--no-verify`, preserve helpers) binds every executor.
|
|
31
|
-
|
|
32
|
-
**Reply transport:** the GitHub MCP `add_reply_to_pull_request_comment` is primary. `python "$HOME/.claude/skills/pr-converge/scripts/post_fix_reply.py" --owner <O> --repo <R> --pr-number <N> --in-reply-to <COMMENT_ID> --body "Fixed in <SHA> — <what changed>"` is the fallback for script-only contexts and multi-PR teammates. Both carry the body shape from [`_shared/pr-loop/audit-reply-template.md`](../../_shared/pr-loop/audit-reply-template.md). For body-only findings with no inline thread, post a top-level review reply citing the new HEAD SHA.
|
|
33
|
-
|
|
34
|
-
**Thread resolution:** `pull_request_review_write(method="resolve_thread", threadId=<PRRT node id>)` right after each reply. Harvest thread node ids (`PRRT_…`) from `get_review_comments` at fetch time.
|
|
35
|
-
|
|
36
|
-
## The unresolved-thread sweep (hard gate)
|
|
37
|
-
|
|
38
|
-
No caller advances a phase, records a clean SHA, or marks a PR ready while ANY unresolved review thread exists on the PR.
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
pull_request_read(method="get_review_comments") → filter threads where is_resolved == false
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- The filter is purely `is_resolved == false`. Author, anchor commit, and `is_outdated` are all irrelevant to the count.
|
|
45
|
-
- `is_outdated` is informational, not a skip flag: GitHub marks a thread outdated when its anchor line changed, but the concern can still apply to current HEAD (the fix may have moved, not landed). Verify each outdated thread against current HEAD like any other.
|
|
46
|
-
- Per unresolved thread: verify the concern against current HEAD. The concern holds → fix (this protocol) → reply → resolve. The concern does not hold on current HEAD → reply-with-note explaining why → resolve.
|
|
47
|
-
- Code changed during the sweep → push and hand control back to the caller's re-entry phase. Only resolutions, no code → re-run the sweep without resetting caller state.
|
|
48
|
-
|
|
49
|
-
## Post-push obligations
|
|
50
|
-
|
|
51
|
-
Every push through this protocol:
|
|
52
|
-
|
|
53
|
-
1. Re-resolve `current_head` (`git rev-parse HEAD` locally; the PR `get` call for API-visible state).
|
|
54
|
-
2. Reset the caller-named clean-SHA fields to null (`bugbot_clean_at`, `code_review_clean_at`, `copilot_clean_at` — whichever the caller tracks). A new HEAD invalidates every prior clean.
|
|
55
|
-
3. Re-trigger reviewers per the caller's parameter (for Cursor Bugbot, the `reviewer-gates` Bugbot flow; for Copilot, the caller's request step). Audit-family callers (`bugteam`, `qbug`) skip re-triggering — their next loop iteration is the reviewer.
|
|
56
|
-
|
|
57
|
-
## Gotchas
|
|
58
|
-
|
|
59
|
-
- **Reply-then-resolve, atomic per thread.** Batching all replies before any resolves, or yielding to the orchestrator between the two, leaves threads half-addressed when a run dies mid-loop.
|
|
60
|
-
- **An unchanged HEAD after step 11 means no commit landed** — exit `stuck — could not address findings` rather than reporting the findings as fixed.
|
|
61
|
-
- **A resolved thread with no reply reads as dismissed.** Reviewers (and the humans reading the PR) need the one-paragraph explanation the template carries.
|
|
62
|
-
|
|
63
|
-
## Folder map
|
|
64
|
-
|
|
65
|
-
- `SKILL.md` — this file. The step sequence, reply template, and payload shapes live in `_shared/pr-loop/` (`fix-protocol.md`, `audit-reply-template.md`, `gh-payloads.md`); the reply fallback script lives in `pr-converge/scripts/`.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# pr-review-responder
|
|
2
|
-
|
|
3
|
-
Mandatory systematic protocol for responding to GitHub PR review comments.
|
|
4
|
-
|
|
5
|
-
**Trigger:** "address feedback", "fix review comments", "respond to code review", "handle PR feedback", "reply to reviewer".
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Prevents missed review comments by enforcing a strict fetch-then-checklist-then-fix order. The skill is declared `MANDATORY` — any PR review response that skips it is an automatic failure per the skill body.
|
|
10
|
-
|
|
11
|
-
## Key files
|
|
12
|
-
|
|
13
|
-
| File | Purpose |
|
|
14
|
-
|---|---|
|
|
15
|
-
| `SKILL.md` | Hub — the seven mandatory rules and the final report format |
|
|
16
|
-
| `EXAMPLES.md` | Concrete good and bad reply examples |
|
|
17
|
-
| `PRINCIPLES.md` | Design rationale behind the protocol |
|
|
18
|
-
| `README.md` | Overview for readers new to the skill |
|
|
19
|
-
| `TESTING.md` | Testing guidance for the skill |
|
|
20
|
-
|
|
21
|
-
## Seven mandatory rules
|
|
22
|
-
|
|
23
|
-
1. Fetch ALL review comments with `per_page=100` before touching any file.
|
|
24
|
-
2. Create a `TodoWrite` checklist — one item per comment — before any fix.
|
|
25
|
-
3. Fix one comment at a time, marking each todo complete before moving on.
|
|
26
|
-
4. Write reply text for every comment; never post directly.
|
|
27
|
-
5. Create ONE new commit for all fixes from this review round; never squash with the original.
|
|
28
|
-
6. Push — the git pre-push hook fires automatically.
|
|
29
|
-
7. Verify the draft count matches the comment count before reporting done.
|
|
30
|
-
|
|
31
|
-
## Conventions
|
|
32
|
-
|
|
33
|
-
- GitHub MCP (`pull_request_read`) with `per_page=100` is the required fetch path.
|
|
34
|
-
- Draft replies are presented for the user to post; Claude never posts them directly.
|
|
35
|
-
- The pre-push hook (`npx claude-dev-env`) runs on `git push` with no manual invocation.
|
|
@@ -1,590 +0,0 @@
|
|
|
1
|
-
# PR Review Responder Examples
|
|
2
|
-
|
|
3
|
-
Real-world examples of responding to PR review comments.
|
|
4
|
-
|
|
5
|
-
## Example 1: Over-Engineering Feedback
|
|
6
|
-
|
|
7
|
-
**Scenario**: Reviewer catches unnecessary wrapper class
|
|
8
|
-
|
|
9
|
-
**PR Context**:
|
|
10
|
-
- PR #12: "Add file upload to admin interface"
|
|
11
|
-
- Reviewer: Reviewer
|
|
12
|
-
- Comment on `src/storage.py:45`
|
|
13
|
-
|
|
14
|
-
**Review comment**:
|
|
15
|
-
```
|
|
16
|
-
Why create a wrapper class here? The Path().read_bytes() approach
|
|
17
|
-
is more straightforward and avoids unnecessary abstraction.
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
**Your changes** (commit addressing feedback):
|
|
21
|
-
```python
|
|
22
|
-
# Before (over-engineered)
|
|
23
|
-
class FileReader:
|
|
24
|
-
def __init__(self, path):
|
|
25
|
-
self.path = path
|
|
26
|
-
|
|
27
|
-
def read(self):
|
|
28
|
-
return Path(self.path).read_bytes()
|
|
29
|
-
|
|
30
|
-
file_data = FileReader(file_path).read()
|
|
31
|
-
|
|
32
|
-
# After (simplified)
|
|
33
|
-
file_data = Path(file_path).read_bytes()
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**Skill execution**:
|
|
37
|
-
```
|
|
38
|
-
$ "Respond to PR review comments"
|
|
39
|
-
|
|
40
|
-
Found 1 review comment addressed:
|
|
41
|
-
|
|
42
|
-
1. @reviewer on src/storage.py:45
|
|
43
|
-
Comment: "Why create a wrapper class here? The Path().read_bytes()..."
|
|
44
|
-
Response: ✅ **Fixed**: Removed FileReader wrapper, using Path().read_bytes() directly
|
|
45
|
-
|
|
46
|
-
Post this response to the PR? (y/n) y
|
|
47
|
-
|
|
48
|
-
Posted 1 response to PR #12
|
|
49
|
-
View PR: https://github.com/yourorg/project/pull/43
|
|
50
|
-
|
|
51
|
-
Ready to push!
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Posted response on GitHub**:
|
|
55
|
-
```
|
|
56
|
-
✅ **Fixed**: Removed FileReader wrapper, using Path().read_bytes() directly
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Example 2: Multiple Comments Across Files
|
|
62
|
-
|
|
63
|
-
**Scenario**: Refactoring PR with feedback on several files
|
|
64
|
-
|
|
65
|
-
**PR Context**:
|
|
66
|
-
- PR #67: "Refactor timing system"
|
|
67
|
-
- Reviewer: Reviewer
|
|
68
|
-
- 4 inline comments across 3 files
|
|
69
|
-
|
|
70
|
-
**Review comments**:
|
|
71
|
-
|
|
72
|
-
1. **src/views.py:23**:
|
|
73
|
-
```
|
|
74
|
-
This animation logic is duplicated in the schedule view.
|
|
75
|
-
Should extract to shared utility.
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
2. **src/views.py:89**:
|
|
79
|
-
```
|
|
80
|
-
Same timing calculation here. DRY principle.
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
3. **templates/base.html:45**:
|
|
84
|
-
```
|
|
85
|
-
Why pass CSS timing values through Python context?
|
|
86
|
-
Put them directly in CSS.
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
4. **src/utils.py:12**:
|
|
90
|
-
```
|
|
91
|
-
Good extraction! But needs type hints on parameters.
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Your changes** (commit addressing all feedback):
|
|
95
|
-
```python
|
|
96
|
-
# src/utils/view_helpers.py (NEW FILE)
|
|
97
|
-
from typing import Dict
|
|
98
|
-
|
|
99
|
-
def calculate_timing(duration: int, delay: int) -> Dict[str, str]:
|
|
100
|
-
"""Calculate CSS animation timing values."""
|
|
101
|
-
return {
|
|
102
|
-
'duration': f'{duration}ms',
|
|
103
|
-
'delay': f'{delay}ms'
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
# src/views.py (MODIFIED - removed duplication)
|
|
107
|
-
from utils.view_helpers import calculate_timing
|
|
108
|
-
|
|
109
|
-
# templates/base.html (MODIFIED - CSS values direct)
|
|
110
|
-
<style>
|
|
111
|
-
.fade-in { animation-duration: 300ms; }
|
|
112
|
-
</style>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
**Skill execution**:
|
|
116
|
-
```
|
|
117
|
-
$ "Respond to PR review comments before I push"
|
|
118
|
-
|
|
119
|
-
Found 4 review comments addressed:
|
|
120
|
-
|
|
121
|
-
1. @reviewer on src/views.py:23
|
|
122
|
-
Comment: "This animation logic is duplicated..."
|
|
123
|
-
Response: ✅ **Fixed**: Extracted to utils/view_helpers.py
|
|
124
|
-
|
|
125
|
-
2. @reviewer on src/views.py:89
|
|
126
|
-
Comment: "Same timing calculation here. DRY principle."
|
|
127
|
-
Response: ✅ **Fixed**: Now using shared calculate_timing()
|
|
128
|
-
|
|
129
|
-
3. @reviewer on templates/base.html:45
|
|
130
|
-
Comment: "Why pass CSS timing values through Python context?"
|
|
131
|
-
Response: ✅ **Fixed**: Moved animation values directly to CSS
|
|
132
|
-
|
|
133
|
-
4. @reviewer on src/utils.py:12
|
|
134
|
-
Comment: "Good extraction! But needs type hints..."
|
|
135
|
-
Response: ✅ **Fixed**: Added type hints (int, Dict[str, str])
|
|
136
|
-
|
|
137
|
-
Post these 4 responses to the PR? (y/n) y
|
|
138
|
-
|
|
139
|
-
Posted 4 responses to PR #67
|
|
140
|
-
View PR: https://github.com/yourorg/project/pull/67
|
|
141
|
-
|
|
142
|
-
Ready to push!
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## Example 3: Partial Addressing (Some Comments Not Fixed)
|
|
148
|
-
|
|
149
|
-
**Scenario**: Some feedback addressed, some deferred
|
|
150
|
-
|
|
151
|
-
**PR Context**:
|
|
152
|
-
- PR #89: "Add user profile customization"
|
|
153
|
-
- Reviewer: Reviewer
|
|
154
|
-
- 3 comments, only 2 addressed in this commit
|
|
155
|
-
|
|
156
|
-
**Review comments**:
|
|
157
|
-
|
|
158
|
-
1. **src/models.py:34**:
|
|
159
|
-
```
|
|
160
|
-
user_name conflicts with User.username. Rename to display_name.
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
2. **src/views.py:56**:
|
|
164
|
-
```
|
|
165
|
-
This profile logic should be in a service layer, not the view.
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
3. **src/forms.py:23**:
|
|
169
|
-
```
|
|
170
|
-
Missing validation on age field (must be positive).
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Your changes** (commit addressing 2 of 3):
|
|
174
|
-
```python
|
|
175
|
-
# Fixed: Renamed field
|
|
176
|
-
class UserProfile(models.Model):
|
|
177
|
-
display_name = models.CharField(max_length=100) # was user_name
|
|
178
|
-
|
|
179
|
-
# Fixed: Added validation
|
|
180
|
-
class ProfileForm(forms.ModelForm):
|
|
181
|
-
def clean_age(self):
|
|
182
|
-
age = self.cleaned_data['age']
|
|
183
|
-
if age <= 0:
|
|
184
|
-
raise ValidationError("Age must be positive")
|
|
185
|
-
return age
|
|
186
|
-
|
|
187
|
-
# NOT FIXED: Service layer refactor (deferred to separate PR)
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
**Skill execution**:
|
|
191
|
-
```
|
|
192
|
-
$ "Respond to PR review comments"
|
|
193
|
-
|
|
194
|
-
Found 3 review comments, 2 addressed in this commit:
|
|
195
|
-
|
|
196
|
-
1. @reviewer on src/models.py:34
|
|
197
|
-
Comment: "user_name conflicts with User.username..."
|
|
198
|
-
Response: ✅ **Fixed**: Renamed to display_name to avoid conflict
|
|
199
|
-
|
|
200
|
-
2. @reviewer on src/forms.py:23
|
|
201
|
-
Comment: "Missing validation on age field..."
|
|
202
|
-
Response: ✅ **Fixed**: Added positive integer validation in clean_age()
|
|
203
|
-
|
|
204
|
-
Not addressed (no changes to these files):
|
|
205
|
-
3. @reviewer on src/views.py:56
|
|
206
|
-
Comment: "This profile logic should be in a service layer..."
|
|
207
|
-
[File not modified in this commit]
|
|
208
|
-
|
|
209
|
-
Post 2 responses to addressed comments? (y/n) y
|
|
210
|
-
What about the view.py comment? Add a response? (y/n) y
|
|
211
|
-
|
|
212
|
-
Custom response for src/views.py:56:
|
|
213
|
-
> 📝 **Noted**: Will refactor to service layer in separate PR to keep changes focused
|
|
214
|
-
|
|
215
|
-
Posted 3 responses to PR #89
|
|
216
|
-
Ready to push!
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Example 4: No Matching Changes (Warning)
|
|
222
|
-
|
|
223
|
-
**Scenario**: Committed changes don't address any review comments
|
|
224
|
-
|
|
225
|
-
**PR Context**:
|
|
226
|
-
- PR #52: "Add notification system"
|
|
227
|
-
- Reviewer: Reviewer
|
|
228
|
-
- Comment on `src/notifications.py:23`
|
|
229
|
-
|
|
230
|
-
**Review comment**:
|
|
231
|
-
```
|
|
232
|
-
The email sending logic should use async/await for better performance.
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
**Your changes** (commit on different topic):
|
|
236
|
-
```python
|
|
237
|
-
# Modified src/templates/notifications.html
|
|
238
|
-
# (Not related to the async/await comment)
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
**Skill execution**:
|
|
242
|
-
```
|
|
243
|
-
$ "Respond to PR review comments"
|
|
244
|
-
|
|
245
|
-
Checking PR #52 for review comments...
|
|
246
|
-
|
|
247
|
-
Found 1 review comment on src/notifications.py:23
|
|
248
|
-
But your commit doesn't modify that file.
|
|
249
|
-
|
|
250
|
-
Review comment:
|
|
251
|
-
@reviewer: "The email sending logic should use async/await..."
|
|
252
|
-
|
|
253
|
-
Your changes:
|
|
254
|
-
- templates/notifications.html
|
|
255
|
-
|
|
256
|
-
No matching changes to respond to. Did you mean to address this comment?
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## Example 5: Already Responded Comments (Filtered Out)
|
|
262
|
-
|
|
263
|
-
**Scenario**: Some comments already have responses
|
|
264
|
-
|
|
265
|
-
**PR Context**:
|
|
266
|
-
- PR #78: "Refactor authentication flow"
|
|
267
|
-
- Multiple commits addressing different comments
|
|
268
|
-
|
|
269
|
-
**Review comments**:
|
|
270
|
-
|
|
271
|
-
1. **src/auth.py:12** (ALREADY REPLIED):
|
|
272
|
-
```
|
|
273
|
-
Reviewer: "Use Django's built-in password validation"
|
|
274
|
-
You (yesterday): "✅ Fixed: Using validate_password()"
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
2. **src/views.py:45** (NOT REPLIED):
|
|
278
|
-
```
|
|
279
|
-
Reviewer: "Session timeout should be configurable"
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**Your changes** (new commit):
|
|
283
|
-
```python
|
|
284
|
-
# src/settings.py (NEW)
|
|
285
|
-
SESSION_TIMEOUT = int(os.getenv('SESSION_TIMEOUT', '3600'))
|
|
286
|
-
|
|
287
|
-
# src/views.py (MODIFIED)
|
|
288
|
-
request.session.set_expiry(settings.SESSION_TIMEOUT)
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Skill execution**:
|
|
292
|
-
```
|
|
293
|
-
$ "Respond to PR review comments"
|
|
294
|
-
|
|
295
|
-
Checking PR #78 for review comments...
|
|
296
|
-
|
|
297
|
-
Found 2 review comments total:
|
|
298
|
-
- 1 already has replies (skipping)
|
|
299
|
-
- 1 needs response
|
|
300
|
-
|
|
301
|
-
Comments to respond to:
|
|
302
|
-
|
|
303
|
-
1. @reviewer on src/views.py:45
|
|
304
|
-
Comment: "Session timeout should be configurable"
|
|
305
|
-
Response: ✅ **Fixed**: Added SESSION_TIMEOUT env variable in settings
|
|
306
|
-
|
|
307
|
-
Post this response? (y/n) y
|
|
308
|
-
|
|
309
|
-
Posted 1 response to PR #78
|
|
310
|
-
(Skipped 1 already-replied comment)
|
|
311
|
-
|
|
312
|
-
Ready to push!
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
---
|
|
316
|
-
|
|
317
|
-
## Example 6: General PR Comments (Not Inline)
|
|
318
|
-
|
|
319
|
-
**Scenario**: PR-level comments, not tied to specific code lines
|
|
320
|
-
|
|
321
|
-
**PR Context**:
|
|
322
|
-
- PR #91: "Add caching layer"
|
|
323
|
-
- General comment (not inline code review)
|
|
324
|
-
|
|
325
|
-
**Review comment** (general PR comment):
|
|
326
|
-
```
|
|
327
|
-
Reviewer: "Looks good overall! Can you add tests for the cache invalidation logic?"
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
**Your changes**:
|
|
331
|
-
```python
|
|
332
|
-
# tests/test_cache.py (NEW)
|
|
333
|
-
def test_cache_invalidation():
|
|
334
|
-
# Test implementation
|
|
335
|
-
pass
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
**Skill execution**:
|
|
339
|
-
```
|
|
340
|
-
$ "Respond to PR review comments"
|
|
341
|
-
|
|
342
|
-
Checking PR #91 for review comments...
|
|
343
|
-
|
|
344
|
-
Found 1 general PR comment (not inline):
|
|
345
|
-
@reviewer: "Looks good overall! Can you add tests..."
|
|
346
|
-
|
|
347
|
-
This is a general comment, not tied to specific code lines.
|
|
348
|
-
Cannot auto-respond to general comments.
|
|
349
|
-
|
|
350
|
-
Suggestion: Reply manually on GitHub or use the MCP tool:
|
|
351
|
-
`add_issue_comment(owner=owner, repo=repo, issueNumber=91, body="✅ **Added**: Cache invalidation tests in tests/test_cache.py")`
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
---
|
|
355
|
-
|
|
356
|
-
## Example 7: Using Custom Responses
|
|
357
|
-
|
|
358
|
-
**Scenario**: Skill drafts response, but you want to customize
|
|
359
|
-
|
|
360
|
-
**PR Context**:
|
|
361
|
-
- PR #103: "Optimize database queries"
|
|
362
|
-
- Comment about N+1 query
|
|
363
|
-
|
|
364
|
-
**Review comment**:
|
|
365
|
-
```
|
|
366
|
-
This causes N+1 queries. Use select_related() or prefetch_related().
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**Your changes**:
|
|
370
|
-
```python
|
|
371
|
-
# Before
|
|
372
|
-
users = User.objects.all()
|
|
373
|
-
for user in users:
|
|
374
|
-
print(user.profile.name) # N+1 query
|
|
375
|
-
|
|
376
|
-
# After
|
|
377
|
-
users = User.objects.select_related('profile').all()
|
|
378
|
-
for user in users:
|
|
379
|
-
print(user.profile.name) # Single query
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
**Skill execution**:
|
|
383
|
-
```
|
|
384
|
-
$ "Respond to PR review comments"
|
|
385
|
-
|
|
386
|
-
Found 1 review comment addressed:
|
|
387
|
-
|
|
388
|
-
1. @reviewer on src/queries.py:23
|
|
389
|
-
Comment: "This causes N+1 queries..."
|
|
390
|
-
Response: ✅ **Fixed**: Added select_related('profile')
|
|
391
|
-
|
|
392
|
-
Post this response? (y/n/edit) edit
|
|
393
|
-
|
|
394
|
-
Edit response:
|
|
395
|
-
> ✅ **Fixed**: Added select_related('profile') to eliminate N+1 query. Reduced from 100 queries to 1.
|
|
396
|
-
|
|
397
|
-
Post edited response? (y/n) y
|
|
398
|
-
|
|
399
|
-
Posted 1 response to PR #103
|
|
400
|
-
Ready to push!
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
---
|
|
404
|
-
|
|
405
|
-
## Example 8: Multiple Commits, One Response Session
|
|
406
|
-
|
|
407
|
-
**Scenario**: Addressed different comments in multiple commits
|
|
408
|
-
|
|
409
|
-
**PR Context**:
|
|
410
|
-
- PR #115: "Refactor data models"
|
|
411
|
-
- Made 3 commits addressing different feedback
|
|
412
|
-
|
|
413
|
-
**Your commits**:
|
|
414
|
-
```
|
|
415
|
-
commit abc123: fix: rename conflicting field names
|
|
416
|
-
commit def456: refactor: extract validation to forms
|
|
417
|
-
commit ghi789: docs: add docstrings to model methods
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
**Skill execution** (run ONCE after all commits):
|
|
421
|
-
```
|
|
422
|
-
$ "Respond to all PR review comments for my recent commits"
|
|
423
|
-
|
|
424
|
-
Analyzing commits abc123..ghi789
|
|
425
|
-
|
|
426
|
-
Found 3 review comments addressed across 3 commits:
|
|
427
|
-
|
|
428
|
-
1. @reviewer on src/models.py:34 (fixed in abc123)
|
|
429
|
-
Comment: "user_name conflicts with User.username"
|
|
430
|
-
Response: ✅ **Fixed**: Renamed to display_name
|
|
431
|
-
|
|
432
|
-
2. @reviewer on src/views.py:45 (fixed in def456)
|
|
433
|
-
Comment: "Validation should be in forms, not views"
|
|
434
|
-
Response: ✅ **Fixed**: Moved validation to ProfileForm.clean()
|
|
435
|
-
|
|
436
|
-
3. @reviewer on src/models.py:12 (fixed in ghi789)
|
|
437
|
-
Comment: "Missing docstring on calculate_score method"
|
|
438
|
-
Response: ✅ **Fixed**: Added docstring explaining score calculation logic
|
|
439
|
-
|
|
440
|
-
Post all 3 responses? (y/n) y
|
|
441
|
-
|
|
442
|
-
Posted 3 responses to PR #115
|
|
443
|
-
Ready to push!
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
## Integration Patterns
|
|
449
|
-
|
|
450
|
-
### Pattern 1: Pre-Push Workflow
|
|
451
|
-
|
|
452
|
-
```bash
|
|
453
|
-
# Your workflow
|
|
454
|
-
git add .
|
|
455
|
-
git commit -m "fix: address PR feedback"
|
|
456
|
-
|
|
457
|
-
# Before pushing, respond to reviews
|
|
458
|
-
"Respond to PR review comments"
|
|
459
|
-
|
|
460
|
-
# Then push
|
|
461
|
-
git push
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
### Pattern 2: Slash Command
|
|
465
|
-
|
|
466
|
-
```bash
|
|
467
|
-
# Add to .claude/settings.json
|
|
468
|
-
{
|
|
469
|
-
"commands": {
|
|
470
|
-
"/respond": "Use pr-review-responder skill"
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
# Usage
|
|
475
|
-
/respond
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### Pattern 3: Automated Hook
|
|
479
|
-
|
|
480
|
-
```bash
|
|
481
|
-
# .git/hooks/pre-push
|
|
482
|
-
#!/bin/bash
|
|
483
|
-
echo "Checking for review comments to respond to..."
|
|
484
|
-
claude "Use pr-review-responder skill for current changes"
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
### Pattern 4: Batch Review Response
|
|
488
|
-
|
|
489
|
-
```bash
|
|
490
|
-
# After fixing multiple PRs
|
|
491
|
-
cd project1 && "Respond to PR reviews" && git push
|
|
492
|
-
cd project2 && "Respond to PR reviews" && git push
|
|
493
|
-
cd project3 && "Respond to PR reviews" && git push
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
---
|
|
497
|
-
|
|
498
|
-
## Response Quality Examples
|
|
499
|
-
|
|
500
|
-
### Good Responses
|
|
501
|
-
|
|
502
|
-
✅ **Specific and actionable**:
|
|
503
|
-
```
|
|
504
|
-
✅ **Fixed**: Extracted upload logic to storage.upload_file()
|
|
505
|
-
✅ **Fixed**: Renamed user_name to display_name to avoid User.username conflict
|
|
506
|
-
✅ **Fixed**: Moved animation timing from Python context to CSS
|
|
507
|
-
✅ **Fixed**: Added type hints (int, str, Optional[Dict])
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
✅ **Acknowledges good feedback**:
|
|
511
|
-
```
|
|
512
|
-
✅ **Fixed**: Good catch! Removed duplicate error handling
|
|
513
|
-
✅ **Fixed**: You're right, using select_related() now
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
✅ **Explains non-obvious changes**:
|
|
517
|
-
```
|
|
518
|
-
✅ **Fixed**: Using Path().read_bytes() instead of wrapper (KISS)
|
|
519
|
-
✅ **Fixed**: Extracted to shared function (DRY principle)
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
### Bad Responses
|
|
523
|
-
|
|
524
|
-
❌ **Too vague**:
|
|
525
|
-
```
|
|
526
|
-
Fixed
|
|
527
|
-
Done
|
|
528
|
-
Updated code
|
|
529
|
-
Changed it
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
❌ **Too verbose**:
|
|
533
|
-
```
|
|
534
|
-
✅ **Fixed**: I removed the FileReader wrapper class that was
|
|
535
|
-
creating unnecessary abstraction and replaced it with a direct
|
|
536
|
-
call to Path().read_bytes() which is more straightforward and
|
|
537
|
-
follows the KISS principle as discussed in CLAUDE.md...
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
❌ **Defensive**:
|
|
541
|
-
```
|
|
542
|
-
Well, I thought the wrapper was cleaner but I changed it
|
|
543
|
-
I guess we can do it your way
|
|
544
|
-
Not sure why this is a problem but fixed
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
❌ **Argues in response**:
|
|
548
|
-
```
|
|
549
|
-
The wrapper class provides better encapsulation though
|
|
550
|
-
This is actually a valid pattern from Design Patterns book
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
## Advanced: Handling Complex Review Threads
|
|
556
|
-
|
|
557
|
-
**Scenario**: Long conversation thread on one comment
|
|
558
|
-
|
|
559
|
-
**Review thread**:
|
|
560
|
-
```
|
|
561
|
-
Reviewer: "This should use the shared upload function"
|
|
562
|
-
You: "Which shared function? I don't see one in the codebase"
|
|
563
|
-
Reviewer: "Check storage.py, upload_file()"
|
|
564
|
-
You: [makes the change]
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
**Skill behavior**:
|
|
568
|
-
- Detects existing conversation thread
|
|
569
|
-
- Posts reply at END of thread
|
|
570
|
-
- Keeps conversation context
|
|
571
|
-
|
|
572
|
-
**Posted response**:
|
|
573
|
-
```
|
|
574
|
-
✅ **Fixed**: Using storage.upload_file() as suggested
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
This appears after the conversation, making it clear this is the resolution.
|
|
578
|
-
|
|
579
|
-
---
|
|
580
|
-
|
|
581
|
-
## Summary
|
|
582
|
-
|
|
583
|
-
The pr-review-responder skill:
|
|
584
|
-
- Finds unresponded review comments
|
|
585
|
-
- Matches them to your code changes
|
|
586
|
-
- Drafts concise, specific responses
|
|
587
|
-
- Posts them to GitHub
|
|
588
|
-
- Makes PR feedback loops faster
|
|
589
|
-
|
|
590
|
-
Use it before every push to keep reviewers informed!
|