一键导入
version-tag
Create and push a version tag for a package (mobile, cli, or web) from the latest main branch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create and push a version tag for a package (mobile, cli, or web) from the latest main branch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Automate the CI fix loop — trigger GitHub Actions (CI + audit), read failure logs, fix locally, push, and repeat until green. Use when CI is red and you want a hands-off remediation loop.
Non-blocking approval flow for Permission Slip — request, optional push wake or detached watcher, heartbeat sweep backstop, end your turn, continue when woken.
Perform a comprehensive, multi-round code review on a GitHub PR. Leaves inline review comments prioritized by severity (Critical/High/Medium/Low) across up to 6 rounds, with 5-minute waits between rounds to check for fixes.
Poll a GitHub PR for new comments and PR reviews and act on them autonomously. Use when the user wants to monitor a PR for feedback and have Claude implement requested changes automatically.
Continuously pull the latest main branch and resolve merge conflicts automatically. Polls every 90 seconds and exits after 10 consecutive clean cycles.
| name | version-tag |
| description | Create and push a version tag for a package (mobile, cli, or web) from the latest main branch. |
| argument-hint | <package> [version] (e.g., "cli 0.1.0" or just "cli") |
Create and push a git tag for a specific package from the latest main branch.
Every merge to main that touches cli/** automatically publishes a new patch
version to npm and creates the cli/v* tag via publish-cli.yml. Merge commit
messages can contain [publish minor] or [publish major] for bigger bumps, or
[skip publish] to skip publishing. The committed cli/package.json version is
NOT the source of truth — the workflow stamps the resolved version at build time;
the latest cli/v* tag is authoritative.
For /version-tag cli, skip steps 2–5 entirely. Just dispatch the publish
workflow — it auto-increments when no version is given, guards against existing
tags itself, and creates the tag after a successful publish:
# Explicit version (omit -f version=... to auto-increment the patch version)
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh workflow run publish-cli.yml --ref main -f version="<version>"
Or, when gh is unavailable, use the GitHub MCP tool
mcp__github__actions_run_trigger with workflow file publish-cli.yml, ref
main, and (optionally) input version: <version>. Report the dispatched run
to the user and finish — no need to watch the publish run to completion.
Every merge to main that touches mobile/** automatically creates the next
mobile/v* tag via tag-mobile.yml. Merge commit messages can contain
[publish minor] or [publish major] for bigger bumps, or [skip publish] to
skip tagging. The workflow is tag-only — it does NOT publish an EAS OTA update;
self-hosted installs publish OTA updates from make redeploy on their own
machines with their own EAS credentials.
For /version-tag mobile, skip steps 2–5 entirely. Just dispatch the tag
workflow — it auto-increments when no version is given, guards against existing
tags itself, and creates the tag on main:
# Explicit version (omit -f version=... to auto-increment the patch version)
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh workflow run tag-mobile.yml --ref main -f version="<version>"
Or, when gh is unavailable, use the GitHub MCP tool
mcp__github__actions_run_trigger with workflow file tag-mobile.yml, ref
main, and (optionally) input version: <version>. Report the dispatched run
to the user and finish — no need to watch the workflow run to completion.
The steps below apply to the web package only.
This skill takes one required and one optional argument:
mobile, cli, or web0.1.0, 1.2.3). If omitted, automatically increments the patch version of the latest existing tag for the package.Example usage:
/version-tag cli 0.1.0 — tags cli/v0.1.0/version-tag cli — if latest cli tag is cli/v0.1.0, tags cli/v0.1.1Parse the arguments from the input. Validate:
mobile, cli, web. If not, print an error and stop.0.1.0, 1.2.3, 0.0.1-beta.1). If not, print an error and stop.If no version argument is provided, look up the latest existing tag for the package and increment its patch version:
LATEST=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/matching-refs/tags/<package>/v \
--jq '[.[].ref | ltrimstr("refs/tags/<package>/v")] | map(select(test("^[0-9]+\\.[0-9]+\\.[0-9]+$"))) | sort_by(split(".") | map(tonumber)) | last')
LATEST is empty), default to 0.0.1.LATEST on ., increment the third (patch) component by 1, and reassemble. For example, 0.1.0 becomes 0.1.1.Construct the tag name: <package>/v<version> (e.g., cli/v0.1.0).
Use the GitHub CLI to check whether the tag already exists on the remote:
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/ref/tags/<package>/v<version> 2>/dev/null
If the command succeeds (exit code 0), the tag already exists — print an error and stop. Do NOT overwrite existing tags.
Fetch the SHA of the tip of main from GitHub without checking out anything locally:
SHA=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/ref/heads/main \
--jq '.object.sha')
If the command fails or SHA is empty, print an error and stop.
Check whether <package>/package.json exists in the repo and whether its version field matches the target version. If it doesn't match, create a branch, commit the bump there, open a PR, merge it, and wait for the merge to complete before proceeding to step 5. This ensures the tag always points at a commit where package.json has the correct version.
Don't wait on branch protections you can bypass. Once the PR's checks are green, if it's still blocked (e.g., a required code-owner review), check whether your credentials can override branch protections — and if they can, merge immediately instead of waiting for a human. The script below does this automatically via gh pr merge --admin, which merges with admin privileges when the token has bypass rights and fails harmlessly when it doesn't (auto-merge remains armed as the fallback).
# Fetch the file metadata and content
FILE_RESP=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/contents/<package>/package.json \
--jq '{sha: .sha, content: .content}')
FILE_SHA=$(echo "$FILE_RESP" | jq -r '.sha')
# Decode content (GitHub returns base64 with newlines; use portable flags for Linux + macOS)
CURRENT_CONTENT=$(echo "$FILE_RESP" | jq -r '.content' | base64 --decode 2>/dev/null || echo "$FILE_RESP" | jq -r '.content' | base64 -D 2>/dev/null)
PKG_VERSION=$(echo "$CURRENT_CONTENT" | jq -r '.version')
if [ "$PKG_VERSION" != "<version>" ]; then
echo "package.json version is $PKG_VERSION, bumping to <version>..."
BUMP_BRANCH="chore/bump-<package>-v<version>"
# Create branch from main
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/refs \
-f ref="refs/heads/$BUMP_BRANCH" \
-f sha="$SHA"
# NOTE: jq reformats the JSON to 2-space indentation. Intentional: keeps files canonical.
UPDATED_CONTENT=$(echo "$CURRENT_CONTENT" | jq --arg v "<version>" '.version = $v')
# tr -d '\n' is portable across Linux and macOS (avoids GNU-only base64 -w 0)
ENCODED=$(echo "$UPDATED_CONTENT" | base64 | tr -d '\n')
# Commit the version bump to the new branch
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/contents/<package>/package.json \
-X PUT \
-f message="chore: bump <package>/package.json to <version>" \
-f content="$ENCODED" \
-f sha="$FILE_SHA" \
-f branch="$BUMP_BRANCH"
# Create a PR and enable auto-merge
PR_URL=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh pr create \
--repo supersuit-tech/permission-slip \
--head "$BUMP_BRANCH" \
--base main \
--title "chore: bump <package>/package.json to <version>" \
--body "Auto-generated by \`/version-tag\`. Syncs \`<package>/package.json\` version to match tag \`<package>/v<version>\`.")
echo "Opened PR to bump package.json: $PR_URL"
# Enable auto-merge so it lands without manual intervention
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh pr merge "$PR_URL" --auto --squash \
--repo supersuit-tech/permission-slip 2>/dev/null || echo "(auto-merge not available — merge manually)"
# Wait for the PR to merge before tagging (poll every 5s, up to 2 minutes).
# Once checks are green, if the PR is still blocked (e.g., required review),
# try one admin-override merge — it succeeds only if the token can bypass
# branch protections, and auto-merge stays armed as the fallback.
echo "Waiting for bump PR to merge before creating tag..."
PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]*$')
ADMIN_MERGE_TRIED=0
for i in $(seq 1 24); do
PR_STATE=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh pr view "$PR_NUMBER" --repo supersuit-tech/permission-slip --json state --jq '.state')
if [ "$PR_STATE" = "MERGED" ]; then
echo "Bump PR merged."
break
fi
if [ "$ADMIN_MERGE_TRIED" = "0" ]; then
PENDING=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh pr checks "$PR_NUMBER" --repo supersuit-tech/permission-slip 2>/dev/null \
| grep -c 'pending\|in_progress' || true)
if [ "$PENDING" = "0" ]; then
ADMIN_MERGE_TRIED=1
if GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh pr merge "$PR_NUMBER" --squash --admin \
--repo supersuit-tech/permission-slip 2>/dev/null; then
echo "Checks green but PR blocked — merged with admin override."
else
echo "No branch-protection bypass available — waiting for auto-merge."
fi
fi
fi
if [ "$i" = "24" ]; then
echo "::error::Bump PR did not merge within 2 minutes. Merge it manually, then re-run /version-tag."
exit 1
fi
sleep 5
done
# Re-resolve main SHA so the tag points at the commit that includes the version bump
SHA=$(GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/ref/heads/main \
--jq '.object.sha')
fi
If the file doesn't exist (404), skip this step silently and proceed with the original SHA.
When gh is unavailable (MCP-only sessions): there is no admin-override flag on the MCP merge tool, but still check whether you can bypass protections by calling mcp__github__merge_pull_request (method squash) once after checks go green. If it succeeds, you had bypass rights — proceed to step 5. If it fails with 405 Repository rule violations (e.g., "Waiting on code owner review"), no bypass is available through MCP: leave auto-merge armed, tell the user exactly what's blocking (and who needs to approve), subscribe to the PR's activity so the merge wakes the session, and resume from step 5 once it merges. Do not fail the flow just because the 2-minute window elapsed — a pending human review is a pause, not an error.
Create the tag reference on GitHub directly via the API — no local branch switching or git push needed. The SHA used here is either the original main SHA (if no bump was needed) or the updated main SHA (after the bump PR merged).
GH_HOST=github.com GH_REPO=supersuit-tech/permission-slip \
gh api repos/supersuit-tech/permission-slip/git/refs \
-f ref="refs/tags/<package>/v<version>" \
-f sha="$SHA"
If the command fails with a write-permission error (e.g. "Write access to this GitHub API path is not permitted through this proxy" — some session types cannot write tags or releases at all), print the error output and stop. (For cli and mobile, this never applies — use the workflow dispatch described at the top instead of creating tags directly.)
Print a summary:
Tagged and pushed: <package>/v<version> -> <SHA>