| name | new-branch |
| description | Only when explicitly asked for /new-branch or a fresh git branch: stash local changes, update main, and create it. Do not auto-run for normal coding, PR, Builder.io, or Fusion branch workflows. |
| user-invocable | true |
| scope | dev |
| metadata | {"internal":true} |
New Branch
Activation guard
Use this skill only when the user explicitly invokes /new-branch, mentions this skill as the workflow to run, or directly asks you to create a fresh git branch from main.
If this skill was loaded without an explicit user request to create a new branch, stop here. Report that branch movement requires explicit confirmation, then continue the original task on the current branch.
Do NOT invoke this skill in any of these situations
These are mistakes other agents have made that stranded concurrent work:
- The user said "fix the bug" / "open a PR" / "ship this" / "address review feedback" — those work on the current branch. PR and ship workflows in this repo push the current branch; they don't branch-then-push.
- The current branch name looks unusual (
ai_*, claude/*, codex/*, changes-N, updates-N, pr-NNN, feat/...). Those are platform-managed or other agents' branches; moving off looks like work-loss to whoever started them.
- You're running inside Builder.io / Fusion / a project container. The platform tracks the user's work by the branch it assigned — leaving silently breaks their UI.
- The working tree has uncommitted changes from work you didn't do. Branching stashes them, and orphaned stashes are how we've lost work in the past. Surface the changes to the user first, never stash silently.
- You think a fresh branch would be "tidier." Tidiness is not a goal here; concurrent-agent durability is.
When in doubt: stay on the current branch. Ask the user before moving.
Quickly stash any local changes, pull latest from origin/main, and create a new working branch. Designed to be as fast as possible since other agents may be working concurrently on this repo.
Pre-flight: verify main has the latest merge
Before creating the branch, always verify that origin/main contains the most recently merged PR. If you just merged a PR (or know one was recently merged), run:
git fetch origin main
gh pr list --state merged --base main --limit 1 --json number,mergedAt,mergeCommit --jq '.[0]'
git log origin/main --oneline -1
Compare the merge commit SHA. If origin/main doesn't include it yet, wait and re-fetch — GitHub can take a few seconds to update after a squash merge. Never create a branch off stale main. Creating a branch that's missing a just-merged PR causes chaos: subsequent work assumes the merged code is there, leading to conflicts, regressions, and duplicated changes.
Steps
Run as a single chained command to minimize time off-branch. Resolve the
authenticated GitHub username before choosing the branch name so concurrent
users have separate branch namespaces. The git stash push is gated so we
only pop a stash we just created — never an old stash from a previous
session. The stash name embeds the source branch so an orphan can be identified
later (orphans are how we've lost work in the past — see "Post-flight check"
below):
GITHUB_USER=$(gh api user --jq .login) && test -n "$GITHUB_USER" || { echo "Unable to resolve the authenticated GitHub username" >&2; exit 1; }; LATEST=$({ git for-each-ref --format='%(refname:short)' refs/heads refs/remotes/origin; git ls-remote --heads origin; } | sed -E -e 's#^[0-9a-f]+[[:space:]]+refs/heads/##' -e 's#^origin/##' | sed -nE 's#^([^/]+/)?changes-([0-9]+)$#\2#p' | awk '$1 >= 50 { print }' | sort -n | tail -1); NEXT=$(( ${LATEST:-49} + 1 )); BRANCH_NAME="${GITHUB_USER}/changes-${NEXT}"; SOURCE=$(git branch --show-current); STASH_MSG="new-branch-from-${SOURCE:-detached}-$(date +%s)"; if git diff-index --quiet HEAD --; then CREATED=0; else git stash push -m "$STASH_MSG" && CREATED=1 || CREATED=0; fi; git checkout main && git pull origin main && git checkout -b "$BRANCH_NAME" && if [ "$CREATED" = "1" ]; then git stash pop; else echo "(no stash to pop)"; fi; echo "--- Done: $(git branch --show-current)"
Why the gate: git stash push exits 0 even when there are no local changes ("No local changes to save"), so chaining && CREATED=1 would always set CREATED=1 and an unconditional git stash pop would pop a pre-existing stash from earlier work, dumping unrelated files into the working tree. The git diff-index --quiet HEAD -- pre-check exits 0 only when there are no differences against HEAD in tracked files — we skip stashing entirely in that case so there's nothing to pop. Untracked files are intentionally not part of the gate (and not stashed): for a fast new-branch flow, untracked files following the user across git checkout is the desired behaviour, and git stash push without -u already ignores them. We let git stash pop errors (e.g. merge conflicts) surface naturally rather than swallowing them with 2>/dev/null, since the next section assumes you'll see and resolve them.
Branch naming
- Use the pattern
<github-username>/changes-N, for example steve8708/changes-545, where N is at least 50
- Resolve
<github-username> with gh api user --jq .login; do not substitute a display name or local git author name
- Choose N from all local refs and current
origin refs matching changes-N, whether legacy unprefixed or already username-prefixed, so the sequence does not reset
- Ignore older numbers below 50 and unrelated branch names
- If no matching branch exists at 50 or above, start with
<github-username>/changes-50
After creation
Post-flight check
After every /new-branch invocation, list any pre-existing stashes and surface them to the user. Orphaned new-branch-from-* / WIP on * / babysit-tick*-concurrent-work-* stashes are how we've lost real work in the past — they pile up unnoticed.
git stash list
If the list shows stashes that aren't yours-from-this-run, name them in your response:
Heads-up — there are 3 pre-existing stashes (stash@{1}: WIP on updates-238, stash@{2}: On changes-3: new-branch-1777654416, stash@{3}: babysit-tick4-concurrent-work...). These may contain unrecovered work. Want me to inspect them?
This is the only reliable way to catch the leak — git won't warn you on its own.
Important
- Speed matters — other agents run concurrently, so minimize time spent on main.
- Never force-push or reset — other agents' work may be in-flight.
- Don't push the new branch until there are actual changes to ship.
- Treat orphaned stashes as bugs. If you see a
new-branch-from-* stash older than this session, surface it. Don't drop it without the user's confirmation — it may be the only copy of someone's work.