From ce67659b751c8ff02afdb21dc14b9b867d5badc8 Mon Sep 17 00:00:00 2001 From: Chris Pezza Date: Sat, 19 Sep 2026 02:03:35 -0400 Subject: [PATCH 1/5] refactor(code-tools): collapse the three format-on-edit hooks into one dispatcher astro-tools, go-tools and rust-tools each registered a PostToolUse Edit|Write hook, so every edit in every repo spawned three processes, two or three of which were silent no-ops. code-tools now ships a single format-file.sh that routes by extension to Biome (still gated on a biome.json), goimports/gofmt, templ fmt or rustfmt (edition-detected). Per-route behaviour is unchanged. The stack plugins no longer format on their own; code-tools must be installed. Co-Authored-By: Claude Fable 5.1 --- plugins/astro-tools/hooks/format-file.sh | 44 ------------ plugins/astro-tools/hooks/hooks.json | 15 ---- plugins/code-tools/hooks/format-file.sh | 91 ++++++++++++++++++++++++ plugins/code-tools/hooks/hooks.json | 11 +++ plugins/go-tools/hooks/format-file.sh | 34 --------- plugins/go-tools/hooks/hooks.json | 15 ---- plugins/rust-tools/hooks/format-file.sh | 47 ------------ plugins/rust-tools/hooks/hooks.json | 15 ---- 8 files changed, 102 insertions(+), 170 deletions(-) delete mode 100755 plugins/astro-tools/hooks/format-file.sh delete mode 100644 plugins/astro-tools/hooks/hooks.json create mode 100755 plugins/code-tools/hooks/format-file.sh delete mode 100755 plugins/go-tools/hooks/format-file.sh delete mode 100644 plugins/go-tools/hooks/hooks.json delete mode 100755 plugins/rust-tools/hooks/format-file.sh delete mode 100644 plugins/rust-tools/hooks/hooks.json diff --git a/plugins/astro-tools/hooks/format-file.sh b/plugins/astro-tools/hooks/format-file.sh deleted file mode 100755 index 42e4174..0000000 --- a/plugins/astro-tools/hooks/format-file.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# PostToolUse formatter: after Claude edits or writes a file, run Biome on -# just that file so the diff never fails the project's format gate. Gated on -# a biome.json at or above the file (stopping at the repo root), so this is -# a silent no-op in projects that don't use Biome. Never fails the turn. -set -uo pipefail - -payload=$(cat) - -if command -v jq >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | jq -r '.tool_input.file_path // empty' 2>/dev/null) -elif command -v python3 >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | python3 -c 'import json,sys -print(json.load(sys.stdin).get("tool_input",{}).get("file_path","") or "")' 2>/dev/null) -else - exit 0 -fi -[ -n "$file" ] && [ -f "$file" ] || exit 0 - -case "$file" in - *.ts|*.tsx|*.js|*.jsx|*.mjs|*.cjs|*.json|*.jsonc|*.css|*.astro) ;; - *) exit 0 ;; -esac - -# Walk up to the nearest biome config, stopping at the repo root. -dir=$(cd "$(dirname "$file")" && pwd) -root="" -while [ -n "$dir" ] && [ "$dir" != "/" ]; do - if [ -f "$dir/biome.json" ] || [ -f "$dir/biome.jsonc" ]; then - root="$dir" - break - fi - [ -d "$dir/.git" ] && break - dir=$(dirname "$dir") -done -[ -n "$root" ] || exit 0 - -cd "$root" || exit 0 -if [ -x node_modules/.bin/biome ]; then - node_modules/.bin/biome format --write "$file" >/dev/null 2>&1 || true -elif command -v biome >/dev/null 2>&1; then - biome format --write "$file" >/dev/null 2>&1 || true -fi -exit 0 diff --git a/plugins/astro-tools/hooks/hooks.json b/plugins/astro-tools/hooks/hooks.json deleted file mode 100644 index c594b49..0000000 --- a/plugins/astro-tools/hooks/hooks.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Edit|Write", - "hooks": [ - { - "type": "command", - "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/format-file.sh" - } - ] - } - ] - } -} diff --git a/plugins/code-tools/hooks/format-file.sh b/plugins/code-tools/hooks/format-file.sh new file mode 100755 index 0000000..3e08a3a --- /dev/null +++ b/plugins/code-tools/hooks/format-file.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# PostToolUse formatter dispatcher: after Claude edits or writes a file, format +# just that file with the stack's own formatter so the diff never fails the +# project's format gate. One process per edit, routed by extension: +# ts/tsx/js/jsx/mjs/cjs/json/jsonc/css/astro -> Biome, gated on a biome.json +# at or above the file (stopping at the repo root) +# go -> goimports, else gofmt; templ -> templ fmt +# rs -> rustfmt, edition from the nearest Cargo.toml (default 2021) +# Replaces the per-stack format-file.sh hooks that astro-tools, go-tools and +# rust-tools each shipped. Silent no-op for any other extension or when the +# formatter is not installed. Never fails the turn. +set -uo pipefail + +payload=$(cat) + +if command -v jq >/dev/null 2>&1; then + file=$(printf '%s' "$payload" | jq -r '.tool_input.file_path // empty' 2>/dev/null) +elif command -v python3 >/dev/null 2>&1; then + file=$(printf '%s' "$payload" | python3 -c 'import json,sys +print(json.load(sys.stdin).get("tool_input",{}).get("file_path","") or "")' 2>/dev/null) +else + exit 0 +fi +[ -n "$file" ] && [ -f "$file" ] || exit 0 + +format_biome() { + # Walk up to the nearest biome config, stopping at the repo root. + local dir root="" + dir=$(cd "$(dirname "$file")" && pwd) + while [ -n "$dir" ] && [ "$dir" != "/" ]; do + if [ -f "$dir/biome.json" ] || [ -f "$dir/biome.jsonc" ]; then + root="$dir" + break + fi + [ -d "$dir/.git" ] && break + dir=$(dirname "$dir") + done + [ -n "$root" ] || return 0 + + cd "$root" || return 0 + if [ -x node_modules/.bin/biome ]; then + node_modules/.bin/biome format --write "$file" >/dev/null 2>&1 || true + elif command -v biome >/dev/null 2>&1; then + biome format --write "$file" >/dev/null 2>&1 || true + fi +} + +format_rust() { + command -v rustfmt >/dev/null 2>&1 || return 0 + # Nearest edition: a crate's own `edition = "20xx"`, else the workspace's + # [workspace.package] edition further up. Stop at the repo root. + local dir edition="" e + dir=$(cd "$(dirname "$file")" && pwd) + while [ -n "$dir" ] && [ "$dir" != "/" ]; do + if [ -f "$dir/Cargo.toml" ]; then + e=$(grep -m1 -oE '^edition *= *"[0-9]{4}"' "$dir/Cargo.toml" 2>/dev/null | grep -oE '[0-9]{4}') + if [ -z "$e" ]; then + e=$(awk '/^\[workspace\.package\]/{f=1;next} /^\[/{f=0} f && /^edition *=/' "$dir/Cargo.toml" 2>/dev/null | grep -m1 -oE '[0-9]{4}') + fi + if [ -n "$e" ]; then + edition="$e" + break + fi + fi + [ -d "$dir/.git" ] && break + dir=$(dirname "$dir") + done + rustfmt --edition "${edition:-2021}" "$file" >/dev/null 2>&1 || true +} + +case "$file" in + *.ts|*.tsx|*.js|*.jsx|*.mjs|*.cjs|*.json|*.jsonc|*.css|*.astro) + format_biome + ;; + *.go) + if command -v goimports >/dev/null 2>&1; then + goimports -w "$file" >/dev/null 2>&1 || true + elif command -v gofmt >/dev/null 2>&1; then + gofmt -w "$file" >/dev/null 2>&1 || true + fi + ;; + *.templ) + if command -v templ >/dev/null 2>&1; then + templ fmt "$file" >/dev/null 2>&1 || true + fi + ;; + *.rs) + format_rust + ;; +esac +exit 0 diff --git a/plugins/code-tools/hooks/hooks.json b/plugins/code-tools/hooks/hooks.json index f51c286..d840d09 100644 --- a/plugins/code-tools/hooks/hooks.json +++ b/plugins/code-tools/hooks/hooks.json @@ -10,6 +10,17 @@ } ] } + ], + "PostToolUse": [ + { + "matcher": "Edit|Write", + "hooks": [ + { + "type": "command", + "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/format-file.sh" + } + ] + } ] } } diff --git a/plugins/go-tools/hooks/format-file.sh b/plugins/go-tools/hooks/format-file.sh deleted file mode 100755 index 303ad6a..0000000 --- a/plugins/go-tools/hooks/format-file.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -# PostToolUse formatter: after Claude edits or writes a .go or .templ file, -# format just that file (goimports > gofmt for Go, templ fmt for templates) -# so the diff never fails the project's fmt:check gate. Silent no-op when no -# formatter is installed. Never fails the turn. -set -uo pipefail - -payload=$(cat) - -if command -v jq >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | jq -r '.tool_input.file_path // empty' 2>/dev/null) -elif command -v python3 >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | python3 -c 'import json,sys -print(json.load(sys.stdin).get("tool_input",{}).get("file_path","") or "")' 2>/dev/null) -else - exit 0 -fi -[ -n "$file" ] && [ -f "$file" ] || exit 0 - -case "$file" in - *.go) - if command -v goimports >/dev/null 2>&1; then - goimports -w "$file" >/dev/null 2>&1 || true - elif command -v gofmt >/dev/null 2>&1; then - gofmt -w "$file" >/dev/null 2>&1 || true - fi - ;; - *.templ) - if command -v templ >/dev/null 2>&1; then - templ fmt "$file" >/dev/null 2>&1 || true - fi - ;; -esac -exit 0 diff --git a/plugins/go-tools/hooks/hooks.json b/plugins/go-tools/hooks/hooks.json deleted file mode 100644 index c594b49..0000000 --- a/plugins/go-tools/hooks/hooks.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Edit|Write", - "hooks": [ - { - "type": "command", - "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/format-file.sh" - } - ] - } - ] - } -} diff --git a/plugins/rust-tools/hooks/format-file.sh b/plugins/rust-tools/hooks/format-file.sh deleted file mode 100755 index d59d1b8..0000000 --- a/plugins/rust-tools/hooks/format-file.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -# PostToolUse formatter: after Claude edits or writes a .rs file, run rustfmt -# on just that file so the diff never fails the repo's `cargo fmt --check` -# gate. Edition is detected from the nearest Cargo.toml walking up (including -# [workspace.package] edition), defaulting to 2021. Silent no-op when rustfmt -# is not installed. Never fails the turn. -set -uo pipefail - -payload=$(cat) - -if command -v jq >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | jq -r '.tool_input.file_path // empty' 2>/dev/null) -elif command -v python3 >/dev/null 2>&1; then - file=$(printf '%s' "$payload" | python3 -c 'import json,sys -print(json.load(sys.stdin).get("tool_input",{}).get("file_path","") or "")' 2>/dev/null) -else - exit 0 -fi -[ -n "$file" ] && [ -f "$file" ] || exit 0 - -case "$file" in - *.rs) ;; - *) exit 0 ;; -esac -command -v rustfmt >/dev/null 2>&1 || exit 0 - -# Nearest edition: a crate's own `edition = "20xx"`, else the workspace's -# [workspace.package] edition further up. Stop at the repo root. -dir=$(cd "$(dirname "$file")" && pwd) -edition="" -while [ -n "$dir" ] && [ "$dir" != "/" ]; do - if [ -f "$dir/Cargo.toml" ]; then - e=$(grep -m1 -oE '^edition *= *"[0-9]{4}"' "$dir/Cargo.toml" 2>/dev/null | grep -oE '[0-9]{4}') - if [ -z "$e" ]; then - e=$(awk '/^\[workspace\.package\]/{f=1;next} /^\[/{f=0} f && /^edition *=/' "$dir/Cargo.toml" 2>/dev/null | grep -m1 -oE '[0-9]{4}') - fi - if [ -n "$e" ]; then - edition="$e" - break - fi - fi - [ -d "$dir/.git" ] && break - dir=$(dirname "$dir") -done - -rustfmt --edition "${edition:-2021}" "$file" >/dev/null 2>&1 || true -exit 0 diff --git a/plugins/rust-tools/hooks/hooks.json b/plugins/rust-tools/hooks/hooks.json deleted file mode 100644 index c594b49..0000000 --- a/plugins/rust-tools/hooks/hooks.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Edit|Write", - "hooks": [ - { - "type": "command", - "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/format-file.sh" - } - ] - } - ] - } -} From 329c8c0f61e2ddcb574d7ccfb3e5f27b1a3ddf5e Mon Sep 17 00:00:00 2001 From: Chris Pezza Date: Sat, 19 Sep 2026 02:03:35 -0400 Subject: [PATCH 2/5] feat(astro-tools): drop the per-plugin Biome hook in favour of the code-tools dispatcher; v0.6.0 - hooks/format-file.sh and hooks/hooks.json removed; the Biome route now lives in clownware-code-tools' single format-file.sh dispatcher - description, marketplace entry and README synced Co-Authored-By: Claude Fable 5.1 --- .claude-plugin/marketplace.json | 2 +- README.md | 6 ++---- plugins/astro-tools/.claude-plugin/plugin.json | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a3c8e1d..c30bf78 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -21,7 +21,7 @@ { "name": "clownware-astro-tools", "source": "./plugins/astro-tools", - "description": "Astro + Preact stack skills \u2014 component scaffolding, template-aware PR descriptions, and performance-budget gate checks (/perf-budget-check) \u2014 following astro-performance-starter conventions with fallbacks for other Astro projects. Plus a format-on-edit hook that runs Biome on every file Claude edits in Biome-configured projects." + "description": "Astro + Preact stack skills \u2014 component scaffolding, template-aware PR descriptions, and performance-budget gate checks (/perf-budget-check) \u2014 following astro-performance-starter conventions with fallbacks for other Astro projects. Formatting on edit moved to the clownware-code-tools dispatcher hook." }, { "name": "clownware-go-tools", diff --git a/README.md b/README.md index f7f6f81..d81f641 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A [Claude Code plugin marketplace](https://code.claude.com/docs/en/plugin-market |--------|------------|--------| | `product-dev` | AI-assisted product development framework: idea → technical spec via UX research, hypothesis, and prototype planning. | [`product-dev/plugin`](https://github.com/clownware/product-dev/tree/main/plugin) | | `clownware-code-tools` | Universal dev workflow skills — an audit suite plus authoring and debugging tools. Probes the repo it runs in; degrades gracefully. Ships a git guard hook (blocks `--no-verify`, secret-scans commits). | [`plugins/code-tools`](plugins/code-tools) | -| `clownware-astro-tools` | Astro + Preact stack skills following astro-performance-starter conventions. Ships a Biome format-on-edit hook. | [`plugins/astro-tools`](plugins/astro-tools) | +| `clownware-astro-tools` | Astro + Preact stack skills following astro-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/astro-tools`](plugins/astro-tools) | | `clownware-go-tools` | Go + templ + sqlc stack skills following go-performance-starter conventions. Ships a goimports/templ format-on-edit hook. | [`plugins/go-tools`](plugins/go-tools) | | `clownware-rust-tools` | Rust stack skills following the tunes_protocol/gittunes workspace conventions. Ships a rustfmt format-on-edit hook. | [`plugins/rust-tools`](plugins/rust-tools) | | `pezza-design-system` | The Pezza brand design system as a skill: guidelines, HSL-channel tokens, animatable brand SVGs, prose layer, motion system, React primitives, two UI kits. | [`plugins/pezza-design-system`](plugins/pezza-design-system) | @@ -50,9 +50,7 @@ before any commit (gitleaks when installed, high-confidence token patterns other | `/astro-pr-description` | PR descriptions for astro-performance-starter template repos | | `/perf-budget-check` | Runs the starter's own budget gates (sizes, overrides, images) and interprets the verdicts | -Hook: a `PostToolUse` formatter — after Claude edits or writes a file, runs Biome on -just that file (gated on a `biome.json` at or above it), so diffs never fail the -project's format gate. +Hook: none. Formatting on edit is handled by the `clownware-code-tools` dispatcher hook; install that plugin alongside this one. **clownware-go-tools** diff --git a/plugins/astro-tools/.claude-plugin/plugin.json b/plugins/astro-tools/.claude-plugin/plugin.json index bef5edc..dd9a224 100644 --- a/plugins/astro-tools/.claude-plugin/plugin.json +++ b/plugins/astro-tools/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "clownware-astro-tools", - "description": "Astro + Preact stack skills: component scaffolding, template-aware PR descriptions, and performance-budget gate checks, following astro-performance-starter conventions with fallbacks for other Astro projects. Also ships a format-on-edit hook that runs Biome on every file Claude edits in Biome-configured projects.", - "version": "0.5.2", + "description": "Astro + Preact stack skills: component scaffolding, template-aware PR descriptions, and performance-budget gate checks, following astro-performance-starter conventions with fallbacks for other Astro projects. Formatting on edit moved to the clownware-code-tools dispatcher hook.", + "version": "0.6.0", "license": "Apache-2.0", "author": { "name": "clownware" From 881fa8233137f31d6539bc16ad11e12470dd3aa9 Mon Sep 17 00:00:00 2001 From: Chris Pezza Date: Sat, 19 Sep 2026 02:04:00 -0400 Subject: [PATCH 3/5] feat(go-tools): drop the per-plugin goimports/templ hook in favour of the code-tools dispatcher; v0.4.0 - hooks/format-file.sh and hooks/hooks.json removed; the .go and .templ routes now live in clownware-code-tools' single format-file.sh dispatcher - description, marketplace entry and README synced Co-Authored-By: Claude Fable 5.1 --- .claude-plugin/marketplace.json | 2 +- README.md | 5 ++--- plugins/go-tools/.claude-plugin/plugin.json | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c30bf78..8b78ca8 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -26,7 +26,7 @@ { "name": "clownware-go-tools", "source": "./plugins/go-tools", - "description": "Go + templ + sqlc stack skills \u2014 templ component scaffolding, table-driven test scaffolding, sqlc query scaffolding (/sqlc-query-scaffold), performance-budget gate checks (/perf-budget-check), and task-ci-aware PR descriptions \u2014 following go-performance-starter conventions with fallbacks for other Go projects. Plus a format-on-edit hook that runs goimports/gofmt and templ fmt on files Claude edits." + "description": "Go + templ + sqlc stack skills \u2014 templ component scaffolding, table-driven test scaffolding, sqlc query scaffolding (/sqlc-query-scaffold), performance-budget gate checks (/perf-budget-check), and task-ci-aware PR descriptions \u2014 following go-performance-starter conventions with fallbacks for other Go projects. Formatting on edit moved to the clownware-code-tools dispatcher hook." }, { "name": "clownware-rust-tools", diff --git a/README.md b/README.md index d81f641..1075d58 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A [Claude Code plugin marketplace](https://code.claude.com/docs/en/plugin-market | `product-dev` | AI-assisted product development framework: idea → technical spec via UX research, hypothesis, and prototype planning. | [`product-dev/plugin`](https://github.com/clownware/product-dev/tree/main/plugin) | | `clownware-code-tools` | Universal dev workflow skills — an audit suite plus authoring and debugging tools. Probes the repo it runs in; degrades gracefully. Ships a git guard hook (blocks `--no-verify`, secret-scans commits). | [`plugins/code-tools`](plugins/code-tools) | | `clownware-astro-tools` | Astro + Preact stack skills following astro-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/astro-tools`](plugins/astro-tools) | -| `clownware-go-tools` | Go + templ + sqlc stack skills following go-performance-starter conventions. Ships a goimports/templ format-on-edit hook. | [`plugins/go-tools`](plugins/go-tools) | +| `clownware-go-tools` | Go + templ + sqlc stack skills following go-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/go-tools`](plugins/go-tools) | | `clownware-rust-tools` | Rust stack skills following the tunes_protocol/gittunes workspace conventions. Ships a rustfmt format-on-edit hook. | [`plugins/rust-tools`](plugins/rust-tools) | | `pezza-design-system` | The Pezza brand design system as a skill: guidelines, HSL-channel tokens, animatable brand SVGs, prose layer, motion system, React primitives, two UI kits. | [`plugins/pezza-design-system`](plugins/pezza-design-system) | @@ -62,8 +62,7 @@ Hook: none. Formatting on edit is handled by the `clownware-code-tools` dispatch | `/perf-budget-check` | Runs the starter's `task test:performance` gates and interprets the verdicts | | `/go-pr-description` | PR descriptions aware of the `task ci` quality gate and the ADR constitution | -Hook: a `PostToolUse` formatter — after Claude edits or writes a `.go` or `.templ` -file, runs goimports/gofmt or `templ fmt` on just that file. +Hook: none. Formatting on edit is handled by the `clownware-code-tools` dispatcher hook; install that plugin alongside this one. **clownware-rust-tools** diff --git a/plugins/go-tools/.claude-plugin/plugin.json b/plugins/go-tools/.claude-plugin/plugin.json index ad94e2c..de7207a 100644 --- a/plugins/go-tools/.claude-plugin/plugin.json +++ b/plugins/go-tools/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "clownware-go-tools", - "description": "Go + templ + sqlc stack skills: templ component scaffolding, table-driven test scaffolding, sqlc query scaffolding, performance-budget gate checks, and task-ci-aware PR descriptions, following go-performance-starter conventions with fallbacks for other Go projects. Also ships a format-on-edit hook that runs goimports/gofmt and templ fmt on files Claude edits.", - "version": "0.3.3", + "description": "Go + templ + sqlc stack skills: templ component scaffolding, table-driven test scaffolding, sqlc query scaffolding, performance-budget gate checks, and task-ci-aware PR descriptions, following go-performance-starter conventions with fallbacks for other Go projects. Formatting on edit moved to the clownware-code-tools dispatcher hook.", + "version": "0.4.0", "license": "Apache-2.0", "author": { "name": "clownware" From a1f5f126be1581292c54c0ca4c3ca51193f5c12c Mon Sep 17 00:00:00 2001 From: Chris Pezza Date: Sat, 19 Sep 2026 02:04:00 -0400 Subject: [PATCH 4/5] feat(rust-tools): drop the per-plugin rustfmt hook in favour of the code-tools dispatcher; v0.2.0 - hooks/format-file.sh and hooks/hooks.json removed; the .rs route (edition-detected) now lives in clownware-code-tools' single format-file.sh dispatcher - description, marketplace entry and README synced Co-Authored-By: Claude Fable 5.1 --- .claude-plugin/marketplace.json | 2 +- README.md | 6 ++---- plugins/rust-tools/.claude-plugin/plugin.json | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8b78ca8..70eac16 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -31,7 +31,7 @@ { "name": "clownware-rust-tools", "source": "./plugins/rust-tools", - "description": "Rust stack skills — table-driven test scaffolding and CI-aware quality-gate checks (/gate-check: cargo fmt/clippy/test/deny and special CI legs) — following the tunes_protocol and gittunes workspace conventions with fallbacks for other Rust projects. Plus a format-on-edit hook that runs rustfmt (edition-detected) on files Claude edits." + "description": "Rust stack skills — table-driven test scaffolding and CI-aware quality-gate checks (/gate-check: cargo fmt/clippy/test/deny and special CI legs) — following the tunes_protocol and gittunes workspace conventions with fallbacks for other Rust projects. Formatting on edit moved to the clownware-code-tools dispatcher hook." }, { "name": "pezza-design-system", diff --git a/README.md b/README.md index 1075d58..fdf10e7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A [Claude Code plugin marketplace](https://code.claude.com/docs/en/plugin-market | `clownware-code-tools` | Universal dev workflow skills — an audit suite plus authoring and debugging tools. Probes the repo it runs in; degrades gracefully. Ships a git guard hook (blocks `--no-verify`, secret-scans commits). | [`plugins/code-tools`](plugins/code-tools) | | `clownware-astro-tools` | Astro + Preact stack skills following astro-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/astro-tools`](plugins/astro-tools) | | `clownware-go-tools` | Go + templ + sqlc stack skills following go-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/go-tools`](plugins/go-tools) | -| `clownware-rust-tools` | Rust stack skills following the tunes_protocol/gittunes workspace conventions. Ships a rustfmt format-on-edit hook. | [`plugins/rust-tools`](plugins/rust-tools) | +| `clownware-rust-tools` | Rust stack skills following the tunes_protocol/gittunes workspace conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/rust-tools`](plugins/rust-tools) | | `pezza-design-system` | The Pezza brand design system as a skill: guidelines, HSL-channel tokens, animatable brand SVGs, prose layer, motion system, React primitives, two UI kits. | [`plugins/pezza-design-system`](plugins/pezza-design-system) | ## Skills at a glance @@ -71,9 +71,7 @@ Hook: none. Formatting on edit is handled by the `clownware-code-tools` dispatch | `/test-scaffold` | Table-driven `#[cfg(test)]` stubs (`#[ignore]`d so the suite stays green), vector-aware for protocol crates | | `/gate-check` | Runs the repo's own gates exactly as CI defines them (fmt/clippy/test/deny + special legs) and interprets each verdict | -Hook: a `PostToolUse` formatter — after Claude edits or writes a `.rs` file, runs -rustfmt on just that file, edition-detected from the nearest Cargo.toml (including -`[workspace.package]`). +Hook: none. Formatting on edit is handled by the `clownware-code-tools` dispatcher hook; install that plugin alongside this one. **pezza-design-system** diff --git a/plugins/rust-tools/.claude-plugin/plugin.json b/plugins/rust-tools/.claude-plugin/plugin.json index 24f74df..b07f245 100644 --- a/plugins/rust-tools/.claude-plugin/plugin.json +++ b/plugins/rust-tools/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "clownware-rust-tools", - "description": "Rust stack skills: table-driven test scaffolding and CI-aware quality-gate checks (cargo fmt/clippy/test/deny, fuzz targets), following the tunes_protocol and gittunes workspace conventions with fallbacks for other Rust projects. Also ships a format-on-edit hook that runs rustfmt (edition-detected from the nearest Cargo.toml) on files Claude edits.", - "version": "0.1.2", + "description": "Rust stack skills: table-driven test scaffolding and CI-aware quality-gate checks (cargo fmt/clippy/test/deny, fuzz targets), following the tunes_protocol and gittunes workspace conventions with fallbacks for other Rust projects. Formatting on edit moved to the clownware-code-tools dispatcher hook.", + "version": "0.2.0", "license": "Apache-2.0", "author": { "name": "clownware" From 01d5f6ae18ba789993f5d1847aac6c8e685cc005 Mon Sep 17 00:00:00 2001 From: Chris Pezza Date: Sat, 19 Sep 2026 02:04:00 -0400 Subject: [PATCH 5/5] feat(code-tools): single format-on-edit dispatcher hook for every stack; v0.16.0 - hooks/format-file.sh added and registered as PostToolUse Edit|Write; replaces the three per-stack format hooks (three processes per edit down to one) - description, marketplace entry and README synced Co-Authored-By: Claude Fable 5.1 --- .claude-plugin/marketplace.json | 2 +- README.md | 8 +++++++- plugins/code-tools/.claude-plugin/plugin.json | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 70eac16..b566579 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -16,7 +16,7 @@ { "name": "clownware-code-tools", "source": "./plugins/code-tools", - "description": "Universal dev workflow skills \u2014 architecture/deployment-readiness auditing (/arch-audit), security auditing (/security-audit), test-suite auditing (/test-audit), Claude Code skill auditing (/skill-audit), design-system auditing (/design-audit), accessibility auditing (/a11y-audit), dependency auditing (/deps-audit), performance auditing (/perf-audit), devops/CI-CD auditing (/devops-audit), audit-fix application (/audit-fix), plugin releasing (/plugin-release), skill validation (/skill-validate), ADR authoring, PR descriptions, root-cause debugging, test scaffolding, and GitHits OSS research conventions (githits-research) \u2014 that probe the repo they run in and degrade gracefully. Plus a git guard hook: blocks --no-verify and secret-scans staged changes before every commit." + "description": "Universal dev workflow skills \u2014 architecture/deployment-readiness auditing (/arch-audit), security auditing (/security-audit), test-suite auditing (/test-audit), Claude Code skill auditing (/skill-audit), design-system auditing (/design-audit), accessibility auditing (/a11y-audit), dependency auditing (/deps-audit), performance auditing (/perf-audit), devops/CI-CD auditing (/devops-audit), audit-fix application (/audit-fix), plugin releasing (/plugin-release), skill validation (/skill-validate), ADR authoring, PR descriptions, root-cause debugging, test scaffolding, and GitHits OSS research conventions (githits-research) \u2014 that probe the repo they run in and degrade gracefully. Plus a git guard hook: blocks --no-verify and secret-scans staged changes before every commit. And a format-on-edit dispatcher hook: Biome (biome.json-gated), goimports/gofmt, templ fmt or rustfmt, routed by extension." }, { "name": "clownware-astro-tools", diff --git a/README.md b/README.md index fdf10e7..ff525ad 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A [Claude Code plugin marketplace](https://code.claude.com/docs/en/plugin-market | Plugin | What it is | Source | |--------|------------|--------| | `product-dev` | AI-assisted product development framework: idea → technical spec via UX research, hypothesis, and prototype planning. | [`product-dev/plugin`](https://github.com/clownware/product-dev/tree/main/plugin) | -| `clownware-code-tools` | Universal dev workflow skills — an audit suite plus authoring and debugging tools. Probes the repo it runs in; degrades gracefully. Ships a git guard hook (blocks `--no-verify`, secret-scans commits). | [`plugins/code-tools`](plugins/code-tools) | +| `clownware-code-tools` | Universal dev workflow skills — an audit suite plus authoring and debugging tools. Probes the repo it runs in; degrades gracefully. Ships a git guard hook (blocks `--no-verify`, secret-scans commits) and the format-on-edit dispatcher for every stack. | [`plugins/code-tools`](plugins/code-tools) | | `clownware-astro-tools` | Astro + Preact stack skills following astro-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/astro-tools`](plugins/astro-tools) | | `clownware-go-tools` | Go + templ + sqlc stack skills following go-performance-starter conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/go-tools`](plugins/go-tools) | | `clownware-rust-tools` | Rust stack skills following the tunes_protocol/gittunes workspace conventions. Format-on-edit lives in `clownware-code-tools`. | [`plugins/rust-tools`](plugins/rust-tools) | @@ -42,6 +42,12 @@ Hook: a `PreToolUse` git guard on every Bash call — denies `git commit`/`git p --no-verify` (the repo's hooks are the quality gate), and secret-scans staged changes before any commit (gitleaks when installed, high-confidence token patterns otherwise). +Hook: a `PostToolUse` format dispatcher — after Claude edits or writes a file, one +process routes by extension: Biome for JS/TS/JSON/CSS/Astro (gated on a `biome.json` +at or above the file), goimports/gofmt for `.go`, `templ fmt` for `.templ`, rustfmt +for `.rs` (edition-detected from the nearest Cargo.toml). Replaces the three per-stack +hooks; silent no-op everywhere else. + **clownware-astro-tools** | Skill | What it does | diff --git a/plugins/code-tools/.claude-plugin/plugin.json b/plugins/code-tools/.claude-plugin/plugin.json index 7684817..8c35ac8 100644 --- a/plugins/code-tools/.claude-plugin/plugin.json +++ b/plugins/code-tools/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "clownware-code-tools", - "description": "Universal dev workflow skills: architecture/deployment-readiness auditing, security auditing, test-suite auditing, skill auditing, design-system auditing, accessibility auditing, dependency auditing, performance auditing, devops/CI-CD auditing, audit-fix application, plugin releasing, skill validation, ADR authoring, PR descriptions, root-cause debugging, test scaffolding, and GitHits OSS research conventions. Each skill probes the repo it runs in and degrades gracefully. Also ships a git guard hook: blocks --no-verify commits/pushes and secret-scans staged changes (gitleaks, with a pattern fallback) before every commit.", - "version": "0.15.4", + "description": "Universal dev workflow skills: architecture/deployment-readiness auditing, security auditing, test-suite auditing, skill auditing, design-system auditing, accessibility auditing, dependency auditing, performance auditing, devops/CI-CD auditing, audit-fix application, plugin releasing, skill validation, ADR authoring, PR descriptions, root-cause debugging, test scaffolding, and GitHits OSS research conventions. Each skill probes the repo it runs in and degrades gracefully. Also ships a git guard hook: blocks --no-verify commits/pushes and secret-scans staged changes (gitleaks, with a pattern fallback) before every commit. And a format-on-edit dispatcher hook: one process per edit, routed by extension to Biome (biome.json-gated), goimports/gofmt, templ fmt or rustfmt.", + "version": "0.16.0", "license": "Apache-2.0", "author": { "name": "clownware"