ktg-plugin-marketplace/plugins/config-audit/scanners/lib/humanizer-data.mjs
Kjell Tore Guttormsen 02ee2a8b83 feat(humanizer): translation table for 12 scanners + plugin-health
Wave 1 / Step 2 of v5.1.0 plain-language UX humanizer.

scanners/lib/humanizer-data.mjs exports TRANSLATIONS keyed by
scanner prefix (CML, SET, HKV, RUL, MCP, IMP, CNF, GAP, TOK, CPS,
DIS, COL, PLH). Each scanner has:

- static: exact-title -> {title, description, recommendation}
- patterns: array of {regex, translation} for template-literal titles
- _default: graceful fallback for unknown findings

Architectural change vs. plan: keys translations by exact scanner
title (not finding ID). Reason: finding IDs are sequence-based
(global counter in lib/output.mjs:34), not stable per finding-type
— two runs can produce different IDs for the same logical issue.
Title strings ARE stable (defined as string literals or template
patterns in the scanner source).

Translations follow research/03 SR-1..SR-17:
- active voice, second person, present tense
- sentences <= 25 words
- tier1 absolute prohibitions and tier3 domain jargon are kept out
  of prose
- tier1/tier3 terms are permitted inside `backtick spans` (code
  references like filenames and field names) — established
  technical-doc convention

Test (12 cases): all 13 scanners covered; every static and pattern
entry has the 3 required fields; tier1 and tier3 forbidden-word
checks pass (with backtick-span exclusion); reference-stable
imports. All pass.
Regression: 657/657 tests (645 + 12 new).

Project: .claude/projects/2026-05-01-config-audit-ux-redesign/
2026-05-01 17:00:59 +02:00

743 lines
44 KiB
JavaScript

/**
* Plain-language translation table for config-audit v5.1.0.
*
* Structure: TRANSLATIONS[scannerPrefix] = {
* static: { '<exact title>': { title, description, recommendation }, ... },
* patterns: [ { regex: RegExp, translation: {...} }, ... ], // for template-literal titles
* _default: { title, description, recommendation } // fallback
* }
*
* Rules (from research/03 SR-1..SR-17):
* - active voice, second person, present tense
* - sentences ≤ 25 words
* - tier1 absolute prohibitions and tier3 domain jargon may NOT appear in prose
* - tier1/tier3 terms ARE permitted inside `backtick spans` (code/filename references)
* - lead with the actual problem, not a label
* - recommendation states a concrete action
*
* The humanizer module looks up: static[title] → patterns matching title → _default → original strings.
* Original `id`, `severity`, `evidence`, `file`, `line`, `category`, `autoFixable` are always preserved by the humanizer caller.
*/
/** @type {Record<string, { static: Record<string, {title:string,description:string,recommendation:string}>, patterns: Array<{regex: RegExp, translation: {title:string,description:string,recommendation:string}}>, _default: {title:string,description:string,recommendation:string} }>} */
export const TRANSLATIONS = {
// ─────────────────────────────────────────────────────────────
// CML — CLAUDE.md Linter
// Category: Configuration mistake
// ─────────────────────────────────────────────────────────────
CML: {
static: {
'No CLAUDE.md found': {
title: 'Your project has no instructions file for Claude',
description: 'Without `CLAUDE.md` at your project root, Claude has to work out your conventions from scratch every conversation. Project-specific guidance is the single highest-impact thing you can add.',
recommendation: 'Create a file called `CLAUDE.md` in your project root. Start with a one-paragraph project overview, common commands, and any quirks Claude should know about.',
},
'CLAUDE.md is nearly empty': {
title: 'Your `CLAUDE.md` is mostly empty',
description: 'An empty instructions file gives Claude no project-specific context, so behavior falls back to defaults.',
recommendation: 'Add at least the project purpose, common commands you run, and any conventions Claude should follow.',
},
'CLAUDE.md exceeds 500 lines': {
title: 'Your `CLAUDE.md` is very long',
description: 'Long instruction files load on every turn and crowd out room for the actual conversation. Over 500 lines is a strong signal to split things up.',
recommendation: 'Move section-specific guidance into separate files and pull them in with `@import`. Keep the main file under 500 lines.',
},
'CLAUDE.md exceeds recommended 200 lines': {
title: 'Your `CLAUDE.md` is getting long',
description: 'Files over 200 lines start to take noticeable space on every turn.',
recommendation: 'Consider splitting longer sections into separate files linked with `@import`.',
},
'CLAUDE.md has no markdown headings': {
title: 'Your instructions file has no section headings',
description: 'Without headings, Claude can\'t easily navigate or reference specific parts of your guidance.',
recommendation: 'Add markdown headings (e.g. `# Project Overview`) to organize the file into sections.',
},
'Missing recommended sections': {
title: 'Your instructions file is missing common sections',
description: 'Sections like Project Overview, Commands, and Conventions help Claude apply your guidance consistently across tasks.',
recommendation: 'Add the missing sections noted in the details.',
},
'@import with deep relative path': {
title: 'A linked file lives several folders away',
description: 'Deep relative paths (`../../`) make the link fragile if files move.',
recommendation: 'Move the linked file closer, or use an absolute reference.',
},
'Repeated content detected': {
title: 'The same text appears more than once',
description: 'Repeated text wastes space on every turn.',
recommendation: 'Remove the duplicate, or pull the shared text into one place and link it.',
},
'Uses HTML comments': {
title: 'Your file has HTML comments',
description: 'HTML comments still count as text sent to Claude on every turn — they don\'t actually hide anything.',
recommendation: 'Delete the comment text if you don\'t want it sent, or convert it to a regular note.',
},
'Contains TODO/FIXME markers': {
title: 'Your file has TODO or FIXME notes',
description: 'These notes are sent to Claude on every turn even when they\'re internal reminders.',
recommendation: 'Resolve the TODO, or move it out of the file into your issue tracker.',
},
},
patterns: [],
_default: {
title: 'Your project instructions file has an issue',
description: 'A check on your instructions file flagged something worth a look.',
recommendation: 'Open the file shown and review the section indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// SET — Settings Validator
// ─────────────────────────────────────────────────────────────
SET: {
static: {
'Unknown settings key': {
title: 'A settings key isn\'t recognized',
description: 'A key in your settings file isn\'t one Claude Code understands. It will be ignored.',
recommendation: 'Check the key name for typos, or remove the key if it\'s no longer in use.',
},
'Deprecated settings key': {
title: 'A settings key is no longer supported',
description: 'This key was removed or renamed in a newer version of Claude Code.',
recommendation: 'Replace it with the current equivalent shown in the details, or remove it.',
},
'Type mismatch in settings': {
title: 'A settings value has the wrong type',
description: 'The value (string, number, boolean, list, etc.) doesn\'t match what this setting expects, so the setting is ignored.',
recommendation: 'Open your settings file and change the value to the type shown in the details.',
},
'Invalid effortLevel value': {
title: 'The `effortLevel` value isn\'t one Claude Code accepts',
description: 'This setting only accepts a fixed list of values; the current one is outside that list.',
recommendation: 'Set `effortLevel` to one of the accepted values shown in the details.',
},
'Hooks configured as array instead of object': {
title: 'Your `hooks` block uses the old list format',
description: 'Newer versions of Claude Code expect `hooks` as an object keyed by event name, not as a list.',
recommendation: 'Convert the list into an object with one key per event (the details show the structure).',
},
'Many additionalDirectories entries': {
title: 'You have many extra directories in `additionalDirectories`',
description: 'Each extra directory adds context Claude has to consider on every turn, which slows responses.',
recommendation: 'Trim the list to only directories Claude actually needs to see.',
},
'No allow rules configured': {
title: 'You have no permission rules letting Claude use specific tools',
description: 'Without `allow` rules, Claude must ask before every tool use, which interrupts your workflow.',
recommendation: 'Add `allow` rules in `permissions` for the tools you trust Claude to use without asking.',
},
'No deny rules configured': {
title: 'You have no permission rules blocking risky tools',
description: 'Without `deny` rules, Claude can be asked to run anything you accept in a prompt.',
recommendation: 'Add `deny` rules for tools or commands that should never run (for example destructive shell commands).',
},
'Missing $schema reference': {
title: 'Your settings file is missing the format link',
description: 'Adding the format link lets your editor offer auto-complete and catch typos as you type.',
recommendation: 'Add `"$schema": "..."` at the top of the settings file (see the details for the right URL).',
},
'Invalid JSON in settings file': {
title: 'Your settings file isn\'t readable as JSON',
description: 'Claude Code can\'t parse the file, so all your settings are skipped.',
recommendation: 'Open the file and fix the JSON syntax shown in the details (often a missing comma or quote).',
},
},
patterns: [],
_default: {
title: 'Your settings file has an issue',
description: 'A check on your settings file flagged something worth a look.',
recommendation: 'Open the file shown and review the line indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// HKV — Hook Validator
// ─────────────────────────────────────────────────────────────
HKV: {
static: {
'Hooks must be an object with event keys': {
title: 'Your hooks block has the wrong shape',
description: 'Claude Code expects `hooks` to be an object whose keys are event names (like `PreToolUse`).',
recommendation: 'Wrap your existing entries inside an object keyed by the event name (see the details for the structure).',
},
'Unknown hook event': {
title: 'An automation is tied to an event Claude Code doesn\'t recognize',
description: 'The event name isn\'t one Claude Code emits, so the automation will never fire.',
recommendation: 'Check the event name for typos. The details list the events Claude Code currently emits.',
},
'Matcher must be a string, not an object': {
title: 'A matcher uses the wrong format',
description: 'The matcher is written as an object, but Claude Code expects a plain string (or regex).',
recommendation: 'Replace the object with a string. The details show what the line should look like.',
},
'Hook handlers must be an array': {
title: 'A handler list uses the wrong format',
description: 'Claude Code expects `hooks` (inside an event) to be a list of handler objects.',
recommendation: 'Wrap the handler in `[ ... ]` if there\'s only one, or list each handler inside the array.',
},
'Missing hooks array in handler group': {
title: 'A handler group has no actual handlers',
description: 'The group declares an event but has no `hooks` list inside it, so nothing runs.',
recommendation: 'Add at least one handler to the group, or remove the empty group.',
},
'Invalid hook handler type': {
title: 'A handler uses an unrecognized type',
description: 'Each handler must say what kind it is (typically `command`). The current type isn\'t one Claude Code accepts.',
recommendation: 'Set `type` to a supported value. The details show the accepted list.',
},
'Hook timeout must be a number': {
title: 'A timeout isn\'t a number',
description: 'The `timeout` value must be an integer (milliseconds), not a string or other type.',
recommendation: 'Change the value to a plain number (for example `5000`).',
},
'Hook timeout outside recommended range': {
title: 'A timeout is unusually short or long',
description: 'Very short timeouts can cause flakiness; very long ones make Claude wait if a script hangs.',
recommendation: 'Pick a value between 500 ms and 30 seconds for typical scripts.',
},
'Hook script not found': {
title: 'A handler points to a script that doesn\'t exist',
description: 'The path in the handler doesn\'t match any file on disk, so the handler will never run.',
recommendation: 'Fix the path, or create the script at the location shown in the details.',
},
'Verbose hook output (loud script)': {
title: 'A handler script prints a lot of text',
description: 'Loud scripts crowd Claude\'s view of what just happened and can confuse later tool calls.',
recommendation: 'Quiet the script — print only what Claude needs to see, and send the rest to a log file.',
},
'Invalid JSON in hooks.json': {
title: 'Your hooks file isn\'t readable as JSON',
description: 'Claude Code can\'t parse the file, so none of your automations run.',
recommendation: 'Open the file and fix the JSON syntax shown in the details.',
},
},
patterns: [],
_default: {
title: 'An automation has an issue',
description: 'A check on your automations flagged something worth a look.',
recommendation: 'Open the automations file shown and review the section indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// RUL — Rules Validator
// ─────────────────────────────────────────────────────────────
RUL: {
static: {
'Rule path pattern matches no files': {
title: 'A rule\'s file pattern matches nothing in your project',
description: 'The rule will never apply, because the pattern doesn\'t match any actual file.',
recommendation: 'Fix the pattern (typo, path change, or generalize it), or delete the rule if it\'s no longer needed.',
},
'Rule has no frontmatter (always active)': {
title: 'A rule has no scoping settings, so it loads everywhere',
description: 'Without scoping, the rule loads on every conversation regardless of which files you\'re working with.',
recommendation: 'Add a scoping block at the top of the file to limit when the rule loads (see the details).',
},
'Rule uses deprecated "globs" field': {
title: 'A rule uses an old field name',
description: 'The field was renamed; the old name still works for now but may stop working in a future release.',
recommendation: 'Rename the field to the current equivalent shown in the details.',
},
'Rule file is not .md': {
title: 'A rule file uses an unexpected extension',
description: 'Claude Code only reads `.md` files in the rules folder.',
recommendation: 'Rename the file to end in `.md`, or move it out of the rules folder.',
},
'Rule file is nearly empty': {
title: 'A rule file has almost no content',
description: 'An empty rule file does nothing for Claude.',
recommendation: 'Either add the rule\'s content, or delete the empty file.',
},
'Large unscoped rule file': {
title: 'A large rule file loads on every conversation',
description: 'Big files without scoping load on every turn and use space whether or not the rule is relevant.',
recommendation: 'Add scoping at the top of the file so it only loads for the files it applies to.',
},
},
patterns: [],
_default: {
title: 'A rule configuration has an issue',
description: 'A check on your rules flagged something worth a look.',
recommendation: 'Open the rule file shown and review the section indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// MCP — MCP Config Validator
// ─────────────────────────────────────────────────────────────
MCP: {
static: {
'Unknown MCP server type': {
title: 'A connected service uses an unrecognized type',
description: 'The `type` field doesn\'t match one Claude Code knows how to start (typically `stdio`, `sse`, or `http`).',
recommendation: 'Change the `type` to one of the supported values shown in the details.',
},
'Invalid trust level': {
title: 'A connected service has an unrecognized trust setting',
description: 'Trust controls whether Claude can use the service\'s tools without asking.',
recommendation: 'Set the trust value to one of the accepted ones (see details).',
},
'Missing trust level': {
title: 'A connected service has no trust setting',
description: 'Without an explicit trust value, Claude has to ask before each tool use, which slows your work.',
recommendation: 'Add a trust value to the entry. The details show the accepted values.',
},
'Unknown MCP server field': {
title: 'A connected service has an unrecognized setting',
description: 'The setting isn\'t one Claude Code reads, so it will be ignored.',
recommendation: 'Check the spelling, or remove the setting if it\'s no longer used.',
},
'SSE server type — consider HTTP': {
title: 'A connected service uses an older transport type',
description: '`sse` works but the newer `http` transport is faster and more reliable for most setups.',
recommendation: 'If your service supports it, change the type to `http`.',
},
'Unreferenced env var in args': {
title: 'A configuration mentions an environment value that isn\'t set',
description: 'The connected service expects to find a value (like an API key) in your environment, but nothing is providing it.',
recommendation: 'Set the environment value before starting Claude Code, or update the entry to point to the right name.',
},
'Invalid JSON in MCP config': {
title: 'A connected-services file isn\'t readable as JSON',
description: 'Claude Code can\'t parse the file, so none of the connected services in it will load.',
recommendation: 'Open the file and fix the JSON syntax shown in the details.',
},
},
patterns: [],
_default: {
title: 'A connected-services configuration has an issue',
description: 'A check on your external-service setup flagged something worth a look.',
recommendation: 'Open the file shown and review the entry indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// IMP — Import Resolver
// ─────────────────────────────────────────────────────────────
IMP: {
static: {
'Broken @import link': {
title: 'A file link points nowhere',
description: 'The link in `@import` references a file that doesn\'t exist, so the linked content never loads.',
recommendation: 'Fix the path, or remove the broken link.',
},
'Circular @import reference': {
title: 'Two files link back to each other in a loop',
description: 'A circular link makes Claude Code stop loading partway, which can drop important context.',
recommendation: 'Break the loop by removing one of the links, or by extracting the shared content into a third file.',
},
'Deep @import chain': {
title: 'A chain of file links goes more than three levels deep',
description: 'Long chains slow down loading and make it hard to see what content actually reaches Claude.',
recommendation: 'Flatten the chain by inlining intermediate files, or by linking directly to the deepest one.',
},
'Tilde path in @import': {
title: 'A file link uses a home-folder shortcut',
description: 'The `~/` shortcut works on your machine but breaks when teammates clone the repository.',
recommendation: 'Replace the tilde path with a relative path inside the project.',
},
},
patterns: [],
_default: {
title: 'A file link has an issue',
description: 'A check on your file links flagged something worth a look.',
recommendation: 'Open the file shown and review the link indicated.',
},
},
// ─────────────────────────────────────────────────────────────
// CNF — Conflict Detector
// ─────────────────────────────────────────────────────────────
CNF: {
static: {
'Permission allow/deny conflict': {
title: 'A tool is both let-in and shut-out by your permissions',
description: 'A `deny` entry takes priority over an `allow`, so the `allow` does nothing — but it also looks like the tool is approved.',
recommendation: 'Remove either the `allow` or the `deny` entry to make your intent clear.',
},
'Duplicate hook definition': {
title: 'The same automation is set up more than once',
description: 'Duplicate handlers run twice on the same event, which can produce double-output or unintended side effects.',
recommendation: 'Keep one copy and remove the others.',
},
},
patterns: [
{
regex: /^Settings key conflict:/,
translation: {
title: 'A settings key is set in more than one place with different values',
description: 'When the same key appears at different scopes (user, project, local) with different values, the more specific one wins — but the conflict often hides a forgotten override.',
recommendation: 'Check the locations shown in the details and decide which value should remain.',
},
},
],
_default: {
title: 'Your configuration has a conflict',
description: 'Two parts of your setup tell Claude different things about the same setting.',
recommendation: 'Review the locations shown in the details and pick one source of truth.',
},
},
// ─────────────────────────────────────────────────────────────
// GAP — Feature Gap Scanner (opportunities, not problems)
// ─────────────────────────────────────────────────────────────
GAP: {
static: {
'No CLAUDE.md file': {
title: 'You haven\'t added project instructions for Claude yet',
description: 'A `CLAUDE.md` at your project root is the highest-impact thing you can add. It tells Claude how you work in this codebase.',
recommendation: 'Create `CLAUDE.md` with a one-paragraph overview, common commands, and any conventions Claude should know.',
},
'No permissions configured': {
title: 'You haven\'t set up tool permissions yet',
description: 'Permission rules let Claude use trusted tools without asking, and block risky ones outright.',
recommendation: 'Add `permissions.allow` for trusted tools and `permissions.deny` for ones to block.',
},
'No hooks configured': {
title: 'You haven\'t set up any automations yet',
description: 'Automations can run before or after Claude\'s actions — for example, formatting on save, or warning before risky commands.',
recommendation: 'Add a `hooks` block with at least one event to start.',
},
'No custom skills or commands': {
title: 'You haven\'t added any custom shortcuts yet',
description: 'Custom skills give you `/your-shortcut` invocations for tasks you do often.',
recommendation: 'Create a skill in `.claude/skills/` for a workflow you find yourself repeating.',
},
'No MCP servers configured': {
title: 'You haven\'t connected Claude to any external tools yet',
description: 'Connected services let Claude reach databases, search engines, browsers, ticket systems, and more.',
recommendation: 'Add a connection in `.mcp.json` for a service you want Claude to use.',
},
'Settings only at one scope': {
title: 'You only have settings at one level',
description: 'Settings can live at user, project, or local-only scope. Using more than one lets you keep personal preferences separate from team-shared ones.',
recommendation: 'Consider moving team-wide settings to project scope and keeping personal ones at user or local scope.',
},
'CLAUDE.md not modular': {
title: 'Your instructions file is one big block',
description: 'Splitting long instructions into smaller linked files makes them easier to maintain and easier on the loading time.',
recommendation: 'Break out long sections into separate files and link them with `@import`.',
},
'No path-scoped rules': {
title: 'Your rules all load on every conversation',
description: 'Path-scoped rules only load when you\'re working with files that match — keeps each conversation focused.',
recommendation: 'Add scoping to your rules so they only load for the files they apply to.',
},
'Auto-memory explicitly disabled': {
title: 'You\'ve turned auto-memory off',
description: 'Auto-memory lets Claude remember facts about you and your projects across conversations.',
recommendation: 'If this was unintentional, re-enable it in your user settings.',
},
'Low hook diversity': {
title: 'Your automations all listen to similar events',
description: 'Listening to a wider range of events (before-tool, after-tool, session-start, etc.) lets you catch more workflow opportunities.',
recommendation: 'Look at the events your current automations skip and consider adding one or two.',
},
'No custom subagents': {
title: 'You haven\'t set up any specialized helper agents yet',
description: 'Subagents handle parallel work in separate contexts (research, code review, testing) without crowding your main conversation.',
recommendation: 'Create a subagent in `.claude/agents/` for a task you delegate often.',
},
'No model configuration': {
title: 'You haven\'t pinned a model preference',
description: 'Setting a default model lets you choose between speed and depth of reasoning for your work.',
recommendation: 'Add a `model` setting in your settings file.',
},
'No status line configured': {
title: 'You haven\'t set up a status line yet',
description: 'A status line shows live context (token usage, current branch, time) at the bottom of your terminal.',
recommendation: 'Add a `statusLine` setting if you want this information at a glance.',
},
'No custom keybindings': {
title: 'You haven\'t set up any custom keybindings',
description: 'Custom keybindings let you trigger your most-used skills with a keystroke.',
recommendation: 'Add bindings in your settings for skills you run often.',
},
'Using default output style': {
title: 'You\'re using the default output style',
description: 'Output styles let you change how Claude formats responses (concise, verbose, bullet-heavy, etc.).',
recommendation: 'Try a different `outputStyle` setting if you have a strong preference.',
},
'No worktree workflow': {
title: 'You haven\'t set up parallel worktree support',
description: 'Worktrees let Claude work on a branch in an isolated copy of the repo without disturbing your main checkout.',
recommendation: 'Enable worktrees if you regularly work on multiple branches at once.',
},
'No advanced skill frontmatter': {
title: 'Your skills don\'t use the richer settings block',
description: 'Adding richer settings at the top of a skill lets you control when it loads, what tools it uses, and more.',
recommendation: 'Add fields like `model`, `tools`, or `description` to your skill files where useful.',
},
'No subagent isolation': {
title: 'Your subagents share Claude\'s main work folder',
description: 'Isolated subagents run in their own copy of the repo so they can\'t accidentally disturb your main work.',
recommendation: 'Add `isolation: worktree` to subagents that do destructive or experimental work.',
},
'No dynamic skill context': {
title: 'Your skills don\'t include live context',
description: 'Dynamic context lets a skill see fresh information (file contents, command output) at the moment it runs, not at the time it was written.',
recommendation: 'Use the dynamic-context block in skills that need up-to-date information.',
},
'No autoMode classifier': {
title: 'You haven\'t set up auto-mode classification',
description: 'Auto-mode classification helps Claude decide when to act on its own vs. ask you, based on the kind of task.',
recommendation: 'Add an auto-mode classifier in your settings if you want this nuance.',
},
'No project .mcp.json in git': {
title: 'Your team has no shared list of connected services',
description: 'Without a project-level connected-services file, every teammate has to set up their own connections.',
recommendation: 'Add `.mcp.json` at the project root so teammates get the same external tools.',
},
'No custom plugin': {
title: 'You haven\'t built a custom plugin yet',
description: 'Plugins let you bundle skills, automations, and connected services that you want available across many projects.',
recommendation: 'If you have workflows you repeat across projects, consider packaging them as a plugin.',
},
'Agent teams not enabled': {
title: 'You haven\'t enabled agent teams',
description: 'Agent teams let multiple subagents collaborate on a complex task, each with its own role.',
recommendation: 'Enable agent teams in settings if you tackle large multi-step work.',
},
'No managed settings': {
title: 'Your project has no settings managed by your organization',
description: 'Managed settings let your organization apply rules everyone has to follow.',
recommendation: 'If you work in a team setting, consider whether managed settings would help.',
},
'No LSP plugins': {
title: 'You haven\'t connected Claude to your editor\'s language servers',
description: 'Language-server connections let Claude see types, error messages, and definitions the same way your editor does.',
recommendation: 'Set up LSP integration if you work in a typed language.',
},
},
patterns: [],
_default: {
title: 'You have a feature opportunity worth a look',
description: 'There\'s a feature you haven\'t set up yet that might help your workflow.',
recommendation: 'See the details for what to add and where.',
},
},
// ─────────────────────────────────────────────────────────────
// TOK — Token Hotspots
// Category: Wasted tokens
// ─────────────────────────────────────────────────────────────
TOK: {
static: {
'CLAUDE.md cascade exceeds 10k tokens per turn': {
title: 'Your instruction files take a lot of space on every turn',
description: 'When the combined size of your instruction files goes above 10,000 tokens, every turn carries that weight. Responses get slower and you have less room for the conversation itself.',
recommendation: 'Trim or split the largest files. The details show which file contributes most.',
},
'Cache-breaking volatile content at top of CLAUDE.md': {
title: 'Your file starts with content that changes between turns',
description: 'Claude reuses earlier turns when the start of your instructions stays the same. Putting changing content (timestamps, session notes, todo lists) at the top breaks that reuse and slows every response.',
recommendation: 'Move the changing content to the bottom of the file, or out of the file entirely.',
},
'Deep @import chain defeats prompt-cache reuse': {
title: 'A long chain of file links breaks Claude\'s memory of your setup',
description: 'When linked files keep changing position, Claude can\'t reuse earlier work and has to re-read the whole chain.',
recommendation: 'Flatten the chain, or pin the most-changing parts at the end.',
},
'Redundant permission declarations': {
title: 'You have permission rules that duplicate each other',
description: 'Duplicate rules waste space and make it harder to see what\'s actually allowed.',
recommendation: 'Consolidate the duplicates into a single rule.',
},
'Bloated skill description (loads on every turn)': {
title: 'A skill description is unusually long',
description: 'Skill descriptions load on every turn whether you use the skill or not. Long descriptions add up.',
recommendation: 'Trim the description to one short sentence and move details into the skill body.',
},
},
patterns: [
{
regex: /^High .+ tool-schema budget on server/,
translation: {
title: 'A connected service exposes many tools, all loading on every turn',
description: 'Each tool a connected service exposes adds its description to every turn. Services with many tools eat space fast.',
recommendation: 'Limit which tools the service exposes (often via a `tools` allow-list), or disconnect services you rarely use.',
},
},
],
_default: {
title: 'Something is using more space than needed',
description: 'A check on space-usage flagged something worth a look.',
recommendation: 'See the details for which file or setting to trim.',
},
},
// ─────────────────────────────────────────────────────────────
// CPS — Cache-Prefix Stability
// Category: Wasted tokens
// ─────────────────────────────────────────────────────────────
CPS: {
static: {
'Volatile content inside cached prefix breaks reuse': {
title: 'Content that changes between turns sits in the part Claude tries to reuse',
description: 'Claude saves space by reusing the start of your instructions across turns. Changing content in that area forces a fresh read every time, which slows responses.',
recommendation: 'Move the changing content (timestamps, session notes) below the first 150 lines, or out of the file.',
},
},
patterns: [],
_default: {
title: 'Content in your instructions is breaking Claude\'s memory of your setup',
description: 'A check on the reusable portion of your instructions flagged something worth a look.',
recommendation: 'See the details for which content to move.',
},
},
// ─────────────────────────────────────────────────────────────
// DIS — Disabled-In-Schema
// Category: Dead config
// ─────────────────────────────────────────────────────────────
DIS: {
static: {
'Tool listed in both permissions.deny and permissions.allow': {
title: 'A tool is in both the let-in list and the shut-out list',
description: 'When a tool is in both lists, the shut-out always wins, so the let-in entry does nothing. It looks like the tool is approved, but it isn\'t.',
recommendation: 'Decide whether the tool should be allowed or denied, and remove it from the other list.',
},
},
patterns: [],
_default: {
title: 'Part of your config doesn\'t actually do anything',
description: 'A check on dead-config flagged something worth a look.',
recommendation: 'See the details for which entry is overridden.',
},
},
// ─────────────────────────────────────────────────────────────
// COL — Collision Scanner
// Category: Conflict
// ─────────────────────────────────────────────────────────────
COL: {
static: {},
patterns: [
{
regex: /^Skill name ".+" used by multiple plugins/,
translation: {
title: 'Two plugins both define a skill with the same name',
description: 'When two plugins offer the same skill name, only one wins, and which one is hard to predict.',
recommendation: 'Rename the skill in one of the plugins, or disable the one you don\'t use.',
},
},
{
regex: /^Skill name ".+" collides between user-level and plugin sources/,
translation: {
title: 'Your personal skill clashes with one from a plugin',
description: 'Your user-level skill and a plugin\'s skill share the same name, so only one of them runs when you call it.',
recommendation: 'Rename your personal version, or disable the plugin\'s version.',
},
},
],
_default: {
title: 'A skill name is used in more than one place',
description: 'A check on overlapping skill names flagged something worth a look.',
recommendation: 'See the details for the overlapping name.',
},
},
// ─────────────────────────────────────────────────────────────
// PLH — Plugin Health
// Category: Configuration mistake
// ─────────────────────────────────────────────────────────────
PLH: {
static: {
'Missing CLAUDE.md': {
title: 'A plugin has no instructions file',
description: 'Plugins should ship with `CLAUDE.md` so users understand what the plugin does and how to use it.',
recommendation: 'Add `CLAUDE.md` to the plugin folder with a brief overview.',
},
'Missing plugin.json': {
title: 'A plugin folder has no manifest',
description: 'A `plugin.json` is required for Claude Code to recognize and load the plugin.',
recommendation: 'Add `plugin.json` to the plugin folder. The details show the required fields.',
},
'Invalid plugin.json': {
title: 'A plugin\'s manifest has a problem',
description: 'The manifest exists but Claude Code can\'t parse it, so the plugin won\'t load.',
recommendation: 'Open `plugin.json` and fix the JSON syntax.',
},
'Command missing frontmatter': {
title: 'A command file has no settings block at the top',
description: 'The settings block at the top of a command file tells Claude how to handle it.',
recommendation: 'Add a settings block (delimited by `---`) at the top of the file.',
},
'Agent missing frontmatter': {
title: 'An agent file has no settings block at the top',
description: 'The settings block tells Claude what tools and model the agent should use.',
recommendation: 'Add a settings block (delimited by `---`) at the top of the file.',
},
'Cross-plugin command name conflict': {
title: 'Two plugins both define a command with the same name',
description: 'When two plugins use the same command name, only one wins.',
recommendation: 'Rename the command in one of the plugins, or disable the one you don\'t need.',
},
'No plugins found': {
title: 'No plugins are installed in this location',
description: 'The location was checked but contains no plugins (or no plugins Claude Code recognizes).',
recommendation: 'Check that the path is correct, or install a plugin if that was intended.',
},
'Invalid hooks.json structure': {
title: 'A plugin\'s automations file has the wrong shape',
description: 'The automations file isn\'t structured the way Claude Code expects, so its automations won\'t load.',
recommendation: 'Open `hooks.json` and fix the structure as shown in the details.',
},
'Invalid hooks.json': {
title: 'A plugin\'s automations file isn\'t valid JSON',
description: 'Claude Code can\'t parse the file, so its automations won\'t load.',
recommendation: 'Open `hooks.json` and fix the JSON syntax.',
},
'hooks.json uses array instead of object': {
title: 'A plugin\'s automations file uses the old list format',
description: 'Newer Claude Code expects automations as an object keyed by event name.',
recommendation: 'Convert the list to an object as shown in the details.',
},
'Unknown file in .claude-plugin/': {
title: 'A file in the plugin folder isn\'t one Claude Code expects',
description: 'Unknown files are ignored, but they often signal a typo or leftover content.',
recommendation: 'Move or delete the file if it isn\'t needed.',
},
},
patterns: [
{
regex: /^Missing required field in plugin\.json/,
translation: {
title: 'A plugin\'s manifest is missing a required field',
description: 'The manifest exists but is missing a field Claude Code needs.',
recommendation: 'Add the missing field shown in the details.',
},
},
{
regex: /^CLAUDE\.md missing .+ section$/,
translation: {
title: 'A plugin\'s instructions file is missing a recommended section',
description: 'The plugin\'s instructions file exists but is missing a section users tend to look for.',
recommendation: 'Add the section shown in the details.',
},
},
{
regex: /^Command missing frontmatter field:/,
translation: {
title: 'A command file is missing a setting at the top',
description: 'A required setting in the command\'s top-of-file block is missing.',
recommendation: 'Add the missing setting shown in the details.',
},
},
{
regex: /^Agent missing frontmatter field:/,
translation: {
title: 'An agent file is missing a setting at the top',
description: 'A required setting in the agent\'s top-of-file block is missing.',
recommendation: 'Add the missing setting shown in the details.',
},
},
],
_default: {
title: 'A plugin has a configuration issue',
description: 'A check on the plugin\'s structure flagged something worth a look.',
recommendation: 'See the details for what needs to change.',
},
},
};