vercel-labs/konsistent-fix-violations
> Run the konsistent CLI, review all reported violations, and fix them in the codebase. Use when the user wants to "fix konsistent violations", "resolve konsistent errors", "clean up konsistent diagnostics", "make konsistent pass", "address structural convention it requires explicit user decisions when many violations stem from the same rule (rule vs. code question), explicit user confirmation before modifying any code, and a triage step for non-trivial violations. For editing `konsistent.json`, this skill defers to the `konsistent-config` skill.
npx skills add https://github.com/vercel-labs/konsistent --skill konsistent-fix-violations
Run konsistent, surface what is broken, and resolve violations. The hard part is not the mechanical fix — it is deciding whether the rule or the code is wrong when a single rule has many violations, and which non-trivial violations are worth attempting versus deferring.
The canonical workflow and per-predicate triage rubric are documented in node_modules/konsistent/docs/guides/fixing-violations.md. Read it before classifying violations. This skill layers strict gating, user confirmation, and AskUserQuestion interactions on top of that workflow.
konsistent.json via the konsistent-config skill if any rules need changes.Do not skip steps. Do not collapse them. The asks for user input at steps 3, 5, and 7 are non-negotiable.
Determine the invocation in this order:
package.json has a konsistent script → use the project's package manager: pnpm konsistent, npm run konsistent, or yarn konsistent (match the lockfile / packageManager field).konsistent is in devDependencies → run via the package runner: pnpm exec konsistent, npx konsistent, etc.npx konsistent.Run the check command with JSON output and a high diagnostic cap so nothing is truncated:
<runner> konsistent check --format=json --max-diagnostics=1000
Note: when invoking via an npm/pnpm script that already wraps konsistent, you may need -- to forward flags:
pnpm konsistent check --format=json --max-diagnostics=1000
# OR if the script runs konsistent without args:
pnpm konsistent -- check --format=json --max-diagnostics=1000
The JSON output is an array of { severity, conventionName, filePath, predicateName, message }. Exit code is non-zero when errors are present; that is expected — read the JSON regardless. See node_modules/konsistent/docs/reference/cli.md for the full output schema.
If the command fails for reasons other than violations (config not found, invalid config, missing dependency), stop and resolve the underlying issue first. Do not proceed.
Aggregate the violations by conventionName (and optionally predicateName). Compute a count per group. Report the totals to the user briefly:
> Found N violations across M conventions. Rule X has K violations; rule Y has J violations; …
A rule is "high-count" when it has roughly 5+ violations OR represents more than half of the violating files for that rule's path pattern. Use judgment — a rule with 4 violations across 4 files where the path pattern only matches 5 files is also high-count.
Why this matters: a rule with 1–2 violations almost always means the *code* is the outlier. A rule with many violations often means the *rule* itself encodes a convention the codebase has not actually adopted — fixing the code without questioning the rule produces churn and may overwrite the team's real convention.
For each high-count rule, explicitly ask the user to choose. Use the AskUserQuestion tool with concrete options. Do not infer — the user owns this decision.
Frame the question with:
Offer at minimum these options:
konsistent.json.severity: warning, narrow the path pattern, add an exception via path negation).Surface meaningful sub-options when "change the rule" admits more than one specific shape. Don't collapse them. Examples of sub-options worth presenting:
${name}-options.ts vs ${name}-model-options.ts.ai use flat-case; everything else uses camelCase") — this is encodable via kebabToCamelMap / kebabToPascalMap overrides or placeholderSatisfies constraints.error for the must-have, warning for the nice-to-have).If the user picks "change", "remove", or "other", capture the specifics needed to execute the change in step 4.
Skip this step for low-count rules — assume code is wrong and fix in step 8.
konsistent.json via konsistent-configIf any rule needs to change based on step 3 decisions, defer to the konsistent-config skill for the actual edits. That skill knows the predicate catalog, path placeholder syntax, case map overrides, conditional/iterative blocks, and the project conventions for konsistent.json. Do not edit konsistent.json ad-hoc here.
When delegating, hand over: the rule name(s) being changed, the user's decision, and the concrete change (e.g. "change exportFunctions name template from ${name.toPascalCase()}Service to create${name.toPascalCase()}Service", "add severity: warning", "add path negation for packages/test-utils").
After the config is updated, validate:
<runner> konsistent validate
Fix any config errors before continuing.
After config changes (or after step 3 if no changes were needed), re-run the CLI to get a fresh violation list reflecting the new rules:
<runner> konsistent check --format=json --max-diagnostics=1000
Report the updated count to the user. Then stop and ask for explicit confirmation before touching any code:
> "Ready to start fixing N code violations. Proceed?"
Use AskUserQuestion with a clear yes/no. Do not begin code edits until the user confirms. This gate is the user's last chance to review the rule set before mass changes.
If the user says no or wants to adjust further, return to step 3 or 4.
Once confirmed, classify each remaining violation. Read node_modules/konsistent/docs/guides/fixing-violations.md for the per-predicate triage rubric and the search heuristics before classifying.
The headline rules:
konsistent very often already exists under a different name, in a different file, or in a different casing. These are still trivial fixes — rename, move, or re-export. Before marking anything non-trivial, search by exact name, case variants, stripped prefixes/suffixes, distinctive word stems, sibling locations, and mirror existing successful matches.The full per-predicate rubric (haveType, haveFiles, export/exportConstants, exportTypes, exportFunctions, exportInterfaces, exportClasses, import/importTypes) lives in node_modules/konsistent/docs/guides/fixing-violations.md.
Compile the non-trivial violations into a clear list. For each, include:
FooConfig does not exist anywhere in the repo", "would require splitting the existing class").Present the list to the user and ask, per violation or per group, which they want to:
konsistent.json for the deferred files via the konsistent-config skill, so CI stays green and the rule still applies to all other matched files. Remove the negation when the deferred work lands.Use AskUserQuestion for the decision. For "Attempt", actively prompt for context — do not silently start a non-trivial change without input.
Before editing any public API, decide on backward-compatibility for renamed exports. This is the most important decision at the start of this step — answer it once, then apply uniformly across the run.
Use AskUserQuestion. Frame it: "Renames will affect package-boundary exports. Are breaking changes acceptable, or do we need to keep back-compat via deprecated aliases?"
Back-compat only matters for symbols exported across the package boundary. Internal renames within a package are noise to alias.
package.json exports / main / module / types fields and tracing what each entry point re-exports (typically src/index.ts). If reachable via any entry point → alias required.export keyword is used between files within the same package, but the symbol is not reachable from any entry point. No alias. Rename freely and update intra-package call sites.For monorepos, repeat this check per package — a rename in packages/foo/src/utils.ts may be internal to foo even if foo's entry point exports many other symbols.
For each package-boundary rename, keep a deprecated alias alongside the new name in the entry point:
export { newName } from "./impl";
/** @deprecated Use `newName` instead. */
export { newName as oldName } from "./impl";
Update intra-package callers to use the new name. Document the renames in the changelog if the project tracks one.
See node_modules/konsistent/docs/guides/fixing-violations.md for the rationale behind the package-boundary distinction.
Fix in this order:
Group fixes by file when possible to minimize churn. Do not re-run konsistent between individual fixes — batch the edits.
When done, re-run the CLI:
<runner> konsistent check --format=json --max-diagnostics=1000
Report:
Run the project's checks to ensure code edits did not break anything else (read package.json for the actual scripts):
pnpm typecheck
pnpm test
pnpm check
konsistent.json to silence violations *after* step 4 without going back through step 3. The point of the rule-vs-code decision is to make it deliberate.Take vercel-labs/konsistent-fix-violations from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.