From c799558d17331a369d8fec63066688311a4e708b Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:04:33 -0400 Subject: [PATCH 01/15] feat: adopt the uniform setup contract across 9 formatter/CLI plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tranche 2 of wave #314 (epic #313, dim 8), cloning the battle-tested markdown-format exemplar from #342 to the collision-free shape-A plugins: actionlint 0.4.0, bash-format 0.5.0, powershell-format 0.4.0, biome-format 0.4.0, ruff-format 0.4.0, eol-normalizer 0.4.0, desktop-notification 0.4.0, firecrawl 0.3.0, playwright 0.3.0. Every setup: check reads the plugin's own hook/skill source as the single source of truth and probes what it actually requires (no hand-copied resolution paths or config lists); apply re-checks first, resolves with guidance for system tools and native toggles, names any write path in the argument-hint, states it before running, and re-verifies after every remediation. Package-manager and environment respect carried over from the exemplar's review rounds: biome-format resolves lockfile -> packageManager -> npm and routes Plug'n'Play to guidance; ruff-format installs only into a managed environment the repo already uses; firecrawl reports FIRECRAWL_API_KEY presence without ever printing it and defers to the plugin's lazy-install design; desktop-notification probes only the current OS family's channel dependencies. Also backfills the undocumented [0.3.1] CHANGELOG entries in actionlint and powershell-format (the #298 hook-utils resync, verified via git log -S). Deferred from this tranche for lane ownership: disk-hygiene (PR #286 touches its plugin.json/CHANGELOG) and guardrails (PR #305 ditto) — they join a later tranche after those PRs land. ## Related - Part of #314 - Part of #313 Co-Authored-By: Claude Fable 5 --- plugins/actionlint/.claude-plugin/plugin.json | 2 +- plugins/actionlint/CHANGELOG.md | 22 +++++ plugins/actionlint/README.md | 2 + plugins/actionlint/skills/setup/SKILL.md | 68 +++++++++++++ .../bash-format/.claude-plugin/plugin.json | 2 +- plugins/bash-format/CHANGELOG.md | 18 ++++ plugins/bash-format/README.md | 2 + plugins/bash-format/skills/setup/SKILL.md | 92 +++++++++++++++++ .../biome-format/.claude-plugin/plugin.json | 2 +- plugins/biome-format/CHANGELOG.md | 13 +++ plugins/biome-format/README.md | 2 + plugins/biome-format/skills/setup/SKILL.md | 87 ++++++++++++++++ .../.claude-plugin/plugin.json | 2 +- plugins/desktop-notification/CHANGELOG.md | 12 +++ plugins/desktop-notification/README.md | 2 + .../skills/setup/SKILL.md | 81 +++++++++++++++ .../eol-normalizer/.claude-plugin/plugin.json | 2 +- plugins/eol-normalizer/CHANGELOG.md | 13 +++ plugins/eol-normalizer/README.md | 2 + plugins/eol-normalizer/skills/setup/SKILL.md | 74 ++++++++++++++ plugins/firecrawl/.claude-plugin/plugin.json | 2 +- plugins/firecrawl/CHANGELOG.md | 12 +++ plugins/firecrawl/README.md | 2 + plugins/firecrawl/skills/setup/SKILL.md | 75 ++++++++++++++ plugins/playwright/.claude-plugin/plugin.json | 2 +- plugins/playwright/CHANGELOG.md | 13 +++ plugins/playwright/README.md | 2 + plugins/playwright/skills/setup/SKILL.md | 69 +++++++++++++ .../.claude-plugin/plugin.json | 2 +- plugins/powershell-format/CHANGELOG.md | 27 +++++ plugins/powershell-format/README.md | 2 + .../powershell-format/skills/setup/SKILL.md | 99 +++++++++++++++++++ .../ruff-format/.claude-plugin/plugin.json | 2 +- plugins/ruff-format/CHANGELOG.md | 15 +++ plugins/ruff-format/README.md | 2 + plugins/ruff-format/skills/setup/SKILL.md | 93 +++++++++++++++++ 36 files changed, 910 insertions(+), 9 deletions(-) create mode 100644 plugins/actionlint/skills/setup/SKILL.md create mode 100644 plugins/bash-format/skills/setup/SKILL.md create mode 100644 plugins/biome-format/skills/setup/SKILL.md create mode 100644 plugins/desktop-notification/skills/setup/SKILL.md create mode 100644 plugins/eol-normalizer/skills/setup/SKILL.md create mode 100644 plugins/firecrawl/skills/setup/SKILL.md create mode 100644 plugins/playwright/skills/setup/SKILL.md create mode 100644 plugins/powershell-format/skills/setup/SKILL.md create mode 100644 plugins/ruff-format/skills/setup/SKILL.md diff --git a/plugins/actionlint/.claude-plugin/plugin.json b/plugins/actionlint/.claude-plugin/plugin.json index f6d8bb2e1..ad58810e1 100644 --- a/plugins/actionlint/.claude-plugin/plugin.json +++ b/plugins/actionlint/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "actionlint", - "version": "0.3.1", + "version": "0.4.0", "description": "Lint GitHub Actions workflow files on edit via actionlint, surfacing findings as advisory context.", "author": { "name": "Melodic Software", diff --git a/plugins/actionlint/CHANGELOG.md b/plugins/actionlint/CHANGELOG.md index 19df7ab34..fbc44ff33 100644 --- a/plugins/actionlint/CHANGELOG.md +++ b/plugins/actionlint/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to the `actionlint` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **`/actionlint:setup` skill** (fleet conformance wave: a uniform check-centric + setup contract across the hook plugins). `check` (default) is read-only — it + reads the hook script as the single source of truth and probes each runtime + prerequisite (Bash, `jq`, `actionlint`), the optional auto-discovered + `.github/actionlint.yaml`, and the effective `actionlint_enabled` toggle, + reporting a PASS/FAIL/INFO table with one remediation line per FAIL. `apply` + re-runs `check` then points at the resolution for each finding. Every + prerequisite is a `PATH` binary or the native toggle, so `apply` is + guidance-only with no write path — it never installs packages and never + modifies the repository, user settings, or the plugin cache. + +## [0.3.1] + +### Changed + +- Shared `hook-utils.sh` resynced from the repository library (no behavior + change in this plugin's hook). + ## [0.3.0] ### Changed diff --git a/plugins/actionlint/README.md b/plugins/actionlint/README.md index 76a8d9164..648fdaac5 100644 --- a/plugins/actionlint/README.md +++ b/plugins/actionlint/README.md @@ -45,6 +45,8 @@ your `PATH`. /plugin install actionlint@melodic-software ``` +Then verify prerequisites with `/actionlint:setup check`. + ## Configuration actionlint auto-discovers its own `.github/actionlint.yaml` config from your diff --git a/plugins/actionlint/skills/setup/SKILL.md b/plugins/actionlint/skills/setup/SKILL.md new file mode 100644 index 000000000..b9d8dc4df --- /dev/null +++ b/plugins/actionlint/skills/setup/SKILL.md @@ -0,0 +1,68 @@ +--- +name: setup +description: "Verify the actionlint-check hook's runtime prerequisites and configuration for this repository. Use when: 'set up actionlint', 'configure actionlint', 'is actionlint working', workflow lint silently isn't happening, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — actionlint auto-discovers its +own optional config from the repository, and the only tunable is the native `userConfig` +toggle. Every prerequisite is a `PATH` binary the plugin never bundles, and the plugin never +installs system packages, so `apply` is guidance-only with **no write path** — it never +modifies the repository, user settings, or the plugin cache. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers remediation guidance. Both are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook script (`${CLAUDE_PLUGIN_ROOT}/hooks/actionlint-check.sh`) is the single source of +truth for what it requires and how it resolves things. **Read it first** — probe what it +actually does, don't recite this file. Then run each probe via Bash and report a +PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + a Bash 5.0+ builtin). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of linting. +3. **`actionlint`** — `command -v actionlint`. FAIL if absent: the hook skips workflow lint + with a visible once-per-session notice (it ships no binary of its own). +4. **actionlint config** — INFO: actionlint auto-discovers an optional + `.github/actionlint.yaml` from the repository when present. It is not required — actionlint + runs with its built-in defaults without one. Report whether one exists for the reader's + awareness; its absence is not a FAIL. +5. **Hook toggle** — report the effective `actionlint_enabled` value: + `${user_config.actionlint_enabled}` (unexpanded or empty means default `true`; any value + other than `true` disables the hook). +6. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL point at the resolution — this skill installs nothing: + +- missing `actionlint`: platform install guidance from the README Requirements section + (the [actionlint install guide](https://github.com/rhysd/actionlint/blob/main/docs/install.md)). +- missing `jq` / Bash: platform install instructions from the README Requirements section. +- toggle off: direct to `/plugin configure actionlint` or + `claude plugin install actionlint@ --config actionlint_enabled=true`; + this skill never writes user settings or `pluginConfigs`. + +After pointing at a remediation, re-run the relevant `check` probe and report its actual +result — never claim resolved on the reader's report that they installed something. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Run the linter — editing any `.github/workflows/*.yml` or `*.yaml` file exercises the hook + end-to-end. +- Write anything: not the repository, not Claude Code user settings, not `pluginConfigs`, not + the plugin cache. Every prerequisite is a `PATH` binary or the native toggle, so remediation + is guidance only. +- Download or execute tools during `check` beyond the read-only `command -v` presence probes. diff --git a/plugins/bash-format/.claude-plugin/plugin.json b/plugins/bash-format/.claude-plugin/plugin.json index 17cb133ec..17c615750 100644 --- a/plugins/bash-format/.claude-plugin/plugin.json +++ b/plugins/bash-format/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "bash-format", - "version": "0.4.1", + "version": "0.5.0", "description": "Auto-format and lint shell scripts on edit via shfmt + ShellCheck, using the consuming repo's own .editorconfig and .shellcheckrc.", "author": { "name": "Melodic Software", diff --git a/plugins/bash-format/CHANGELOG.md b/plugins/bash-format/CHANGELOG.md index b002203ea..96fc3afa4 100644 --- a/plugins/bash-format/CHANGELOG.md +++ b/plugins/bash-format/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to the `bash-format` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.5.0] + +### Added + +- **`/bash-format:setup` skill** (fleet conformance wave: a uniform check-centric + setup contract across the hook plugins). `check` (default) is read-only — it + reads the hook script as the single source of truth and probes each runtime + prerequisite (Bash, `jq`, ShellCheck for the lint pass, shfmt for the format + pass), the `.editorconfig` shell opt-in that gates formatting (mirroring the + hook's `shell_editorconfig_opt_in` logic — a section governing shell files, + not merely a present `.editorconfig`), the auto-discovered `.shellcheckrc`, and + the effective `bash_format_enabled` toggle, reporting a PASS/FAIL/INFO table + with one remediation line per FAIL. `apply` re-runs `check` then points at the + resolution for each finding. Every prerequisite is a `PATH` binary or the + native toggle, so `apply` is guidance-only with no write path — it never + installs packages and never modifies the repository (including `.editorconfig` + / `.shellcheckrc`), user settings, or the plugin cache. + ## [0.4.1] ### Changed diff --git a/plugins/bash-format/README.md b/plugins/bash-format/README.md index 22752580d..dd6d86423 100644 --- a/plugins/bash-format/README.md +++ b/plugins/bash-format/README.md @@ -59,6 +59,8 @@ formatting still run. /plugin install bash-format@melodic-software ``` +Then verify prerequisites with `/bash-format:setup check`. + ## Configuration The linting and formatting rules come from the `.shellcheckrc` and diff --git a/plugins/bash-format/skills/setup/SKILL.md b/plugins/bash-format/skills/setup/SKILL.md new file mode 100644 index 000000000..7e4468d25 --- /dev/null +++ b/plugins/bash-format/skills/setup/SKILL.md @@ -0,0 +1,92 @@ +--- +name: setup +description: "Verify the bash-format hook's runtime prerequisites and configuration for this repository. Use when: 'set up bash-format', 'configure bash-format', 'is bash-format working', shell lint or formatting silently isn't happening, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — linting rules come from the +repository's own `.shellcheckrc`, formatting from its `.editorconfig`, and the only tunable is +the native `userConfig` toggle. Every prerequisite is a `PATH` binary the plugin never +bundles, and the plugin never installs system packages, so `apply` is guidance-only with **no +write path** — it never modifies the repository, user settings, or the plugin cache. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers remediation guidance. Both are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook script (`${CLAUDE_PLUGIN_ROOT}/hooks/bash-format.sh`) is the single source of truth +for what it requires and how it resolves things. **Read it first** — probe what it actually +does, don't recite this file. The lint pass and the format pass are independent; report each +separately. Then run each probe via Bash and report a PASS/FAIL/INFO table with one +remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + a Bash 5.0+ builtin). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of running either pass. +3. **`shellcheck`** (lint pass) — `command -v shellcheck`. FAIL if absent: the lint pass + skips with a visible once-per-session notice. +4. **`shfmt`** (format pass) — `command -v shfmt`. Its FAIL/INFO status depends on the + `.editorconfig` opt-in below, because the format pass runs **only when the repo has opted + in**: + - opted in AND `shfmt` absent → FAIL: the format pass skips with a visible once-per-session + notice. + - not opted in → INFO regardless of `shfmt`: the format pass stays quiet by design (the + repo chose not to format), so a missing `shfmt` is not a defect here. +5. **`.editorconfig` shell opt-in** — mirror the hook's opt-in logic + (`shell_editorconfig_opt_in` / `section_applies_to_shell`), not merely "does an + `.editorconfig` exist". The opt-in is an EditorConfig **section that governs shell files** + — a `[*]` catch-all or a shell glob such as `[*.sh]`, `[*.bash]`, or `[*.{sh,bash}]` + (including path-prefixed forms like `[**/*.sh]`) — discovered by walking up from the file's + directory to the repo root and stopping at a `root = true` config. Path-only sections like + `[scripts/**]` do NOT count. Report as INFO: whether a governing shell section exists and + therefore whether the format pass is active. If none exists, INFO-note the consequence per + the hook's logic: shell files are left unformatted rather than rewritten to shfmt's + built-in defaults. +6. **`.shellcheckrc`** — INFO: ShellCheck auto-discovers `.shellcheckrc` by walking up from + the file's directory. Report whether one exists; its absence is not a FAIL (ShellCheck + applies its own defaults). +7. **Hook toggle** — report the effective `bash_format_enabled` value: + `${user_config.bash_format_enabled}` (unexpanded or empty means default `true`; any value + other than `true` disables the hook). +8. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL point at the resolution — this skill installs nothing: + +- missing `shellcheck`: install guidance from the README Requirements section + (the [ShellCheck install guide](https://github.com/koalaman/shellcheck#installing)); this + skill never installs system packages. +- missing `shfmt` while the repo opts in: install guidance + ([shfmt](https://github.com/mvdan/sh#shfmt)); this skill never installs system packages. +- missing `jq` / Bash: platform install instructions from the README Requirements section. +- no shell `.editorconfig` opt-in (and formatting is wanted): explain that adding a governing + shell section (`[*]`, `[*.sh]`, `[*.bash]`, or `[*.{sh,bash}]`) to an `.editorconfig` opts + the repo in — but this skill does not write it. `.editorconfig` is cross-cutting (it governs + every editor and tool in the repo), so the choice and the edit belong to the consumer. +- toggle off: direct to `/plugin configure bash-format` or + `claude plugin install bash-format@ --config bash_format_enabled=true`; + this skill never writes user settings or `pluginConfigs`. + +After pointing at a remediation, re-run the relevant `check` probe and report its actual +result — never claim resolved on the reader's report that they installed something. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Run the linter or formatter — editing any `.sh` or `.bash` file exercises the hook + end-to-end. +- Write anything: not the repository (including `.editorconfig` / `.shellcheckrc`), not Claude + Code user settings, not `pluginConfigs`, not the plugin cache. Every prerequisite is a `PATH` + binary or the native toggle, so remediation is guidance only. +- Download or execute tools during `check` beyond the read-only `command -v` presence probes. diff --git a/plugins/biome-format/.claude-plugin/plugin.json b/plugins/biome-format/.claude-plugin/plugin.json index 1263dc718..2f6f997f9 100644 --- a/plugins/biome-format/.claude-plugin/plugin.json +++ b/plugins/biome-format/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "biome-format", - "version": "0.3.1", + "version": "0.4.0", "description": "Auto-format and lint JS/TS/JSX/JSON on edit via Biome, only when a biome.json governs the repo — using the consuming repo's own Biome config.", "author": { "name": "Melodic Software", diff --git a/plugins/biome-format/CHANGELOG.md b/plugins/biome-format/CHANGELOG.md index 4a0904a20..c6f477cff 100644 --- a/plugins/biome-format/CHANGELOG.md +++ b/plugins/biome-format/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to the `biome-format` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **`/biome-format:setup` skill** (fleet conformance wave, dim 8). A uniform check-centric + setup contract: `check` (default, read-only) reads the hook as the single source of truth + and reports a PASS/FAIL/INFO table for Bash, `jq`, the Biome binary (resolved exactly as + the hook resolves it), the governing Biome config opt-in, and the `biome_format_enabled` + toggle. `apply` is idempotent and guidance-first: it re-runs `check`, points at system-tool + remediations, and the one write path — `apply install-biome` — adds `@biomejs/biome` as a + dev dependency using the repository's own package manager, re-verifying the binary probe + after the install rather than trusting its exit code. + ## [0.3.0] ### Changed diff --git a/plugins/biome-format/README.md b/plugins/biome-format/README.md index 9eeaac44d..fe88d621f 100644 --- a/plugins/biome-format/README.md +++ b/plugins/biome-format/README.md @@ -63,6 +63,8 @@ linting still run. /plugin install biome-format@melodic-software ``` +Then verify prerequisites with `/biome-format:setup check`. + ## Configuration The formatting rules come from the `biome.json` already in your repository, which diff --git a/plugins/biome-format/skills/setup/SKILL.md b/plugins/biome-format/skills/setup/SKILL.md new file mode 100644 index 000000000..f57cbcf3e --- /dev/null +++ b/plugins/biome-format/skills/setup/SKILL.md @@ -0,0 +1,87 @@ +--- +name: setup +description: "Verify the biome-format hook's runtime prerequisites and configuration for this repository. Use when: 'set up biome-format', 'configure biome-format', 'is biome-format working', formatting silently isn't happening, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply [install-biome]" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — rules come from the +repository's own Biome config, and the only tunable is the native `userConfig` toggle — so +`apply` is guidance-and-verify, with exactly one write path: the explicitly invoked +`apply install-biome` dependency install described below. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +remediation; `apply install-biome` additionally authorizes the consumer-repo dependency +install described below. All are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook script (`${CLAUDE_PLUGIN_ROOT}/hooks/biome-format.sh`) is the single source of +truth for what it requires and how it resolves things. **Read it first** — probe what it +actually does, don't recite this file. Then run each probe via Bash and report a +PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + Bash 5.0+). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of formatting. +3. **Biome binary** — resolve it exactly the way the hook's resolution code does: its + repo-local install walk (the `node_modules/.bin` path it tests, walking up from the + edited file toward the repo root) and then `PATH`. Test only what the hook tests — a + binary the hook would not accept must not PASS here. FAIL when nothing the hook would + resolve is present while a Biome config governs the repo; the hook then emits a visible + once-per-session skip notice instead of formatting. +4. **Consumer Biome config** — mirror the hook's opt-in walk: it records the topmost + governing config found walking from the edited file's directory up to the repo root, and + deliberately accepts only the config names the hook treats as the opt-in (read the hook — + the hidden dotted variants are intentionally excluded). Report the governing config the + walk discovers, or INFO that none exists — absence is the opt-out by design, so the + plugin is inert (INFO, not FAIL), matching the README's "ships no rules of its own" + stance. +5. **Hook toggle** — report the effective `biome_format_enabled` value: + `${user_config.biome_format_enabled}` (unexpanded or empty means default `true`). +6. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL offer the resolution — never install anything without the +consumer's explicit go-ahead in the invocation. `apply install-biome` adds +`@biomejs/biome` as a dev dependency in the consumer repository **using the repository's +own package manager**, resolved in order: lockfile (`pnpm-lock.yaml` → `pnpm add -D`, +`yarn.lock` → `yarn add -D`, `bun.lock`/`bun.lockb` → `bun add -d`, `package-lock.json` → +`npm install --save-dev`), then the `package.json` `"packageManager"` field when no +lockfile exists, then npm only when neither signal is present. With no `package.json`, an +ambiguous multi-lockfile state, or a lockfile that contradicts `packageManager`, stop with +manager-specific guidance instead of guessing — never introduce a competing lockfile. The +change is stated before running. For a Yarn repository, don't infer the linker — ask the +repo's own Yarn: run `yarn config get nodeLinker` in the repo. `pnp` (Berry's default when +unset) → skip the install and give guidance, because Plug'n'Play generates a loader file, +not the `node_modules/.bin` shim the hook resolves; install `@biomejs/biome` on `PATH` or +switch the linker. `node-modules`/`pnpm`, or Yarn Classic (which has no such setting and +always materializes `node_modules`) → install. The verify-after-remediation rule below is +the backstop when an install still yields no usable shim. After ANY remediation, re-run the +relevant `check` probe and report its actual result — never claim resolved on the install +command's exit code alone. For everything else `apply` only points: + +- missing `jq` / Bash: platform install instructions from the README Requirements section; + this skill never installs system packages. +- toggle off: direct to `/plugin configure biome-format` or + `claude plugin install biome-format@ --config biome_format_enabled=true`; + this skill never writes user settings or `pluginConfigs`. +- no Biome config: offer to create a minimal `biome.json` in the repository root only when + explicitly asked — the plugin imposes no rules of its own. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Run the formatter — editing any supported file exercises the hook end-to-end. +- Write the plugin cache, Claude Code user settings, or `pluginConfigs`. +- Download or execute tools during `check`; network use happens only in an explicitly + requested `apply install-biome` inside the consumer repository. diff --git a/plugins/desktop-notification/.claude-plugin/plugin.json b/plugins/desktop-notification/.claude-plugin/plugin.json index 7ad6e2b98..c8a48cc10 100644 --- a/plugins/desktop-notification/.claude-plugin/plugin.json +++ b/plugins/desktop-notification/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "desktop-notification", - "version": "0.3.2", + "version": "0.4.0", "description": "Alert you when Claude Code needs input — an audible terminal bell, an OSC 9 terminal notification, and an OS-native toast (macOS/Linux) on permission and idle prompts.", "author": { "name": "Melodic Software", diff --git a/plugins/desktop-notification/CHANGELOG.md b/plugins/desktop-notification/CHANGELOG.md index 6b4e6c530..380907688 100644 --- a/plugins/desktop-notification/CHANGELOG.md +++ b/plugins/desktop-notification/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to the `desktop-notification` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **Uniform-contract `setup` skill** (fleet conformance wave). `/desktop-notification:setup + check` reads the hook scripts as the single source of truth and probes Bash version, `jq`, + and — for the current OS only — the `os_toast` channel dependency (Linux `notify-send`; + macOS built-in `osascript`; Windows terminal-only), then reports the four channel toggles' + effective values. `apply` is guidance-and-verify with no write path: it points at the + README install steps and `/plugin configure` for a muted toggle, installs nothing, and + re-runs the probe after any system-tool remediation. + ## [0.3.2] ### Changed diff --git a/plugins/desktop-notification/README.md b/plugins/desktop-notification/README.md index a2f9565ca..c92dab0a4 100644 --- a/plugins/desktop-notification/README.md +++ b/plugins/desktop-notification/README.md @@ -53,6 +53,8 @@ skipped while notifications still fire. /plugin install desktop-notification@melodic-software ``` +Then verify prerequisites with `/desktop-notification:setup check`. + ## Configuration Every channel is toggled by its own `userConfig` boolean (default **on**; set to diff --git a/plugins/desktop-notification/skills/setup/SKILL.md b/plugins/desktop-notification/skills/setup/SKILL.md new file mode 100644 index 000000000..c0ce6e7eb --- /dev/null +++ b/plugins/desktop-notification/skills/setup/SKILL.md @@ -0,0 +1,81 @@ +--- +name: setup +description: "Verify the desktop-notification hook's runtime prerequisites and per-OS channel configuration for this machine. Use when: 'set up desktop-notification', 'configure desktop-notification', 'is desktop-notification working', notifications silently aren't firing, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — the only tunables are the +four native `userConfig` toggles (master + one per channel), and every remaining +prerequisite is a system tool or an OS package. So `apply` is pure guidance-and-verify +with **no write path**: it installs nothing and edits nothing. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers the resolution for each finding. Both are non-interactive — never prompt when the +action is given. + +## `check` (read-only) + +The hook scripts are the single source of truth for what they require and how they degrade: +`${CLAUDE_PLUGIN_ROOT}/hooks/desktop-notification.sh` and the shared +`${CLAUDE_PLUGIN_ROOT}/hooks/hook-utils.sh`. **Read them first** — probe what they actually +do, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table +with one remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check `${BASH_VERSION}` against the hook's documented floor (README + Requirements: Bash 3.2+). INFO when below 5.0: `EPOCHREALTIME` is unset there, so the + opt-in telemetry envelope is skipped while notifications still fire — a degrade, not a + failure. +2. **`jq`** — `command -v jq`. FAIL if absent: without it the hook can neither classify the + notification nor emit its terminal sequence, so it surfaces a once-per-session + `systemMessage` notice and drops every notification for the session. +3. **Per-OS `os_toast` dependency** — detect the current OS family with `uname -s` and probe + ONLY that family's requirement (the hook's `case "$(uname -s)"` does exactly this): + - **Linux** — `command -v notify-send` (libnotify). FAIL only if the `os_toast` channel is + enabled and it is absent; otherwise INFO. Absent → the `os_toast` channel is a + documented silent no-op; remediation is the README's install hint (`libnotify-bin` on + Debian/Ubuntu, `libnotify` on Fedora). The terminal channels are unaffected. + - **macOS (Darwin)** — INFO: `osascript` is built-in, no dependency. Note the first toast + prompts to allow notifications for the terminal app. + - **Windows / other** — INFO: the hook has no `os_toast` branch on this platform (a + fire-and-forget process leaves no live activator host for a WinRT toast). The + `terminal_notify` OSC 9 channel carries attention here; nothing to install. +4. **Channel toggles** — report the effective value of all four native booleans (unexpanded + or empty means the default `true`): master `${user_config.desktop_notification_enabled}`, + `${user_config.desktop_notification_bell_enabled}`, + `${user_config.desktop_notification_terminal_notify_enabled}`, and + `${user_config.desktop_notification_os_toast_enabled}`. Call out when the master toggle is + off (the whole hook is muted) or when the only channel that would fire on this OS is + disabled. +5. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL or actionable INFO offer the resolution — this skill installs +nothing and writes nothing, so every remediation is a pointer the user acts on: + +- **missing `jq` / old Bash** — the platform install instructions from the README Requirements + section. This skill never installs system packages. +- **missing `notify-send`** (Linux, `os_toast` enabled) — `sudo apt install libnotify-bin` + (Debian/Ubuntu) or `sudo dnf install libnotify` (Fedora), per the README's per-OS table. + Guidance only — the user runs it. +- **a toggle is off** — direct to `/plugin configure desktop-notification` or + `claude plugin install desktop-notification@ --config =true`; these + options are user-scoped, so this skill never writes user settings or `pluginConfigs`. + +After the user reports acting on any system-tool remediation, re-run the relevant `check` +probe and report its actual result — never claim resolved on the user's say-so alone. +Re-running `apply` when everything already passes changes nothing and reports "already +configured". + +## What this skill does NOT do + +- Install `jq`, `libnotify`, or any system package, and never writes user settings or + `pluginConfigs` — `apply` is guidance-and-verify with no write path. +- Fire a notification — a `permission_prompt` or `idle_prompt` exercises the hook end-to-end. +- Modify the plugin cache or the hook scripts. diff --git a/plugins/eol-normalizer/.claude-plugin/plugin.json b/plugins/eol-normalizer/.claude-plugin/plugin.json index 6618d65df..0513e72c3 100644 --- a/plugins/eol-normalizer/.claude-plugin/plugin.json +++ b/plugins/eol-normalizer/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "eol-normalizer", - "version": "0.3.1", + "version": "0.4.0", "description": "Normalize a written file's working-tree line endings to its .gitattributes eol value on edit — symmetric CRLF/LF driven by git check-attr, advisory and never blocking.", "author": { "name": "Melodic Software", diff --git a/plugins/eol-normalizer/CHANGELOG.md b/plugins/eol-normalizer/CHANGELOG.md index 2630274fa..47b0f51ad 100644 --- a/plugins/eol-normalizer/CHANGELOG.md +++ b/plugins/eol-normalizer/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to the `eol-normalizer` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **`/eol-normalizer:setup` skill** (fleet conformance wave, dim 8). A uniform check-centric + setup contract: `check` (default, read-only) reads both the hook and its sourced + `normalize-eol.sh` library as the single source of truth and reports a PASS/FAIL/INFO table + for Bash, `jq`, `git` (FAIL when absent — the hook silently no-ops without it, so the check + is the only visibility), the governing `.gitattributes` `eol=` policy, and the + `eol_normalizer_enabled` toggle. `apply` is idempotent and pure guidance — every + prerequisite is a system tool, so it installs nothing and writes nothing (never + `.gitattributes`). + ## [0.3.0] ### Changed diff --git a/plugins/eol-normalizer/README.md b/plugins/eol-normalizer/README.md index 5d9f49ef8..9b1065890 100644 --- a/plugins/eol-normalizer/README.md +++ b/plugins/eol-normalizer/README.md @@ -54,6 +54,8 @@ still runs. /plugin install eol-normalizer@melodic-software ``` +Then verify prerequisites with `/eol-normalizer:setup check`. + ## Configuration The normalization policy itself is your repository's `.gitattributes`, which the diff --git a/plugins/eol-normalizer/skills/setup/SKILL.md b/plugins/eol-normalizer/skills/setup/SKILL.md new file mode 100644 index 000000000..b2feec097 --- /dev/null +++ b/plugins/eol-normalizer/skills/setup/SKILL.md @@ -0,0 +1,74 @@ +--- +name: setup +description: "Verify the eol-normalizer hook's runtime prerequisites and configuration for this repository. Use when: 'set up eol-normalizer', 'configure eol-normalizer', 'is eol-normalizer working', line endings silently aren't normalizing, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — the normalization policy is +the repository's own `.gitattributes`, and the only tunable is the native `userConfig` +toggle. Every prerequisite is a system tool (Bash, jq, git), so `apply` is pure guidance and +writes nothing. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +points at each remediation. Both are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook is the single source of truth for what it requires and how it resolves things. +**Read it first** — the entry script (`${CLAUDE_PLUGIN_ROOT}/hooks/eol-normalizer.sh`) sources +`${CLAUDE_PLUGIN_ROOT}/hooks/normalize-eol.sh`, and that sourced library is where the real +resolution lives (the `git check-attr` calls, the repo-root anchoring, and the NUL-byte +binary guard). Read both, probe what they actually do, don't recite this file. Then run each +probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not +modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + Bash 5.0+). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of normalizing. +3. **`git`** — `command -v git`. FAIL if absent: unlike jq, the hook emits NO visible notice + when git is missing — `git check-attr` and repo-root resolution silently fail and the + hook no-ops, so this probe is the only visibility. Distinguish the two non-failure cases + the hook treats differently: git present but the path is not inside a git repository → + INFO (not applicable — nothing to normalize against, per the README), and git present + inside a repo but no `eol=` rule governs any path → INFO (inert by design, the opt-in + analog: resolution is entirely `.gitattributes`-driven). +4. **Consumer `.gitattributes` `eol=` policy** — using the hook's own resolver + (`git check-attr eol` anchored at the repo root), confirm whether any `eol=lf`/`eol=crlf` + rule governs tracked paths. Report what governs, or INFO that none does — absence is the + opt-out by design, so the plugin is inert (INFO, not FAIL), matching the README's "ships + no policy of its own" stance. +5. **Hook toggle** — report the effective `eol_normalizer_enabled` value: + `${user_config.eol_normalizer_enabled}` (unexpanded or empty means default `true`). +6. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL point at the resolution. Every prerequisite here is a system +tool, so `apply` installs nothing and writes nothing — it only points: + +- missing `jq` / Bash / git: platform install instructions from the README Requirements + section; this skill never installs system packages. +- toggle off: direct to `/plugin configure eol-normalizer` or + `claude plugin install eol-normalizer@ --config eol_normalizer_enabled=true`; + this skill never writes user settings or `pluginConfigs`. +- no `eol=` policy: this is the opt-out, not a defect. Point at the repository's own + `.gitattributes` as the place to declare policy; this skill never writes `.gitattributes`, + because that would impose a repo-wide line-ending policy the plugin has no mandate to + choose. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Normalize any file — editing a file exercises the hook end-to-end. +- Write `.gitattributes`, the plugin cache, Claude Code user settings, or `pluginConfigs`. +- Install any tool, during either `check` or `apply` — all prerequisites are system tools + resolved with guidance only. diff --git a/plugins/firecrawl/.claude-plugin/plugin.json b/plugins/firecrawl/.claude-plugin/plugin.json index fb7cc205d..15fb0d044 100644 --- a/plugins/firecrawl/.claude-plugin/plugin.json +++ b/plugins/firecrawl/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "firecrawl", - "version": "0.2.2", + "version": "0.3.0", "description": "Web scraping, search, crawling, and file parsing through the firecrawl-cli binary with a write-to-disk-then-Read pattern that keeps large results out of context — plus a gated maintainer update flow tracking the upstream CLI and skill source.", "author": { "name": "Melodic Software", diff --git a/plugins/firecrawl/CHANGELOG.md b/plugins/firecrawl/CHANGELOG.md index accf96d1d..18fb95414 100644 --- a/plugins/firecrawl/CHANGELOG.md +++ b/plugins/firecrawl/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to the `firecrawl` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.3.0] + +### Added + +- **Uniform-contract `setup` skill** (fleet conformance wave). `/firecrawl:setup check` reads + the main skill as the single source of truth and probes the `firecrawl` binary (absence is + INFO — the plugin is lazy-install by design) and `FIRECRAWL_API_KEY` presence in the OS + user environment (presence only — the key value is never printed, logged, or persisted). + `apply` is guidance-and-verify with no write path: it defers to the main skill's documented + `npm install -g firecrawl-cli` flow and points at the OS-appropriate way to set the key, + writing nothing. + ## [0.2.2] ### Added diff --git a/plugins/firecrawl/README.md b/plugins/firecrawl/README.md index 68c540df3..62911dd16 100644 --- a/plugins/firecrawl/README.md +++ b/plugins/firecrawl/README.md @@ -47,6 +47,8 @@ appears worth its own surface. /plugin install firecrawl@melodic-software ``` +Then verify prerequisites with `/firecrawl:setup check`. + ## Configuration This plugin has no `userConfig`. The CLI reads `FIRECRAWL_API_KEY`, diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md new file mode 100644 index 000000000..b6fdf7440 --- /dev/null +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -0,0 +1,75 @@ +--- +name: setup +description: "Verify the firecrawl plugin's runtime prerequisites — the firecrawl-cli binary and FIRECRAWL_API_KEY auth — for this machine, respecting the plugin's lazy-install design. Use when: 'set up firecrawl', 'configure firecrawl', 'is firecrawl working', 'firecrawl auth', a scrape reports the CLI is missing, or before a first Firecrawl call. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin is **lazy-install by design** — the main skill treats `firecrawl-cli` +as an escalation option installed when first needed and flags its own absence in its status +line — so a missing CLI is an INFO here, not a failure. This plugin owns no consumer-project +configuration and no `userConfig`; auth is an OS-environment concern. So `apply` is pure +guidance-and-verify with **no write path**: it installs nothing, writes no environment +variables, and defers to the main skill's own documented install flow. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers the resolution for each finding. Both are non-interactive — never prompt when the +action is given. + +## `check` (read-only) + +The main skill is the single source of truth for what the CLI requires and how auth is wired: +`${CLAUDE_PLUGIN_ROOT}/skills/firecrawl/SKILL.md` (Prerequisites + Configuration sections) and +`${CLAUDE_PLUGIN_ROOT}/skills/firecrawl/context/configuration.md` (the exact env vars the CLI +reads). **Read them first** — probe what they actually require, don't recite this file. Then +run each probe via Bash and report a PASS/FAIL/INFO table. Do not modify anything. + +1. **`firecrawl-cli` binary** — the installed binary is `firecrawl` (the npm package is + `firecrawl-cli`). `command -v firecrawl`. INFO when absent (lazy-install design): report + that the CLI installs on first need and the main skill self-flags it; remediation is the + `apply` guidance below. When present, report the version (`firecrawl --version`) and the + auth line from `firecrawl --status` (which states authenticated/unauthenticated). +2. **`FIRECRAWL_API_KEY`** — presence only, in the OS user environment. Test + `[[ -n "${FIRECRAWL_API_KEY:-}" ]]` and report **set** or **unset** — NEVER print, echo, + log, or persist the value. The verdict is state-dependent, matching the lazy-install design: + when set, PASS. When unset AND the CLI is also absent, INFO — both the binary and the key + arrive at first use, so nothing is broken yet. When unset but the CLI IS present, FAIL — a + binary that cannot authenticate. Cross-check against the `firecrawl --status` auth line + whenever the CLI is present. +3. **Optional env vars** — INFO the effective state of the other two the CLI reads + (`FIRECRAWL_API_URL` for a self-hosted endpoint, `FIRECRAWL_NO_TELEMETRY`), presence only, + again without printing any value. +4. **Install flow location** — INFO: the main skill's own install and update flow lives in + `${CLAUDE_PLUGIN_ROOT}/skills/firecrawl/SKILL.md`; `apply` defers there rather than + duplicating it. + +## `apply` (idempotent) + +Run `check`, then for each finding offer the resolution — this skill installs nothing and +writes nothing, so every remediation is a pointer the user acts on: + +- **CLI absent** — defer to the main skill's documented flow: `npm install -g firecrawl-cli` + (stated guidance; the user runs it). Do not duplicate the update/rollback mechanics the main + skill owns. Avoid `firecrawl init --all --browser`, which installs a parallel shadow copy — + the main skill IS the maintained integration. +- **`FIRECRAWL_API_KEY` unset** — obtain a key from the dashboard and + set `FIRECRAWL_API_KEY` as an OS user environment variable (Windows: `setx` or System + Properties → Environment Variables; macOS/Linux: the login shell profile or a secret store). + Prefer env-var auth over `firecrawl login` / `firecrawl config`, which write a second source + of truth. This skill never writes the key anywhere. + +After the user reports acting on any remediation, re-run the relevant `check` probe (for the +key, re-check `firecrawl --status` / presence — never the value) and report its actual result. +Re-running `apply` when everything already passes changes nothing and reports "already +configured". + +## What this skill does NOT do + +- Install `firecrawl-cli`, write `FIRECRAWL_API_KEY` or any environment variable, or print the + key's value — `apply` is guidance-and-verify with no write path. +- Perform scrapes, searches, or any Firecrawl API call — that is `/firecrawl:firecrawl`. +- Run the maintainer update flow (`/firecrawl:firecrawl update`) — a separate, gated action. diff --git a/plugins/playwright/.claude-plugin/plugin.json b/plugins/playwright/.claude-plugin/plugin.json index 56fb07f27..b88760f20 100644 --- a/plugins/playwright/.claude-plugin/plugin.json +++ b/plugins/playwright/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "playwright", - "version": "0.2.1", + "version": "0.3.0", "description": "Live E2E browser automation via Microsoft's @playwright/cli — named sessions, accessibility-ref snapshots, click/fill by ref, screenshots, console and network capture, mocking, tracing, video, and auth state, with artifacts written to disk so only paths enter context, plus a vendored upstream baseline and maintainer drift-check update flow.", "author": { "name": "Melodic Software", diff --git a/plugins/playwright/CHANGELOG.md b/plugins/playwright/CHANGELOG.md index a14b18294..d5997aa08 100644 --- a/plugins/playwright/CHANGELOG.md +++ b/plugins/playwright/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to the `playwright` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.3.0] + +### Added + +- **Uniform-contract `setup` skill** (fleet conformance wave). `/playwright:setup check` reads + the main skill and its `reference/` files as the single source of truth and probes the + `playwright-cli` binary and browser resolvability (surfacing the `install-browser` step and + sandbox-egress caveat from the plugin's own docs). `apply` is guidance-and-verify with + exactly one write path — the explicitly invoked `apply install-cli`, which runs the global + `npm install -g @playwright/cli` (stated before running) and re-probes the binary + afterward. It points at `/playwright:playwright update` for the vendored-baseline flow + rather than wrapping it. + ## [0.2.1] ### Added diff --git a/plugins/playwright/README.md b/plugins/playwright/README.md index 9c29fcb73..33f8efb73 100644 --- a/plugins/playwright/README.md +++ b/plugins/playwright/README.md @@ -65,6 +65,8 @@ loaded via `--plugin-dir`) — consumers receive updates through /plugin install playwright@melodic-software ``` +Then verify prerequisites with `/playwright:setup check`. + ## Configuration This plugin has no `userConfig`. Behavior tuning happens through diff --git a/plugins/playwright/skills/setup/SKILL.md b/plugins/playwright/skills/setup/SKILL.md new file mode 100644 index 000000000..b81f34fb4 --- /dev/null +++ b/plugins/playwright/skills/setup/SKILL.md @@ -0,0 +1,69 @@ +--- +name: setup +description: "Verify the playwright plugin's runtime prerequisites — the playwright-cli binary and a resolvable browser — for this machine. Use when: 'set up playwright', 'configure playwright', 'is playwright working', 'install playwright-cli', a browser flow reports the CLI is missing, or before a first E2E run. Actions: check (read-only verification, default) | apply (resolve what check found; apply install-cli performs the global CLI install). Re-runnable and safe." +argument-hint: "check | apply [install-cli]" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration and no `userConfig` — it +recommends `@playwright/cli`'s own defaults — so the only tunable prerequisite is the CLI +binary itself. `apply` is guidance-and-verify with exactly one write path: the explicitly +invoked `apply install-cli` global npm install described below. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers the resolution for each finding; `apply install-cli` additionally authorizes the global +CLI install. All are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The main skill and its reference files are the single source of truth for what the CLI +requires: `${CLAUDE_PLUGIN_ROOT}/skills/playwright/SKILL.md` (Prerequisite + quick start) and +`${CLAUDE_PLUGIN_ROOT}/skills/playwright/reference/` (`commands.md`, `windows-quirks.md`). +**Read them first** — probe what they actually require, don't recite this file. Then run each +probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not +modify anything. + +1. **`playwright-cli` binary** — `command -v playwright-cli` (the binary name the skill drives; + the npm package is `@playwright/cli`). FAIL if absent — remediation is `apply install-cli` + below. When present, report the version (`playwright-cli --version`). +2. **Browser availability** — the CLI needs a browser beyond its own install. Per the plugin's + own `reference/windows-quirks.md`, local sessions on Windows/macOS/Linux auto-detect system + Chrome, while a sandboxed/cloud session must run `playwright-cli install-browser` and that + download can be egress-blocked. INFO: state whether a system browser is resolvable on this + host and, when it is not, surface the `playwright-cli install-browser` step and the + sandbox-egress caveat from that reference — do not assert a browser requirement the shipped + docs do not; read them and report what they say. +3. **Artifact directory** — INFO: artifacts land in `.playwright-cli/` relative to the working + directory; note whether it is gitignored in the current project (the skill recommends + adding it). No write — reporting only. + +## `apply` (idempotent) + +Run `check`, then for each FAIL offer the resolution. `apply install-cli` is the one write +path — state the change before running it: + +- **CLI absent** — `apply install-cli` runs `npm install -g @playwright/cli`. This is a + **global install that mutates the user's machine** (the global npm prefix), stated before it + runs; without the `install-cli` argument, `apply` only prints this command for the user to + run. After the install, re-run `command -v playwright-cli` and report the actual result — + never claim success on npm's exit code alone. +- **browser not resolvable** — point at `playwright-cli install-browser` per the plugin's + reference, and note the sandbox-egress caveat when relevant. Guidance only — this skill does + not provision browsers. +- **`.playwright-cli/` not gitignored** — suggest adding it to the project `.gitignore`; + guidance only, no edit. + +The vendored-baseline update flow (`/playwright:playwright update`) is **not** this skill's +job — point at it, do not wrap it. Re-running `apply` when everything already passes changes +nothing and reports "already configured". + +## What this skill does NOT do + +- Write anything other than the one explicitly invoked `apply install-cli` global npm install; + it never edits project files, settings, or the plugin cache. +- Provision browsers, run E2E flows, or take screenshots — that is `/playwright:playwright`. +- Run or wrap the maintainer update flow (`/playwright:playwright update`). diff --git a/plugins/powershell-format/.claude-plugin/plugin.json b/plugins/powershell-format/.claude-plugin/plugin.json index 68716d76a..45b1b7b8d 100644 --- a/plugins/powershell-format/.claude-plugin/plugin.json +++ b/plugins/powershell-format/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "powershell-format", - "version": "0.3.1", + "version": "0.4.0", "description": "Auto-format and lint PowerShell on edit via PSScriptAnalyzer, only when a PSScriptAnalyzerSettings.psd1 governs the repo — using the consuming repo's own analyzer settings.", "author": { "name": "Melodic Software", diff --git a/plugins/powershell-format/CHANGELOG.md b/plugins/powershell-format/CHANGELOG.md index 9a3ccdbce..d16ee0def 100644 --- a/plugins/powershell-format/CHANGELOG.md +++ b/plugins/powershell-format/CHANGELOG.md @@ -3,6 +3,33 @@ All notable changes to the `powershell-format` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **`/powershell-format:setup` skill** (fleet conformance wave: a uniform + check-centric setup contract across the hook plugins). `check` (default) is + read-only — it reads the hook script as the single source of truth and probes + each runtime prerequisite (Bash, `jq`, `pwsh` 7+, the PSScriptAnalyzer module), + the `PSScriptAnalyzerSettings.psd1` opt-in, and the effective + `powershell_format_enabled` toggle, reporting a PASS/FAIL/INFO table with one + remediation line per FAIL. It preserves the plugin's deliberate asymmetry: only + `jq` absence is a FAIL, while absent `pwsh` / module / settings file are + by-design not-applicable INFO. The module and settings probes surface the + README trust boundary (a settings file's `CustomRulePath` runs during + analysis). `apply` re-runs `check` then points at the resolution for each + finding — `pwsh` install and `Install-Module PSScriptAnalyzer` are user-scope + guidance only, never run. `apply` is guidance-only with no write path — it + never installs anything and never modifies the repository (including + `PSScriptAnalyzerSettings.psd1`), user settings, or the plugin cache. + +## [0.3.1] + +### Changed + +- Shared `hook-utils.sh` resynced from the repository library (no behavior + change in this plugin's hook). + ## [0.3.0] ### Changed diff --git a/plugins/powershell-format/README.md b/plugins/powershell-format/README.md index ab28d937b..78b6a6ef9 100644 --- a/plugins/powershell-format/README.md +++ b/plugins/powershell-format/README.md @@ -71,6 +71,8 @@ linting still run. /plugin install powershell-format@melodic-software ``` +Then verify prerequisites with `/powershell-format:setup check`. + ## Configuration The formatting and linting rules come from the diff --git a/plugins/powershell-format/skills/setup/SKILL.md b/plugins/powershell-format/skills/setup/SKILL.md new file mode 100644 index 000000000..96e6e75ea --- /dev/null +++ b/plugins/powershell-format/skills/setup/SKILL.md @@ -0,0 +1,99 @@ +--- +name: setup +description: "Verify the powershell-format hook's runtime prerequisites and configuration for this repository. Use when: 'set up powershell-format', 'configure powershell-format', 'is powershell-format working', PowerShell formatting or linting silently isn't happening, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — formatting and linting rules +come from the repository's own `PSScriptAnalyzerSettings.psd1`, and the only tunable is the +native `userConfig` toggle. The `pwsh` runtime and the PSScriptAnalyzer module are resolved +from the environment (never bundled, never downloaded), and the plugin installs nothing, so +`apply` is guidance-only with **no write path** — it never modifies the repository, user +settings, or the plugin cache. + +Note the deliberate asymmetry vs the sibling formatter plugins: only `jq` absence is a +prerequisite defect here. A machine without PowerShell — or without the PSScriptAnalyzer +module, or a repo without a settings file — is treated as **not-applicable, not missing**: the +hook stays quiet by design, so `check` reports these as INFO, never FAIL. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +offers remediation guidance. Both are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook script (`${CLAUDE_PLUGIN_ROOT}/hooks/powershell-format.sh`) is the single source of +truth for what it requires and how it resolves things. **Read it first** — probe what it +actually does, don't recite this file. Then run each probe via Bash and report a +PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + a Bash 5.0+ builtin). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of running. This is the only FAIL-class prerequisite. +3. **`pwsh` (PowerShell 7+)** — probe read-only: + `pwsh -NoProfile -NonInteractive -Command '$PSVersionTable.PSVersion.ToString()'`. INFO, + not FAIL: the hook probes `pwsh` only (never legacy `powershell.exe`) and stays quiet when + it is absent — a machine without PowerShell is not-applicable by design. Report the version + when present. +4. **PSScriptAnalyzer module** — probe **only when `pwsh` resolved** (chain behind step 3 so + the probe never errors on a pwsh-less box): + `pwsh -NoProfile -NonInteractive -Command 'if (Get-Module -ListAvailable -Name PSScriptAnalyzer) { "present" } else { "absent" }'`. + INFO, not FAIL: absent → the hook is a clean quiet no-op (same not-applicable + classification). This probe is read-only — `Get-Module -ListAvailable` inspects, it does + not format, lint, or mutate. +5. **`PSScriptAnalyzerSettings.psd1` opt-in** — INFO: the hook runs **only when a + `PSScriptAnalyzerSettings.psd1` governs the edited file** (walking up from the file to the + repo root, bounded by `CLAUDE_PROJECT_DIR` when set, stopping at the closest one). Absence + is the opt-out and is **by design, not a defect** — the plugin is inert until a repo adopts + a settings file. Report whether one exists and its location. When one exists, surface the + README **Trust model**: the settings file is executed-adjacent configuration — a + `CustomRulePath` it declares is loaded and run during analysis on every edit — so it + carries the same trust as build/CI configuration. Do not enable this plugin against an + untrusted working tree. +6. **Hook toggle** — report the effective `powershell_format_enabled` value: + `${user_config.powershell_format_enabled}` (unexpanded or empty means default `true`; any + value other than `true` disables the hook). +7. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each finding point at the resolution — this skill installs nothing: + +- missing `jq` / Bash: platform install instructions from the README Requirements section; + this skill never installs system packages. +- `pwsh` absent (and PowerShell support is wanted): point at installing + [PowerShell 7+](https://learn.microsoft.com/powershell/scripting/install/installing-powershell); + this skill never installs it. If PowerShell is genuinely not applicable on this machine, + leaving it absent is a valid end state — the hook stays quiet. +- PSScriptAnalyzer module absent: `Install-Module PSScriptAnalyzer` is **user-scope guidance + only** — state the command for the reader to run; this skill never runs it. +- no `PSScriptAnalyzerSettings.psd1` (and linting/formatting is wanted): explain that adding a + settings file at or below the project root opts the repo in — but this skill does not write + it. The settings file is the executed-adjacent trust boundary above; the choice and the edit + belong to the consumer. +- toggle off: direct to `/plugin configure powershell-format` or + `claude plugin install powershell-format@ --config powershell_format_enabled=true`; + this skill never writes user settings or `pluginConfigs`. + +After pointing at a remediation, re-run the relevant `check` probe and report its actual +result — never claim resolved on the reader's report that they installed something. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Run the formatter or linter — editing any `.ps1`, `.psm1`, or `.psd1` file exercises the + hook end-to-end. The `check` pwsh probes are read-only capability checks; they never format, + lint, or mutate any file. +- Write anything: not the repository (including `PSScriptAnalyzerSettings.psd1`), not Claude + Code user settings, not `pluginConfigs`, not the plugin cache. The `pwsh` runtime and the + PSScriptAnalyzer module are resolved from the environment, never installed, so remediation is + guidance only. +- Download tools during `check` beyond the read-only presence and version probes. diff --git a/plugins/ruff-format/.claude-plugin/plugin.json b/plugins/ruff-format/.claude-plugin/plugin.json index c7cff3c38..97e4b7a4c 100644 --- a/plugins/ruff-format/.claude-plugin/plugin.json +++ b/plugins/ruff-format/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "ruff-format", - "version": "0.3.1", + "version": "0.4.0", "description": "Auto-format and lint Python on edit via Ruff, only when a Ruff config governs the repo — using the consuming repo's own Ruff config.", "author": { "name": "Melodic Software", diff --git a/plugins/ruff-format/CHANGELOG.md b/plugins/ruff-format/CHANGELOG.md index ab9830ea3..19736a683 100644 --- a/plugins/ruff-format/CHANGELOG.md +++ b/plugins/ruff-format/CHANGELOG.md @@ -3,6 +3,21 @@ All notable changes to the `ruff-format` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.4.0] + +### Added + +- **`/ruff-format:setup` skill** (fleet conformance wave, dim 8). A uniform check-centric + setup contract: `check` (default, read-only) reads the hook as the single source of truth + and reports a PASS/FAIL/INFO table for Bash, `jq`, the Ruff binary (resolved exactly as the + hook resolves it), the governing Ruff config opt-in, and the `ruff_format_enabled` toggle. + `apply` is idempotent and guidance-first: it re-runs `check`, points at system-tool + remediations, and the one write path — `apply install-ruff` — installs Ruff only into a + managed environment the repo already uses (an existing `.venv` via its own pip/uv; a + uv/Poetry project gets that tool's add command as guidance), never creating a virtual + environment or installing globally, and re-verifies the binary probe after the install + rather than trusting its exit code. + ## [0.3.0] ### Changed diff --git a/plugins/ruff-format/README.md b/plugins/ruff-format/README.md index d682e454f..3764381f6 100644 --- a/plugins/ruff-format/README.md +++ b/plugins/ruff-format/README.md @@ -67,6 +67,8 @@ and linting still run. /plugin install ruff-format@melodic-software ``` +Then verify prerequisites with `/ruff-format:setup check`. + ## Configuration The rules themselves are never configured here — they come from the Ruff config diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md new file mode 100644 index 000000000..93606c18d --- /dev/null +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -0,0 +1,93 @@ +--- +name: setup +description: "Verify the ruff-format hook's runtime prerequisites and configuration for this repository. Use when: 'set up ruff-format', 'configure ruff-format', 'is ruff-format working', formatting silently isn't happening, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe." +argument-hint: "check | apply [install-ruff]" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Thin check-centric setup per the uniform contract: `check` inspects and reports, `apply` +resolves. This plugin owns no consumer-project configuration — rules come from the +repository's own Ruff config, and the only tunable is the native `userConfig` toggle — so +`apply` is guidance-and-verify, with exactly one write path: the explicitly invoked +`apply install-ruff` install into the repo's existing managed environment described below. + +Action routing: no argument or `check` runs the check; `apply` runs the check first, then +remediation; `apply install-ruff` additionally authorizes the consumer-repo install +described below. All are non-interactive — never prompt when the action is given. + +## `check` (read-only) + +The hook script (`${CLAUDE_PLUGIN_ROOT}/hooks/ruff-format.sh`) is the single source of +truth for what it requires and how it resolves things. **Read it first** — probe what it +actually does, don't recite this file. Then run each probe via Bash and report a +PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. + +1. **Bash version** — check against the hook's documented floor (README Requirements), + noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, + Bash 5.0+). +2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible + once-per-session notice instead of formatting. +3. **Ruff binary** — resolve it exactly the way the hook's resolution code does: its + repo-managed virtual-environment walk (the exact `.venv` interpreter paths it tests for + the current platform, walking up from the edited file toward the repo root) and then + `PATH`. Test only what the hook tests — a binary the hook would not accept must not PASS + here. FAIL when nothing the hook would resolve is present while a Ruff config governs the + repo; the hook then emits a visible once-per-session skip notice instead of formatting. +4. **Consumer Ruff config** — mirror the hook's opt-in walk: it stops at the FIRST + (closest) governing config found walking from the edited file's directory up to the repo + root, honoring Ruff's own same-directory precedence and counting a `pyproject.toml` only + when it carries a `[tool.ruff]` section (read the hook for the exact names and the + section test). Report the governing config the walk discovers, or INFO that none exists — + absence is the opt-out by design, so the plugin is inert (INFO, not FAIL), matching the + README's "ships no rules of its own" stance. +5. **Hook toggle** — report the effective `ruff_format_enabled` value: + `${user_config.ruff_format_enabled}` (unexpanded or empty means default `true`). +6. **Hook registration** — INFO: confirm the plugin is enabled for this project + (`/plugin` → Installed) rather than parsing settings files. + +## `apply` (idempotent) + +Run `check`, then for each FAIL offer the resolution — never install anything without the +consumer's explicit go-ahead in the invocation. `apply install-ruff` installs Ruff **only +into a managed Python environment the repo already uses**, never by creating one and never +globally, mirroring how the hook resolves the binary. Resolve the target from what the repo +already declares: + +- An existing `.venv` (the environment the hook's walk targets) → install into it with the + repo's own tooling: `uv pip install ruff` when the repo uses uv, otherwise + `.venv`'s own `pip install ruff`. State the change and the target environment before + running. +- A `pyproject.toml` whose tooling is uv or Poetry but with no environment yet → don't + create one; give that tool's own add command as guidance (`uv add --dev ruff`, + `poetry add --group dev ruff`) for the consumer to run. +- Anything ambiguous — no `.venv`, no recognized project tool, or conflicting signals — + stops with guidance rather than guessing; never create a virtual environment or + `pip install` outside a managed environment. The README's astral install URL + (`https://docs.astral.sh/ruff/installation/`) is the fallback pointer, matching the + hook's own skip-notice text. + +After ANY remediation, re-run the relevant `check` probe and report its actual result — +never claim resolved on the install command's exit code alone. For everything else `apply` +only points: + +- missing `jq` / Bash: platform install instructions from the README Requirements section; + this skill never installs system packages. +- toggle off: direct to `/plugin configure ruff-format` or + `claude plugin install ruff-format@ --config ruff_format_enabled=true`; + this skill never writes user settings or `pluginConfigs`. +- no Ruff config: offer to create a minimal Ruff config in the repository root only when + explicitly asked — the plugin imposes no rules of its own. + +Re-running `apply` after everything passes changes nothing and reports "already configured". + +## What this skill does NOT do + +- Run the formatter — editing any `.py`/`.pyi` file exercises the hook end-to-end. +- Write the plugin cache, Claude Code user settings, or `pluginConfigs`. +- Create a virtual environment, install Ruff globally, or install outside a managed + environment the repo already uses. +- Download or execute tools during `check`; network use happens only in an explicitly + requested `apply install-ruff` inside the consumer repository. From 3be5adc83a97ad2e191e2e3babf1dc7c7f4c7f55 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:11:46 -0400 Subject: [PATCH 02/15] fix(eol-normalizer): setup probes candidate paths, not a tracked-file list Codex on #355: git check-attr answers for any candidate path and the hook normalizes untracked and brand-new files the same as tracked ones (verified: no tracked-only restriction in the hook source), so the policy probe no longer scopes itself to tracked paths. Co-Authored-By: Claude Fable 5 --- plugins/eol-normalizer/skills/setup/SKILL.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/eol-normalizer/skills/setup/SKILL.md b/plugins/eol-normalizer/skills/setup/SKILL.md index b2feec097..29092eb81 100644 --- a/plugins/eol-normalizer/skills/setup/SKILL.md +++ b/plugins/eol-normalizer/skills/setup/SKILL.md @@ -41,9 +41,12 @@ modify anything. analog: resolution is entirely `.gitattributes`-driven). 4. **Consumer `.gitattributes` `eol=` policy** — using the hook's own resolver (`git check-attr eol` anchored at the repo root), confirm whether any `eol=lf`/`eol=crlf` - rule governs tracked paths. Report what governs, or INFO that none does — absence is the - opt-out by design, so the plugin is inert (INFO, not FAIL), matching the README's "ships - no policy of its own" stance. + rule governs paths the hook would touch. `check-attr` answers for ANY candidate path, + tracked or not — the hook normalizes a first write to a brand-new file the same as an + edit to a tracked one — so probe representative candidate paths (or report the declared + patterns), never a tracked-files listing that would miss untracked matches. Report what + governs, or INFO that none does — absence is the opt-out by design, so the plugin is + inert (INFO, not FAIL), matching the README's "ships no policy of its own" stance. 5. **Hook toggle** — report the effective `eol_normalizer_enabled` value: `${user_config.eol_normalizer_enabled}` (unexpanded or empty means default `true`). 6. **Hook registration** — INFO: confirm the plugin is enabled for this project From 45f4c6618f59fde1b6762ab5cce704445f2f6719 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:13:05 -0400 Subject: [PATCH 03/15] docs: backfill undocumented [0.3.1] entries (biome-format, ruff-format, eol-normalizer) The #298 hook-utils resync bumped these three to 0.3.1 without a changelog entry (verified via git log -S on main); same backfill as actionlint and powershell-format in this tranche. Co-Authored-By: Claude Fable 5 --- plugins/biome-format/CHANGELOG.md | 7 +++++++ plugins/eol-normalizer/CHANGELOG.md | 7 +++++++ plugins/ruff-format/CHANGELOG.md | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/plugins/biome-format/CHANGELOG.md b/plugins/biome-format/CHANGELOG.md index c6f477cff..d2d449ce8 100644 --- a/plugins/biome-format/CHANGELOG.md +++ b/plugins/biome-format/CHANGELOG.md @@ -16,6 +16,13 @@ All notable changes to the `biome-format` plugin are documented here. Format fol dev dependency using the repository's own package manager, re-verifying the binary probe after the install rather than trusting its exit code. +## [0.3.1] + +### Changed + +- Shared `hook-utils.sh` resynced from the repository library (no behavior + change in this plugin's hook). + ## [0.3.0] ### Changed diff --git a/plugins/eol-normalizer/CHANGELOG.md b/plugins/eol-normalizer/CHANGELOG.md index 47b0f51ad..307d81175 100644 --- a/plugins/eol-normalizer/CHANGELOG.md +++ b/plugins/eol-normalizer/CHANGELOG.md @@ -16,6 +16,13 @@ All notable changes to the `eol-normalizer` plugin are documented here. Format f prerequisite is a system tool, so it installs nothing and writes nothing (never `.gitattributes`). +## [0.3.1] + +### Changed + +- Shared `hook-utils.sh` resynced from the repository library (no behavior + change in this plugin's hook). + ## [0.3.0] ### Changed diff --git a/plugins/ruff-format/CHANGELOG.md b/plugins/ruff-format/CHANGELOG.md index 19736a683..362792dbb 100644 --- a/plugins/ruff-format/CHANGELOG.md +++ b/plugins/ruff-format/CHANGELOG.md @@ -18,6 +18,13 @@ All notable changes to the `ruff-format` plugin are documented here. Format foll environment or installing globally, and re-verifies the binary probe after the install rather than trusting its exit code. +## [0.3.1] + +### Changed + +- Shared `hook-utils.sh` resynced from the repository library (no behavior + change in this plugin's hook). + ## [0.3.0] ### Changed From 1ba8a1e68da6e5527a0f8d03b9e3b3f785ad92c9 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:19:19 -0400 Subject: [PATCH 04/15] fix(firecrawl): setup env-var remediation defers verification to a fresh session Codex on #355: setx and profile edits do not reach the running process, so the immediate re-check would report a false failure. The env-var remediation now states the new-session requirement and defers its verification to a fresh-session check instead. Co-Authored-By: Claude Fable 5 --- plugins/firecrawl/skills/setup/SKILL.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md index b6fdf7440..2e2092e2c 100644 --- a/plugins/firecrawl/skills/setup/SKILL.md +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -60,7 +60,11 @@ writes nothing, so every remediation is a pointer the user acts on: set `FIRECRAWL_API_KEY` as an OS user environment variable (Windows: `setx` or System Properties → Environment Variables; macOS/Linux: the login shell profile or a secret store). Prefer env-var auth over `firecrawl login` / `firecrawl config`, which write a second source - of truth. This skill never writes the key anywhere. + of truth. This skill never writes the key anywhere. Persistent env changes (`setx`, a + profile edit) do NOT reach the already-running session — tell the user the variable becomes + visible only in a new terminal/Claude Code session, and skip the immediate re-check for this + remediation: report "set persistently; verify with `setup check` in a fresh session" instead + of a false failure. After the user reports acting on any remediation, re-run the relevant `check` probe (for the key, re-check `firecrawl --status` / presence — never the value) and report its actual result. From a5ce3aa975a3a91437694eb8cd491c5b1e45f899 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:25:54 -0400 Subject: [PATCH 05/15] fix(firecrawl): setup treats the CLI status line as the auth verdict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on #355: firecrawl login/config state authenticates without any env var, so env-unset with CLI present is not a failure when firecrawl --status reports authenticated. The status line is now the verdict; env-var presence is reported alongside, with an INFO note when auth comes from persisted CLI config — never directing the user to stack an env key on top of working CLI-config auth. Co-Authored-By: Claude Fable 5 --- plugins/firecrawl/skills/setup/SKILL.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md index 2e2092e2c..b2503bc4a 100644 --- a/plugins/firecrawl/skills/setup/SKILL.md +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -33,13 +33,17 @@ run each probe via Bash and report a PASS/FAIL/INFO table. Do not modify anythin that the CLI installs on first need and the main skill self-flags it; remediation is the `apply` guidance below. When present, report the version (`firecrawl --version`) and the auth line from `firecrawl --status` (which states authenticated/unauthenticated). -2. **`FIRECRAWL_API_KEY`** — presence only, in the OS user environment. Test - `[[ -n "${FIRECRAWL_API_KEY:-}" ]]` and report **set** or **unset** — NEVER print, echo, - log, or persist the value. The verdict is state-dependent, matching the lazy-install design: - when set, PASS. When unset AND the CLI is also absent, INFO — both the binary and the key - arrive at first use, so nothing is broken yet. When unset but the CLI IS present, FAIL — a - binary that cannot authenticate. Cross-check against the `firecrawl --status` auth line - whenever the CLI is present. +2. **Authentication** — the verdict comes from the CLI itself when present: the + `firecrawl --status` auth line is authoritative, because `firecrawl login`/`config` state + in the user-level config dir authenticates without any env var. Alongside it, report + `FIRECRAWL_API_KEY` presence only — test `[[ -n "${FIRECRAWL_API_KEY:-}" ]]` and report + **set** or **unset**; NEVER print, echo, log, or persist the value. Verdicts, matching the + lazy-install design: status says authenticated → PASS (INFO-note when the source is + persisted CLI config rather than the env var — env-var auth is the plugin's preferred + single source of truth, but never direct the user to ADD an env key on top of working + CLI-config auth; that would create the second source the plugin warns against). Status + says unauthenticated (or the CLI cannot answer) and the key is unset → FAIL. CLI absent + AND key unset → INFO — both arrive at first use, nothing is broken yet. 3. **Optional env vars** — INFO the effective state of the other two the CLI reads (`FIRECRAWL_API_URL` for a self-hosted endpoint, `FIRECRAWL_NO_TELEMETRY`), presence only, again without printing any value. From 424c3fb5175246767b980b372d3f501a09db3779 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:00:41 -0400 Subject: [PATCH 06/15] fix(ruff-format): setup records Ruff in managed dependency state Codex on #355: a bare install into a uv- or Poetry-managed .venv bypasses the manifest/lockfile, so uv sync or environment recreation silently removes Ruff and the hook returns to its skip state. Managed projects now get the project's own dependency command (uv add --dev / poetry add --group dev); the direct pip install path is reserved for a plain .venv with no managing tool. Co-Authored-By: Claude Fable 5 --- plugins/ruff-format/skills/setup/SKILL.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index 93606c18d..b8be0b812 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -56,13 +56,14 @@ into a managed Python environment the repo already uses**, never by creating one globally, mirroring how the hook resolves the binary. Resolve the target from what the repo already declares: -- An existing `.venv` (the environment the hook's walk targets) → install into it with the - repo's own tooling: `uv pip install ruff` when the repo uses uv, otherwise - `.venv`'s own `pip install ruff`. State the change and the target environment before - running. -- A `pyproject.toml` whose tooling is uv or Poetry but with no environment yet → don't - create one; give that tool's own add command as guidance (`uv add --dev ruff`, - `poetry add --group dev ruff`) for the consumer to run. +- A uv- or Poetry-managed project (`uv.lock`, `poetry.lock`, or the matching + `pyproject.toml` tool section) → use the project's own dependency command so the + manifest and lockfile record it — `uv add --dev ruff` / `poetry add --group dev ruff` — + never a bare install into the `.venv`, which the next `uv sync` or environment + recreation would silently remove. State the change before running. +- A plain existing `.venv` with NO managing tool detected → install with the + environment's own `pip install ruff`. State the change and the target environment + before running. - Anything ambiguous — no `.venv`, no recognized project tool, or conflicting signals — stops with guidance rather than guessing; never create a virtual environment or `pip install` outside a managed environment. The README's astral install URL From 7efba136d9ac1c6c818766f1e8fac7fd905e5928 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:07:14 -0400 Subject: [PATCH 07/15] fix: firecrawl invalid-key remediation; ruff Poetry in-project gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on #355: (1) firecrawl setup gains a remediation for the key-set-but-unauthenticated state (replace the key without handling the old value, then re-run --status) so apply can resolve its own finding; (2) ruff-format's Poetry path first confirms an in-project environment — Poetry defaults to a cache-dir virtualenv the hook never resolves (hook resolves repo-ancestor .venv or PATH only), so without one the skill guides (virtualenvs.in-project true + recreate, or PATH) instead of running an install that leaves the check failing. Co-Authored-By: Claude Fable 5 --- plugins/firecrawl/skills/setup/SKILL.md | 12 ++++++++++-- plugins/ruff-format/skills/setup/SKILL.md | 9 ++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md index b2503bc4a..64ad514cf 100644 --- a/plugins/firecrawl/skills/setup/SKILL.md +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -42,8 +42,10 @@ run each probe via Bash and report a PASS/FAIL/INFO table. Do not modify anythin persisted CLI config rather than the env var — env-var auth is the plugin's preferred single source of truth, but never direct the user to ADD an env key on top of working CLI-config auth; that would create the second source the plugin warns against). Status - says unauthenticated (or the CLI cannot answer) and the key is unset → FAIL. CLI absent - AND key unset → INFO — both arrive at first use, nothing is broken yet. + says unauthenticated (or the CLI cannot answer) and the key is unset → FAIL. Status says + unauthenticated while the key IS set → FAIL with the invalid-key remediation (below), not + the unset-key one. CLI absent AND key unset → INFO — both arrive at first use, nothing is + broken yet. 3. **Optional env vars** — INFO the effective state of the other two the CLI reads (`FIRECRAWL_API_URL` for a self-hosted endpoint, `FIRECRAWL_NO_TELEMETRY`), presence only, again without printing any value. @@ -69,6 +71,12 @@ writes nothing, so every remediation is a pointer the user acts on: visible only in a new terminal/Claude Code session, and skip the immediate re-check for this remediation: report "set persistently; verify with `setup check` in a fresh session" instead of a false failure. +- **Key set but `--status` says unauthenticated** (expired, revoked, or malformed key) — + direct the user to mint a fresh key on the dashboard and replace + the stored value wherever they keep it (env var or secret store) — never display, compare, + or handle the old value. Then re-run `firecrawl --status` (same session works when the + replacement was exported into it; a persistent-only change follows the fresh-session rule + above). After the user reports acting on any remediation, re-run the relevant `check` probe (for the key, re-check `firecrawl --status` / presence — never the value) and report its actual result. diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index b8be0b812..fe66cb4df 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -60,7 +60,14 @@ already declares: `pyproject.toml` tool section) → use the project's own dependency command so the manifest and lockfile record it — `uv add --dev ruff` / `poetry add --group dev ruff` — never a bare install into the `.venv`, which the next `uv sync` or environment - recreation would silently remove. State the change before running. + recreation would silently remove. State the change before running. **Poetry only when + the environment is somewhere the hook resolves**: by default Poetry keeps its + virtualenv in a cache directory, not the repo `.venv`, and the hook resolves only the + repo-ancestor `.venv` interpreters or `PATH` — so first confirm an in-project + environment (`poetry config virtualenvs.in-project` effective true, or a repo `.venv` + Poetry manages). Without one, don't run the install; guide instead: enable + `poetry config virtualenvs.in-project true` and recreate the environment, or otherwise + put `ruff` on `PATH` — then re-check. - A plain existing `.venv` with NO managing tool detected → install with the environment's own `pip install ruff`. State the change and the target environment before running. From a8f2c110bb4c4114f8fd5cc1dc467fe68b225632 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:12:37 -0400 Subject: [PATCH 08/15] fix(ruff-format): setup recognizes Pipenv in the managed-tool gate Codex on #355: a Pipenv project with an in-repo .venv fell through to the bare pip install branch, leaving Pipfile/Pipfile.lock unchanged so pipenv clean or recreation removes Ruff. Pipenv joins the managed-tool set (pipenv install --dev ruff) with the same in-project-environment gate as Poetry, and the plain-.venv branch now requires no uv/Poetry/Pipenv markers. Co-Authored-By: Claude Fable 5 --- plugins/ruff-format/skills/setup/SKILL.md | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index fe66cb4df..8787f47c3 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -56,21 +56,22 @@ into a managed Python environment the repo already uses**, never by creating one globally, mirroring how the hook resolves the binary. Resolve the target from what the repo already declares: -- A uv- or Poetry-managed project (`uv.lock`, `poetry.lock`, or the matching - `pyproject.toml` tool section) → use the project's own dependency command so the - manifest and lockfile record it — `uv add --dev ruff` / `poetry add --group dev ruff` — - never a bare install into the `.venv`, which the next `uv sync` or environment - recreation would silently remove. State the change before running. **Poetry only when - the environment is somewhere the hook resolves**: by default Poetry keeps its - virtualenv in a cache directory, not the repo `.venv`, and the hook resolves only the - repo-ancestor `.venv` interpreters or `PATH` — so first confirm an in-project - environment (`poetry config virtualenvs.in-project` effective true, or a repo `.venv` - Poetry manages). Without one, don't run the install; guide instead: enable - `poetry config virtualenvs.in-project true` and recreate the environment, or otherwise - put `ruff` on `PATH` — then re-check. -- A plain existing `.venv` with NO managing tool detected → install with the - environment's own `pip install ruff`. State the change and the target environment - before running. +- A tool-managed project — uv (`uv.lock`), Poetry (`poetry.lock` / `[tool.poetry]`), or + Pipenv (`Pipfile`/`Pipfile.lock`) → use that tool's own dependency command so the + manifest and lockfile record it — `uv add --dev ruff`, `poetry add --group dev ruff`, + `pipenv install --dev ruff` — never a bare install into the `.venv`, which the tool's + next sync, `pipenv clean`, or environment recreation would silently remove. State the + change before running. **And only when the environment is somewhere the hook + resolves**: Poetry and Pipenv both default their virtualenv to a cache directory, not + the repo `.venv`, while the hook resolves only repo-ancestor `.venv` interpreters or + `PATH` — so first confirm an in-project environment (Poetry: + `poetry config virtualenvs.in-project` effective true or a Poetry-managed repo + `.venv`; Pipenv: `PIPENV_VENV_IN_PROJECT=1` or a Pipenv-managed repo `.venv`). Without + one, don't run the install; guide instead — enable the tool's in-project mode and + recreate the environment, or otherwise put `ruff` on `PATH` — then re-check. +- A plain existing `.venv` with NO managing tool detected (no uv/Poetry/Pipenv + markers) → install with the environment's own `pip install ruff`. State the change and + the target environment before running. - Anything ambiguous — no `.venv`, no recognized project tool, or conflicting signals — stops with guidance rather than guessing; never create a virtual environment or `pip install` outside a managed environment. The README's astral install URL From a97fd8f6d384b98f5866c910b060583d34645a87 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:19:08 -0400 Subject: [PATCH 09/15] fix: firecrawl indeterminate-status verdict; ruff subtable config test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on #355: (1) firecrawl setup adds the missing decision-table row — status errors with a set key report INDETERMINATE with the error and a retry suggestion, never a key-change directive off an unanswered probe; (2) ruff-format's pyproject test now states the hook's actual rule: [tool.ruff] or any [tool.ruff.*] subtable counts as governing. Co-Authored-By: Claude Fable 5 --- plugins/firecrawl/skills/setup/SKILL.md | 7 +++++-- plugins/ruff-format/skills/setup/SKILL.md | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md index 64ad514cf..6ed230bda 100644 --- a/plugins/firecrawl/skills/setup/SKILL.md +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -44,8 +44,11 @@ run each probe via Bash and report a PASS/FAIL/INFO table. Do not modify anythin CLI-config auth; that would create the second source the plugin warns against). Status says unauthenticated (or the CLI cannot answer) and the key is unset → FAIL. Status says unauthenticated while the key IS set → FAIL with the invalid-key remediation (below), not - the unset-key one. CLI absent AND key unset → INFO — both arrive at first use, nothing is - broken yet. + the unset-key one. Status CANNOT answer (error, timeout, network failure) while the key IS + set → INDETERMINATE, not FAIL: report the status error verbatim, suggest retrying + `firecrawl --status` (transient failures are common), and do not direct any key change on + an unanswered probe. CLI absent AND key unset → INFO — both arrive at first use, nothing + is broken yet. 3. **Optional env vars** — INFO the effective state of the other two the CLI reads (`FIRECRAWL_API_URL` for a self-hosted endpoint, `FIRECRAWL_NO_TELEMETRY`), presence only, again without printing any value. diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index 8787f47c3..df171fecc 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -39,8 +39,9 @@ PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. 4. **Consumer Ruff config** — mirror the hook's opt-in walk: it stops at the FIRST (closest) governing config found walking from the edited file's directory up to the repo root, honoring Ruff's own same-directory precedence and counting a `pyproject.toml` only - when it carries a `[tool.ruff]` section (read the hook for the exact names and the - section test). Report the governing config the walk discovers, or INFO that none exists — + when it carries a `[tool.ruff]` section or any `[tool.ruff.*]` subtable such as + `[tool.ruff.lint]` (read the hook for the exact names and the section test — its test is + the authority). Report the governing config the walk discovers, or INFO that none exists — absence is the opt-out by design, so the plugin is inert (INFO, not FAIL), matching the README's "ships no rules of its own" stance. 5. **Hook toggle** — report the effective `ruff_format_enabled` value: From beed7e9c6a8ccf939fbb22fce65dc6bf66682cf3 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:24:45 -0400 Subject: [PATCH 10/15] fix(ruff-format): [tool.uv] counts as a uv marker before the pip fallback Codex on #355: a uv project before its first lock ([tool.uv] present, no uv.lock) with an existing .venv fell through to bare pip install, leaving Ruff out of uv's declared dependencies. The uv marker set now includes the [tool.uv] section, and the plain-venv branch requires the absence of lockfiles AND pyproject sections for all three tools. Co-Authored-By: Claude Fable 5 --- plugins/ruff-format/skills/setup/SKILL.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index df171fecc..13b63f7f0 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -57,8 +57,9 @@ into a managed Python environment the repo already uses**, never by creating one globally, mirroring how the hook resolves the binary. Resolve the target from what the repo already declares: -- A tool-managed project — uv (`uv.lock`), Poetry (`poetry.lock` / `[tool.poetry]`), or - Pipenv (`Pipfile`/`Pipfile.lock`) → use that tool's own dependency command so the +- A tool-managed project — uv (`uv.lock` or a `[tool.uv]` section), Poetry + (`poetry.lock` / `[tool.poetry]`), or Pipenv (`Pipfile`/`Pipfile.lock`) → use that + tool's own dependency command so the manifest and lockfile record it — `uv add --dev ruff`, `poetry add --group dev ruff`, `pipenv install --dev ruff` — never a bare install into the `.venv`, which the tool's next sync, `pipenv clean`, or environment recreation would silently remove. State the @@ -70,9 +71,10 @@ already declares: `.venv`; Pipenv: `PIPENV_VENV_IN_PROJECT=1` or a Pipenv-managed repo `.venv`). Without one, don't run the install; guide instead — enable the tool's in-project mode and recreate the environment, or otherwise put `ruff` on `PATH` — then re-check. -- A plain existing `.venv` with NO managing tool detected (no uv/Poetry/Pipenv - markers) → install with the environment's own `pip install ruff`. State the change and - the target environment before running. +- A plain existing `.venv` with NO managing tool detected (none of the uv, Poetry, or + Pipenv markers above — lockfiles OR their pyproject sections) → install with the + environment's own `pip install ruff`. State the change and the target environment + before running. - Anything ambiguous — no `.venv`, no recognized project tool, or conflicting signals — stops with guidance rather than guessing; never create a virtual environment or `pip install` outside a managed environment. The README's astral install URL From 249c52c1cb26009b08890f4f0062433f090ebe7d Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:32:07 -0400 Subject: [PATCH 11/15] fix: disabled-toggle downgrades prereq FAILs (7 setups); firecrawl indeterminate covers unset key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on #355 flagged actionlint's setup reporting FAIL prerequisites while the toggle deliberately disables the hook (which exits through its enabled-gate before probing). Applied as a class fix across all seven hook-plugin setups in this tranche: a disabled toggle downgrades every prerequisite absence to INFO, noted as restoring FAIL semantics on re-enable. Firecrawl's INDETERMINATE verdict now covers an unanswered status probe regardless of key state — persisted CLI-config credentials may be valid, so no key creation is directed off an unanswered probe. Co-Authored-By: Claude Fable 5 --- plugins/actionlint/skills/setup/SKILL.md | 5 +++++ plugins/bash-format/skills/setup/SKILL.md | 5 +++++ plugins/biome-format/skills/setup/SKILL.md | 5 +++++ .../desktop-notification/skills/setup/SKILL.md | 5 +++++ plugins/eol-normalizer/skills/setup/SKILL.md | 5 +++++ plugins/firecrawl/skills/setup/SKILL.md | 15 ++++++++------- plugins/powershell-format/skills/setup/SKILL.md | 5 +++++ plugins/ruff-format/skills/setup/SKILL.md | 5 +++++ 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/plugins/actionlint/skills/setup/SKILL.md b/plugins/actionlint/skills/setup/SKILL.md index b9d8dc4df..172a2af13 100644 --- a/plugins/actionlint/skills/setup/SKILL.md +++ b/plugins/actionlint/skills/setup/SKILL.md @@ -25,6 +25,11 @@ truth for what it requires and how it resolves things. **Read it first** — pro actually does, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, a Bash 5.0+ builtin). diff --git a/plugins/bash-format/skills/setup/SKILL.md b/plugins/bash-format/skills/setup/SKILL.md index 7e4468d25..373206800 100644 --- a/plugins/bash-format/skills/setup/SKILL.md +++ b/plugins/bash-format/skills/setup/SKILL.md @@ -26,6 +26,11 @@ does, don't recite this file. The lint pass and the format pass are independent; separately. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, a Bash 5.0+ builtin). diff --git a/plugins/biome-format/skills/setup/SKILL.md b/plugins/biome-format/skills/setup/SKILL.md index f57cbcf3e..f88db156f 100644 --- a/plugins/biome-format/skills/setup/SKILL.md +++ b/plugins/biome-format/skills/setup/SKILL.md @@ -25,6 +25,11 @@ truth for what it requires and how it resolves things. **Read it first** — pro actually does, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, Bash 5.0+). diff --git a/plugins/desktop-notification/skills/setup/SKILL.md b/plugins/desktop-notification/skills/setup/SKILL.md index c0ce6e7eb..e73cfed41 100644 --- a/plugins/desktop-notification/skills/setup/SKILL.md +++ b/plugins/desktop-notification/skills/setup/SKILL.md @@ -26,6 +26,11 @@ The hook scripts are the single source of truth for what they require and how th do, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check `${BASH_VERSION}` against the hook's documented floor (README Requirements: Bash 3.2+). INFO when below 5.0: `EPOCHREALTIME` is unset there, so the opt-in telemetry envelope is skipped while notifications still fire — a degrade, not a diff --git a/plugins/eol-normalizer/skills/setup/SKILL.md b/plugins/eol-normalizer/skills/setup/SKILL.md index 29092eb81..ff98b512e 100644 --- a/plugins/eol-normalizer/skills/setup/SKILL.md +++ b/plugins/eol-normalizer/skills/setup/SKILL.md @@ -27,6 +27,11 @@ binary guard). Read both, probe what they actually do, don't recite this file. T probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, Bash 5.0+). diff --git a/plugins/firecrawl/skills/setup/SKILL.md b/plugins/firecrawl/skills/setup/SKILL.md index 6ed230bda..5593c3cf2 100644 --- a/plugins/firecrawl/skills/setup/SKILL.md +++ b/plugins/firecrawl/skills/setup/SKILL.md @@ -42,13 +42,14 @@ run each probe via Bash and report a PASS/FAIL/INFO table. Do not modify anythin persisted CLI config rather than the env var — env-var auth is the plugin's preferred single source of truth, but never direct the user to ADD an env key on top of working CLI-config auth; that would create the second source the plugin warns against). Status - says unauthenticated (or the CLI cannot answer) and the key is unset → FAIL. Status says - unauthenticated while the key IS set → FAIL with the invalid-key remediation (below), not - the unset-key one. Status CANNOT answer (error, timeout, network failure) while the key IS - set → INDETERMINATE, not FAIL: report the status error verbatim, suggest retrying - `firecrawl --status` (transient failures are common), and do not direct any key change on - an unanswered probe. CLI absent AND key unset → INFO — both arrive at first use, nothing - is broken yet. + says unauthenticated (an answered probe) and the key is unset → FAIL with the unset-key + remediation. Status says unauthenticated while the key IS set → FAIL with the invalid-key + remediation (below), not the unset-key one. Status CANNOT answer (error, timeout, network + failure) → INDETERMINATE regardless of the key's state, never a FAIL: persisted + `login`/`config` credentials may be valid and an unanswered probe proves nothing either + way — report the status error verbatim, suggest retrying `firecrawl --status`, and direct + no key change or key creation off an unanswered probe. CLI absent AND key unset → INFO — + both arrive at first use, nothing is broken yet. 3. **Optional env vars** — INFO the effective state of the other two the CLI reads (`FIRECRAWL_API_URL` for a self-hosted endpoint, `FIRECRAWL_NO_TELEMETRY`), presence only, again without printing any value. diff --git a/plugins/powershell-format/skills/setup/SKILL.md b/plugins/powershell-format/skills/setup/SKILL.md index 96e6e75ea..c64b5e9e1 100644 --- a/plugins/powershell-format/skills/setup/SKILL.md +++ b/plugins/powershell-format/skills/setup/SKILL.md @@ -31,6 +31,11 @@ truth for what it requires and how it resolves things. **Read it first** — pro actually does, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, a Bash 5.0+ builtin). diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index 13b63f7f0..e484cf758 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -25,6 +25,11 @@ truth for what it requires and how it resolves things. **Read it first** — pro actually does, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's `EPOCHREALTIME`, Bash 5.0+). From d1ec67298c29f5a52b95698e7d47be2b20135797 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:58:30 -0400 Subject: [PATCH 12/15] fix(ruff-format): uv add uses --no-sync when no environment exists Codex on #355: uv add syncs by default and creates .venv when absent, violating the skill's never-create guarantee. With no existing .venv the skill now records the dependency via uv add --dev ruff --no-sync and hands uv sync to the consumer as their own step, deferring the re-check until after it. Co-Authored-By: Claude Fable 5 --- plugins/ruff-format/skills/setup/SKILL.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index e484cf758..15f7aa0f1 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -75,7 +75,11 @@ already declares: `poetry config virtualenvs.in-project` effective true or a Poetry-managed repo `.venv`; Pipenv: `PIPENV_VENV_IN_PROJECT=1` or a Pipenv-managed repo `.venv`). Without one, don't run the install; guide instead — enable the tool's in-project mode and - recreate the environment, or otherwise put `ruff` on `PATH` — then re-check. + recreate the environment, or otherwise put `ruff` on `PATH` — then re-check. uv with NO + existing `.venv`: record the dependency without touching environments — + `uv add --dev ruff --no-sync` (`uv add` otherwise syncs and would create `.venv`, + violating this skill's never-create guarantee) — then hand `uv sync` to the consumer as + their own step and defer the re-check until after it. - A plain existing `.venv` with NO managing tool detected (none of the uv, Poetry, or Pipenv markers above — lockfiles OR their pyproject sections) → install with the environment's own `pip install ruff`. State the change and the target environment From 421051aa1eb4fd7a4b3b880bbe3453ce33e21777 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:58:59 -0400 Subject: [PATCH 13/15] fix(markdown-format): setup gets the disabled-toggle downgrade (0.5.1) Carries the class fix from this PR's seven other hook-plugin setups to the freshly merged flagship: a disabled toggle downgrades prerequisite FAILs to INFO, noted as restoring FAIL semantics on re-enable. Co-Authored-By: Claude Fable 5 --- plugins/markdown-format/.claude-plugin/plugin.json | 2 +- plugins/markdown-format/CHANGELOG.md | 9 +++++++++ plugins/markdown-format/skills/setup/SKILL.md | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/markdown-format/.claude-plugin/plugin.json b/plugins/markdown-format/.claude-plugin/plugin.json index b4a8bb2f0..f50d4702d 100644 --- a/plugins/markdown-format/.claude-plugin/plugin.json +++ b/plugins/markdown-format/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "markdown-format", - "version": "0.5.0", + "version": "0.5.1", "description": "Auto-format and lint Markdown on edit via markdownlint-cli2, using the consuming repo's own markdownlint config.", "author": { "name": "Melodic Software", diff --git a/plugins/markdown-format/CHANGELOG.md b/plugins/markdown-format/CHANGELOG.md index b1d4ab373..d7e7a6141 100644 --- a/plugins/markdown-format/CHANGELOG.md +++ b/plugins/markdown-format/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to the `markdown-format` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.5.1] + +### Changed + +- Setup `check` downgrades every prerequisite absence from FAIL to INFO while + the plugin's toggle is disabled (the hook exits through its enabled-gate + before probing, so a deliberately disabled plugin is not broken) — the same + class fix applied across the fleet's other hook-plugin setups. + ## [0.5.0] ### Added diff --git a/plugins/markdown-format/skills/setup/SKILL.md b/plugins/markdown-format/skills/setup/SKILL.md index 251a8dcd8..23588cb36 100644 --- a/plugins/markdown-format/skills/setup/SKILL.md +++ b/plugins/markdown-format/skills/setup/SKILL.md @@ -25,6 +25,11 @@ truth for what it requires and how it resolves things. **Read it first** — pro actually does, don't recite this file. Then run each probe via Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything. +When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to +INFO — the hook exits through its enabled-gate before probing anything, so a deliberately +disabled plugin is not broken. Report the probes informationally and note that re-enabling +restores the FAIL semantics. + 1. **Bash version** — check against the hook's documented floor (README Requirements), noting any features the hook degrades without (for example telemetry's Bash builtin). 2. **`jq`** — `command -v jq`. FAIL if absent: the hook then skips with a visible From 90f184f8e28731f3770ee049e70d3b90a6c037f0 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 20:05:13 -0400 Subject: [PATCH 14/15] refactor(ruff-format): install-ruff as ordered principles, not a tool ladder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex rounds kept finding tools and states the enumerated ladder missed (PDM; env-creating add commands under in-project config). The section is now six ordered principles — identify the manager from the repo's own markers, record through it never around it, never create or mutate an environment (record-only mode or hand the sync to the consumer), install only where the hook resolves, bare pip only in a plain unmanaged .venv, ambiguity stops — with the tool commands as examples. Any manager, present or future, resolves through the same rules. Co-Authored-By: Claude Fable 5 --- plugins/ruff-format/skills/setup/SKILL.md | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index 15f7aa0f1..8e67a694c 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -62,33 +62,33 @@ into a managed Python environment the repo already uses**, never by creating one globally, mirroring how the hook resolves the binary. Resolve the target from what the repo already declares: -- A tool-managed project — uv (`uv.lock` or a `[tool.uv]` section), Poetry - (`poetry.lock` / `[tool.poetry]`), or Pipenv (`Pipfile`/`Pipfile.lock`) → use that - tool's own dependency command so the - manifest and lockfile record it — `uv add --dev ruff`, `poetry add --group dev ruff`, - `pipenv install --dev ruff` — never a bare install into the `.venv`, which the tool's - next sync, `pipenv clean`, or environment recreation would silently remove. State the - change before running. **And only when the environment is somewhere the hook - resolves**: Poetry and Pipenv both default their virtualenv to a cache directory, not - the repo `.venv`, while the hook resolves only repo-ancestor `.venv` interpreters or - `PATH` — so first confirm an in-project environment (Poetry: - `poetry config virtualenvs.in-project` effective true or a Poetry-managed repo - `.venv`; Pipenv: `PIPENV_VENV_IN_PROJECT=1` or a Pipenv-managed repo `.venv`). Without - one, don't run the install; guide instead — enable the tool's in-project mode and - recreate the environment, or otherwise put `ruff` on `PATH` — then re-check. uv with NO - existing `.venv`: record the dependency without touching environments — - `uv add --dev ruff --no-sync` (`uv add` otherwise syncs and would create `.venv`, - violating this skill's never-create guarantee) — then hand `uv sync` to the consumer as - their own step and defer the re-check until after it. -- A plain existing `.venv` with NO managing tool detected (none of the uv, Poetry, or - Pipenv markers above — lockfiles OR their pyproject sections) → install with the - environment's own `pip install ruff`. State the change and the target environment - before running. -- Anything ambiguous — no `.venv`, no recognized project tool, or conflicting signals — - stops with guidance rather than guessing; never create a virtual environment or - `pip install` outside a managed environment. The README's astral install URL - (`https://docs.astral.sh/ruff/installation/`) is the fallback pointer, matching the - hook's own skip-notice text. +Principles, in order — they decide every case, whatever the tool: + +1. **Identify the repo's dependency manager from its own markers** — a lockfile or a + `pyproject.toml` tool section (uv, Poetry, Pipenv, PDM, Hatch, …). Recognize the tool + from what the repo declares; don't assume from an enumerated list. +2. **Record through the manager, never around it.** A managed project gets Ruff via that + tool's own dev-dependency add command (e.g. `uv add --dev ruff`, + `poetry add --group dev ruff`, `pipenv install --dev ruff`, `pdm add -d ruff`) so the + manifest and lockfile record it — a bare `pip install` into its environment is state + the tool's next sync or clean silently removes. +3. **Never create or mutate an environment.** When no environment exists yet, use the + tool's record-only mode when it has one (e.g. `uv add --dev ruff --no-sync` — plain + `uv add` syncs and would create `.venv`) and hand the sync/install step to the + consumer as their own command; when the tool's add command cannot avoid + creating/instantiating an environment, don't run it — give it as guidance instead. +4. **Only where the hook resolves.** The hook resolves repo-ancestor `.venv` interpreters + or `PATH`, nothing else. Tools that default their environment to a cache directory + (Poetry, Pipenv, and any similar) must have an in-project environment confirmed first + (the tool's own config/env answers — e.g. `poetry config virtualenvs.in-project`, + `PIPENV_VENV_IN_PROJECT`); otherwise guide (enable in-project mode + recreate, or put + `ruff` on `PATH`) rather than installing somewhere the hook never looks. +5. **Bare `pip install` only into a plain existing `.venv`** with no manager markers of + any kind. State the change and target environment before running. +6. **Ambiguity stops.** No environment plus no recognized manager, or conflicting + signals → guidance only, anchored on the README's astral install URL + (`https://docs.astral.sh/ruff/installation/`), matching the hook's own skip-notice + text. After ANY remediation, re-run the relevant `check` probe and report its actual result — never claim resolved on the install command's exit code alone. For everything else `apply` From 9851ef857c4c56e0c5bf81434dd919c6a05ea67d Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 18 Jul 2026 20:12:31 -0400 Subject: [PATCH 15/15] fix: headless toggle remediation matches --config's fresh-install-only semantics (8 setups) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex on #355: per the playbook's smoke-tested finding, --config is ignored once a plugin is installed, so the advertised headless reconfigure command could not change the setting on the only state setup runs in. All eight hook-plugin setups now direct interactive /plugin configure any time, and the headless path states the fresh-install-only semantics with uninstall-then-install --config. (source-control's setup carries the same stale command — tranche-3 scope, noted for that PR.) Co-Authored-By: Claude Fable 5 --- plugins/actionlint/skills/setup/SKILL.md | 3 ++- plugins/bash-format/skills/setup/SKILL.md | 3 ++- plugins/biome-format/skills/setup/SKILL.md | 3 ++- plugins/desktop-notification/skills/setup/SKILL.md | 4 +++- plugins/eol-normalizer/skills/setup/SKILL.md | 3 ++- plugins/markdown-format/skills/setup/SKILL.md | 3 ++- plugins/powershell-format/skills/setup/SKILL.md | 3 ++- plugins/ruff-format/skills/setup/SKILL.md | 3 ++- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/actionlint/skills/setup/SKILL.md b/plugins/actionlint/skills/setup/SKILL.md index 172a2af13..9bd1f0581 100644 --- a/plugins/actionlint/skills/setup/SKILL.md +++ b/plugins/actionlint/skills/setup/SKILL.md @@ -54,7 +54,8 @@ Run `check`, then for each FAIL point at the resolution — this skill installs - missing `actionlint`: platform install guidance from the README Requirements section (the [actionlint install guide](https://github.com/rhysd/actionlint/blob/main/docs/install.md)). - missing `jq` / Bash: platform install instructions from the README Requirements section. -- toggle off: direct to `/plugin configure actionlint` or +- toggle off: direct to `/plugin configure actionlint` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall actionlint` then `claude plugin install actionlint@ --config actionlint_enabled=true`; this skill never writes user settings or `pluginConfigs`. diff --git a/plugins/bash-format/skills/setup/SKILL.md b/plugins/bash-format/skills/setup/SKILL.md index 373206800..f44f03a0f 100644 --- a/plugins/bash-format/skills/setup/SKILL.md +++ b/plugins/bash-format/skills/setup/SKILL.md @@ -78,7 +78,8 @@ Run `check`, then for each FAIL point at the resolution — this skill installs shell section (`[*]`, `[*.sh]`, `[*.bash]`, or `[*.{sh,bash}]`) to an `.editorconfig` opts the repo in — but this skill does not write it. `.editorconfig` is cross-cutting (it governs every editor and tool in the repo), so the choice and the edit belong to the consumer. -- toggle off: direct to `/plugin configure bash-format` or +- toggle off: direct to `/plugin configure bash-format` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall bash-format` then `claude plugin install bash-format@ --config bash_format_enabled=true`; this skill never writes user settings or `pluginConfigs`. diff --git a/plugins/biome-format/skills/setup/SKILL.md b/plugins/biome-format/skills/setup/SKILL.md index f88db156f..1b2855f3a 100644 --- a/plugins/biome-format/skills/setup/SKILL.md +++ b/plugins/biome-format/skills/setup/SKILL.md @@ -76,7 +76,8 @@ command's exit code alone. For everything else `apply` only points: - missing `jq` / Bash: platform install instructions from the README Requirements section; this skill never installs system packages. -- toggle off: direct to `/plugin configure biome-format` or +- toggle off: direct to `/plugin configure biome-format` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall biome-format` then `claude plugin install biome-format@ --config biome_format_enabled=true`; this skill never writes user settings or `pluginConfigs`. - no Biome config: offer to create a minimal `biome.json` in the repository root only when diff --git a/plugins/desktop-notification/skills/setup/SKILL.md b/plugins/desktop-notification/skills/setup/SKILL.md index e73cfed41..13b4c2822 100644 --- a/plugins/desktop-notification/skills/setup/SKILL.md +++ b/plugins/desktop-notification/skills/setup/SKILL.md @@ -69,7 +69,9 @@ nothing and writes nothing, so every remediation is a pointer the user acts on: - **missing `notify-send`** (Linux, `os_toast` enabled) — `sudo apt install libnotify-bin` (Debian/Ubuntu) or `sudo dnf install libnotify` (Fedora), per the README's per-OS table. Guidance only — the user runs it. -- **a toggle is off** — direct to `/plugin configure desktop-notification` or +- **a toggle is off** — direct to `/plugin configure desktop-notification` (interactive, + any time). Headless: `--config` only applies on a fresh install (ignored once + installed), so reconfigure via `claude plugin uninstall desktop-notification` then `claude plugin install desktop-notification@ --config =true`; these options are user-scoped, so this skill never writes user settings or `pluginConfigs`. diff --git a/plugins/eol-normalizer/skills/setup/SKILL.md b/plugins/eol-normalizer/skills/setup/SKILL.md index ff98b512e..4a9aaedd3 100644 --- a/plugins/eol-normalizer/skills/setup/SKILL.md +++ b/plugins/eol-normalizer/skills/setup/SKILL.md @@ -64,7 +64,8 @@ tool, so `apply` installs nothing and writes nothing — it only points: - missing `jq` / Bash / git: platform install instructions from the README Requirements section; this skill never installs system packages. -- toggle off: direct to `/plugin configure eol-normalizer` or +- toggle off: direct to `/plugin configure eol-normalizer` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall eol-normalizer` then `claude plugin install eol-normalizer@ --config eol_normalizer_enabled=true`; this skill never writes user settings or `pluginConfigs`. - no `eol=` policy: this is the opt-out, not a defect. Point at the repository's own diff --git a/plugins/markdown-format/skills/setup/SKILL.md b/plugins/markdown-format/skills/setup/SKILL.md index 23588cb36..313738e69 100644 --- a/plugins/markdown-format/skills/setup/SKILL.md +++ b/plugins/markdown-format/skills/setup/SKILL.md @@ -76,7 +76,8 @@ install command's exit code alone. For everything else `apply` only points: - missing `jq` / Bash: platform install instructions from the README Requirements section; this skill never installs system packages. -- toggle off: direct to `/plugin configure markdown-format` or +- toggle off: direct to `/plugin configure markdown-format` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall markdown-format` then `claude plugin install markdown-format@ --config markdown_format_enabled=true`; this skill never writes user settings or `pluginConfigs`. - no markdownlint config: offer to create a minimal `.markdownlint-cli2.jsonc` in the diff --git a/plugins/powershell-format/skills/setup/SKILL.md b/plugins/powershell-format/skills/setup/SKILL.md index c64b5e9e1..29aa6c7a8 100644 --- a/plugins/powershell-format/skills/setup/SKILL.md +++ b/plugins/powershell-format/skills/setup/SKILL.md @@ -83,7 +83,8 @@ Run `check`, then for each finding point at the resolution — this skill instal settings file at or below the project root opts the repo in — but this skill does not write it. The settings file is the executed-adjacent trust boundary above; the choice and the edit belong to the consumer. -- toggle off: direct to `/plugin configure powershell-format` or +- toggle off: direct to `/plugin configure powershell-format` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall powershell-format` then `claude plugin install powershell-format@ --config powershell_format_enabled=true`; this skill never writes user settings or `pluginConfigs`. diff --git a/plugins/ruff-format/skills/setup/SKILL.md b/plugins/ruff-format/skills/setup/SKILL.md index 8e67a694c..c30077728 100644 --- a/plugins/ruff-format/skills/setup/SKILL.md +++ b/plugins/ruff-format/skills/setup/SKILL.md @@ -96,7 +96,8 @@ only points: - missing `jq` / Bash: platform install instructions from the README Requirements section; this skill never installs system packages. -- toggle off: direct to `/plugin configure ruff-format` or +- toggle off: direct to `/plugin configure ruff-format` (interactive, any + time). Headless: `--config` only applies on a fresh install (ignored once installed), so reconfigure via `claude plugin uninstall ruff-format` then `claude plugin install ruff-format@ --config ruff_format_enabled=true`; this skill never writes user settings or `pluginConfigs`. - no Ruff config: offer to create a minimal Ruff config in the repository root only when