Claude-skill-registry comment-style-guide
Code comment style guidelines - when to comment and when not to
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/comment-style-guide" ~/.claude/skills/majiayu000-claude-skill-registry-comment-style-guide && rm -rf "$T"
manifest:
skills/data/comment-style-guide/SKILL.mdsource content
Code Comment Style Guidelines
Philosophy
Write code that doesn't need comments. When comments are needed, make them count.
🚨 CRITICAL RULES
Rule #1: No Redundant Comments
FORBIDDEN: Comments that restate what the code obviously does
// ❌ WRONG - Comment restates the code // Convert pageNumber/pageSize to offset/limit if (results.pageNumber && results.pageSize) { params.offset = (results.pageNumber - 1) * results.pageSize; params.limit = Math.min(Math.max(results.pageSize, 1), 1000); } // ✅ CORRECT - No comment needed, code is self-explanatory if (results.pageNumber && results.pageSize) { params.offset = (results.pageNumber - 1) * results.pageSize; params.limit = Math.min(Math.max(results.pageSize, 1), 1000); }
// ❌ WRONG - Obvious from context // Apply mappers and set pagination info from response structure results.items = response.data.data.map(toUser); results.count = response.data.totalCount || 0; // ✅ CORRECT - Code speaks for itself results.items = response.data.data.map(toUser); results.count = response.data.totalCount || 0;
Rule #2: No Structural Comments in Tests
FORBIDDEN: Comments that describe test structure instead of business logic
// ❌ WRONG // Validate structure const groups = groupsResult.items; expect(groups).to.be.an('array'); // If groups exist, validate the first one if (groups.length > 0) { const firstGroup = groups[0]; // Validate common group fields that should exist if (firstGroup.id) { // ID should be a string expect(firstGroup.id).to.be.a('string'); } } // ✅ CORRECT - Let the test structure be self-documenting const groups = groupsResult.items; expect(groups).to.be.an('array'); if (groups.length > 0) { const firstGroup = groups[0]; if (firstGroup.id) { expect(firstGroup.id).to.be.a('string'); } }
Rule #3: Concise JSDoc
Keep JSDoc focused and minimal. Avoid redundant examples.
// ❌ WRONG - Excessive examples /** * Normalizes null to undefined for optional properties * * This helper ensures consistent handling of optional values by converting * null to undefined, while preserving all other values including falsy ones * like 0, false, and empty strings. * * @param value - The value to normalize * @returns undefined if input is null or undefined, otherwise returns the value as-is * * @example * // Replaces manual normalization * // Before: * phoneNumber: raw.phoneNumber ?? undefined, * avatarUrl: raw.avatarUrl ?? undefined, * * // After: * phoneNumber: optional(raw.phoneNumber), * avatarUrl: optional(raw.avatarUrl), * * @example * // Preserves falsy values (0, false, "") * optional(0) // returns 0 (not undefined) * optional(false) // returns false (not undefined) * optional("") // returns "" (not undefined) * optional(null) // returns undefined * optional(undefined) // returns undefined */ export function optional<T>(value: T | null | undefined): T | undefined { return (value ?? undefined) as T | undefined; } // ✅ CORRECT - Concise and focused /** * Normalizes null to undefined for optional properties * * Converts null to undefined while preserving other falsy values (0, false, "") * * @param value - The value to normalize * @returns undefined if input is null or undefined, otherwise returns the value as-is */ export function optional<T>(value: T | null | undefined): T | undefined { return (value ?? undefined) as T | undefined; }
Rule #4: No Function Name Restating
FORBIDDEN: JSDoc that only restates the function name
// ❌ WRONG - Adds no information /** * Mock authenticated request with proper headers */ export function mockAuthenticatedRequest(baseUrl: string, token: string) { // ... } /** * Clean up all nock mocks */ export function cleanNock(): void { nock.cleanAll(); } // ✅ CORRECT - Function names are self-documenting for simple functions export function mockAuthenticatedRequest(baseUrl: string, token: string) { // ... } export function cleanNock(): void { nock.cleanAll(); }
When Comments ARE Valuable
1. Business Logic Explanation
// ✅ GOOD - Explains WHY, not WHAT // API returns 400 for invalid credentials but 404 for missing users // We normalize both to NotConnectedError for consistent handling if (error.status === 400 || error.status === 404) { throw new NotConnectedError(); }
2. Non-Obvious Behavior
// ✅ GOOD - Warns about API quirk // API returns user data in response.data.data for single gets // but directly in response.data for list operations const rawData = response.data.data || response.data;
3. TODOs and Future Work
// ✅ GOOD - Tracks technical debt // TODO: Move to @zerobias-org/util-hub-module-utils once stabilized export function mapWith<T>(mapper: (raw: any) => T, value: any): T | undefined { // ... }
4. Complex Algorithm Explanation
// ✅ GOOD - Explains non-trivial logic // Calculate weighted priority: active bugs (3x) + planned features (1x) const priority = (bugCount * 3) + featureCount;
Producer-Specific Guidelines
Pagination Pattern Comments
NEVER comment standard pagination conversion:
// ❌ WRONG // Convert pageNumber/pageSize to offset/limit if (results.pageNumber && results.pageSize) { params.offset = (results.pageNumber - 1) * results.pageSize; params.limit = Math.min(Math.max(results.pageSize, 1), 1000); } // ✅ CORRECT - Standard pattern, no comment needed if (results.pageNumber && results.pageSize) { params.offset = (results.pageNumber - 1) * results.pageSize; params.limit = Math.min(Math.max(results.pageSize, 1), 1000); }
Parameter Handling
NEVER comment obvious parameter handling:
// ❌ WRONG // Add optional filter parameter if (filter) { params.filter = filter; } // Add optional options parameter if (options) { params.options = options; } // ✅ CORRECT if (filter) { params.filter = filter; } if (options) { params.options = options; }
Test-Specific Guidelines
Assertion Comments
NEVER comment assertions that match their code:
// ❌ WRONG // Required fields expect(entry).to.have.property('id'); expect(entry).to.have.property('name'); // ID should be a string expect(entry.id).to.be.a('string'); // ✅ CORRECT expect(entry).to.have.property('id'); expect(entry).to.have.property('name'); expect(entry.id).to.be.a('string');
Setup Comments
Only comment non-obvious test setup:
// ❌ WRONG - Obvious from describe block and test name describe('Group Operations', () => { it('should list groups with pagination', async () => { // First get a list to find valid IDs const result = await groupApi.list(orgId, 1, 10); // ... }); }); // ✅ CORRECT - Comment explains special case describe('Group Operations', () => { it('should handle groups with special characters in names', async () => { // Unicode group names require special URL encoding on this endpoint const result = await groupApi.get(orgId, '测试组'); // ... }); });
Summary
Write Comments That:
- ✅ Explain WHY, not WHAT
- ✅ Document non-obvious behavior
- ✅ Warn about API quirks
- ✅ Track technical debt (TODOs)
Avoid Comments That:
- ❌ Restate the code
- ❌ Describe obvious structure
- ❌ Repeat function names
- ❌ Explain self-documenting code