Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c799558
feat: adopt the uniform setup contract across 9 formatter/CLI plugins
kyle-sexton Jul 18, 2026
cb2a0f7
Merge branch 'main' into feat/setup-contract-tranche-a
kyle-sexton Jul 18, 2026
3be5adc
fix(eol-normalizer): setup probes candidate paths, not a tracked-file…
kyle-sexton Jul 18, 2026
45f4c66
docs: backfill undocumented [0.3.1] entries (biome-format, ruff-forma…
kyle-sexton Jul 18, 2026
1ba8a1e
fix(firecrawl): setup env-var remediation defers verification to a fr…
kyle-sexton Jul 18, 2026
a5ce3aa
fix(firecrawl): setup treats the CLI status line as the auth verdict
kyle-sexton Jul 18, 2026
6368269
Merge remote-tracking branch 'origin/main' into feat/setup-contract-t…
kyle-sexton Jul 18, 2026
424c3fb
fix(ruff-format): setup records Ruff in managed dependency state
kyle-sexton Jul 18, 2026
aab8607
Merge branch 'feat/setup-contract-tranche-a' of https://github.com/me…
kyle-sexton Jul 18, 2026
7efba13
fix: firecrawl invalid-key remediation; ruff Poetry in-project gate
kyle-sexton Jul 18, 2026
a8f2c11
fix(ruff-format): setup recognizes Pipenv in the managed-tool gate
kyle-sexton Jul 18, 2026
a97fd8f
fix: firecrawl indeterminate-status verdict; ruff subtable config test
kyle-sexton Jul 18, 2026
beed7e9
fix(ruff-format): [tool.uv] counts as a uv marker before the pip fall…
kyle-sexton Jul 18, 2026
249c52c
fix: disabled-toggle downgrades prereq FAILs (7 setups); firecrawl in…
kyle-sexton Jul 18, 2026
7326558
Merge remote-tracking branch 'origin/main' into feat/setup-contract-t…
kyle-sexton Jul 18, 2026
d1ec672
fix(ruff-format): uv add uses --no-sync when no environment exists
kyle-sexton Jul 18, 2026
421051a
fix(markdown-format): setup gets the disabled-toggle downgrade (0.5.1)
kyle-sexton Jul 18, 2026
90f184f
refactor(ruff-format): install-ruff as ordered principles, not a tool…
kyle-sexton Jul 19, 2026
9851ef8
fix: headless toggle remediation matches --config's fresh-install-onl…
kyle-sexton Jul 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/actionlint/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
22 changes: 22 additions & 0 deletions plugins/actionlint/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions plugins/actionlint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
74 changes: 74 additions & 0 deletions plugins/actionlint/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
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.

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).
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).
Comment thread
kyle-sexton marked this conversation as resolved.
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` (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@<marketplace> --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.
2 changes: 1 addition & 1 deletion plugins/bash-format/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
18 changes: 18 additions & 0 deletions plugins/bash-format/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions plugins/bash-format/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
98 changes: 98 additions & 0 deletions plugins/bash-format/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
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.

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).
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` (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@<marketplace> --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.
2 changes: 1 addition & 1 deletion plugins/biome-format/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
20 changes: 20 additions & 0 deletions plugins/biome-format/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@
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.1]

### Changed

- Shared `hook-utils.sh` resynced from the repository library (no behavior
change in this plugin's hook).

## [0.3.0]

### Changed
Expand Down
2 changes: 2 additions & 0 deletions plugins/biome-format/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading