From perfect-typescripter
Set up or edit .claude/ai-lab/perfect-typescripter/config.json to tune TypeScript enforcement rules. Use when the typescript guard blocks writes and the user wants to disable a rule, add exemptions, or configure the enforcer, or when the user says 'configure typescripter', 'disable boolean rule', 'add exemption', 'typescripter config'.
How this skill is triggered — by the user, by Claude, or both
Slash command
/perfect-typescripter:setup-typescripter-configThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Scaffold or edit `.claude/ai-lab/perfect-typescripter/config.json` in the current project root. This config overrides the plugin's default rules — disable rules, add field/function/type exemptions, or tune enforcement per project.
Scaffold or edit .claude/ai-lab/perfect-typescripter/config.json in the current project root. This config overrides the plugin's default rules — disable rules, add field/function/type exemptions, or tune enforcement per project.
The typescript guard blocks Write/Edit when it detects banned patterns (booleans, null/undefined, optionals, enums, etc.). Some projects have legitimate reasons to relax specific rules — framework APIs that require booleans, legacy code with optionals, TSX props that need boolean fields.
Place .claude/ai-lab/perfect-typescripter/config.json at the project root. The hook walks up from the edited file to find it, then merges it on top of the plugin's built-in defaults.
{
"ignorePaths": [
{ "path": "src/generated", "reason": "auto-generated types from external schema" },
{ "path": "src/vendor", "reason": "third-party code, not under our control" }
],
"rules": {
"booleanFields": { "enabled": true, "exemptions": { "fieldNames": [], "typeNames": [], "tsxFiles": true } },
"booleanParams": { "enabled": true, "exemptions": { "privateFunctions": true } },
"booleanReturns": { "enabled": true },
"nullUndefined": { "enabled": true, "exemptions": { "functionNames": [], "commentTag": "@api-boundary" } },
"optionalProperties": { "enabled": true, "exemptions": { "commentTag": "@api-boundary" } },
"optionalChaining": { "enabled": true },
"anyUnknown": { "enabled": true },
"typeAssertions": { "enabled": true, "allowConst": true, "allowBrandedTypes": true, "exemptions": { "allowedTypes": [] } },
"doubleBang": { "enabled": true },
"enums": { "enabled": true },
"exhaustiveSwitches": { "enabled": true },
"fallthroughGrouping": { "enabled": true },
"productSwitchMatrix": { "enabled": true, "minRepeatedReturnKind": 3 },
"stateBranching": { "enabled": true, "exemptions": { "allowedFiles": [], "allowedDirectories": [] } },
"resultPatterns": { "enabled": true, "bannedNames": ["Success", "Failed", "Ok", "Error"] },
"ifOnField": { "enabled": true, "suspiciousNames": [] },
"positionalArgs": { "enabled": true, "exemptPrivateFunctions": true, "exemptFunctions": [] }
},
"projectOverrides": {
"exemptFunctions": [],
"exemptTypes": []
}
}
Skip entire directories or files. Each entry requires both path (substring match, case-insensitive) and reason (why this path is exempt). No blind exclusions.
Common exclusions:
| Rule | What it bans | Common exemption reason |
|---|---|---|
booleanFields | isX, hasX boolean fields | TSX component props (disabled, loading, checked) — use tsxFiles: true |
booleanParams | Boolean function parameters | Private helper functions — use privateFunctions: true |
booleanReturns | Functions returning boolean | Rare; usually means the function should return a DU |
nullUndefined | null, undefined, ?: params | API boundaries — mark with @api-boundary comment |
optionalProperties | Optional properties (prop?:) | API response types — mark with @api-boundary comment |
optionalChaining | ?. operator | Disable if codebase has many external API responses |
anyUnknown | any, unknown types | Should almost never be exempted |
typeAssertions | as Type casts | as const and branded types allowed by default |
doubleBang | !!value coercion | Disable if migrating legacy code |
enums | TypeScript enums | Disable if project convention uses enums |
exhaustiveSwitches | Non-exhaustive switch on unions | Rarely needs exemption |
productSwitchMatrix | Nested DU product matrices that repeatedly return the same Kind | Raise minRepeatedReturnKind only for generated exhaustive matrix code |
stateBranching | else if, state if/return ladders, nullish-combination ladders, equality ternaries | Narrow presentation/framework files only; use allowedFiles / allowedDirectories |
resultPatterns | Banned result type names | Add project-specific names to bannedNames |
ifOnField | if (obj.field) truthy checks | Add field names to suspiciousNames for stricter checking |
positionalArgs | Functions with 3+ positional args | Private functions exempted by default |
"enabled": false to fully disable a rule.Read .claude/ai-lab/perfect-typescripter/config.json at the project root if it exists. Preserve existing overrides.
If you're here because a hook blocked a write, identify which rule fired from the error message and add the minimum exemption needed. Prefer exemptions over disabling entire rules.
Common patterns:
"ignorePaths": [{ "path": "src/moon", "reason": "Roblox moon module with external API types" }]"booleanFields": { "exemptions": { "tsxFiles": true } }"nullUndefined": { "enabled": false } or mark boundaries with @api-boundary"enums": { "enabled": false }When the right config change isn't obvious, use AskUserQuestion. Present the candidate changes as options (e.g., "Disable rule X", "Add exemption for Y", "Exclude path Z"), mark the one that fixes the blocked write with the least enforcement loss as "(Recommended)", and describe for each option what TypeScript patterns it allows through and what correctness checks the user loses.
Show the user the exact JSON you intend to write to .claude/ai-lab/perfect-typescripter/config.json and call AskUserQuestion. Frame it as a real decision: which rule is being relaxed, what bug class that rule prevents, and what the user loses by relaxing it. Options should be along the lines of "Apply this exact config (Recommended)", "Apply with a narrower exemption (specify what)", "Cancel and leave the config unchanged".
Do NOT proceed to Step 4 unless the user picks an Apply option. If the user picks Cancel, stop and report.
config_write_guard.js blocks every AI Write/Edit to the config by default. The skill bypasses that block by touching a 60-second-TTL marker in the same directory as the target. The marker is single-shot (the hook deletes it on first read), and the Bash tool is intentionally NOT matched by the guard, so this is the only path that gets through.
Use Bash to create the marker. Both commands work; pick the one that fits the project's shell:
mkdir -p .claude/ai-lab/perfect-typescripter && touch .claude/ai-lab/perfect-typescripter/.config-write-approved
Or, if touch is unavailable on this platform:
mkdir -p .claude/ai-lab/perfect-typescripter && node -e "require('fs').writeFileSync('.claude/ai-lab/perfect-typescripter/.config-write-approved', '')"
The marker file must exist with a mtime fresher than 60 seconds when the Write fires. If the workflow stalls between Step 3 (AskUserQuestion approval) and Step 5 (the actual Write), redo Step 4 to refresh the marker.
Write .claude/ai-lab/perfect-typescripter/config.json at the project root. Only include rules that differ from defaults to keep the config minimal. The guard sees the fresh marker, deletes it, and lets the Write through.
If the Write is denied with a [perfect-typescripter] Refusing to edit enforcement config message, the marker was either missing or stale. Redo Step 4 immediately before the Write retry. Never resort to a Bash heredoc that bypasses the guard entirely; that loses the user-approval handshake the guard is meant to enforce.
This step is non-optional. Skipping it means a malformed config silently fails to load, and the user discovers the regression next time the guard fires unexpectedly.
.claude/ai-lab/perfect-typescripter/config.json exists and parses as valid JSON (run node -e "JSON.parse(require('fs').readFileSync('.claude/ai-lab/perfect-typescripter/config.json','utf8'))" and confirm no error).package.json has a "type-check" script: npm run type-check (or pnpm/yarn per the lockfile present)npx tsc --noEmit from the project roottsc --noEmit reported.npx claudepluginhub checkpickerupper/perfect-typescripter --plugin perfect-typescripterProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.