Agent Skillsafx-team/hebb-mind › push-to-github

push-to-github

GitHub

将当前分支未推送的提交推送到 GitHub 并创建 PR。仅处理已提交的代码,忽略工作区状态。若无待推送内容、非分支状态或未认证则中止操作,且禁止在 main/master 分支上创建 PR。

.claude/skills/push-to-github/SKILL.md afx-team/hebb-mind

Trigger Scenarios

用户希望将本地已提交的更改推送到远程仓库 用户希望通过 gh CLI 为当前分支发起或更新 Pull Request

Install

npx skills add afx-team/hebb-mind --skill push-to-github -g -y
More Options

Non-standard path

npx skills add https://github.com/afx-team/hebb-mind/tree/main/.claude/skills/push-to-github -g -y

Use without installing

npx skills use afx-team/hebb-mind@push-to-github

指定 Agent (Claude Code)

npx skills add afx-team/hebb-mind --skill push-to-github -a claude-code -g -y

安装 repo 全部 skill

npx skills add afx-team/hebb-mind --all -g -y

预览 repo 内 skill

npx skills add afx-team/hebb-mind --list

SKILL.md

Frontmatter
{
    "name": "push-to-github",
    "arguments": [
        {
            "name": "title",
            "required": false,
            "description": "Optional PR title override. Defaults to the latest commit subject."
        },
        {
            "name": "body",
            "required": false,
            "description": "Optional PR body override. Defaults to a Summary + Test plan template generated from the unpushed commits."
        }
    ],
    "description": "Push unpushed commits on the current branch to GitHub and open a PR via gh CLI. Aborts if there are no unpushed commits. Ignores working tree state entirely — for uncommitted changes use \/commit first.",
    "user_invocable": true
}

Push to GitHub

Pure "send my committed work upstream" skill. Pushes whatever commits are already in the local branch but not yet on the remote, then opens (or reports) a PR.

Out of scope (handled by /commit):

  • Staging files
  • Creating commits
  • Creating branches
  • Anything about uncommitted changes in the working tree

This skill does not look at the working tree at all. Uncommitted files are the user's business; this skill only cares about commits.


Hard rules (MUST)

  • MUST NOT run git add, git commit, git stash, or any staging/committing command.
  • MUST NOT inspect or report on working-tree cleanliness as a precondition.
  • MUST NOT git push --force, git push --no-verify, git reset --hard, git commit --amend, git config, or git rebase -i.
  • MUST abort if there are no unpushed commits on the current branch.
  • MUST NOT create a PR when on main / master (those are the trunk; pushing there is the release trigger — publish.yml ships to PyPI when pyproject.toml's version changes on main).

Pre-flight (run in parallel)

git rev-parse --git-dir                    # in a git repo?
git remote get-url origin                  # has remote?
gh auth status                             # gh CLI authed?
git rev-parse --abbrev-ref HEAD            # current branch

Bail out if any fail:

Failure Action
Not a git repo Exit; tell the user
No origin remote Exit; tell user to add one (gh repo create / git remote add origin …)
gh not authed Exit; tell user to run gh auth login themselves (do NOT run it — interactive)
Detached HEAD (HEAD returned) Exit; tell user to checkout a branch

Workflow

Step 1 — Find unpushed commits

BRANCH=$(git rev-parse --abbrev-ref HEAD)

# Refresh the remote ref so we have an up-to-date view
git fetch origin "$BRANCH" 2>/dev/null || true

# Three cases:
#   (a) upstream is set → diff against @{u}
#   (b) no upstream but remote branch exists → diff against origin/$BRANCH
#   (c) remote branch does not exist → every local commit on this branch is unpushed
if git rev-parse --verify --quiet '@{u}' >/dev/null 2>&1; then
    UNPUSHED=$(git log --oneline '@{u}..HEAD')
    BASE='@{u}'
elif git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then
    UNPUSHED=$(git log --oneline "origin/${BRANCH}..HEAD")
    BASE="origin/${BRANCH}"
else
    UNPUSHED=$(git log --oneline HEAD)
    BASE='(new branch — no remote counterpart)'
fi

Step 2 — Abort if nothing to push

If UNPUSHED is empty, abort:

❌ Nothing to push. Local branch <BRANCH> is up-to-date with <BASE>.

If you have uncommitted changes you want to ship, run /commit first.

Stop here.

Step 3 — Show what will be pushed

Print to the user (don't ask for confirmation — pushing committed work is the explicit user request):

Pushing <N> commit(s) on <BRANCH> → origin/<BRANCH>:

  abc1234 feat(retrieval): add lexical signals
  def5678 test(retrieval): add lexical signals tests
  …

Step 4 — Push

git push -u origin "$BRANCH"
Failure Action
Non-fast-forward reject git fetch origin "$BRANCH"git pull --rebase origin "$BRANCH". Conflicts → abort, ask user. Never --force.
Pre-push hook fails Show stderr; abort. Do not --no-verify.
Auth fails Tell user to re-run gh auth login or check token scopes

Step 5 — PR step (skip when on main / master)

If BRANCH ∈ {main, master}:

  • skip PR creation entirely
  • in the report, mention: "Pushed directly to <BRANCH>. Releases are manual — to ship, bump the version in pyproject.toml (+ src/hebb/__init__.py, .release-please-manifest.json, .claude-plugin/plugin.json) and add a CHANGELOG.md entry; the pyproject.toml version change on main triggers publish.yml."
  • jump to Step 6

Otherwise, check whether a PR already exists for this branch:

gh pr view --json url,state,title 2>/dev/null
  • If state == OPEN → skip create; record the existing URL
  • If state == MERGED / CLOSED → create a fresh PR (branch was re-used)
  • If gh pr view fails (no PR yet) → create

Create:

# Title: ${title} arg if provided, else latest commit subject
TITLE=$(git log -1 --pretty=format:'%s')   # or ${title}

# Body: ${body} arg if provided, else generated from unpushed commit subjects
BODY=$(cat <<EOF
## Summary

$(git log --pretty=format:'- %s' "${BASE}..HEAD")

## Test plan
- [ ] <fill in relevant checks>

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)

gh pr create --title "$TITLE" --body "$BODY"

Note: the PR title is not validated against conventional-commits in this skill. What matters for the manually-maintained CHANGELOG.md is the commit subjects (authored via /commit or by hand); the PR title is cosmetic.

Step 6 — Report back

Output:

  • Branch: <BRANCH>
  • Pushed range: <BASE>..<HEAD short SHA> (or "new branch, all commits")
  • Commits pushed: <N>
  • PR URL (if a feature branch) — newly created or pre-existing
  • For main / master pushes: note that releases are manual — a pyproject.toml version bump on main is what triggers publish.yml

Quick decision tree

unpushed commits exist? ── no → ABORT: "nothing to push"
   │
   yes
   ▼
git push -u origin <branch>     (no --force, no --no-verify)
   │
   ▼
branch == main/master? ── yes → done; releases are manual (bump version to publish)
   │
   no
   ▼
gh pr view → state == OPEN? ── yes → report existing URL
                              no  → gh pr create
   │
   ▼
report branch / range / PR URL

What this skill explicitly does NOT do

  • Does not read git status or git diff for working-tree changes
  • Does not stage, commit, amend, or stash
  • Does not create or switch branches
  • Does not validate commit messages (that's /commit's job)
  • Does not force-push or bypass hooks

If any of those are needed, use /commit first or do it manually before invoking this skill.

Version History

  • a8914bb Current 2026-07-05 12:09

Same Skill Collection

.agents/skills/arxiv-search/SKILL.md
.agents/skills/bench-compare/SKILL.md
.agents/skills/github-explore/SKILL.md
.agents/skills/research-survey/SKILL.md
.claude/skills/arxiv-search/SKILL.md
.claude/skills/bench-compare/SKILL.md
.claude/skills/commit/SKILL.md
.claude/skills/github-explore/SKILL.md
.claude/skills/research-survey/SKILL.md

Metadata

Files
0
Version
a8914bb
Hash
452eda80
Indexed
2026-07-05 12:09

Home - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-13 20:21
浙ICP备14020137号-1 $Map of visitor$