Skip to content

feat: add gh-release-status skill #2

@cbeaulieu-gt

Description

@cbeaulieu-gt

Summary

Add a new skill, gh-release-status, that gives a fast "where are we since we last shipped" view of a GitHub repo: a summary of the last N releases (up to 5), a diff of the default branch against the latest release, and a feature/area-grouped summary of what changed.

Context

The plugin already has gh-summary (roadmap snapshot) and gh-refresh-issues/gh-quick-wins (backlog views), but none answer "what has landed since the last release?" — the question you ask right before cutting the next release or writing changelog notes. gh-release-status fills that gap.

It follows the plugin's established hybrid pattern (deterministic script + optional LLM prose), exactly like gh-summary: a zero-token script produces the structural facts, and a single LLM step adds the narrative on top.

Design (agreed)

  • Diff base: latest release tag → default-branch HEAD, i.e. "what is unreleased." Computed via the GitHub compare API (gh api repos/{owner}/{repo}/compare/{tag}...{defaultBranch}) so it needs no local clone and stays repo-agnostic like the other scripts.
  • Summary engine: hybrid. The script emits per-area file/insertion/deletion stats grouped by top-level path; the LLM step writes the feature/area narrative from the script's stats + commit subjects in the compare payload.
  • Scope: just the new skill + its script. The release-list rendering currently lives privately in gh-summary.py (_render_recent_releases); if reusing it cleanly is straightforward, lift it into _gh_common.py as part of this work so both skills share one implementation. If extraction proves messy, keep them separate and note why.

Acceptance Criteria

  • skills/gh-release-status/SKILL.md with frontmatter (name, description with trigger phrases) and triggers.yml sidecar, matching the dispatch-catalog conventions of the existing skills
  • scripts/gh-release-status.py invoked via the ${CLAUDE_PLUGIN_DATA}/venv interpreter + ${CLAUDE_PLUGIN_ROOT}/scripts/ path contract (mirror gh-summary's skill body)
  • Releases section: last N releases (default 5, --limit override) — tag, name, published date — rendered as a markdown table; graceful "no releases" handling (skip/placeholder, like gh-summary)
  • Diff section: files changed, total insertions/deletions, and per-top-level-area breakdown for latest-tag...HEAD, via the compare API
  • Change summary (LLM step): a ### Changes since <tag> prose section grouping the diff by feature/area, written from the script's stats + commit subjects; documented as the only token-spending step
  • --repo OWNER/REPO override and cwd auto-detection via _gh_common.get_current_repo(), consistent with sibling scripts
  • Edge cases handled: zero releases (no tag to diff against — surface a clear message), no commits since the last release (empty diff → explicit "up to date" line), and gh non-zero exit (surface stderr, exit non-zero)
  • Unit tests in scripts/tests/test_gh_release_status.py covering the rendering/grouping logic against fixture compare payloads (no live network), consistent with the existing script tests
  • ruff check scripts/ clean and pytest green (note the new test count)
  • If _render_recent_releases is extracted to _gh_common, gh-summary is updated to use the shared version and its tests still pass
  • Docs: README.md skills table updated to list gh-release-status
  • Marketplace: after merge, bump the plugin version and update the glitchwerks/claude-plugins marketplace SHA pin so installers receive the new skill (tracked as the release step, not necessarily this PR)

Technical Notes

  • Reference implementation: scripts/gh-summary.py is the closest template — two-step hybrid shape, _gh_common usage, --repo handling, markdown table rendering, and the _render_recent_releases helper this skill should reuse.
  • Compare API shape: repos/{owner}/{repo}/compare/{base}...{head} returns files[] (each with filename, additions, deletions, status), commits[] (with commit.message), and top-level ahead_by/behind_by/total_commits. Group files[] by first path segment for the area breakdown. Resolve the latest tag from gh release list --limit 1 (or the releases list already fetched) and the default branch from gh api repos/{owner}/{repo} --jq .default_branch.
  • No local clone: deliberately use the compare API rather than git diff, so the skill works from any cwd and matches the repo-agnostic, API-driven design of the other scripts.
  • Large diffs: the compare API caps files[] at 300 entries and may paginate commits; for big releases, render totals from the top-level files/stats counts and note truncation rather than enumerating every file. The LLM step must not be handed an unbounded raw diff — feed it the grouped stats + commit subjects.
  • Windows/encoding: keep subprocess.run(..., encoding="utf-8") per the existing scripts (cp1252 default would mojibake release names / commit messages).

Out of Scope

  • Creating, editing, or publishing releases (read-only skill).
  • Diffing arbitrary ref pairs / previous-release-to-latest comparison (could be a later --from/--to enhancement; not this issue).
  • Local working-tree diffs (uncommitted changes) — the skill is API-driven and operates on pushed state only.
  • Generating or posting changelog/release notes (this summarizes; it doesn't write release artifacts).

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions