Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/tomes --skill dev-release명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | dev-release |
| description | >- Use when this capability is needed. |
Hard triggers (always do it):
/releaseProactive triggers (offer it, don't auto-execute):
main and there are ≥5 commits since the last tag.brew upgrade / npm update would resolve to the previous version.Three live releases, all reachable from the same vX.Y.Z tag:
alecs5am/ralphy/releases/tag/vX.Y.Z with 5 binaries
(darwin-arm64/x64, linux-arm64/x64, windows-x64.exe) + SHA256SUMS,
built and published by the Release GitHub Actions workflow on tag push.alecs5am/homebrew-tap — Formula/ralphy.rb bumped
to point at the new release with sha256-pinned URLs for each platform.@alecs5am/ralphy@X.Y.Z published with public access.
The thin npm wrapper's postinstall hook downloads the matching binary
from the GitHub Release the first time it runs.All three reference the same vX.Y.Z tag and the same set of binaries — there is no version drift between channels.
This skill never touches:
landing/ — the Next.js marketing landing is shipped independently (Vercel / Netlify).docs/, README.md — these are repo-internal playbook / orientation docs. Only package.json / cli/lib/version.ts / npm/package.json / AGENTS.md (the single version line) / scripts/release/last-release-commit / docs-mintlify/** get edited under this skill..agents/skills/ — other skills are versioned with the repo, not with the binary.Two targeted exceptions that go inside the version-bump commit (or the docs-sync commit right before it):
AGENTS.md carries a single line (> **Current ralphy CLI: \vX.Y.Z`** ...) that lives in the system prompt of every ralphy session. The /release` skill bumps that line in lockstep with the four real version files so the agent always knows which binary the user should be on. Find/replace only — never restructure AGENTS.md otherwise.docs-mintlify/** is the public docs site for the CLI (hosted at the Mintlify URL — see docs-mintlify/docs.json for the deploy config). It describes the same binary this skill ships, so it MUST be kept in sync. Each release walks the diff since the last release commit and updates any affected page under docs-mintlify/cli/, docs-mintlify/reference/, docs-mintlify/authoring/, plus quickstart.mdx / introduction.mdx / concepts.mdx if the surface they describe changed. New top-level commands → new .mdx page + entry in docs.json. See step 3b below.scripts/release/last-release-commit stores the exact commit SHA the previous release shipped. Step 1 reads it to scope the diff; step 5 rewrites it with HEAD of the new release commit so the next /release invocation starts from a clean baseline.If the user asks to "release the landing" — handback. Not this skill.
Run the steps in order. After step 4 you must stop and confirm before doing anything destructive. After step 6 the GitHub Release happens automatically via CI; steps 8 and 9 are local-only and require an authenticated gh (alecs5am) plus npm login session.
# Credential preflight — both must succeed BEFORE any destructive step.
gh auth status --hostname github.com 2>&1 | head -5 # expect: account alecs5am, active
npm whoami # expect: alecs5am
# Repo state
gh repo view alecs5am/ralphy --json defaultBranchRef,latestRelease | jq
git fetch origin --tags
# Diff baseline — prefer the explicit pointer at scripts/release/last-release-commit
# (rewritten by the previous /release run), then fall back to the last tag, then
# to HEAD~50 if this is a freshly-cloned repo with no tags / no pointer.
BASELINE="$(cat scripts/release/last-release-commit 2>/dev/null | tr -d '[:space:]')"
if [ -z "$BASELINE" ] || ! git cat-file -e "$BASELINE^{commit}" 2>/dev/null; then
BASELINE="$(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~50)"
echo "⚠️ scripts/release/last-release-commit missing or stale — falling back to ${BASELINE}"
fi
echo "Release diff baseline: ${BASELINE}"
git log --no-merges --pretty=format:"%h %s" "${BASELINE}..HEAD"
git diff --stat "${BASELINE}..HEAD"
git status --short
What you need:
scripts/release/last-release-commit, the single source of truth for "what shipped last time"). Keep ${BASELINE} in a variable for the rest of the release — steps 3, 4, and 4b all reuse it.gh and npm resolve to the alecs5am account.If working tree isn't clean: stop. Tell the user, suggest committing or stashing.
If scripts/release/last-release-commit is missing entirely (first time after this skill change rolled out): use the last tag as baseline for this release, but still rewrite the pointer in step 5 so subsequent runs are clean.
If npm whoami errors: the bypass token in ~/.npmrc is missing or revoked. Stop and ask the user to regenerate per the "Credentials" section at the bottom of this skill.
Inspect commit subjects since ${BASELINE} and apply Conventional-Commits-ish logic:
| Pattern in commits | Bump |
|---|---|
BREAKING CHANGE: body line OR !: in subject (e.g. feat!:) | major |
At least one feat: / feat(scope): | minor |
Only fix: / chore: / docs: / refactor: / test: / style: | patch |
| Pre-1.0.0 and there's a breaking change | patch (we're still in baseline shaping) |
Show the user the proposed bump in one line: "5 feats + 8 fixes → minor → v0.1.0".
Group commits into buckets, dropping noise (merge commits, version bumps, pure formatting):
## Highlights
- 1-3 sentences of what users will actually feel different about.
## Features
- feat(scope): description (#PR)
## Fixes
- fix(scope): description (#PR)
## Internal / Chores
- chore: description
- refactor: description
Useful raw sources:
git log --no-merges --pretty=format:"%h %s%n%b%n---" "${BASELINE}..HEAD" — the canonical input. Read full bodies, not just subjects, so BREAKING CHANGE: footers don't slip past.gh pr list --search "merged:>=YYYY-MM-DD" --json number,title,author — PR titles are usually richer than raw commit subjects.gh api repos/alecs5am/ralphy/compare/${BASELINE}...main --jq '.commits[].commit.message' — handy if ${BASELINE} is older than the local clone has fetched.docs-mintlify/ syncThe Mintlify docs site is the public-facing reference for the binary this skill ships. Out-of-date docs published alongside a new binary are a release defect, not a follow-up task.
Walk the diff under three CLI-surface paths and identify any user-visible changes:
# What CLI surface changed since the last release?
git diff --stat "${BASELINE}..HEAD" -- cli/commands/ cli/lib/ scripts/install.sh
git log --no-merges --pretty=format:"%h %s" "${BASELINE}..HEAD" -- cli/commands/ cli/lib/ scripts/install.sh
For each user-visible change, decide which Mintlify page(s) need an update. The current layout (verify with ls docs-mintlify/):
| What changed in code | Page(s) to touch under docs-mintlify/ |
|---|---|
New top-level command (e.g. ralphy foo) added in cli/commands/foo.ts | New cli/foo.mdx + add to docs.json navigation; cross-link from cli/overview.mdx |
| New / renamed flag on existing command | The matching cli/<verb>.mdx page |
Sub-command added to existing resource (e.g. ralphy project log-prompt) | The matching cli/<resource>.mdx page |
New / removed model in cli/lib/providers/ or MODELS.md | reference/models.mdx |
New env var, install path, or doctor check | quickstart.mdx and/or reference/troubleshooting.mdx |
| Conceptual change (project layout, asset pool, template kinds, log format) | concepts.mdx, introduction.mdx, or the matching authoring/*.mdx |
| Pure refactor with no user-visible delta | Nothing — note "no docs delta" in the changelog and move on |
Rules for the doc edits:
ralphy <cmd> --help as ground truth when wording a flag or sub-command description. Don't invent flags from memory.vX.Y.Z strings inside docs-mintlify/ (e.g. install snippets, --version output) get bumped in the same find/replace as AGENTS.md in step 5.docs.json holds the nav tree. New page → add an entry under the right group. Renamed page → rename the entry. Use jq or sd to keep the file valid JSON.bunx mintlify dev docs-mintlify (if Mintlify CLI is installed locally) or just jq . docs-mintlify/docs.json to confirm the nav file is still valid JSON. Don't ship a broken docs build.docs-mintlify/ lives in this repo and is deployed by Mintlify on push to main. The version-bump commit is what triggers the docs redeploy — you don't gh release the docs separately.Output for step 4 review: either the list [file → change] pairs, or the literal string "no docs delta".
Print to the user:
0.0.1 → 0.1.0).${BASELINE} (so the user can sanity-check what "since last release" means).package.json, cli/lib/version.ts, npm/package.json, AGENTS.md (single line), plus whatever docs-mintlify/** pages came out of step 3b.scripts/release/last-release-commit (step 5) — call this out so the user isn't surprised by two commits.Wait for explicit user confirmation ("yes" / "go" / "let's go") before doing anything destructive.
Four files hold the version — keep them in sync so ralphy --version, the GitHub Release tag, the brew formula version, the npm package version, AND the AGENTS.md system-prompt line all agree. The version-bump commit also carries the docs-mintlify/ edits from step 3b and the pointer rewrite so the next /release run has a clean baseline.
NEW_VERSION="0.1.0" # without the v prefix
TODAY="$(date -u +%Y-%m-%d)"
# Core version files
jq --arg v "$NEW_VERSION" '.version = $v' package.json > package.json.tmp && mv package.json.tmp package.json
sd 'export const VERSION = "[^"]+"' "export const VERSION = \"${NEW_VERSION}\"" cli/lib/version.ts
jq --arg v "$NEW_VERSION" '.version = $v' npm/package.json > npm/package.json.tmp && mv npm/package.json.tmp npm/package.json
# AGENTS.md system-prompt line — the agent reads this on every session start
sd '> \*\*Current ralphy CLI: `v[^`]+`\*\* \(released [^)]+\)' \
"> **Current ralphy CLI: \`v${NEW_VERSION}\`** (released ${TODAY})" AGENTS.md
# docs-mintlify: bump any hard-coded version strings (install snippets, --version
# example output, etc). This is a sweep — actual content edits already happened
# in step 3b and should already be staged in the working tree.
PREV_VERSION="$(git show "${BASELINE}:package.json" 2>/dev/null | jq -r .version)"
if [ -n "$PREV_VERSION" ] && [ "$PREV_VERSION" != "$NEW_VERSION" ]; then
rg -l --fixed-strings "v${PREV_VERSION}" docs-mintlify/ 2>/dev/null \
| xargs -r -I {} sd "v${PREV_VERSION}" "v${NEW_VERSION}" {}
rg -l --fixed-strings docs-mintlify/ 2>/dev/null \
| xargs -r -I {} sd {}
git add package.json cli/lib/version.ts npm/package.json AGENTS.md docs-mintlify/
git commit -m
git rev-parse HEAD > scripts/release/last-release-commit
git add scripts/release/last-release-commit
git commit -m
Verification before tagging: confirm all four version files agree, the pointer file matches the parent of HEAD (the release commit we'll tag), and docs-mintlify/docs.json is still valid JSON.
grep -E "0\.0\.|0\.1\.|1\.0\." package.json cli/lib/version.ts npm/package.json AGENTS.md | head -10
diff <(cat scripts/release/last-release-commit) <(git rev-parse HEAD~1) # must be empty — points at the release commit
jq -e . docs-mintlify/docs.json >/dev/null && echo "docs.json OK"
Don't ship a tag the local box can't build:
bun run build:bin:current
dist/binaries/ralphy-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed -e 's/x86_64/x64/' -e 's/aarch64/arm64/') --version
The full cross-compile happens on CI; this is just a sanity check. If it fails, stop and fix before tagging.
The tag goes on the release commit (HEAD~1 — chore(release): v${NEW_VERSION}), not the pointer-bump commit (HEAD — chore(release): bump diff baseline ...). This keeps the tag attached to the actual version bump.
NEW_TAG="v${NEW_VERSION}"
git tag -a "$NEW_TAG" HEAD~1 -m "Release ${NEW_TAG}"
git push origin main
git push origin "$NEW_TAG"
The Release GitHub Actions workflow fires on tag push: cross-compiles all 5 binaries, generates SHA256SUMS, creates the GitHub Release with assets, and writes basic release notes. Watch it finish:
gh run watch -R alecs5am/ralphy --exit-status
If you want to replace the auto-generated notes with the changelog from step 3:
CHANGELOG_FILE=$(mktemp)
cat > "$CHANGELOG_FILE" <<'EOF'
<paste the full drafted changelog from step 3>
EOF
gh release edit "$NEW_TAG" --notes-file "$CHANGELOG_FILE"
rm -f "$CHANGELOG_FILE"
Wait until gh run watch exits cleanly — the brew step depends on the release's SHA256SUMS asset being present.
./scripts/release/update-brew-tap.sh "$NEW_VERSION"
That script (scripts/release/update-brew-tap.sh):
SHA256SUMS from https://github.com/alecs5am/ralphy/releases/download/${NEW_TAG}/SHA256SUMS.alecs5am/homebrew-tap, regenerates Formula/ralphy.rb with the new version + URLs + SHAs.ralphy: bump to vX.Y.Z and pushes to main of the tap.Smoke-test the formula after:
brew update
brew upgrade ralphy # or: brew install alecs5am/tap/ralphy
ralphy --version # should match $NEW_VERSION
./scripts/release/publish-npm.sh "$NEW_VERSION"
That script (scripts/release/publish-npm.sh):
npm whoami returns the alecs5am account.npm pack --dry-run (catches a bad token before bumping the version).npm/package.json to the new version (redundant safety — already done in step 5).npm publish --access public from npm/ — non-interactive. Auth comes from ~/.npmrc, which holds a Granular Access Token with the "bypass 2FA" capability (rotated 2026-05-14). No OTP prompt.If npm publish fails with granular access token with bypass 2fa enabled is required, the token in ~/.npmrc has been revoked or regenerated without the bypass flag. Regenerate at https://www.npmjs.com/settings/alecs5am/tokens and tick "Allow this token to bypass 2FA" (the box is under Permissions, easy to miss). Then:
echo "//registry.npmjs.org/:_authToken=npm_NEW_TOKEN" > ~/.npmrc
chmod 600 ~/.npmrc
Smoke-test:
npm view @alecs5am/ralphy version # should match $NEW_VERSION
Don't trust, verify:
# Direct from GH Release (what install.sh resolves to)
curl -fsSL "https://api.github.com/repos/alecs5am/ralphy/releases/latest" | jq -r '.tag_name'
# brew
brew info alecs5am/tap/ralphy | head -3
# npm
npm view @alecs5am/ralphy version
All three should print the new vX.Y.Z / X.Y.Z.
Print to the user a single-message summary with all three live URLs:
v0.1.0 published across all channels:
• GitHub → https://github.com/alecs5am/ralphy/releases/tag/v0.1.0
• brew → brew install alecs5am/tap/ralphy (formula sha256-pinned)
• npm → npm install -g @alecs5am/ralphy@0.1.0 (binaries auto-fetched)
gh release create manually. CI does it on tag push. Manually creating the release would race with the workflow and produce duplicate assets.update-brew-tap.sh before CI is done. It pulls SHAs from the release's SHA256SUMS asset; if CI hasn't uploaded it yet, the script aborts with a friendly error. Run gh run watch between step 7 and step 8.npm publish --otp=<code> is fine if you can get the OTP into the script's stdin (e.g. via read), but --ignore-scripts style bypasses are not — they leave the package unpublishable without a manual npm unpublish.update-brew-tap.sh fails halfway, don't delete + retag — bump to the next patch instead. Published versions on npm and brew are one-shot.npm/vendor/. It's the postinstall download cache and is gitignored. Re-running npm install always re-fetches it.bun run build:bin (the full cross-compile) locally as part of the release. CI does it; the local build is just the current-platform sanity check.feat: and get minor bumps. After 1.0.0, feat!: / BREAKING CHANGE: triggers major.docs-mintlify/ stale is a public docs defect — Mintlify auto-deploys on push to main, so out-of-date pages go live the moment you push the bump commit. If the diff is genuinely doc-irrelevant, say "no docs delta" in the changelog and move on; don't silently skip the check.scripts/release/last-release-commit. It's the diff baseline for the next release. If you forget, the next /release either falls back to the previous tag (works, but loses any post-tag commits the pointer was meant to capture) or — worse — re-includes the version-bump commit itself in the next changelog.chore(release): v${NEW_VERSION} commit (HEAD~1 after step 5), not on the trailing pointer commit. Tagging the wrong commit means returns one short of the real release.landing/, docs/ (internal playbooks), .agents/skills/, or a non-CLI directory — that's not what this skill ships. Note: a docs-only change inside docs-mintlify/ also doesn't need a tagged release — Mintlify auto-redeploys on any push to main. Just commit and push without invoking /release.npm whoami / gh auth status is not the right account.package.json → .version (single source of truth, mirrored to cli/lib/version.ts and npm/package.json).scripts/release/last-release-commit — a one-line file containing a single git SHA, rewritten by step 5 of every release. Falls back to git describe --tags --abbrev=0 only if missing/stale.git describe --tags --abbrev=0.gh repo view --json defaultBranchRef --jq .defaultBranchRef.name.scripts/build-binaries.ts.alecs5am/homebrew-tap (overrideable via RALPHY_BREW_TAP).@alecs5am/ralphy, lives in npm/ of this repo.docs-mintlify/ — content + docs.json nav config. Auto-deployed by Mintlify on push to main.scripts/release/update-brew-tap.sh and scripts/release/publish-npm.sh..github/workflows/release.yml (fires on push: tags: ['v*']).The skill assumes these are persisted locally — it never asks for them mid-run:
gh auth status should show alecs5am as active.
Used for: git push, gh release edit, gh repo clone alecs5am/homebrew-tap.
Rotate via gh auth login if revoked.~/.npmrc line //registry.npmjs.org/:_authToken=npm_XXX, chmod 600.
Must be a Granular Access Token with "Allow this token to bypass 2FA" enabled, scoped to @alecs5am/* with read+write permission.
Rotate at https://www.npmjs.com/settings/alecs5am/tokens.npm whoami and gh auth status --hostname github.com are the two pre-flight checks. If either fails, stop and ask the user to refresh the relevant credential before proceeding.
Source: alecs5am/ralphy — distributed by TomeVault.
git describe