Skip to content
Back to skills

Setup

ASecurity

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.

  • 13 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
ai-agentspythongoshellbashnodegit

Works with

  • claude code

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add melodic-software/claude-code-plugins --skill setup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Setup?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Setup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/melodic-software-setup-61e48445/badge)](https://www.skillsdirectory.com/skills/melodic-software-setup-61e48445)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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
shell: bash
---

## Pre-computed context

`check`'s `jq` probe ran at load time. Read this row instead of re-issuing it; it shows
the tool's path when present, or `absent` when missing:

- `jq`: !`{ command -v jq 2>/dev/null || echo "absent"; }`

A row reading `[shell command execution disabled by policy]` carries no result: run that tool's
`command -v` probe via Bash instead.

## Purpose

Thin check-centric setup per the uniform setup contract (`docs/plugin-philosophy.md`
"Setup is explicit and repeatable" in the marketplace repository): `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 read the
pre-computed `jq` row, run the remaining probes 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 except Node.js downgrades
from FAIL to INFO. The hook script exits through its enabled-gate before probing anything, so
a deliberately disabled plugin is not broken. Node.js stays FAIL: `hooks.json` spawns `node`
before the script can read the toggle. 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+).
2. **`jq`.** The pre-computed `jq` row. FAIL if absent: the hook then skips with a visible
   once per session and agent 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 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:
   `${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.
7. **Node.js.** Run `command -v node` via Bash. FAIL when absent: every hook launch goes
   through `node hooks/exec-bash.mjs`, so a missing `node` is a hook launch error, not a skip
   notice. On Windows, `command -v node` is not the hook's environment: a version manager can
   return an ephemeral per-call shim (fnm's `fnm_multishells\<pid>_<timestamp>\node`) that the <!-- portability-ok: Windows path, not a shell regex -->
   hook process cannot resolve. FAIL when the only hit is such a shim, and report the persisted
   resolution from `[Environment]::GetEnvironmentVariable('Path','Machine')` and `'User'`. An
   in-process hit that is not ephemeral is INFO beside that result, not a PASS by itself.

## `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:

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 live via Bash (a pre-computed row
predates the remediation) 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: reconfigure through Claude Code's native flow, per the marketplace's
  plugin-reconfiguration convention
  (<https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md>,
  which owns the verified-version record): interactive `/plugin configure ruff-format@<marketplace>`
  any time, or headless `claude plugin install ruff-format@<marketplace> -s <scope> --config ruff_format_enabled=true`
  (repeatable per key). Against an already-installed plugin it prints `already installed` and
  still writes the value. Do **not** uninstall to reconfigure: that drops this plugin's entire
  stored `pluginConfigs` entry, resetting every option in the README's Options reference to its
  manifest default. `-s` defaults to `user`; pass the scope `claude plugin list` reports, and run
  from that project's directory for a `project`/`local` scope, or the rerun adds a second
  install record at the scope passed and enables the plugin there; the value itself always
  lands in user settings. A rejected value prints a warning yet exits 0, so read the output.
  This skill never writes user settings or `pluginConfigs`. Afterwards rerun
  `check` in a **fresh session**. The rendered `${user_config.*}` is injected at skill load and
  each hook's `CLAUDE_PLUGIN_OPTION_*` is fixed at session start, so a same-session `check` still
  reports the OLD value; report the observed effective value, never an unobserved change.
- 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.

Files in this skill

  • SKILL.md8.7 KB
  • evals/evals.json7.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…