Skip to content

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 25 Jul 17:01
· 33 commits to main since this release
856f53e

shuck is one portable binary again — and it now tells you when your PR breaks, instead of waiting to be asked.

The headline

shuck monitor is a local background daemon. Point it at a working tree and it follows that tree: reads the branch out of .git/HEAD (linked worktrees included), finds the open PR for it, and re-checks on a cadence that tightens to 12s while a run is in flight and relaxes to 90s once everything is terminal. Switch branches or worktrees and it retargets itself — you never tell it a PR number.

shuck monitor          # what it is watching, and where those PRs stand
shuck monitor watch    # follow this working tree (starts the daemon if needed)
shuck monitor events   # hand over what has happened since you last looked

In Claude Code you run none of that. The plugin's hooks register the session's working tree on start, deliver new events into the conversation on each prompt, poke the monitor after a git push, and — on Stop — hand over anything still asking to be dealt with rather than let a turn end on a red build. A ci.failed event carries the failing job's log inline (whole under 8 KiB, distilled failing steps above that) plus the on-disk path to the rest.

Everything is local: no webhook, no server, no credential beyond the GITHUB_TOKEN the CLI already used.

⚠️ Breaking changes

The self-hosted v2 backend is gone. The gateway, ingest, worker and portal services, the Terraform module, the Helm chart, the shuck-channel plugin, and the four ghcr.io/justanotherspy/shuck-{ingest,worker,gateway,portal} images are all removed. If you deployed any of it, it is no longer built or published — the monitor replaces it with a daemon on your own machine.

The MCP server is gone. Every tool it exposed was a thin wrapper over a subcommand that already existed. Remove the registration:

claude mcp remove --scope user shuck

Each removed tool has a direct CLI equivalent — inspect_logsshuck logs, monitor_eventsshuck monitor events, check_pinsshuck pins.

Three commands are gone: shuck compliance, shuck dependabot, shuck image. They answered a quarterly question about a repository rather than "what is wrong with this branch". Running any of them now prints what replaced it instead of a confusing parse error. Dependabot alerts are unaffected — shuck security still reports them.

The command surface

Command
shuck monitor (m) the background monitor: CI, reviews and pin drift as they happen
shuck logs (l) failing CI step logs for a PR or a single run
shuck reviews (r) a PR's reviews and review-comment threads
shuck / shuck all CI + reviews + security in one report
shuck security (s) code scanning, secret scanning, Dependabot alerts
shuck pins (p) workflow actions that are unpinned or stale
shuck action (a) resolve one Action to its latest tag + SHA

Plus setup / version / upgrade.

Also new

shuck pins — finds uses: references that are not SHA-pinned, or whose # v4.2.2 comment names a superseded release, each with the corrected line to paste. Workflow YAML is walked as yaml.Node, so line numbers and trailing comments are exact.

A standing portability budget. CI fails the build if the binary's import graph ever picks up a cloud SDK, a serverless runtime, or a server framework. Dependencies are down from 35 modules to 3 direct + 22 indirect.

Fixes

Nine production defects, every one of which had passing tests over it. Each was proved by applying a mutation that reinstates the bug and observing a real test failure:

  • Reviews sharing a watermark second were lost forever. GitHub stamps submitted_at to the whole second and filters strictly-after, so a second reviewer landing in the same second was excluded from every later poll.
  • First-sighting watermarks came from the daemon's clock, then were compared against GitHub-stamped times — a daemon a second fast swallowed every review inside the skew.
  • The CI-failure dedupe evicted the wrong end, trimming by text order over "<id>/<attempt>" keys, so a failure could be reported into a session twice.
  • shuck monitor events --wait 30m stopped at ten minutes and said nothing new — indistinguishable from a genuinely quiet wait.
  • The monitor never reclaimed its own disk. Nothing swept the cache from the daemon, so a machine that only ran shuck monitor accumulated job logs forever.
  • pins.json was rewritten once per watched tree per second, for the life of the daemon.
  • shuck monitor status --json answered in prose when no daemon was running.
  • The Stop hook could hold a turn open for a stale action pin or a review that was an approval.
  • shuck upgrade left the old daemon running, so a new binary's clients talked to the previous version's daemon. It now stops it; the next session starts a fresh one.

Upgrading

shuck upgrade                                    # in-place, checksum-verified
brew upgrade --cask justanotherspy/tap/shuck     # Homebrew

The Claude Code plugin requires v1.0.0 or newer for the monitor hooks; on anything older it says so at session start rather than failing quietly.

Dependency and tooling updates since v0.4.3
  • fix(deps): bump toolchain to go1.26.5 and migrate go-github v88 → v89 (#180)
  • fix(deps): update all non-major dependencies (#188, #173, #157, #155, #150, #140, #137)
  • fix(deps): tidy go.sum to unblock the CI tidy check (#192)
  • fix(deps): bump semgrep pinned deps to clear security alerts (#131)
  • fix(release): cap binary extraction to bound decompression bombs (#132)
  • chore(deps): update actions/setup-node to v7 (#183), actions/setup-python to v7 (#191), actions/setup-go to v7 (#184), actions/checkout to v7 (#117)
  • chore(deps): update github/codeql-action to v4.37.3 (#195)
  • chore(deps): update release-drafter/release-drafter to v7.5.0 (#136)
  • chore(deps): update goreleaser/goreleaser-action to v7.2.3 (#149)
  • chore(deps): update docker/build-push-action to v7.3.0 (#154)
  • chore(deps): update dependency @anthropic-ai/claude-code (#194, #169, #168, #147, #144, #142)
  • chore(deps): rolling cgr.dev/chainguard/go and chainguard/static digest bumps (#203, #199, #196, #189, #181, #175, #177, #172, #156, #153, #152, #151, #148, #146, #145, #143, #141, #139, #138, #135, #133)
  • chore(deps): lock file maintenance (#190, #174)
  • chore: migrate release-drafter config off deprecated label fields (#134)