Delacour Ship
Take uncommitted work all the way to an open pull request in one run. Phase 1 turns the working tree into clean, atomic, gitmoji conventional commits. Phase 2 hands the branch to the dlc-pr skill, which pushes it, writes a title and body that match the repo's conventions, and signs it off where the repo gates on signoff.
When to Use
- When the user has uncommitted changes and wants them committed and opened as a PR
- When the user says "ship it", "commit and PR", or "push this up for review"
- When a task is finished and the next step is review on the base branch
Use dlc-pr on its own when the work is already committed. Use a plain commit when no PR is wanted.
Arguments
| Argument |
Effect |
--no-verify |
Skip the pre-commit checks in step 3. Say so in the final report. |
--style=simple |
Default. Single line commit subjects. |
--style=full |
Subject, body and footer on every commit. |
--type=<type> |
Force the commit type instead of detecting it. Only valid when the changes form one commit. |
--draft |
Passed through to dlc-pr to open a draft PR. |
Rules / Steps
Phase 1: Commit
1. Preflight
gh auth status
git status --short
git branch --show-current
gh repo view --json defaultBranchRef -q .defaultBranchRef.name
- If
gh is missing or not authenticated, stop before committing anything. Tell the user to install gh or run gh auth login in their own terminal. Committing first and failing at the PR step leaves the user halfway.
- If there is nothing to commit and the branch has commits ahead of the base branch, skip to Phase 2.
- If there is nothing to commit and nothing ahead of the base branch, stop and say so.
2. Get off the base branch
If the current branch is the base branch, create a feature branch before committing. Never commit straight to the base branch in this flow.
- Derive a name from the change:
<type>/<short-kebab-summary>, for example feat/token-refresh or fix/issue-482-token-refresh when an issue number is known.
- Follow any branch naming rule in
CONTRIBUTING.md, AGENTS.md or CLAUDE.md over this default.
git switch -c <branch>. Uncommitted changes carry over.
3. Run the repo's pre-commit checks
Skip this step when --no-verify is passed.
- Detect the package manager from the lockfile (
bun.lock, pnpm-lock.yaml, yarn.lock, package-lock.json) and use it. Never assume one.
- Run only scripts that exist, in this order:
lint, typecheck, test, build. Check package.json scripts first, or the equivalent for the stack (Makefile, Cargo.toml, pyproject.toml).
- If the repo has a git pre-commit hook or
.pre-commit-config.yaml, let the hook run during git commit instead of duplicating it.
- If a check fails, stop and fix the cause, or ask the user. Do not commit failing code and do not pass
--no-verify to git commit on the user's behalf.
4. Plan the commits
git diff
git diff --staged
git status --short
- If files are already staged, treat the staged set as the user's intended first commit and leave unstaged files for later commits.
- Group the rest into atomic commits. Split when the diff mixes:
- a feature and an unrelated fix
- unrelated areas of the codebase
- dependency bumps and feature work
- formatting-only changes and logic changes
- Keep a test with the code it tests. Keep docs with the change they describe unless they are unrelated.
- Never stage secrets,
.env files, credentials, large binaries or build output. If any are present and not ignored, stop and ask.
- Stage by explicit path (
git add <file> ...). Never use git add -A or git add . in this flow.
5. Write the commit messages
Detect the repo's commit convention first: commitlint.config.*, .commitlintrc*, commit rules in CONTRIBUTING.md, AGENTS.md or CLAUDE.md, and the counted majority of the last 100 subjects on the base branch. Repo rules beat the defaults below.
Default format:
<gitmoji> <type>(<optional scope>): <imperative summary>
| Type |
Gitmoji |
feat |
✨ |
fix |
🐛 |
docs |
📝 |
style |
🎨 |
refactor |
♻️ |
perf |
⚡️ |
test |
✅ |
chore |
🔧 |
ci |
👷 |
build |
📦 |
revert |
⏪ |
wip |
🚧 |
- Imperative mood, no trailing period, subject under 72 characters.
- Scope is a noun naming the area changed, matching scopes already used in history.
- Use the full style (body plus footer) for breaking changes, non-obvious fixes and changes that span systems, even when
--style=simple is the default. The body explains what and why, wrapped at 72 characters.
- Footers:
BREAKING CHANGE: <what broke>, Closes #<n> when an issue is known.
- Follow the repo's and the user's rules on attribution trailers. Do not add any the user has said to leave out.
Commit each group:
git add <paths> && git commit -m "<subject>" -m "<body>"
If a commit hook rewrites files, re-stage those files and create a new commit. Never --amend a commit that already existed before this run.
6. Confirm the history
git log origin/<base>..HEAD --oneline --no-decorate
git status --short
The tree must be clean before Phase 2, apart from files the user chose to leave out. Show the new commits in the final report.
Phase 2: Pull request
7. Hand off to dlc-pr
Invoke the dlc-pr skill and follow it in full, passing --draft through if it was given. It owns the push, branch hygiene, convention detection, the PR title and body, signoff, and the follow-up report.
- Its step 1 dirty-tree question does not apply, since Phase 1 left the tree clean.
- Reuse what Phase 1 learned: the issue number, the change type and the commit convention. Do not ask the user for anything Phase 1 already settled.
If dlc-pr is not installed, stop after Phase 1, report the commits, and tell the user to install it:
bunx skills add https://github.com/UrbanChrisy/delacour-agent-skills.git --skill dlc-pr
8. Report
One combined report:
- The branch, and whether it was created in step 2
- The commits created, one line each
- Which checks ran, which were skipped, and why
- The PR URL and the
dlc-pr report (convention source, signoff result, anything still blocking the merge)
Edge Cases
| Situation |
Action |
| On the base branch with changes |
Create a feature branch in step 2 before committing. |
| Branch has an open PR already |
Commit, then let dlc-pr update the existing PR instead of opening a new one. |
| Pre-commit check fails |
Stop. Fix or ask. Never bypass the check without --no-verify from the user. |
| Commit hook rejects the message |
Rewrite the message to satisfy the hook and commit again. Do not skip the hook. |
| Untracked files that look unrelated |
Ask whether to include them before staging. |
| Merge or rebase in progress |
Stop and tell the user to finish or abort it first. |
--type given but changes split into several commits |
Ask whether to apply the type to all commits or detect per commit. |
Examples
Example: feature work on main
Before:
branch: main
changes:
M src/auth/refresh.ts
M src/auth/refresh.test.ts
M package.json (dependency bump)
After:
branch: feat/token-refresh (created)
commits:
📦 build(deps): bump jose to 5.9.0
✨ feat(auth): refresh token before expiry window
checks: bun run lint, bun run typecheck, bun test (all passed)
PR: https://github.com/{owner}/{repo}/pull/{n}
The dependency bump was split from the feature, and the test stayed with the code it covers.
1---2name: dlc-ship3description: Commit the working tree with gitmoji conventional commit messages, then open a GitHub pull request for the branch in one run. Runs the repo's own pre-commit checks, splits unrelated changes into atomic commits, creates a feature branch when on the base branch, then hands off to the dlc-pr skill for push, PR title and body, and signoff. Use when the user wants to commit and open a PR in one step, ship uncommitted work, or go straight from changes to a pull request. Triggers on "ship it", "commit and PR", "commit and open a PR", "commit then PR", "/ship", "push this up for review", "commit and raise a PR".4metadata:5 source: https://skillmd.com/skills/delacournz/dlc-ship6 author: chris@delacour.co.nz7 version: "0.1.0"8 category: git9 tags: [git, github, commit, pull-request, gh-cli, workflow]10 argument-hint: "[--no-verify] [--style=simple|full] [--type=<type>] [--draft]"11license: UNLICENSED12---1314# Delacour Ship1516Take uncommitted work all the way to an open pull request in one run. Phase 1 turns the working tree into clean, atomic, gitmoji conventional commits. Phase 2 hands the branch to the `dlc-pr` skill, which pushes it, writes a title and body that match the repo's conventions, and signs it off where the repo gates on signoff.1718## When to Use1920- When the user has uncommitted changes and wants them committed and opened as a PR21- When the user says "ship it", "commit and PR", or "push this up for review"22- When a task is finished and the next step is review on the base branch2324Use `dlc-pr` on its own when the work is already committed. Use a plain commit when no PR is wanted.2526## Arguments2728| Argument | Effect |29| --- | --- |30| `--no-verify` | Skip the pre-commit checks in step 3. Say so in the final report. |31| `--style=simple` | Default. Single line commit subjects. |32| `--style=full` | Subject, body and footer on every commit. |33| `--type=<type>` | Force the commit type instead of detecting it. Only valid when the changes form one commit. |34| `--draft` | Passed through to `dlc-pr` to open a draft PR. |3536## Rules / Steps3738### Phase 1: Commit3940#### 1. Preflight4142```bash43gh auth status44git status --short45git branch --show-current46gh repo view --json defaultBranchRef -q .defaultBranchRef.name47```4849- If `gh` is missing or not authenticated, stop before committing anything. Tell the user to install `gh` or run `gh auth login` in their own terminal. Committing first and failing at the PR step leaves the user halfway.50- If there is nothing to commit and the branch has commits ahead of the base branch, skip to Phase 2.51- If there is nothing to commit and nothing ahead of the base branch, stop and say so.5253#### 2. Get off the base branch5455If the current branch is the base branch, create a feature branch before committing. Never commit straight to the base branch in this flow.5657- Derive a name from the change: `<type>/<short-kebab-summary>`, for example `feat/token-refresh` or `fix/issue-482-token-refresh` when an issue number is known.58- Follow any branch naming rule in `CONTRIBUTING.md`, `AGENTS.md` or `CLAUDE.md` over this default.59- `git switch -c <branch>`. Uncommitted changes carry over.6061#### 3. Run the repo's pre-commit checks6263Skip this step when `--no-verify` is passed.6465- Detect the package manager from the lockfile (`bun.lock`, `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`) and use it. Never assume one.66- Run only scripts that exist, in this order: `lint`, `typecheck`, `test`, `build`. Check `package.json` scripts first, or the equivalent for the stack (`Makefile`, `Cargo.toml`, `pyproject.toml`).67- If the repo has a git pre-commit hook or `.pre-commit-config.yaml`, let the hook run during `git commit` instead of duplicating it.68- If a check fails, stop and fix the cause, or ask the user. Do not commit failing code and do not pass `--no-verify` to `git commit` on the user's behalf.6970#### 4. Plan the commits7172```bash73git diff74git diff --staged75git status --short76```7778- If files are already staged, treat the staged set as the user's intended first commit and leave unstaged files for later commits.79- Group the rest into atomic commits. Split when the diff mixes:80 - a feature and an unrelated fix81 - unrelated areas of the codebase82 - dependency bumps and feature work83 - formatting-only changes and logic changes84- Keep a test with the code it tests. Keep docs with the change they describe unless they are unrelated.85- Never stage secrets, `.env` files, credentials, large binaries or build output. If any are present and not ignored, stop and ask.86- Stage by explicit path (`git add <file> ...`). Never use `git add -A` or `git add .` in this flow.8788#### 5. Write the commit messages8990Detect the repo's commit convention first: `commitlint.config.*`, `.commitlintrc*`, commit rules in `CONTRIBUTING.md`, `AGENTS.md` or `CLAUDE.md`, and the counted majority of the last 100 subjects on the base branch. Repo rules beat the defaults below.9192Default format:9394```95<gitmoji> <type>(<optional scope>): <imperative summary>96```9798| Type | Gitmoji |99| --- | --- |100| `feat` | ✨ |101| `fix` | 🐛 |102| `docs` | 📝 |103| `style` | 🎨 |104| `refactor` | ♻️ |105| `perf` | ⚡️ |106| `test` | ✅ |107| `chore` | 🔧 |108| `ci` | 👷 |109| `build` | 📦 |110| `revert` | ⏪ |111| `wip` | 🚧 |112113- Imperative mood, no trailing period, subject under 72 characters.114- Scope is a noun naming the area changed, matching scopes already used in history.115- Use the full style (body plus footer) for breaking changes, non-obvious fixes and changes that span systems, even when `--style=simple` is the default. The body explains what and why, wrapped at 72 characters.116- Footers: `BREAKING CHANGE: <what broke>`, `Closes #<n>` when an issue is known.117- Follow the repo's and the user's rules on attribution trailers. Do not add any the user has said to leave out.118119Commit each group:120121```bash122git add <paths> && git commit -m "<subject>" -m "<body>"123```124125If a commit hook rewrites files, re-stage those files and create a new commit. Never `--amend` a commit that already existed before this run.126127#### 6. Confirm the history128129```bash130git log origin/<base>..HEAD --oneline --no-decorate131git status --short132```133134The tree must be clean before Phase 2, apart from files the user chose to leave out. Show the new commits in the final report.135136### Phase 2: Pull request137138#### 7. Hand off to dlc-pr139140Invoke the `dlc-pr` skill and follow it in full, passing `--draft` through if it was given. It owns the push, branch hygiene, convention detection, the PR title and body, signoff, and the follow-up report.141142- Its step 1 dirty-tree question does not apply, since Phase 1 left the tree clean.143- Reuse what Phase 1 learned: the issue number, the change type and the commit convention. Do not ask the user for anything Phase 1 already settled.144145If `dlc-pr` is not installed, stop after Phase 1, report the commits, and tell the user to install it:146147```bash148bunx skills add https://github.com/UrbanChrisy/delacour-agent-skills.git --skill dlc-pr149```150151#### 8. Report152153One combined report:154155- The branch, and whether it was created in step 2156- The commits created, one line each157- Which checks ran, which were skipped, and why158- The PR URL and the `dlc-pr` report (convention source, signoff result, anything still blocking the merge)159160### Edge Cases161162| Situation | Action |163| --- | --- |164| On the base branch with changes | Create a feature branch in step 2 before committing. |165| Branch has an open PR already | Commit, then let `dlc-pr` update the existing PR instead of opening a new one. |166| Pre-commit check fails | Stop. Fix or ask. Never bypass the check without `--no-verify` from the user. |167| Commit hook rejects the message | Rewrite the message to satisfy the hook and commit again. Do not skip the hook. |168| Untracked files that look unrelated | Ask whether to include them before staging. |169| Merge or rebase in progress | Stop and tell the user to finish or abort it first. |170| `--type` given but changes split into several commits | Ask whether to apply the type to all commits or detect per commit. |171172## Examples173174### Example: feature work on main175176**Before:**177178```179branch: main180changes:181 M src/auth/refresh.ts182 M src/auth/refresh.test.ts183 M package.json (dependency bump)184```185186**After:**187188```189branch: feat/token-refresh (created)190commits:191 📦 build(deps): bump jose to 5.9.0192 ✨ feat(auth): refresh token before expiry window193checks: bun run lint, bun run typecheck, bun test (all passed)194PR: https://github.com/{owner}/{repo}/pull/{n}195```196197The dependency bump was split from the feature, and the test stayed with the code it covers.