This skill should be used when writing, editing, or reviewing code, creating tests, or when the user asks about "code style", "codestyle", "formatting", "best practices", or code quality. Apply these rules to all code changes.
This skill defines the code style and quality standards to follow for all code written or modified.
Apply these rules consistently across all code changes:
let - Always use const for immutable bindings, or restructure code to avoid reassignmentconst foo = () => {} instead of function foo() {}// ✅ Correct - arrow function
const processData = (data: string) => {
return data.trim();
};
const calculate = (a: number, b: number) => a + b;
// ❌ Wrong - function declaration
function processData(data: string) {
return data.trim();
}
function calculate(a: number, b: number) {
return a + b;
}
Object.assign() - Use object spread syntax instead
// ✅ Correct - object spread
const updated = { ...original, newProp: 'value' };
const merged = { ...obj1, ...obj2 };
// ❌ Wrong - Object.assign()
const updated = Object.assign({}, original, { newProp: 'value' });
const merged = Object.assign({}, obj1, obj2);
+ - Use template literals instead
// ✅ Correct - template literals
const message = `Hello, ${name}!`;
const path = `${baseUrl}/api/${endpoint}`;
const multiline = `
Line 1
Line 2
`;
// ❌ Wrong - string concatenation
const message = 'Hello, ' + name + '!';
const path = baseUrl + '/api/' + endpoint;
const multiline = 'Line 1\n' + 'Line 2';
NEVER use type hacks like any - Always use proper types
Use unknown if the type is truly unknown, then narrow it with type guards
Prefer explicit types over implicit any
Use proper generics and type inference instead of type escape hatches
Types are always defined with a first capital letter - Use PascalCase for all type names
// ✅ Correct
type UserProfile = { name: string; age: number };
interface ApiResponse { data: unknown; }
class ServiceManager { }
// ❌ Wrong
type userProfile = { name: string; age: number };
interface apiResponse { data: unknown; }
class serviceManager { }
// ✅ Correct - focused try/catch
const data = await validateInput(input);
let result;
try {
result = await riskyOperation(data);
} catch (error) {
return handleOperationError(error);
}
return processResult(result);
// ❌ Wrong - massive try/catch
try {
const data = await validateInput(input);
const result = await riskyOperation(data);
const processed = processResult(result);
const formatted = formatOutput(processed);
return formatted;
} catch (error) {
return handleError(error);
}
.map(), .reduce(), .filter(), etc. over imperative loops
// ✅ Correct - functional approach with map
const doubled = numbers.map(n => n * 2);
// ✅ Correct - chaining functional methods
const result = users
.filter(user => user.isActive)
.map(user => user.name)
.sort();
// ✅ Correct - reduce for aggregation
const sum = numbers.reduce((acc, n) => acc + n, 0);
const grouped = items.reduce((acc, item) => {
const key = item.category;
return { ...acc, [key]: [...(acc[key] ?? []), item] };
}, {} as Record<string, Item[]>);
// ❌ Wrong - imperative loop
const doubled = [];
for (let i = 0; i < numbers.length; i++) {
doubled.push(numbers[i] * 2);
}
// ❌ Wrong - manual filtering and mapping
const result = [];
for (const user of users) {
if (user.isActive) {
result.push(user.name);
}
}
result.sort();
Avoid while loops - Use recursion, functional patterns, or for loops instead
while loops are harder to reason about and more error-prone.map(), .filter(), .reduce() when working with collectionsfor loop with clear bounds// ✅ Correct - recursion
const factorial = (n: number): number => {
if (n <= 1) return 1;
return n * factorial(n - 1);
};
const processItems = (items: Item[], index = 0): void => {
if (index >= items.length) return;
process(items[index]);
processItems(items, index + 1);
};
// ✅ Correct - functional approach
const results = items.map(item => process(item));
// ✅ Correct - for...of loop (when side effects are needed)
for (const item of items) {
process(item);
}
// ❌ Wrong - while loop
let i = 0;
while (i < items.length) {
process(items[i]);
i++;
}
let n = 5;
let result = 1;
while (n > 1) {
result *= n;
n--;
}
Avoid nested conditions - Prefer early returns and guard clauses
// ✅ Correct - early returns, flat structure
function processUser(user: User) {
if (!user) return null;
if (!user.isActive) return null;
if (!user.hasPermission) return null;
return performAction(user);
}
// ❌ Wrong - nested conditions
function processUser(user: User) {
if (user) {
if (user.isActive) {
if (user.hasPermission) {
return performAction(user);
}
}
}
return null;
}
When creating tests, follow these strict rules:
Keep tests simple - Follow the AAA (Arrange, Act, Assert) pattern:
Minimal test creation - DO NOT create extensive test suites unless explicitly requested
DO NOT use .js extensions in imports - Use extensionless imports
// ✅ Correct
import { foo } from './module'
import { bar } from '../utils/helper'
// ❌ Wrong
import { foo } from './module.js'
import { bar } from '../utils/helper.js'
NEVER use dynamic import() - Always use static imports at the top of the file
// ✅ Correct - static imports at top
import fs from "fs";
import path from "path";
import prettier from "prettier";
import { parseProjectManifest, resolveRef } from "./schema/project";
import { parseServiceManifest } from "./schema/service";
import { generateApiFile } from "./generators/api";
export async function generate(opts: { project: string }): Promise<void> {
// Use the imported modules directly
const content = fs.readFileSync(opts.project);
// ...
}
// ❌ Wrong - dynamic imports inside function
export async function generate(opts: { project: string }): Promise<void> {
const fs = await import("fs");
const path = await import("path");
const prettier = await import("prettier");
const { parseProjectManifest, resolveRef } = await import("./schema/project");
const { parseServiceManifest } = await import("./schema/service");
const { generateApiFile } = await import("./generators/api");
// ...
}
NEVER run git write commands - You are prohibited from executing:
git commitgit pushgit mergegit rebasegit cherry-pickRead-only git access - You may only:
git loggit statusgit diffWhen reviewing or writing code, verify:
let declarations presentany types or type escape hatchesObject.assign() - use object spread syntax+ - use template literals.map(), .reduce(), .filter()) used instead of loopswhile loops - use recursion, functional patterns, or for loops.js)import() - use static imports