mroberts fc4a939482 Gate nested projects in bash-guard instead of passing them ungated
The build-and-test gate searched for marker files only two levels below the
repo root. This repo keeps its python projects at
plugins/<name>/skills/<skill>/, four levels down, so every push reported "no
recognized project layout" and pushed without running a single test. A gate
that announces it did nothing is worse than no gate, because the announcement
scrolls past and the push still succeeds.

Walk to depth 4, and resolve python tooling properly. A bare `ruff` or
`pytest` is usually absent from PATH, and run() treats ENOENT as a pass, so an
unresolved tool would have skipped the check just as silently. Resolution now
tries the project's own .venv, then uv (which needs a [project] table that
audit-terraform does not have), then the interpreter's -m form.

A tool that is genuinely not installed is reported as an advisory note rather
than blocking. Its absence is a gap in coverage, not a defect in the change
being pushed. Silence is the one outcome that is never acceptable.

Verified by injecting a failing test into each skill and confirming the guard
blocks: audit-code resolves through its .venv, audit-terraform through
python -m pytest. The new regression tests fail against the old depth-2 walk
and pass against this one.

Tests: 8 passing (bash-guard), 197 (audit-code), 106 (audit-terraform).
2026-07-21 11:49:48 -05:00

mroberts — Claude Code plugin marketplace

Personal marketplace hosting multiple Claude Code plugins.

Install

claude plugin marketplace add ssh://[email protected]/mroberts/claude-plugin.git
claude plugin install guards@mroberts

Layout

.claude-plugin/marketplace.json   # index — every plugin must be listed here
plugins/
  guards/
    .claude-plugin/plugin.json
    hooks/hooks.json
    hooks/bash-guard.mjs

Adding a plugin

  1. mkdir -p plugins/<name>/.claude-plugin
  2. Write plugins/<name>/.claude-plugin/plugin.json with name, version, description.
  3. Add components: hooks/hooks.json, commands/, agents/, skills/ as needed.
  4. Append an entry to plugins[] in .claude-plugin/marketplace.json:
{ "name": "<name>", "source": "./plugins/<name>", "description": "...", "category": "productivity" }

A plugin absent from plugins[] is not installable, regardless of its directory.

  1. Push, then claude plugin marketplace update mroberts.

Plugins

Plugin Purpose
guards Enforces the hard constraints in ~/.claude/CLAUDE.md — jj-only VCS, no Claude attribution, build+test gate before push/tag, secret scrubbing on writes.

Note on guards

hooks/bash-guard.mjs is referenced via ${CLAUDE_PLUGIN_ROOT} and travels with the plugin. shush is referenced by absolute path (/home/mroberts/.local/bin/shush) because it is a separately installed binary, not a repo file — that path is machine-specific and will need changing on another host.

S
Description
My personal claude plugins
Readme
396 KiB
Languages
Python 91.6%
JavaScript 5.6%
Shell 2.8%