| name | implement-gh-issue |
| description | Implement a GitHub issue end-to-end in the QuickCut repo using a git worktree, then open a PR and produce an issue-specific manual test plan. Use this skill whenever the user asks to "implement issue |
Implement a GitHub Issue (QuickCut)
Overview
This skill takes the user from a GitHub issue number/URL all the way to a
ready-to-review PR plus a manual test plan tailored to the issue. It chains
together the worktree workflow, implementation, verification, PR creation,
and test-plan writing so the user gets one consistent flow every time.
Announce at start: "I'm using the implement-gh-issue skill to work issue
# in a fresh worktree."
When to use
- The user gives you an issue number, an issue URL, or a description that
references an existing GitHub issue and asks you to implement it.
- The user pastes a
github.com/jamesqquick/quickcut/issues/<n> link and the
intent is implementation (not just discussion or triage).
- The user says "implement", "work on", "knock out", "build", "fix", or
"do" + an issue reference.
Do not use this skill for:
- Pure discussion / clarification of an issue (no code changes intended).
- Quick edits the user wants on the current branch — this skill always
branches off
origin/main in a new worktree.
Workflow
Follow these steps in order. Don't batch — finish a step, confirm it, then
move on. Use TodoWrite to track the steps so the user can see progress.
1. Fetch the issue
Use gh to read the issue. You need the title, body, and labels:
gh issue view <num> --repo jamesqquick/quickcut --json number,title,body,labels,url
Read the body carefully. Surface acceptance criteria, file references, and
any constraints to the user before writing code. If the issue is vague,
ask for clarification rather than guessing — implementing the wrong thing
wastes a worktree and a PR.
2. Pick the branch name
Branch convention: <prefix>-issue-<num>-<slug>
Pick the prefix from the issue's labels:
| Label contains | Prefix |
|---|
bug, fix, regression | fix |
enhancement, feature, feat | feature |
chore, refactor, docs, ci, deps | chore |
| (no clear signal) | feature (default; ask if unsure) |
<slug> is a short kebab-case version of the issue title — 3-6 words,
lowercase, no punctuation. Example: issue #42 "Add CSV export to clip
library" with label enhancement →
feature-issue-42-add-csv-export.
3. Create the worktree and run setup
Use the using-git-worktrees skill (global) to create the worktree at
.worktrees/<branch> based on origin/main and run pnpm install.
Then immediately run the worktree-setup skill (local to this repo)
to copy .dev.vars and .wrangler/state/ from the main checkout and apply
local migrations. This is mandatory — see AGENTS.md. Skipping it produces
empty list views, Bearer undefined Stream API errors, and 500s on
anything bound.
After this, all subsequent commands run from the worktree directory.
4. Implement the change
- Re-read the issue body and acceptance criteria once more before editing.
- Make the smallest change that satisfies the issue. Resist scope creep.
- Follow the repo's conventions (TypeScript, named exports, comments only
when not self-explanatory — see root
AGENTS.md).
- If you discover the issue is bigger or different than described, stop and
surface that to the user before continuing.
5. Verify before pushing
Run typecheck, build, and lint from inside the worktree. The build script
(wrangler types && astro build) covers both Wrangler binding types and
Astro's TypeScript check, so it satisfies typecheck + build in one go:
pnpm build
If a lint script exists in package.json at the time you run this, run it
too. Today QuickCut does not ship a dedicated lint script — don't invent
one. If tsc is configured for a separate check, run that. Otherwise
pnpm build is the gate.
Do not push or open a PR if the build fails. Fix the failures first.
5b. Update CHANGELOG.md
Before committing, prepend a user-facing entry to CHANGELOG.md at the repo root.
- If today's date group already exists at the top, append a bullet to it.
- If not, add a new
## Month DD, YYYY heading above the previous top entry.
- Write one sentence in plain user-facing language — no component names, no
internal jargon, no Conventional Commit scopes. Write it as something a user
would read to understand what changed for them.
- End the bullet with the PR number in parentheses, e.g.
(#42).
Example entry:
## May 27, 2026
- You can now export clips as a CSV file from the clip library. (#42)
Stage CHANGELOG.md alongside the rest of the commit. This is not optional —
every user-facing change must have a changelog entry. Skip this step only for
purely internal changes (chore, refactor, docs, ci) that have no visible effect
on users.
6. Commit
Use Conventional Commits, scoped to the area of change. Match the prefix
you chose for the branch when reasonable:
feat(actions): add CSV export to clip library
fix(stream): handle undefined token in upload flow
chore(deps): bump wrangler to 4.85
Per project rules in AGENTS.md: never git add files inside tmp/, and
never commit .dev.vars.
7. Push and open the PR
Confirm with the user before pushing if this is the first time in the
session — root AGENTS.md says don't push without asking. Once confirmed:
git push -u origin <branch>
Open the PR with gh pr create. The body must reference the issue with
Closes #<num> so GitHub auto-closes it on merge.
PR template:
## Summary
<1-3 bullets on what changed and why>
## Changes
- <file or area>: <what>
- <file or area>: <what>
## Testing
See test plan below / in the comment that follows.
Closes #<num>
Use a HEREDOC to pass the body so newlines survive the shell:
gh pr create --title "<conventional commit-style title>" --body "$(cat <<'EOF'
## Summary
...
Closes #<num>
EOF
)"
Return the PR URL to the user.
8. Write the local test plan
This is the part users care most about. Output it directly in chat as the
final message, using this exact structure:
## How to test locally
### Setup
1. `cd .worktrees/<branch>`
2. `pnpm dev` (Wrangler types regenerate, then Astro starts on its dev port)
3. Open the dev URL printed in the terminal
### Test scenarios
1. **<Scenario name>** — <what to do, step by step>
- Expected: <what should happen>
2. **<Edge case>** — <what to do>
- Expected: <what should happen>
3. **<Failure path, if relevant>** — <what to do>
- Expected: <what should happen>
### What to verify in the data layer (if applicable)
- <D1 table or KV key>: <expected state>
- Run `wrangler d1 execute quickcut-db --local --command "..."` to inspect.
### Cleanup
- Nothing destructive was done; the worktree is safe to leave running.
- To tear down: see the worktree-pr-flow skill.
The test scenarios must be issue-specific — derived from the
acceptance criteria in the issue body. Generic "open the app, click
around" is not acceptable. Include at least one happy path, one edge
case, and one failure path when the issue's surface area allows.
If the change is purely backend / has no UI, replace the dev-server steps
with the equivalent way to exercise the code (e.g. an API call via
curl, or running a script).
Quick reference
| Step | Command / Action |
|---|
| Read issue | gh issue view <n> --repo jamesqquick/quickcut --json number,title,body,labels,url |
| Create worktree | using-git-worktrees skill |
| Restore local state | worktree-setup skill |
| Verify | pnpm build (typecheck + build) |
| Changelog | Prepend entry to CHANGELOG.md, stage it |
| Push | git push -u origin <branch> (after confirming) |
| Open PR | gh pr create with Closes #<n> in body |
Red flags
Stop and ask the user if:
- The issue body is ambiguous or contradicts itself.
- The change touches
.dev.vars, secrets, auth config, or migrations that
could affect production data.
- The build fails in a way unrelated to your change (suggests a broken
main, not a coding issue you should fix in this PR).
- You're about to force-push or amend a pushed commit — never do this
without explicit permission (see root
AGENTS.md git safety rules).
Never:
- Skip the
worktree-setup step. The dev server starts but every binding
fails at runtime.
- Push or open a PR without running
pnpm build successfully first.
- Commit files in
tmp/ or .dev.vars.
- Open the PR without
Closes #<num> in the body.
- Skip the
CHANGELOG.md update for user-facing changes.
Integration
Pairs with:
- using-git-worktrees (global) — creates the isolated worktree.
- worktree-setup (this repo) — restores Wrangler/D1 state and
.dev.vars.
- worktree-pr-flow (global) — for cleanup after the PR is merged.
- git-commit (global) — for Conventional Commits formatting.
Example flow
User: Implement issue 42 https://github.com/jamesqquick/quickcut/issues/42
You: I'm using the implement-gh-issue skill to work issue #42 in a fresh worktree.
[gh issue view 42 → "Add CSV export to clip library", label: enhancement]
[Surface acceptance criteria back to the user]
[Create .worktrees/feature-issue-42-add-csv-export from origin/main]
[Run pnpm install]
[Run worktree-setup: copy .dev.vars + .wrangler/state, run migrations]
[Implement: add /api/clips/export.csv route + UI button]
[pnpm build → passes]
[Commit: feat(clips): add CSV export]
[Confirm push with user → push → gh pr create with Closes #42]
[Output the local test plan tailored to CSV export]