agentleFS
keithmackaykeithmackay/git-release/SKILL.md

git-release

Skill1 starsChanged 32 days agoMITView on GitHub

Use when preparing a project for public release on GitHub - adds MIT license, verifies README and .gitignore, creates a GitHub remote if needed, applies branch protection requiring PRs, and creates a tagged GitHub release

  • Pipes a download into a shell
  • Commits and pushes

5 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions5 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 5

    1. mgiovani/cc-arsenal★ 8same name
    2. denghuinow/agent-skills★ 4same name
    3. qhkm/zeptoclaw-skills★ 4same name
    4. Zenobia000/agent-skills-starter★ 4same name
    5. troskater/flowdeck-claude★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repositoryOne other file it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

43 rules. 0 are common, 12 are distinctive, and 31 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 12

    Distinctive

    This author's own choices. Worth a look.

  • 31

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If the user invokes this skill with a --help flag (e.g.

    line 27
  2. Very specific:

    If the user invokes this skill with a --version flag (e.g.

    line 31
  3. Very specific:

    Read the installed version from this skill's own manifest: .claude-plugin/plugin.json if present, else .codex-plugin/plugin.json, else …

    line 33
  4. Very specific:

    If a repo was found: run gh api repos/<owner>/<repo>/releases/latest -q .tag_name (strip a leading v).

    line 39
  5. Distinctive:

    If the API call fails for any reason (network, auth, rate limit, malformed tag): print nothing further — no status line, no error shown to …

    line 43
  6. Distinctive:

    Stop — do not proceed to run the skill's actual workflow.

    line 44
  7. Distinctive:

    Step 2 (LICENSE): if missing, report "Would create LICENSE (MIT)" instead of creating/committing it.

    line 52
  8. Very specific:

    Step 5 (--version support): if missing, report which files would receive the flag/command (e.g.

    line 53
  9. Very specific:

    Step 8 (GitHub remote): if no remote, report "Would create public GitHub repo <repo-name>" instead of running gh repo create.

    line 55
  10. Very specific:

    If the user invokes this skill with a --marketplace flag (e.g.

    line 66
  11. Distinctive:

    If the given path is a file, use it directly.

    line 78
  12. Very specific:

    If it's a folder, check <folder>/marketplace.json and <folder>/.claude-plugin/marketplace.json first.

    line 79
  13. Very specific:

    Determine this project's current version: Use the same version-detection logic as the --version flag: read the version field from …

    line 83
  14. Very specific:

    Update (or create) the marketplace entry: Read the target marketplace.json.

    line 87
  15. Very specific:

    Write the updated marketplace.json back, preserving formatting and the ordering/content of every other entry.

    line 90
  16. Very specific:

    If this project has a help.md and/or CHANGELOG.md at its root, append a line at the end of that project's README entry linking directly to …

    line 93
  17. Distinctive:

    Run each step in order. Report what was done or skipped at each step.

    line 116
  18. Distinctive:

    If not a git repo, stop and tell the user: "This directory is not a git repository.

    line 122
  19. Very specific:

    Check if a LICENSE or LICENSE.md or LICENSE.txt file exists at the project root.

    line 126
  20. Very specific:

    If missing: Create a LICENSE file with the full MIT License text.

    line 128
  21. Distinctive:

    Check if README.md exists and has more than just a title line.

    line 134
  22. Very specific:

    If it is a skill/plugin: check whether it already has a working help mechanism — a --help flag (skills) or :help command (plugins) …

    line 154
  23. Very specific:

    If it is a skill/plugin: check whether it already has a --version flag (skills) or :version command (plugins) documented in the core …

    line 163
  24. Very specific:

    If missing or incomplete: add it now — unlike the help mechanism and CHANGELOG (which are /make-readme's job), this skill adds …

    line 166
  25. Distinctive:

    Use this block format (adapt labels/values, don't force it verbatim if the existing README already covers the same ground in its own voice):

    line 209
  26. Very specific:

    If it is a skill/plugin: check whether it ships any executable script, CLI, or MCP server of its own beyond the skill manifest itself — a …

    line 239
  27. Very specific:

    Check if CHANGELOG.md exists.

    line 253
  28. Very specific:

    Check whether a dependency manifest exists at the project root: package.json, requirements.txt, pyproject.toml, Gemfile, go.mod, or …

    line 277
  29. Very specific:

    If one exists: check for its matching lockfile — package-lock.json/yarn.lock/pnpm-lock.yaml for package.json.

    line 281
  30. Very specific:

    Check if a remote named origin exists and points to a GitHub URL.

    line 289
  31. Very specific:

    Ask the user: "No GitHub remote found.

    line 293
  32. Very specific:

    If yes, run: gh repo create <repo-name> --public --source=.

    line 294
  33. Distinctive:

    Determine the type prefix: Every proposed/checked description leads with what the project *is*, before the actual description — this is …

    line 303
  34. Very specific:

    Skill, multiple platforms: if more than one platform is present, join them with / in this fixed order — Claude, Codex, Gemini — e.g.

    line 306
  35. Very specific:

    Run gh repo view <owner>/<repo> --json description -q .description to check the current value.

    line 310
  36. Very specific:

    Run gh repo view <owner>/<repo> --json repositoryTopics -q '.repositoryTopics[].name' to get the current topic list.

    line 338
  37. Distinctive:

    Run this API call:

    line 363
  38. Very specific:

    Ask the user for a version tag.

    line 390
  39. Very specific:

    If it is a skill or plugin: check for an existing entry in this skill's own .git-release/marketplace-config.json (see the --marketplace …

    line 419
  40. Very specific:

    If no saved marketplace path exists: ask the user: "Sync this release to a marketplace listing?" If yes, run the full --marketplace …

    line 422
  41. Very specific:

    If gh CLI is not installed or not authenticated, stop and tell the user to install/authenticate it

    line 459
  42. Distinctive:

    If branch protection fails (e.g., free plan limitations), warn but continue with the release

    line 460
  43. Distinctive:

    If any step fails, report the failure and continue with remaining steps where possible

    line 461

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

gitrelease

Overview

Prepare a local git project for public release on GitHub. Ensures the project has an MIT license, essential files, a properly configured remote, branch protection requiring pull requests, and a tagged release.

When to Use

  • First time releasing a project publicly
  • Setting up a new repo for collaboration
  • User says "release this", "make this public", "set up GitHub for this project"

When NOT to Use

  • Project is already released and you just want to create a new version tag (use gh release create directly)
  • Project is not a git repository

Flags

--help

If the user invokes this skill with a --help flag (e.g. /git-release --help), do not run the workflow. Instead, read and display the contents of help.md (in this skill's folder) verbatim, then stop.

--version

If the user invokes this skill with a --version flag (e.g. /git-release --version), do not run the workflow. Instead:

  1. Read the installed version from this skill's own manifest: .claude-plugin/plugin.json if present, else .codex-plugin/plugin.json, else gemini-extension.json — whichever exists for this platform install. If none exist (a bare Claude Code skill with only SKILL.md), read the topmost version heading in CHANGELOG.md instead.
  2. Print: git-release v<installed-version>
  3. Best-effort update check — determine this skill's GitHub source repo: a. If .git exists here and git remote get-url origin resolves to a github.com URL, use that owner/repo. b. Otherwise, search this skill's own README.md for the first https://github.com/<owner>/<repo> URL and use that. c. If neither yields a repo, or the gh CLI isn't installed/authenticated: stop here. Print nothing further — no status line, no error.
  4. If a repo was found: run gh api repos/<owner>/<repo>/releases/latest -q .tag_name (strip a leading v). Compare to the installed version:
    • Equal → append: Status: up to date
    • Installed is older → append: Status: newer version available (v<latest>). To update: if you installed this via a Claude Code marketplace, run /plugin marketplace update <marketplace-name> then reinstall; otherwise, git pull in your install directory if it's a git checkout, or re-copy from https://github.com/<owner>/<repo> per this README's Installation section.
    • Installed is newer → append: Status: ahead of latest release (development checkout)
    • If the API call fails for any reason (network, auth, rate limit, malformed tag): print nothing further — no status line, no error shown to the user.
  5. Stop — do not proceed to run the skill's actual workflow.

--dry-run

If the user invokes this skill with a --dry-run flag (e.g. /git-release --dry-run), run through the full Workflow below, but treat every step that would create, modify, commit, push, tag, or call a mutating GitHub API as report-only: state what it would do, then move on without doing it. Steps that are already pure checks (1, 3, 3b, 4, 5c, 5d, 6, 7, 7b, 7c) run exactly as normal — there's nothing to hold back. Combine with --marketplace (i.e. --marketplace --dry-run) to preview that flag's sync instead of the full release workflow, under the same rule.

Concretely, in dry-run mode:

  • Step 2 (LICENSE): if missing, report "Would create LICENSE (MIT)" instead of creating/committing it. If present with a stale copyright year, report "Would update LICENSE copyright year to <year>" instead of writing/committing it.
  • Step 5 (--version support): if missing, report which files would receive the flag/command (e.g. "Would add --version to SKILL.md, skills/<name>/SKILL.md") instead of writing them.
  • Step 5b (distributed skill README, skills/plugins only): if a packaging folder's README.md is missing or missing required fields, report which folder(s) would get a new/updated README.md and which fields would be added, instead of writing/committing it. If every folder already has a complete one, this step is a pure check and runs normally.
  • Step 8 (GitHub remote): if no remote, report "Would create public GitHub repo <repo-name>" instead of running gh repo create. If a remote exists and local is behind, report "Would push <N> commit(s) to origin" instead of pushing.
  • Step 9 (repo description): if missing, empty, or missing/mismatching the correct type prefix, report the proposed one-line description (with its type prefix) and "Would set repo description to: "<proposed description>"" instead of calling the API. If already set with the correct prefix, this step is a pure check and runs normally.
  • Step 9b (repo topics, skills/plugins only): if anything is missing or stale, report the proposed add/remove lists and "Would add topics: <missing topics>" / "Would remove topics: <stale topics>" instead of calling gh repo edit. If already in sync, this step is a pure check and runs normally.
  • Step 10 (branch protection): report "Would apply branch protection: PRs required (1 approval), stale reviews dismissed, force push blocked, branch deletion blocked" instead of calling the API.
  • Step 11 (version bump/CHANGELOG/release): still ask the user for a version tag (this is informational, not mutating), then report "Would bump manifest version to <version> in <N> file(s)", "Would finalize CHANGELOG.md: [Unreleased] → [<version>] - <date>" (or "Unreleased is empty — would prompt before proceeding" if applicable), "Would append <version> to versions.json" (if one exists), and "Would create tag <version> and GitHub release" — without touching any file, committing, tagging, or calling gh release create.
  • Step 12 / --marketplace procedure: perform the read-only parts (resolving the repo, locating/asking for the marketplace config path, determining current version) normally, but report "Would update <marketplace-name>'s marketplace.json entry to <version>" / "Would create new entry for <plugin-name>", "Would update marketplace README.md entry", "Would update this project's own README.md Installation section" — without writing or pushing to either repo, and without saving a newly-given marketplace path into the config file (ask first: "Save this path for future runs?" — a --dry-run shouldn't silently persist state).

End with the same Step 12 summary table, but every row that describes a would-be action is prefixed Would: (e.g. Would: Create (MIT)), and the table itself is headed with "## Dry Run — no changes were made" instead of "## Release Summary".

--marketplace

If the user invokes this skill with a --marketplace flag (e.g. /git-release --marketplace), do not run the release workflow. Instead, run the marketplace-sync procedure below and stop.

Applicability check: determine whether the current project is itself a skill or plugin, using the same detection as Step 4 (a SKILL.md at the project root or in a skills/*/ subdirectory, or a .codex-plugin/plugin.json manifest). If it is not: stop and tell the user "This project isn't a skill or plugin — --marketplace only applies to skill/plugin releases."

  1. Resolve the project's public repo. Run git remote get-url origin and normalize it to owner/repo. If there's no remote or it isn't a github.com URL, stop and tell the user to set up a GitHub remote first (run /git-release without flags, which handles this in Step 8).
  2. Locate the config file. This skill stores its marketplace config in its own installed folder (the same directory as this SKILL.md and help.md), not the project being released — at .git-release/marketplace-config.json. Determine that folder by finding the SKILL.md currently being executed on disk (e.g. it sits alongside help.md and CHANGELOG.md for this skill's own package). Create the .git-release/ subfolder if it doesn't exist. The file is a JSON object keyed by owner/repo of the project being released, valued with the absolute path to that project's chosen marketplace.json:
    { "someowner/some-project": "/Users/you/Projects/some-marketplace/.claude-plugin/marketplace.json" }
  3. Ask for the marketplace location. If the config file has an existing entry for this project's owner/repo, use its path as the default when asking. Ask the user: "Where is the marketplace.json for the marketplace you want to list this project in?" (showing the default, if any, so they can just confirm it).
    • If the given path is a file, use it directly.
    • If it's a folder, check <folder>/marketplace.json and <folder>/.claude-plugin/marketplace.json first.
    • If neither exists, recursively search the folder's subfolders for any file named marketplace.json. If exactly one is found, use it. If several are found, list them and ask the user to pick one. If none are found, tell the user and ask again for a location.
    • Save the resolved full absolute path into the config file under this project's owner/repo key, preserving all other entries already in the file.
  4. Determine this project's current version. Use the same version-detection logic as the --version flag: read the version field from .claude-plugin/plugin.json / .codex-plugin/plugin.json / gemini-extension.json (whichever exists), falling back to the topmost version heading in CHANGELOG.md if none of those manifests exist.
  5. Determine the base description. If this project has a GitHub repo description set (per Step 9 — fetch it live with gh repo view <owner>/<repo> --json description -q .description if not already known this run), use it verbatim as the base description. Otherwise fall back to this project's own manifest description (or its SKILL.md frontmatter description field if no manifest exists).
  6. Update (or create) the marketplace entry. Read the target marketplace.json. Find the plugins[] entry whose source repo matches this project's owner/repo.
    • If found: replace its description with <version> — <base description> (from step 5), so the marketplace listing always mirrors the GitHub repo's own one-line description rather than drifting from it. Leave every other field untouched.
    • If not found: create a new entry. Use the name and the base description from step 5, prefix the description with <version> — , and set the source field to reference this project's public repo, matching the field shape already used by sibling entries in that marketplace.json (e.g. {"source": "github", "repo": "owner/repo"} or whatever convention that file already follows — don't invent a new shape). Ask the user for a category if the marketplace's other entries use one and it isn't obvious from context.
    • Write the updated marketplace.json back, preserving formatting and the ordering/content of every other entry.
  7. Update the marketplace project's README.md. Find README.md at the root of the marketplace repo (the directory containing marketplace.json, or its parent if marketplace.json lives in a .claude-plugin/ subfolder). Find this project's existing entry in the README (matched by plugin name) and update its description line to match the new version-prefixed description; if no entry exists yet, add one following the same structure/heading level as the README's other listed entries.
    • If this project has a help.md and/or CHANGELOG.md at its root, append a line at the end of that project's README entry linking directly to them in the project's public GitHub repo, e.g.: [Help](https://github.com/<owner>/<repo>/blob/<default-branch>/help.md) · [Changelog](https://github.com/<owner>/<repo>/blob/<default-branch>/CHANGELOG.md) (omit whichever of the two doesn't exist).
  8. Commit and push the marketplace repo. Stage marketplace.json and README.md there, commit with a message like "Sync <plugin-name> to <version> in marketplace listing", and push using that marketplace repo's own push method (plain git push, or the gh-push helper / manual GraphQL fallback if its remote is under an account known to need it).
  9. Update this project's own README.md Installation section. Determine the marketplace's own name (the top-level "name" field in its marketplace.json) and its public owner/repo (from git remote get-url origin inside the marketplace repo). At the very top of this project's ## Installation section — before any existing per-platform subsections — add or update a subsection pointing at marketplace installation, e.g.:

    ### From the <marketplace-name> marketplace (recommended)
    

    /plugin marketplace add <marketplace-owner>/<marketplace-repo> /plugin install <plugin-name>@<marketplace-name>

    If this subsection already exists (from a prior --marketplace run), just update the marketplace name/repo/plugin name in place rather than duplicating it. Stage this README.md change alongside this project's own commits (commit it now with a message like "Document <marketplace-name> marketplace installation in README" — this is a change to the project being released, not the marketplace repo, so it does not get pushed as part of step 8).

  10. Report the marketplace path used (and whether it was newly saved to config or reused), whether the entry was created or updated, the version applied, whether the marketplace's README was updated, which of help.md/CHANGELOG.md were linked, and whether this project's own README.md installation section was updated.

Workflow

Run each step in order. Report what was done or skipped at each step.

Step 1: Verify Git Repository

Confirm the current directory is a git repository. Identify the default branch name (usually main or master).

If not a git repo, stop and tell the user: "This directory is not a git repository. Run git init first, or navigate to a git project."

Step 2: Add MIT License

Check if a LICENSE or LICENSE.md or LICENSE.txt file exists at the project root.

If missing: Create a LICENSE file with the full MIT License text. Use the current year and derive the copyright holder name from git config user.name. Stage and commit the file with the message "Add MIT license".

If present: Check the copyright year in the license text (e.g. Copyright (c) <year> <holder>). If it's not the current year, update it to the current year and stage/commit the change with the message "Update LICENSE copyright year to <year>". Report "LICENSE already exists, updated copyright year to <year>." If the year already matches, report "LICENSE already exists, skipping." Do not otherwise modify the file.

Step 3: Check README.md

Check if README.md exists and has more than just a title line.

If missing or stub-only: Warn the user: "No README.md found (or it's just a title). Consider running /readme to generate one before releasing." Do not generate a README — that is the /readme skill's job.

If present: Report "README.md found." Continue.

Step 3b: Check Install Instructions Don't Pipe to Shell

Scan README.md's installation/usage sections for a download-straight-into-a-shell pattern — e.g. curl ... | sh, curl ... | bash, or the wget equivalent. findsafeskills' safety guidance flags this: download it, say how to verify it, then run it, rather than piping it blind.

If found: warn the user: "README.md's install instructions pipe a download directly into a shell (<matched line>) — consider splitting this into download, verify, then run steps." Do not rewrite the README yourself — that's a content decision for the author.

If not found (or no README): report "No pipe-to-shell install pattern found." Continue.

Step 4: Check Help Mechanism (Skills/Plugins Only)

Determine whether this project is itself an agent skill or plugin: look for a SKILL.md file (at the project root or in a skills/*/ subdirectory) or a .codex-plugin/plugin.json manifest.

If this project is not a skill/plugin: skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill/plugin: check whether it already has a working help mechanism — a --help flag (skills) or :help command (plugins) documented in the core manifest file(s), backed by a help.md file alongside each one.

  • If present for every manifest copy: report "Help mechanism found, skipping."
  • If missing or incomplete: warn the user: "No --help/:help mechanism found for this skill/plugin. Consider running /make-readme to add one." Do not create it yourself — creating the mechanism is /make-readme's job, not this skill's.

Step 5: Check/Add --version Support (Skills/Plugins Only)

If this project is not a skill/plugin (per Step 4's detection): skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill/plugin: check whether it already has a --version flag (skills) or :version command (plugins) documented in the core manifest file(s) (and any skills/<name>/ copies used for cross-platform packaging).

  • If present for every manifest copy: report "Version flag found, skipping."
  • If missing or incomplete: add it now — unlike the help mechanism and CHANGELOG (which are /make-readme's job), this skill adds --version/:version support itself, since it's directly tied to the version-management this skill already owns.

For a skill (has SKILL.md): add a ## Flags entry (or extend the existing one) to every SKILL.md copy — root, skills/<name>/, antigravity/ if present — with this exact procedure:

### `--version`

If the user invokes this skill with a `--version` flag (e.g. `/<skill-name> --version`), do not run the workflow. Instead:

1. Read the installed version from this skill's own manifest: `.claude-plugin/plugin.json` if present, else `.codex-plugin/plugin.json`, else `gemini-extension.json` — whichever exists for this platform install. If none exist (a bare Claude Code skill with only SKILL.md), read the topmost version heading in `CHANGELOG.md` instead.
2. Print: `<skill-name> v<installed-version>`
3. Best-effort update check — determine this skill's GitHub source repo:
   a. If `.git` exists here and `git remote get-url origin` resolves to a `github.com` URL, use that `owner/repo`.
   b. Otherwise, search this skill's own `README.md` for the first `https://github.com/<owner>/<repo>` URL and use that.
   c. If neither yields a repo, or the `gh` CLI isn't installed/authenticated: stop here. Print nothing further — no status line, no error.
4. If a repo was found: run `gh api repos/<owner>/<repo>/releases/latest -q .tag_name` (strip a leading `v`). Compare to the installed version:
   - Equal → append: `Status: up to date`
   - Installed is older → append: `Status: newer version available (v<latest>). To update: if you installed this via a Claude Code marketplace, run /plugin marketplace update <marketplace-name> then reinstall; otherwise, git pull in your install directory if it's a git checkout, or re-copy from https://github.com/<owner>/<repo> per this README's Installation section.`
   - Installed is newer → append: `Status: ahead of latest release (development checkout)`
   - If the API call fails for any reason (network, auth, rate limit, malformed tag): print nothing further — no status line, no error shown to the user.
5. Stop — do not proceed to run the skill's actual workflow.

For a plugin (commands-based, no SKILL.md): add a commands/version.md file (and its mirror under any build/packaging directory, e.g. plugin/commands/) implementing the same 5-step procedure, invoked as /<plugin-name>:version.

Present the added flag/command to the user before writing, mirroring how the help mechanism is added.

Step 5b: Ensure Distributed Skill README (Skills/Plugins Only)

If this project is not a skill/plugin (per Step 4's detection): skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill/plugin: what actually travels with an installed skill is just the files inside its packaging folder — skills/<name>/ for Claude Code (and any antigravity/<name>/ copy), the files alongside .codex-plugin/plugin.json for Codex, the files alongside gemini-extension.json for Gemini. The project's root README.md does not travel with that copy unless the packaging folder is the project root (a bare single-platform skill with no subfolder). This means an installed skill, viewed on its own with no surrounding repo, needs its own README.md so whoever has it can trace it back to where it came from — this is findsafeskills' skill-distribution best practice ("Say who made it and where it came from"): https://findsafeskills.com/diy#best-practices.

Determine each packaging folder that needs its own README.md: every folder containing a SKILL.md or a commands/*.md set that is distinct from the project root (i.e. skills/<name>/, antigravity/<name>/, or equivalent). If the only SKILL.md is at the project root with no subfolder copy, the root README.md itself is the distributed copy — check it there instead of creating a separate one.

For each such folder, check whether its README.md (create one if totally missing) contains, at minimum:

  • A one-paragraph description of what it does and when it triggers (pull from the manifest/SKILL.md frontmatter description if not already present)
  • Who made it and how to reach them (derive from git config user.name / user.email, falling back to asking the user if git config has no email)
  • The source repo URL, written out in full (git remote get-url origin, normalized to https://github.com/<owner>/<repo>)
  • How to update it (a git pull in the install directory, or the marketplace reinstall command if Step 12 found a saved marketplace entry)
  • The current version (matching the manifest version field, or the latest tag if this project has no manifest)
  • The license (per Step 2) and where to report an issue (<repo-url>/issues)

Use this block format (adapt labels/values, don't force it verbatim if the existing README already covers the same ground in its own voice):

Version <version> · <LICENSE type> license
Source:  <repo-url>
Author:  <name> <<email>>
Update:  git -C ~/.claude/skills/<skill-name> pull   (or: reinstall via the marketplace, if applicable)
Issues:  <repo-url>/issues

If a folder's README.md is missing entirely: show the proposed full file (opening paragraph + the block above) and ask the user to confirm before writing. Stage and commit with message "Add distributed README.md to <folder>".

If present but missing one or more of the items above: show just the proposed additions (don't rewrite existing prose) and ask before applying. Report which folder(s) were updated and which fields were added.

If every packaging folder already has a README.md covering all the items: report "Distributed README found for <folder(s)>, skipping."

Step 5c: Check --dry-run Support for Mutating Skills/Plugins

If this project is not a skill/plugin (per Step 4's detection): skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill/plugin: determine, heuristically, whether its documented workflow performs mutating actions — writes or deletes files, calls a paid or external API, or sends data somewhere — beyond pure local analysis/reporting. Look for things like git commit/git push, gh api --method POST/PUT/PATCH/DELETE, gh release create, file-write instructions, or similar side effects described in its SKILL.md/command files.

  • If it has no such mutating actions (e.g. a pure evaluate-and-report skill): skip this step, not applicable — don't mention it in the summary.
  • If it has mutating actions and already documents a --dry-run flag (or an equivalent preview mode) that reports what would happen without doing it: report "--dry-run found, skipping."
  • If it has mutating actions and no --dry-run flag is documented: warn the user: "This skill performs mutating actions (<brief list>) but has no --dry-run flag to preview them first — findsafeskills' CLI guidance recommends one. Consider adding one." Do not design or add the dry-run logic yourself — unlike --version (which is mechanical and this skill adds directly), a meaningful dry-run requires per-step judgment about what to report at each mutating point, so this is left to the author.

Step 5d: Check Shipped Scripts/CLIs Follow CLI Best Practices (Skills/Plugins Only)

If this project is not a skill/plugin (per Step 4's detection): skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill/plugin: check whether it ships any executable script, CLI, or MCP server of its own beyond the skill manifest itself — a scripts/ directory with executable entrypoints, a package.json bin field, a pyproject.toml [project.scripts] section, or similar.

If it ships none: skip this step, not applicable — don't mention it in the summary.

If it does: for each such entrypoint, do a best-effort static check (read its own argument-parsing/usage code or text, don't execute it) of whether it supports:

  • --help: usage, every option, examples, and what the exit codes mean
  • --version: prints the name and version (matching the manifest), then exits 0
  • --dry-run: for anything that writes/deletes files or calls a paid/external API — shows what would happen without doing it
  • If every shipped entrypoint already supports the applicable flags: report "Shipped CLI(s) already support --help/--version/--dry-run where applicable, skipping."
  • If any are missing: warn the user, listing which entrypoint is missing which flag(s), citing findsafeskills' CLI guidance (--help/--version/--dry-run conventions, non-zero exit on failure, secrets from environment variables rather than arguments, never printed). Do not add this code yourself — these are per-script implementation details outside this skill's scope.

Step 6: Check CHANGELOG.md

Check if CHANGELOG.md exists.

If missing: Warn the user: "No CHANGELOG.md found. Consider running /make-readme to add one." Do not create it yourself — creating the file is /make-readme's job, not this skill's.

If present: Report "CHANGELOG.md found." Continue.

Step 7: Check .gitignore

Check if .gitignore exists.

If missing: Warn the user: "No .gitignore found. Consider adding one to prevent committing build artifacts, secrets, or OS files."

If present: Report ".gitignore found." Continue.

Step 7b: Check SECURITY.md

Check if SECURITY.md exists.

If missing: Warn the user: "No SECURITY.md found. Consider adding one (or running /make-readme) describing how to report a security vulnerability — findsafeskills' safety guidance lists this as a trust signal reviewers look for." Do not create it yourself — creating the file is /make-readme's job, not this skill's.

If present: Report "SECURITY.md found." Continue.

Step 7c: Check Dependency Lockfile (If Applicable)

Check whether a dependency manifest exists at the project root: package.json, requirements.txt, pyproject.toml, Gemfile, go.mod, or Cargo.toml.

If none exist: skip this step, not applicable — don't mention it in the summary.

If one exists: check for its matching lockfile — package-lock.json/yarn.lock/pnpm-lock.yaml for package.json; poetry.lock/uv.lock for pyproject.toml; requirements.txt pins its own versions directly (no separate lockfile expected); Gemfile.lock for Gemfile; go.sum for go.mod; Cargo.lock for Cargo.toml.

If missing: warn the user: "No lockfile found for <manifest>. Consider committing one to pin dependency versions — findsafeskills notes this as a safety signal reviewers look for."

If present: report "<lockfile> found." Continue.

Step 8: Ensure GitHub Remote

Check if a remote named origin exists and points to a GitHub URL.

If no remote exists:

  1. Derive the repo name from the current directory name
  2. Ask the user: "No GitHub remote found. Create a public repo named <repo-name> on GitHub?"
  3. If yes, run: gh repo create <repo-name> --public --source=. --push
  4. Report the URL of the created repo

If remote exists: Report the remote URL. Ensure local branch is pushed and up to date. Push if behind.

Step 9: Ensure Repo Description

GitHub's repo description field is what surfaces this project's one-line summary in places like dev.to's GitHub Connections, gh repo list, and the repo header — it isn't derived from the README or SKILL.md frontmatter, so it has to be set explicitly.

Determine the type prefix. Every proposed/checked description leads with what the project is, before the actual description — this is what lets someone scanning a repo list or a marketplace tell at a glance whether something is a skill, a plugin, or something else entirely:

  • Skill, single platform: detect which agent platform(s) this project is built for by checking for a SKILL.md (root or skills/*/, and/or an antigravity/ copy) → Claude Code; a .codex-plugin/plugin.json manifest → Codex; a gemini-extension.json or GEMINI.md → Gemini. If exactly one platform is present, the prefix is "<Platform> skill: " (e.g. "Claude skill: ").
  • Skill, multiple platforms: if more than one platform is present, join them with / in this fixed order — Claude, Codex, Gemini — e.g. "Claude/Codex/Gemini skill: " or "Claude/Gemini skill: ". Only include a platform actually present; never list one that isn't.
  • Plugin: a commands-based project (a .claude-plugin/plugin.json manifest, commands/*.md files, no SKILL.md) is a Claude Code plugin — prefix "Claude Code plugin: ".
  • Neither: for any other kind of project (a website, a library, a CLI tool, documentation, an application, etc.), infer the single most fitting noun from its structure/README and use "<Noun>: " (e.g. "Website: ", "CLI tool: ", "Documentation: "). Don't force skill/plugin phrasing onto a project that isn't one.

Run gh repo view <owner>/<repo> --json description -q .description to check the current value.

If already set and it already starts with the correct type prefix determined above: Report "Repo description already set: "<description>", skipping." Do not modify it.

If missing, empty, or set but missing/mismatching the correct type prefix: Propose a one-line description: "<type prefix><summary>" where the summary (roughly 10-15 words, no trailing period) is derived from — in order of preference — the existing repo description (stripped of any stale prefix) if one was set, then this project's SKILL.md/manifest description frontmatter field, then the README's opening summary/tagline, then a plain-language summary of what the project does inferred from its code/structure. Show the full proposed description (prefix + summary) to the user and ask them to accept it as-is or supply their own replacement. Once confirmed, set it:

gh repo edit <owner>/<repo> --description "<description>"

Report the description that was applied.

Step 9b: Keep Repo Topics in Sync (Skills/Plugins Only)

GitHub topic tags are how skill/plugin directories and search (including topic-based discovery tooling, and findsafeskills' own listing search) find this project — a repo with the right description but no topics is still invisible to gh search repos --topic <topic>. This step only applies to skills/plugins (the same platform detection as Step 9); skip it for non-skill/plugin projects.

Determine the correct topics based on the platform(s) actually present (same file-based detection as Step 4/9 — SKILL.md root or skills/*/, .codex-plugin/plugin.json, gemini-extension.json/GEMINI.md, or a commands-based plugin manifest):

  • Claude Code skill: claude-code-skill, claude-skills, agent-skills
  • Claude Code plugin: claude-code-plugin, agent-skills
  • Codex skill: codex-skill, agent-skills
  • Gemini CLI skill: gemini-cli-skill, agent-skills
  • Multi-platform: include every platform-specific topic that applies, plus agent-skills once (don't duplicate it).

agent-skills is the cross-platform umbrella tag — always include it for any skill/plugin project regardless of platform, since some discovery tooling (including skillfinder and findsafeskills) searches on it directly rather than every platform-specific tag individually.

This step keeps topics in sync, not just additive — run it on every release so a platform a project drops (e.g. it no longer ships a gemini-extension.json) doesn't leave a stale tag behind:

  1. Run gh repo view <owner>/<repo> --json repositoryTopics -q '.repositoryTopics[].name' to get the current topic list.
  2. Compute missing = determined topics not currently present, and stale = currently-present topics that are part of this skill's known topic vocabulary (claude-code-skill, claude-skills, claude-code-plugin, codex-skill, gemini-cli-skill, agent-skills) but not in the determined set for this project's current platforms. Never touch a topic outside that vocabulary (e.g. a manually-added unrelated topic like productivity) — this step only reconciles the skill/plugin platform tags, not the full topic list.
  3. If nothing is missing and nothing is stale: report "Repo topics already in sync: <topics>, skipping." Do not modify.
  4. If anything is missing or stale: show the proposed change (topics to add, topics to remove, and the resulting full list) and ask the user to accept or adjust it. Once confirmed, apply both in one call each (the flag takes a single comma-separated value, not repeated flags):
gh repo edit <owner>/<repo> --add-topic <topic1>,<topic2>,...
gh repo edit <owner>/<repo> --remove-topic <stale1>,<stale2>,...

Report the resulting topic list, noting what was added and what (if anything) was removed.

Step 10: Apply Branch Protection

Apply branch protection rules to the default branch using the GitHub API:

Required pull request reviews:
  - Required approving review count: 1
  - Dismiss stale reviews: true
Enforce admins: false
Force pushes: blocked
Branch deletion: blocked

Run this API call:

gh api repos/<owner>/<repo>/branches/<default-branch>/protection \
  --method PUT \
  --input - <<'EOF'
{
  "required_pull_request_reviews": {
    "required_approving_review_count": 1,
    "dismiss_stale_reviews": true
  },
  "enforce_admins": false,
  "required_status_checks": null,
  "restrictions": null
}
EOF

Report the settings applied:

  • PRs required with 1 approving review
  • Stale reviews dismissed on new pushes
  • Force pushes blocked
  • Branch deletion blocked
  • Admin bypass enabled (repo owner can still push directly)

Step 11: Bump Manifest Versions, Finalize CHANGELOG, and Create GitHub Release

Ask the user for a version tag. Suggest v1.0.0 if this is the first release (no existing tags), or suggest the next patch/minor/major version based on the latest existing tag.

If this project is itself a skill or plugin (per Step 4's detection): before tagging, find every manifest file that declares a "version" field — .claude-plugin/plugin.json, .codex-plugin/plugin.json, gemini-extension.json — including any copies under skills/<name>/ used for cross-platform packaging. Update each one's version field to match the new tag with the leading v stripped (e.g. tag v1.2.0 → "version": "1.2.0"). This is what keeps a plugin's declared version from drifting out of sync with its actual release, a real bug this step exists to prevent.

If this project is not a skill/plugin: skip the manifest bump — not applicable, don't mention it in the summary.

If CHANGELOG.md exists (per Step 6): before finalizing, check whether ## [Unreleased] has any content under it (bullets, or non-empty ### Added/### Changed/etc. subsections).

  • If Unreleased is empty: stop and ask the user: "CHANGELOG.md's Unreleased section is empty — this release would ship with no changelog entry. Add an entry now, or proceed anyway?" Wait for their answer before continuing. Do not write a placeholder entry yourself and do not silently proceed — this is a deliberate gate, not a step to route around.
  • If Unreleased has content, or the user confirmed proceeding anyway despite it being empty: finalize it for this release — this is a mechanical rename, not content generation. Rename the ## [Unreleased] heading to ## [<version>] - <YYYY-MM-DD> (version without the leading v, date = today), then insert a fresh, empty ## [Unreleased] heading above it. Do not invent, summarize, or generate changelog entries yourself — whatever prose already sits under Unreleased becomes that version's entry verbatim, unedited.

If CHANGELOG.md is missing: skip this — not applicable.

Optional — versions.json: if this project already has a versions.json at its root (a flat map of version → short changelog note, a pattern borrowed from Obsidian's community-plugin convention and called out in findsafeskills' versioning guidance), append an entry for the new version using the same Unreleased content just finalized above — don't invent new text, just carry over what's already written. If no versions.json exists, don't create one automatically; it's optional tooling-readable history, not a requirement.

Stage and commit the manifest bump, CHANGELOG finalization, and any versions.json update together with the message "Bump version to <version>" before creating the tag, so the tagged commit already reflects the version being released.

Create the release:

gh release create <tag> --generate-notes --latest

Report the release URL, which manifest files were bumped (if any), and whether CHANGELOG.md was finalized.

Step 12: Sync Marketplace Listing (Optional)

If this project is not itself a skill or plugin (per Step 4's detection): skip this step entirely — not applicable, don't mention it in the summary.

If it is a skill or plugin: check for an existing entry in this skill's own .git-release/marketplace-config.json (see the --marketplace flag above) for this project's owner/repo.

  • If a saved marketplace path exists: ask the user: "Sync this release to <saved-marketplace-path> (as configured)?" If yes, run the full --marketplace procedure (steps 4-10 above — version detection, base-description resolution, entry update/create, marketplace README sync, commit and push, and this project's own README install-instructions update), reusing that saved path without re-asking for a location. If no: skip, not applicable.
  • If no saved marketplace path exists: ask the user: "Sync this release to a marketplace listing?" If yes, run the full --marketplace procedure from the top (steps 1-10 above), which will ask for and save a marketplace location. If no: skip, not applicable.

Report which marketplace (if any) was updated, and to what version.

Step 13: Summary

Present a summary table of everything that was done. Include the Help mechanism, Distributed README, --dry-run support, Shipped CLI check, Version flag, and Manifest version(s) rows only if Step 4 / Step 11's skill-or-plugin check applied (i.e. this project is a skill/plugin) and that step wasn't itself skipped as not-applicable; include the Repo topics row only if Step 9b applied (same skill/plugin check); include the CHANGELOG.md row only if Step 6 found the file present; include the Lockfile row only if Step 7c found a dependency manifest; include the Marketplace listing row only if Step 12 found a match:

## Release Summary

| Step | Status |
|------|--------|
| Git repo | Confirmed (branch: main) |
| LICENSE | Created (MIT) / Already existed / Copyright year updated to <year> |
| README.md | Found / Warning: missing |
| Install instructions | No pipe-to-shell pattern found / Warning: pipes to shell |
| Help mechanism | Found / Warning: missing (run /make-readme) |
| Distributed README | Found for all packaging folders / Added to <folder(s)> / Updated <field(s)> in <folder(s)> |
| Version flag | Found / Added |
| `--dry-run` support | Found / Not applicable (no mutating actions) / Warning: missing |
| Shipped CLI check | Compliant / Not applicable (no scripts/CLI shipped) / Warning: missing flags on <entrypoint(s)> |
| CHANGELOG.md | Finalized: [Unreleased] → [<version>] / Empty, confirmed by user / Warning: missing (run /make-readme) |
| .gitignore | Found / Warning: missing |
| SECURITY.md | Found / Warning: missing (run /make-readme) |
| Lockfile | Found / Warning: missing |
| GitHub remote | Created: <url> / Existing: <url> |
| Repo description | Set: "<description>" / Already set / Kept user-supplied |
| Repo topics | In sync: <topics> / Added: <topics>, Removed: <topics> |
| Branch protection | Applied (PRs required, force push blocked) |
| Manifest version(s) | Bumped to <version> in <N> file(s) |
| Marketplace listing | Updated <marketplace>/marketplace.json to <version> / Not found |
| Release | Created: <tag> — <url> |

Error Handling

  • If gh CLI is not installed or not authenticated, stop and tell the user to install/authenticate it
  • If branch protection fails (e.g., free plan limitations), warn but continue with the release
  • If any step fails, report the failure and continue with remaining steps where possible

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.