gh-weld-adopt
You did the work first — or you're about to. Either way, gh-weld-adopt creates the paper trail.
NEVER
NEVER proceed adoption from
mainwhen working tree is clean and no commits are ahead oforigin/mainInstead: Output "Nothing to adopt — working tree is clean and main is up to date." and stop. Why: There is genuinely nothing to adopt — adoption requires loose work to formalize.NEVER create the issue before confirming the summary with the user Instead: Show the synthesized summary and proposed issue body; wait for (a)ccept before calling
gh issue create. Why: The issue is permanent. A wrong title or misattributed scope creates backlog noise that outlasts the session.NEVER commit without showing what will be staged Instead: Display
git status --porcelainoutput and ask "(a)ccept / (s)kip" before staging anything. Why: Unintended files (.env, build artifacts) committed here will be pushed and visible in the GitHub issue thread.NEVER commit with a generic subject like
adopt: capture in-progress work for issue #<N>Instead: Derive the subject from the issue title created in Step 4 —<type>: <what changed>. Why: Adopt branches usually carry a single commit, and GitHub's squash-merge inherits that commit's subject over the PR title. A generic subject lands onmainpermanently and says nothing about what changed.NEVER pass a body with
#-prefixed lines as an inline--bodyargument Instead: Write to.weld/tmp/adopt-issue-body.mdwith the Write tool and pass via--body-file. Why:#-prefixed lines trigger Claude Code's security check on every execution, interrupting the agent mid-flow.NEVER skip deleting the old remote branch after rename Instead: After pushing the new branch name, run
git push origin --delete <old-name>if the old remote existed. Why: GitHub shows both branches as linked to the issue — the stale name creates ambiguity in the development sidebar.NEVER skip the session export Instead: Always invoke
/gh-weld-exportwith the new issue number as context after pushing. Why: The Gist comment is the audit trail — it proves what was already done before the issue was created.
Workflow
1 — Handle if on main
git branch --show-current
If the result is main or master:
Check for uncommitted changes:
git status --porcelain
Check for commits ahead of remote:
git log origin/main..HEAD --oneline
If neither has output: output "Nothing to adopt — working tree is clean and main is up to date." and stop.
If both are present: follow the uncommitted-changes path below — the ahead-commits carry over automatically since HEAD is preserved.
The branch created here is a provisional throwaway — Step 6 renames it to the final <prefix>/<issue-number>-<slug> once the issue number is known. Do not prompt for a name here; generate one silently and just inform the user it's temporary.
If uncommitted changes exist:
Generate a temporary local branch name silently — adopt/wip-<short-slug>, where <short-slug> is a brief slug derived from the session work (lowercase, hyphens). Do not prompt.
git checkout -b adopt/wip-<short-slug>
Tell the user: "Working on provisional branch adopt/wip-<short-slug> — I'll rename it to the final name once the issue exists."
Continue to Step 2.
If commits are ahead of origin/main:
Generate a temporary local branch name silently — adopt/wip-<short-slug> (lowercase, hyphens). Do not prompt.
Create the branch at the current HEAD, reset main, then check out the new branch:
git branch adopt/wip-<short-slug>
git reset --hard origin/main
git checkout adopt/wip-<short-slug>
Tell the user: "Working on provisional branch adopt/wip-<short-slug> — I'll rename it to the final name once the issue exists."
Continue to Step 2.
2 — Read working state
Run each as a separate Bash call:
git status --porcelain
git log main..HEAD --oneline
git diff main..HEAD --name-only
Save the current branch name — you'll need it to detect and delete the old remote after renaming.
3 — Synthesize and confirm
Before synthesizing, ask:
- Does the diff scope match the session discussion, or are there changes outside the stated work?
- Does this read as a bug fix, feature, or chore?
- Are there uncommitted files that should NOT be part of this issue (build artifacts, unrelated edits)?
From session context (what has been discussed and built in this conversation) and the git output above, synthesize:
- A proposed issue title (one line, imperative mood)
- The work type (bug / feature / chore) — use this to frame the issue title and acceptance criteria; for the branch prefix, use whatever pattern was inferred from
git branch -aabove - A structured issue body (see template below)
Before naming the type, inspect the repo's existing branch names to infer the local convention (skip if already run in Step 1 — reuse that result):
git branch -a
Look for patterns in existing branches (e.g. fix/, feat/, feature/, bugfix/, chore/, no prefix at all). Match whatever convention the repo already uses. If no pattern is apparent, use no prefix. Do not impose a convention the repo hasn't adopted.
Show the synthesis to the user:
Here's what I see you working on:
**Title:** <proposed title>
**Type:** <bug / feature / chore>
**Body preview:**
<body>
(a)ccept / (e)dit / (q)uit
a— proceed to Step 4e— user provides corrections; update and loopq— abort
Issue body template:
## Summary
<2–3 sentence description of what is being built and why>
## Acceptance Criteria
- [ ] <verifiable criterion — names a command, visible change, or measurable value>
## Blockers
None
---
*Created with [gh-weld](https://github.com/WrathZA/github-weld)*
Acceptance criteria must be verifiable. Reject vague entries like "works correctly" — they must name a command, visible change, or measurable value.
4 — Create the issue
Write the confirmed body to .weld/tmp/adopt-issue-body.md using the Write tool.
Apply the appropriate label if it exists in the repo:
gh label list
Create the issue, redirecting output to capture the URL:
gh issue create --title "<title>" --label "<label>" --body-file .weld/tmp/adopt-issue-body.md > .weld/tmp/adopt-issue-url.txt
If the label doesn't exist, omit --label.
Read .weld/tmp/adopt-issue-url.txt with the Read tool to get the issue URL. Extract the issue number from the URL (it appears as .../issues/<N>).
Clean up:
rm .weld/tmp/adopt-issue-body.md
rm .weld/tmp/adopt-issue-url.txt
5 — Commit uncommitted changes
Check for loose work:
git status --porcelain
If output is non-empty, show it and ask:
These changes will be committed and pushed:
<git status output>
(a)ccept / (s)kip
If accepted:
git add .
Derive the commit subject from the issue title created in Step 4 — never a generic "adopt:" subject. When a branch has a single commit, GitHub's squash-merge inherits that commit's subject rather than the PR title, so this message is what lands on main permanently.
Format the subject as <type>: <what changed>, where <type> is the conventional-commit type matching the issue's label (fix, feat, docs, chore, refactor, test). Rewrite the issue title into an imperative description of the change; keep it under 72 characters. Do not append the issue number — gh-weld-ship appends the PR number at squash time, and Closes #<N> in the PR body links the issue.
git commit -m "<type>: <what changed>"
Examples, given the issue title in hand:
| Issue title | Commit subject |
|---|---|
Adopt commit message destroys the main log |
fix: derive adopt commit subject from the issue title |
Add activity digest skill |
feat: add gh-weld-activity digest skill |
README setup steps are out of date |
docs: update README setup steps |
6 — Rename the branch
Construct the new branch name using the prefix convention inferred from git branch -a (Step 3), the issue number, and a slug derived from the issue title. Slug rules: lowercase, hyphens only, max 40 chars. The final form is <prefix>/<issue-number>-<slug>.
This is the only branch-name approval prompt in the workflow. Show the final name and ask: "(a)ccept or enter a different name?" Use the result for the rename below.
Check whether the current branch has a remote tracking branch:
git rev-parse --abbrev-ref --symbolic-full-name @{u}
If this succeeds, record the old remote branch name (strip the origin/ prefix). If it fails (no upstream), there's nothing to delete after rename.
Rename locally:
git branch -m <new-branch-name>
7 — Push
git push -u origin <new-branch-name>
If an old remote branch existed, delete it:
git push origin --delete <old-branch-name>
8 — Export session
Invoke /gh-weld-export with the issue number as context. This exports the current session transcript, uploads it as a secret Gist, and posts a structured summary comment on the issue.
9 — Output
Adopted.
Issue: <issue-url>
Branch: <new-branch-name>
Done.
Errors
| Situation | Action |
|---|---|
On a non-main branch, git log main..HEAD is empty (branch exists but no commits ahead of main) |
Warn "Branch has no commits ahead of main — loose changes only. Continue? (y/n)" |
gh issue create fails |
Surface the error; do not rename the branch or push (nothing to link to yet) |
git push --delete fails on old remote name |
Warn "Could not delete old remote branch <name> — delete it manually via GitHub." and continue |
git branch -m fails because new name already exists |
Output the conflict and ask the user for an alternative branch name |
/gh-weld-export fails |
Warn "Session export failed — adopt is otherwise complete." and output issue URL and branch name |