Contribute fork changes back to an upstream open-source project. Use when the user says "contribute upstream", "submit a PR to upstream", "open a PR on the original repo", "file an issue upstream", "upstream my changes", "upstream prep", "submit pr", or wants to submit work from a fork to the parent project. Use only when the target repo is different from origin (fork → upstream contribution). For same-repo PRs, use git-commit-push-pr instead.
gh is not authenticated for itgit fetch upstream instead)gh CLI available or no GitHub authentication configuredTake changes from a fork and contribute them back to the upstream open-source project following upstream expectations:
develop vs main, release branches).gh while verifying the final body stored on GitHub.Before calling prep, check:
git remote -v — confirm there is a remote named upstream pointing to the original repo. If only origin exists and it looks like the fork, note it.git status — confirm the branch is committed and pushed to origin.git push origin <branch>.Branch naming: If the work is on main or a branch that doesn't follow the upstream project's contribution conventions (e.g., upstream expects fix/, feat/, username/ prefixes), create a properly named branch first. Use the worktrunk skill to create and manage the new branch, then cherry-pick or rebase the commits onto it before proceeding.
prepBefore running prep, decide which flags to use:
| Scenario | Decision |
|---|---|
| Feature addition | Assume issue-first; omit --no-issue unless CONTRIBUTING.md says otherwise |
| Small bug fix (<10 lines) | --no-issue usually safe |
| CONTRIBUTING.md explicitly says "open issue first" | Never use --no-issue |
| No CONTRIBUTING.md in upstream | Use --no-issue; mention it in the PR body |
Use --base to skip interactive prompts when the target branch is known (e.g., from running gh api repos/<upstream>/... --jq .default_branch):
python3 <skill-dir>/scripts/upstream.py prep --base main --no-issue
<skill-dir>is the directory containing this SKILL.md file. Resolve it at runtime as the absolute path to the skill directory (e.g., use$SKILL_DIRif set by the agent framework, or locate the directory containingscripts/upstream.py).
--base <branch> skips the interactive branch selection prompt.--no-issue skips issue-first gating when you know a standalone PR is appropriate.draft-pr.mdAfter prep generates draft-pr.md, you must edit it before submitting. The template contains placeholder tokens (<problem>, <what changed>, etc.) that need real content. The file also contains a commented-out git log block to help you understand what the commits do. Replace the placeholder lines with a short, honest description of:
Keep it brief and human. Don't add headings or bullets unless truly necessary.
submit prpython3 <skill-dir>/scripts/upstream.py submit pr --title "fix(scope): short description"
Always pass --title explicitly. The script will automatically:
owner:branch head prefix and --repo flag.Report the PR URL to the user.
gh pr create --body "..." inline — shell quoting corrupts markdown; always use --body-file (the script handles this automatically)upstream remote — always PR from your fork's branch to upstream--title flag on submit pr — gh will prompt interactively and block agent executionupstream-skill--skillname or environment variable SKILLNAME.draft-pr.md — generated by prep; must be edited before submittingdraft-issue.md — generated when issue-first is required.draft-pr.rendered.md, .draft-issue.rendered.md — ephemeral; used for safe gh --body-file submissiondraft-pr.github.md, draft-issue.github.md — written only on unrecoverable body garblingWhen the repo has both an origin remote (your fork) and an upstream remote (the original project), submit pr automatically:
upstream remote.fork-owner:branch-name.--repo upstream-owner/upstream-repo to gh pr create.This means you do not need to manually run gh pr create --repo ... — the script handles it.
Each issue/PR begins with a short disclosure:
Note: I used an AI agent ({skillname}) to help draft this, but I ({username}) reviewed the write-up and the code. If the tone/format isn't a good fit here, please let me know and I'll adjust the skill.
prep [--base <branch>] [--no-issue]Discovers upstream process, resolves target branch, and generates draft-pr.md (and optionally draft-issue.md).
--base <branch> — override target branch; skips interactive selection entirely--no-issue — suppress issue-first gating; don't generate draft-issue.mdsubmit issue [--title <title>]Creates or updates an issue from draft-issue.md.
submit pr [--title <title>] [--head <branch>] [--draft]Creates or updates a PR from draft-pr.md. Always pass --title.
statusShows recorded URLs, branches, and draft file state.
fix (issue|pr)Re-verifies and repairs a posted body without re-running prep.
cleanRemoves all draft and rendered files.
Signal order (highest to lowest confidence):
--base CLI flag (skips all discovery)--no-issue)--body-file (never inline --body) to avoid shell quoting<!-- upstream-skill:sha256=<hash> -->ASK_BACKEND=stdio (default): interactive CLI promptsASK_BACKEND=jsonrpc: host-native ask dialogspython3gitgh (GitHub CLI) authenticated (gh auth login)Verify scripts/upstream.py exists in the skill directory. If it does not, inform the user that the implementation file is missing and halt.
Run from the repo root:
python3 <skill-dir>/scripts/upstream.py <subcommand>
python3 upstream.py prep --base main --no-issue
# edit draft-pr.md — fill in the placeholder text
python3 upstream.py submit pr --title "fix(scope): description"
python3 upstream.py prep --base main
python3 upstream.py submit issue --title "bug: short description"
python3 upstream.py submit pr --title "fix: short description"
python3 upstream.py prep # will ask which branch to target
# edit draft-pr.md
python3 upstream.py submit pr --title "feat: ..."
The reference implementation is included as scripts/upstream.py.