mroberts d3258b224a Route isolated checkouts to jj workspaces
bash-guard mapped 20 mutating git verbs to their jj equivalents but not
`worktree`, so `git worktree add` passed the hook untouched. Claude Code's
built-in EnterWorktree/ExitWorktree tools were a second hole: they create a
git worktree directly, never going through Bash, so the guard never saw them.

A git worktree in a jj repo is not a jj workspace. jj does not manage it, it
never appears in `jj workspace list`, and none of jj's workspace bookkeeping
applies to it -- the isolated checkout ends up outside the VCS that owns the
repo.

Add the `worktree` entry to the git->jj map and a PreToolUse matcher on
EnterWorktree|ExitWorktree that exits 2 with the jj workspace commands on
stderr. The tool matcher replaces a `permissions.deny` entry in user
settings.json: it travels with the plugin and names the replacement command
instead of failing silently.

Read-only `git worktree list` is blocked along with the rest of the verb.
It cannot see jj workspaces, so its empty output reads as "no isolated
checkouts exist" when several do -- worse than a denial.

Verified by running the guard against `git worktree add ../feature` over
socket stdin and confirming both the denial and that the reason names
`jj workspace add`. The new checks fail against the 1.1.1 map.

Tests: 12 passing (bash-guard).
2026-07-28 13:07:00 -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%