From ship-it-ops
Apply clean code principles (naming, functions, classes, error handling, testing, formatting) when writing or reviewing production-quality Python, TypeScript/JavaScript, or Java code. Invoke explicitly for PR reviews or code quality assessments. Do not invoke for shell scripts, SQL queries, config files, quick prototypes, or single-expression snippets.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ship-it-ops:ship-clean-codeThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill applies clean code principles plus modern software engineering best practices to help you write readable, maintainable, and debuggable code. It operates in two modes: writing (apply silently) and review (structured report).
examples/java-before-after.mdexamples/python-before-after.mdexamples/review-output-example.mdexamples/typescript-before-after.mdlang-java.mdlang-python.mdlang-typescript.mdoverrides.example.mdreference-smells.mdreference.mdtests/README.mdtests/fixture-1-python-bugs/expected-output.mdtests/fixture-1-python-bugs/input.pytests/fixture-2-typescript-types/expected-output.mdtests/fixture-2-typescript-types/input.tstests/fixture-3-java-srp/expected-output.mdtests/fixture-3-java-srp/input.javaThis skill applies clean code principles plus modern software engineering best practices to help you write readable, maintainable, and debuggable code. It operates in two modes: writing (apply silently) and review (structured report).
Start with these 3 rules and internalize them before learning the rest:
The detailed reference files (reference.md, reference-smells.md) assume familiarity with design patterns and SOLID principles — build up to those over time.
Writing mode (default when generating or modifying code): Apply all principles proactively. Produce clean code by default without commentary unless asked. Do not explain the principles being applied -- just write good code.
Review mode (when explicitly reviewing, using /ship-clean-code, or asked to review): Read the target code, analyze against the rules below, and produce a structured report using the Review Output Format defined in this skill.
Trigger review mode when the user says: "review", "clean code review", "code quality", "check this code", or invokes the skill explicitly. When in doubt, default to writing mode.
These 12 rules apply to ALL code, ALL languages, EVERY time:
Name every variable, function, and class to reveal its purpose. If a name requires a comment, rename it. No single-letter names except loop counters (i, j, k). No abbreviations unless universally understood (url, id, http).
Target under 20 lines. Hard ceiling at 50. If you can describe what a function does only by using "and" or "or", split it. Extract blocks in if/else/while into well-named functions.
Zero is ideal, one is good, two is OK, three requires justification. Group related parameters into objects/dataclasses/interfaces. Never use boolean flag arguments -- split into two functions instead.
A function named checkPassword must not initialize a session. If a function has side
effects, its name must say so (checkPasswordAndInitSession or better: split into two
calls).
Don't return null -- use Optional/Maybe types, empty collections, or throw exceptions. Don't pass null as an argument. Provide context when throwing exceptions (what operation, what input).
Delete it. Version control has the history. Commented-out code confuses readers who don't know if it's safe to delete.
If code needs a comment explaining what it does, refactor the code to be self-documenting. Good comments: intent explanations, warnings about consequences, TODO with ticket numbers.
Extract repeated logic into named functions. But apply the Rule of Three: wait for three instances before abstracting. Premature abstraction is worse than duplication.
Don't mix high-level orchestration with low-level details. Follow the Stepdown Rule: read the code top-to-bottom like a narrative, each function calling functions one abstraction level below.
Replace if (timer.hasExpired() && !timer.isRecurrent()) with
if (shouldBeDeleted(timer)). Extract complex boolean expressions into well-named
functions.
Every literal value with domain meaning must be a named constant.
if (age >= 18) becomes if (age >= LEGAL_DRINKING_AGE). This applies to array
indices, timeout values, status codes, and configuration values.
Each class/module has one and only one reason to change. If you can think of more than one motive for changing a class, it has more than one responsibility. Split it.
When reviewing code, report issues in this priority order:
P1 - BUGS: Logic errors, off-by-one, null dereference, race conditions, resource leaks, unreachable code, infinite loops.
P2 - SECURITY: Injection vulnerabilities (SQL, XSS, command), hardcoded secrets, insecure deserialization, path traversal, missing auth checks, unvalidated external input.
P3 - ERROR HANDLING: Swallowed exceptions, missing error paths, null returns, bare except/catch blocks, missing resource cleanup.
P4 - TESTABILITY: Untestable code (hidden dependencies, global state, static coupling), missing boundary handling.
P5 - MAINTAINABILITY: SRP violations, high coupling, missing abstractions, hardcoded config, backward-compatibility breaks.
P6 - READABILITY: Bad names, long functions (>50 lines), deep nesting (>3 levels), unclear intent, misleading comments, magic numbers.
P7 - STYLE: Formatting inconsistencies, import order, whitespace. Report ONLY if egregious or inconsistent within the file.
Rules for when NOT to be strict:
Don't rewrite untouched code. If the user asks to add a feature, don't simultaneously rename all variables in the file. Focus on the requested change.
Don't lecture. In writing mode, apply principles silently. Only explain when the user asks "why" or when in review mode.
Prototype code gets a pass. If the user says "quick hack", "prototype", "spike", or "just try this", relax all rules except: no hardcoded secrets, no injection vulnerabilities, no obvious security holes.
Consistency with existing codebase outweighs ideals. If the project uses snake_case in TypeScript, follow that convention. Match the surrounding code's style.
Performance-critical code can be ugly. When the user explicitly prioritizes performance, allow longer functions, less abstraction, and inline code. Note the trade-off in a comment.
Rule of Three for abstractions. Don't extract a shared function/class until the pattern appears three times. Two instances of similar code is not yet a pattern.
Never block on style. In review mode, style issues (P7) are suggestions only, never "must fix".
Detect the programming language from file extensions and context. Load the appropriate language-specific reference:
.py files → Read lang-python.md.ts, .tsx, .js, .jsx files → Read lang-typescript.md.java files → Read lang-java.mdApply universal principles first, then layer language-specific idioms on top. When the language is ambiguous or not covered, apply only universal principles.
When in review mode, produce this structured output:
## Code Review: [filename or scope]
### Critical (must fix before merge)
- **[P1-BUG] Line XX**: [Problem description]. -> [Specific fix suggestion with code snippet].
- **[P2-SEC] Line XX**: [Problem description]. -> [Specific fix suggestion].
### Important (should fix)
- **[P3-ERR] Line XX**: [Problem description]. -> [Fix suggestion].
- **[P4-TEST] Line XX**: `ServiceClass` instantiates `Dependency` internally via `new Dependency()`, making it impossible to test without the real implementation. -> Inject via constructor parameter; provide a fake in tests.
- **[P5-MAINT] Line XX**: [Problem description]. -> [Fix suggestion].
### Suggestions (improve when convenient)
- **[P6-READ] Line XX**: [Problem description]. -> [Fix suggestion].
### What's Good
- [Substantive positive observation about architecture, error handling, or test coverage -- not surface-level compliments. Name specific patterns done well.]
Rules for the output:
Before applying clean code rules, check for override files in this order (later files win on conflicts):
overrides.md next to this SKILL.md (team-wide overrides bundled with the skill).claude/ship-clean-code-overrides.md in the user's project root (project-specific overrides)Read whichever exist and apply their rules on top of the defaults below. Use overrides for: agreed naming deviations, relaxed line-length limits, project-specific idioms, disabled rules, custom additions.
A template is available at overrides.example.md — copy and edit. Do not modify overrides.example.md directly; it is reference material.
Phased rollout recommended:
Track: P1/P2 findings per PR (should trend toward zero), team friction reports.
This skill covers testing and debugging at a high level. For deeper work in those areas, defer to the sibling skills:
ship-tested-code. This skill flags only obvious test gaps and surface-level smells; ship-tested-code carries the T1-T7 priority hierarchy, mocking strategy, flakiness diagnosis, and language-specific test idioms.ship-debugged-code. This skill notes likely bugs in code review; ship-debugged-code runs the actual debugging process.ship-reviewed-prs. That skill runs a multi-persona PR-level review and delegates file-level naming/SRP/readability concerns back to this skill. When working a PR end-to-end, run ship-reviewed-prs first; it will tell you which files to run this skill on.When both apply, run this skill first (clean structure makes other reviews easier), then the specialized skill.
For deeper analysis, load supporting reference files alongside this SKILL.md:
reference.md — Detailed rules organized by concern (naming, functions, classes, errors, testing, logging, boundaries, quality gates)reference-smells.md — 66 code smells with detection signatures and fixes (C1-C5, E1-E2, F1-F4, G1-G36, J1-J3, N1-N7, T1-T9)lang-python.md, lang-typescript.md, lang-java.md — Language idiomsexamples/python-before-after.md, examples/typescript-before-after.md, examples/java-before-after.md — Concrete refactoring examplesexamples/review-output-example.md — End-to-end review output sampletests/ — Self-test fixtures (sample input code + expected review output)Paths are relative to this SKILL.md. Load on-demand when doing thorough reviews or when the user asks for detailed guidance on a specific topic.
Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub ship-it-ops/ship-code --plugin ship-secure-code