Claude
Skills
Sign in
Back

tune-precious

Included with Lifetime
$97 forever

Use when adding, migrating to, or auditing `precious.toml` in a Perl repo (or any repo with a `typos.toml`). Generates the canonical config (perltidy + perlvars + omegasort + optional perlcritic + optional typos), consolidates `.perltidyrc`, edits `dist.ini` to drop Code::TidyAll, wires a CI lint job, and adds a self-installing `scripts/pre-commit` shell hook so `precious lint --staged` runs locally on commit. Idempotent across re-runs.

Cloud & DevOps

What this skill does


# Tune Precious

## Overview

**Six idempotent transforms that land [precious](https://github.com/houseabsolute/precious) as the canonical tidy/lint driver for a Perl repo (or any repo that has opted into `typos`):**

1. Generate or refresh `precious.toml` with `perltidy`, `perlvars`, `omegasort-gitignore`, `omegasort-stopwords`, optionally `perlcritic`, and optionally `typos`.
2. Consolidate the `perltidy` profile to the hidden `.perltidyrc` and strip `-b` (precious manages backup mode).
3. Delete `Code::TidyAll` config (`.tidyallrc`, `tidyall.ini`, `.tidyall.d/` ignore line).
4. Edit `dist.ini` to remove the tidyall plugin + prereqs via the bundle's `PluginRemover` and a trailing `[RemovePrereqs]` block.
5. Add a `.github/workflows/lint.yml` job that installs `precious` + `omegasort` (+ `typos` when wired) via ubi and runs `precious lint --all`.
6. Add a self-installing `scripts/pre-commit` shell hook that runs `precious lint --staged` and blocks direct commits to the default branch, so contributors catch tidy/lint drift before pushing.

**Core principle:** apply the canonical recipe without changing the user's tidy/lint intent. Each transform is its own commit so any single change is revertable. Re-running on an already-tuned repo is a no-op.

**Four modes** the skill handles transparently:

| Mode | Trigger | What changes |
|---|---|---|
| Migrate | Repo has `.tidyallrc`, `tidyall.ini`, or `[Test::TidyAll]` in `dist.ini` | All six transforms apply |
| Greenfield | Perl repo, no tidyall config, no `precious.toml` | T1 + T2 (consolidate any visible `perltidyrc`) + T5 + T6 |
| Tune | `precious.toml` already exists | All transforms run as no-ops; surfaces drift between current config and canonical recipe |
| Typos-only | No Perl files, but `typos.toml` / `_typos.toml` / `.typos.toml` is present | T1 (typos block only) + T5; T2/T3/T4 are no-ops |

**Worked example PR:** [libwww-perl/WWW-Mechanize-Cached#35](https://github.com/libwww-perl/WWW-Mechanize-Cached/pull/35) — the recipe was extracted from this PR.

## Dispatch this skill to a subagent

When this skill is invoked, dispatch the work to a `general-purpose` subagent via the `Agent` tool. **Do not run the six transforms inline in the caller's context.**

Why:
- Each transform reads several files, computes a diff, writes the files, verifies with `precious config list` / TOML parse / YAML parse / `dzil build --no-tgz`, then stages and commits. Across six transforms and several files, that is a lot of `Read`/`Edit`/`Bash` tool traffic — none of it useful to the caller's session.
- The caller only needs the final summary line (`Applied N transforms across M files in K commits`) and the list of commit SHAs. Everything else is intermediate state.

How to dispatch:
- Brief the subagent with this SKILL.md as its working spec — pass the path to the file or invoke the skill from inside the subagent.
- Tell the subagent the working directory.
- Require the subagent to report back, in under 200 words: the summary line, the per-transform commit SHAs, and any skipped transforms with reason.
- If a transform's verification fails, the subagent must stop and surface the failure rather than continuing or auto-reverting.

If the user explicitly asks to run inline (e.g. "do it here so I can watch"), honour that — the subagent dispatch is the default, not a hard requirement.

## When to Use

- User asks to migrate from `Code::TidyAll` to `precious`
- User asks to set up `precious` from scratch in a Perl repo
- User asks to audit / refresh an existing `precious.toml` against the canonical recipe
- Repo contains `.tidyallrc` or `tidyall.ini`
- `dist.ini` includes `Test::TidyAll`, `[@Author::*]` with a tidyall prereqs block, or `[PerlCritic]` you want to migrate behind precious

**Skip when:**
- Not a Perl repo (no `*.pm`, `*.pl`, `*.t`, `*.psgi`, or `dist.ini`) **and** no typos config (`typos.toml`, `_typos.toml`, `.typos.toml`) at repo root
- The user has deliberately customised `precious.toml` for tools outside the canonical set (e.g. they run `prettier` over Mojolicious templates) — idempotency preserves their commands; only report drift in the six canonical commands.

## Workflow

```dot
digraph tune_precious {
    "Detect mode" [shape=box];
    "Migrate, Greenfield, Tune, or Typos-only?" [shape=diamond];
    "T1: precious.toml" [shape=box];
    "Verify + commit T1" [shape=box];
    "T2: consolidate .perltidyrc" [shape=box];
    "Verify + commit T2" [shape=box];
    "T3: delete tidyall config" [shape=box];
    "Verify + commit T3" [shape=box];
    "T4: edit dist.ini" [shape=box];
    "Verify + commit T4" [shape=box];
    "T5: add CI lint job" [shape=box];
    "Verify + commit T5" [shape=box];
    "T6: add pre-commit hook" [shape=box];
    "Verify + commit T6" [shape=box];
    "Report summary" [shape=box];

    "Detect mode" -> "Migrate, Greenfield, Tune, or Typos-only?";
    "Migrate, Greenfield, Tune, or Typos-only?" -> "T1: precious.toml";
    "T1: precious.toml" -> "Verify + commit T1";
    "Verify + commit T1" -> "T2: consolidate .perltidyrc";
    "T2: consolidate .perltidyrc" -> "Verify + commit T2";
    "Verify + commit T2" -> "T3: delete tidyall config";
    "T3: delete tidyall config" -> "Verify + commit T3";
    "Verify + commit T3" -> "T4: edit dist.ini";
    "T4: edit dist.ini" -> "Verify + commit T4";
    "Verify + commit T4" -> "T5: add CI lint job";
    "T5: add CI lint job" -> "Verify + commit T5";
    "Verify + commit T5" -> "T6: add pre-commit hook";
    "T6: add pre-commit hook" -> "Verify + commit T6";
    "Verify + commit T6" -> "Report summary";
}
```

## Scope Detection

Before running, fingerprint the repo:

| Probe | Implication |
|---|---|
| `.tidyallrc` or `tidyall.ini` present | Mode = migrate; T3 will delete |
| `dist.ini` mentions `Test::TidyAll`, `tidyall`, or has a `[Prereqs / *]` block named for tidyall | Mode = migrate; T4 will rewrite |
| `precious.toml` present | Mode = tune; T1 audits-only and reports drift |
| Neither tidyall nor precious config present, but `*.pm` files exist | Mode = greenfield; T3 + T4 are no-ops |
| `typos.toml`, `_typos.toml`, or `.typos.toml` present at repo root | T1 wires up `typos`; T5 adds `crate-ci/typos` to the ubi `projects:` list |
| No Perl files AND no typos config | Exit cleanly with "no Perl or typos config found" |

`perlcritic` detection (drives whether T1 wires up a `perlcritic` command):

- `.tidyallrc` / `tidyall.ini` has `[PerlCritic]` → auto-enforced; wire up.
- `dist.ini` has `[Test::Perl::Critic]` → auto-enforced; wire up.
- `dist.ini` has `[PerlCritic]` (Dist::Zilla plugin) → auto-enforced; wire up.
- `.perlcriticrc` exists but no auto-enforcement → leave for manual use; do NOT wire up.

**Rule:** don't widen the scan set. If perlcritic wasn't enforced before, precious shouldn't enforce it after.

`typos` detection (drives whether T1 wires up a `typos` command):

- `typos.toml`, `_typos.toml`, or `.typos.toml` exists at repo root → wire up.
- None of the above → do NOT wire up.

**Rule:** only wire `typos` when the user has already opted in by writing a typos config. Don't introduce a new lint dimension on a previously-clean tree.

## The Six Transforms

### 1. Generate or refresh `precious.toml`

**What:** write `precious.toml` at repo root with the canonical commands. Skip blocks whose source file/binary isn't present (no `.stopwords` → skip `omegasort-stopwords`).

**Canonical template:**

```toml
[commands.perltidy]
type    = "both"
include = ["**/*.{pl,pm,t,psgi}"]
cmd     = ["perltidy", "--profile=$PRECIOUS_ROOT/.perltidyrc"]
lint-flags = ["--assert-tidy", "--no-standard-output", "--outfile=/dev/null"]
tidy-flags = ["--backup-and-modify-in-place", "--backup-file-extension=/"]
ok-exit-codes = [0]
lint-failure-exit-codes = [2]

[commands.perlvars]
type    = "lint"
include = ["**/*.pm"]
cmd     = ["perlvars"]
ok-exit-codes = [0]
lint-failure-exit-codes = [1]

[commands.omegasort-gitignore]
type    = "both"
include = [".gitignore
Files: 1
Size: 48.0 KB
Complexity: 42/100
Category: Cloud & DevOps

Related in Cloud & DevOps