skills/deliver-feature/SKILL.md
From inside a linked worktree, deliver the current feature branch into main — merge with --no-ff, push, and optionally clean up the worktree, all without leaving CWD.
npx skillsauth add nesnilnehc/ai-cortex deliver-featureInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Lands the current worktree's feature branch onto main without requiring the user to switch directories. Operates the main repo via git -C <main-repo> so the user keeps working in their feature worktree until they explicitly choose to leave it. Eliminates the round trip: cd to main repo → invoke batch tool → select just-finished branch → cd back.
Primary goal: Deliver the current worktree's feature branch onto main (via --no-ff merge), push to origin, and let the user decide whether to keep or remove the worktree — all without leaving the worktree directory.
Success Criteria (all must be satisfied):
git status --porcelain empty)git -C <main-repo> used for pull / merge --no-ff / push; CWD remains the worktree throughout the mergegit push origin <main-branch> returns 0 before any cleanup is offered-d only); no implicit removalAcceptance Test: After skill completes, git -C <main-repo> log --oneline <main-branch> shows exactly one new merge commit referencing the feature branch; git -C <main-repo> ls-remote origin <main-branch> matches local; if user chose remove, git worktree list no longer contains the source worktree.
This skill handles:
git worktree list --porcelain--no-ff merge → push, executed against the main repo via git -C-d only)This skill does NOT handle:
integrate-worktrees from the main repo on the main branch)commit-work first)Handoff points:
integrate-worktrees: when the user is in the main repo on the main branch and wants to land multiple worktrees in one batchgit -C <main-repo> reset --hard HEAD~1), pull, and retry manually/repos/myapp-api (worktree on feat/api-v2) and wants to land it into main without leaving the worktreecommit-work in a worktree, immediately delivering that single branchStep 1 — Verify invocation context
git rev-parse --git-dir # main repo: <root>/.git ; linked worktree: <main-root>/.git/worktrees/<name>
git rev-parse --git-common-dir # both contexts return the same value: <main-root>/.git
git rev-parse --abbrev-ref HEAD # current branch
git rev-parse --show-toplevel # current worktree root (CWD's repo root)
Determine the context: a linked worktree has git-dir != git-common-dir (the per-worktree .git/worktrees/<name> vs the shared .git). Equivalently, the file at <toplevel>/.git is a regular file (gitlink) in a linked worktree, and a directory in the main repo.
If git rev-parse --git-dir equals git rev-parse --git-common-dir (i.e., CWD is the main repo, not a linked worktree) → halt:
"This skill must be run from inside a linked worktree, not from the main repo. Current location:
<cwd>. To batch-merge multiple worktrees from the main repo, useintegrate-worktrees."
If current branch equals the detected main branch (see Step 2) → halt:
"Current branch is
<main-branch>. This skill delivers a feature branch into main, not main into itself. Switch to a feature branch in this worktree, or useintegrate-worktreesfrom the main repo."
Record <feature-worktree> (= git rev-parse --show-toplevel) and <feature-branch> (= current branch).
Step 2 — Determine main branch and locate main repo
git remote show origin | grep 'HEAD branch'
HEAD branch: main) → use it.git branch -r for origin/main then origin/master."Could not determine the main branch automatically. What is the name of the main branch (e.g., main, master, develop)?"
Record <main-branch>.
Locate the main repo from the worktree list:
git worktree list --porcelain
Parse the porcelain output. The first record is the main repo (its worktree line gives the path). Record <main-repo>. Sanity check: <main-repo> != <feature-worktree>.
Step 3 — Pre-flight: current worktree must be clean
git status --porcelain
If output is non-empty → halt:
"Current worktree
<feature-worktree>has uncommitted changes. Commit them first (e.g., viacommit-work) and re-invoke. No auto-stash."
Step 4 — Pull main, merge feature branch, push (executed via git -C <main-repo>)
git -C <main-repo> checkout <main-branch>
git -C <main-repo> pull origin <main-branch>
git -C <main-repo> merge --no-ff <feature-branch> -m "Merge branch '<feature-branch>' into <main-branch>"
git -C <main-repo> push origin <main-branch>
CWD remains <feature-worktree> for every command — the git -C flag drives the main repo without changing the user's location.
On conflict during merge → halt:
"Merge conflict merging
<feature-branch>into<main-branch>(in main repo<main-repo>). Resolve conflicts there manually, complete the merge, then rungit -C <main-repo> push origin <main-branch>. The worktree is untouched."
On push rejection (non-fast-forward) → halt:
"Push rejected after merging
<feature-branch>. In<main-repo>, rungit reset --hard HEAD~1to undo the merge, thengit pull, re-merge, and push manually."
After successful push, capture <merge-commit-hash> via git -C <main-repo> rev-parse <main-branch>.
Step 5 — Ask the user about cleanup
Present a single prompt with three options:
"Delivery complete. What should happen to the worktree
<feature-worktree>and branch<feature-branch>?[1] Keep worktree (stay here, branch kept) [2] Remove worktree, keep branch (cd back to main repo) [3] Remove worktree and delete branch (
git branch -d, safe delete)Choose 1 / 2 / 3:"
For options 2 and 3, the skill outputs a final instruction telling the user to cd to <main-repo> (the skill itself cannot change the user's shell CWD; it only runs the git commands).
For options 2 and 3, execute (from <main-repo> via git -C):
git -C <main-repo> worktree remove <feature-worktree>
For option 3 only, after worktree removal:
git -C <main-repo> branch -d <feature-branch>
Use -d only — never -D. If -d fails (unexpected after a successful --no-ff merge), report the error and stop deletion (do not retry with -D).
Step 6 — Summary report
deliver-feature summary
──────────────────────────────────────────────────────────────────────────
Feature branch: feat/api-v2
Worktree: /repos/myapp-api
Main repo: /repos/myapp
Main branch: main
Merge commit: a1b2c3d (--no-ff)
Push: ✓
Worktree: removed | kept
Branch: deleted | kept
──────────────────────────────────────────────────────────────────────────
Next: cd /repos/myapp (only when worktree was removed)
| Input | Required | Description |
|---|---|---|
| Worktree context | Yes | CWD must be inside a linked worktree; halts if in main repo |
| Non-main branch | Yes | Current branch must not be <main-branch>; halts otherwise |
| Clean working tree | Yes | git status --porcelain must be empty; no auto-stash |
| Cleanup choice | User input | One of keep / remove-keep-branch / remove-and-delete-branch |
| Main branch name | Auto/Ask | Detected from remote; user asked if ambiguous |
| Network access | Yes | Required to pull and push to origin |
Produces (side-effects):
| Element | Description |
|---|---|
| Merge commit | Exactly one --no-ff merge commit on <main-branch> in the main repo |
| Remote push | origin/<main-branch> updated once |
| Worktree removal | Optional, user-chosen |
| Branch deletion | Optional, user-chosen; git branch -d only |
| Summary report | Single-branch table with merge commit hash, push status, cleanup outcome, and a follow-up cd hint when applicable |
git -C <main-repo>; the user's shell stays in the worktree--force, --force-with-lease) to any branchgit branch -D — only -dDo not do these (other skills or tools handle them):
integrate-worktrees from the main repo on the main branchcommit-work before invoking this skillgit rebase directly before invoking this skillreview-diff before committing; this skill does not review code✅ Run from inside a linked worktree on a non-main branch
❌ Do not run from the main repo — that's integrate-worktrees's job; running this from main has no current worktree to deliver
✅ Use git -C <main-repo> for every main-repo operation; CWD stays in the worktree
❌ Do not cd <main-repo> mid-skill — if the user later removes the worktree, they expect to remain wherever they invoked from until they pick option 2/3
✅ Verify clean tree before any merge attempt ❌ Do not start the merge and discover dirty files mid-flow
✅ git merge --no-ff to preserve branch history
❌ Do not use git merge --squash or fast-forward — history would be lost
✅ Remove worktree only after the user explicitly chose option 2 or 3, AND merge+push succeeded ❌ Do not auto-remove the worktree — the user may want to keep working there
✅ Use git branch -d (safe) only on user's explicit option-3 choice
❌ Never use git branch -D — it can delete unmerged commits
Scenario: Developer just finished feat/api-v2 in worktree /repos/myapp-api. Wants to land it and clean up.
Execution:
# CWD: /repos/myapp-api
# Step 1: Context — in a linked worktree on a non-main branch ✓
git rev-parse --git-dir # /repos/myapp/.git/worktrees/myapp-api
git rev-parse --git-common-dir # /repos/myapp/.git (differs from --git-dir → linked worktree ✓)
git rev-parse --abbrev-ref HEAD # feat/api-v2
git rev-parse --show-toplevel # /repos/myapp-api
# Step 2: Main branch + main repo
git remote show origin | grep 'HEAD branch' # HEAD branch: main
git worktree list --porcelain # first record → /repos/myapp
# Step 3: Pre-flight — clean ✓
git status --porcelain # (empty)
# Step 4: Pull → merge → push, all via git -C; CWD stays /repos/myapp-api
git -C /repos/myapp checkout main
git -C /repos/myapp pull origin main
git -C /repos/myapp merge --no-ff feat/api-v2 -m "Merge branch 'feat/api-v2' into main"
git -C /repos/myapp push origin main
# merge commit: a1b2c3d
# Step 5: User chooses [3] Remove worktree and delete branch
git -C /repos/myapp worktree remove /repos/myapp-api
git -C /repos/myapp branch -d feat/api-v2
Summary:
deliver-feature summary
──────────────────────────────────────────────────────────────────────────
Feature branch: feat/api-v2
Worktree: /repos/myapp-api
Main repo: /repos/myapp
Main branch: main
Merge commit: a1b2c3d (--no-ff)
Push: ✓
Worktree: removed
Branch: deleted
──────────────────────────────────────────────────────────────────────────
Next: cd /repos/myapp
Scenario: Developer is in /repos/myapp on main and runs deliver-feature by habit.
Execution:
# CWD: /repos/myapp
git rev-parse --git-dir # /repos/myapp/.git
git rev-parse --git-common-dir # /repos/myapp/.git (equal → main repo, NOT a worktree)
Skill halts:
"This skill must be run from inside a linked worktree, not from the main repo. Current location:
/repos/myapp. To batch-merge multiple worktrees from the main repo, useintegrate-worktrees."
No git operations performed. Exit code non-zero.
Scenario: Developer ran deliver-feature from /repos/myapp-api on feat/api-v2. Pre-flight clean. The merge into main hits a conflict.
Execution:
# CWD: /repos/myapp-api (stays here throughout)
git -C /repos/myapp pull origin main
git -C /repos/myapp merge --no-ff feat/api-v2 -m "Merge branch 'feat/api-v2' into main"
# CONFLICT (content): Merge conflict in src/api.ts
Skill halts:
"Merge conflict merging
feat/api-v2intomain(in main repo/repos/myapp). Resolve conflicts there manually, complete the merge, then rungit -C /repos/myapp push origin main. The worktree is untouched."
CWD is still /repos/myapp-api. Worktree is intact. No push. No cleanup. Summary reports Merge: ✗(conflict).
If this skill produces incorrect behavior:
cd <main-repo> or used a non--C git command on the main repo → rewind; switch to git -C <main-repo> for all main-repo operationsgit rev-parse --git-dir equals git rev-parse --git-common-dir) → rewind to Step 1, add the git-dir vs git-common-dir comparison guardgit stash appeared anywhere → remove; halt on dirty tree per Step 3git worktree remove ran before git push returned 0 → halt; only run cleanup after Step 4 completes successfully and the user picks option 2 or 3--force or --force-with-lease appears in any push command → substitute standard push; if rejected, halt and reportgit rev-parse --git-dir differs from git rev-parse --git-common-dir before proceedinggit worktree list --porcelain first recordgit status --porcelain empty before any mergegit -C <main-repo>; user's shell stayed in <feature-worktree>git -C <main-repo> pull origin <main-branch> ran before git merge --no-ffgit merge --no-ff confirmed; no fast-forward or squashgit push returned 0 was the cleanup prompt shown-d: no -D flag; option 3 only--force or --force-with-lease never appeared in any commanddevelopment
Generate an LLM agent test suite (golden cases, mock-LLM unit tests, evaluator harness) from an agent implementation and its agent-test contract. Use when an agent has no tests, or a contract exists but the test code is missing.
development
After code changes, auto-detect the project's build system and local deployment method for a given directory, then build the project and restart its locally-deployed environment (Docker Compose / systemd / process manager). Never assumes — asks only when detection is ambiguous. Caches detected commands per project in .cortex/redeploy-local.yaml; re-invocations on the same project skip re-scanning until signal files change, the cache expires (30 days), or the skill version bumps.
tools
Publish a NATS message conforming to a cross-team contract, using NATS MCP tools. Authors the contract on first use if missing. Reads project-level cache (.cortex/nats.yaml) to avoid re-prompting basics across sessions.
tools
Drain pending NATS messages from a producer contract via NATS MCP tools (default batch / drain-style). Applies Tolerant Reader semantics and per-message ack/nak/term, returning aggregated stats. Reads project-level cache (.cortex/nats.yaml) to avoid re-prompting.