Ship to Prod
When the user says "ship it" or similar after completing work, follow these steps without being asked twice.
The flow depends on which branch you're on. Detect the environment once, then reuse it through the steps.
Detect the environment
Run these once at the start, in parallel:
- Package manager: check for a lockfile in the repo root.
pnpm-lock.yaml->pnpmyarn.lock->yarnbun.lockborbun.lock->bunpackage-lock.json->npm- If
package.jsonhas apackageManagerfield, use that instead. - If none found, default to
npm.
- Default branch:
git symbolic-ref refs/remotes/origin/HEAD(orgit config init.defaultBranchas a fallback). If both fail, default tomain. - PR tooling:
gh --version. Ifghis installed and authenticated, use it for PR creation and merge. If not, fall back to printing the PR URL for the user to create manually. - Shell: detect the current shell. On Windows (PowerShell), heredocs don't work, so use multiple
-mflags forgit commit. On bash/zsh/fish and other Unix shells, use a heredoc.
Store these as <pkg>, <default-branch>, <gh-available>, and <shell> for the rest of the flow.
Steps
1. Clean up (optional)
Two skills clean up AI-generated slop before committing. Run both if available:
deslop: removes AI code slop from the diff (unnecessary comments, defensive checks on trusted paths,anycasts, deep nesting). Invoke it on the current diff against the default branch.unslop: removes AI text tells from prose (UI strings, comments, commit messages, PR descriptions). Invoke it on any text you wrote this session.
Fix everything either skill flags before moving on.
If either skill is not installed, do not just skip it silently. Ask the user whether to install the missing one(s), offering these choices. Mention that both skills come from Cursor AI's official plugins repo (https://github.com/cursor/plugins), so they're a trusted source:
- Globally (for future uses across all projects):
npx skills add https://github.com/cursor/plugins --skill deslop unslop -g - Locally (this project only):
npx skills add https://github.com/cursor/plugins --skill deslop unslop - Skip for this run: continue without the missing skill(s). Do not block the flow on a missing optional dependency.
Use the ask_user_question tool to present the choice. If the user picks global or local, run the install command, then re-check that the skill(s) are now available before invoking them. If the install fails or the user picks skip, continue the flow with whatever is available.
2. Verify the work
Run these in order, fixing any issues before continuing. Substitute <pkg> for the detected package manager. npm always requires run (e.g. npm run format); pnpm/yarn/bun allow direct invocation (e.g. pnpm format):
<pkg> run format(or<pkg> formatfor pnpm/yarn/bun): auto-format<pkg> run lint(or<pkg> lintfor pnpm/yarn/bun): fix lint errors in files you touched (ignore pre-existing issues in other files)<pkg> run typecheck(or<pkg> typecheckfor pnpm/yarn/bun): must pass with exit code 0<pkg> run build(or<pkg> buildfor pnpm/yarn/bun): must pass with exit code 0
If a script is missing (e.g. no format script), skip that step and note it. Do not fail the whole flow on a missing optional script. typecheck and build are required if they exist; if neither exists, proceed with a warning.
Do not proceed to commit until the available checks pass.
If git status is clean after verification (nothing staged or unstaged), report "nothing to ship" and stop. Do not attempt an empty commit.
3. Assess the current branch
Run git branch --show-current to get the current branch name. Compare it to <default-branch>. Then decide:
- If on
<default-branch>: Commit and push directly. No PR, no merge. Skip to step 5. - If on any other branch: Commit, push, create a PR to
<default-branch>, and merge. Continue to step 4.
4. Review changes
Run git status, git diff, and git log --oneline -5 in parallel to understand what changed and match commit style.
5. Stage and commit
git add -A, then commit with a conventional-commit message (feat/fix/refactor).
Commit message format:
<type>: <short description>
<optional body>
On bash/zsh/fish and other Unix shells, use a heredoc:
git commit -m "$(cat <<'EOF'
type: subject
body
EOF
)"
On PowerShell (Windows), heredocs don't work, so use multiple -m flags:
git commit -m "type: subject" -m "body"
6. Push
git push (or git push -u origin <branch> if the branch has no upstream yet).
7. If on a feature branch: create PR and merge
If <gh-available>:
- Write the PR body to a temp file, then create the PR with
--body-file(works on every shell, including PowerShell):gh pr create --base <default-branch> --head <current-branch> --title "<title>" --body-file <temp-file>
- Delete the temp file after
gh pr createreturns. Do not leave it on disk. - Merge without specifying a strategy, so the user's repo default applies:
gh pr merge <number>
PR body format:
## Summary
<bullet points>
#### Test plan
- [ ] <checklist>
If gh is not available:
- Push the branch (step 6).
- Print the URL the user should open to create the PR manually:
<repo-url>/compare/<default-branch>...<current-branch> - Stop. Let the user create and merge the PR themselves. Do not attempt to merge without
gh.
8. Keep the current branch alive
Do NOT delete the working branch after merge. It stays open for the next feature.
9. Confirm
Report the PR URL (if applicable) and merge/push status to the user.
Conflict handling
If the feature branch is behind <default-branch>, rebase before pushing:
git fetch origin <default-branch>
git rebase origin/<default-branch>
Resolve any conflicts, then continue with push + PR + merge.
Notes
- The target is always the detected
<default-branch>, not a hardcoded name. - Never delete the working branch after merge.
- If on
<default-branch>, just commit and push. No PR needed. - Never skip the verification step, even if the user is in a hurry.
- The
deslopstep is optional. If a skill is missing, offer to install it (globally or locally) before falling back to skipping.