agents-standards
Standards for authoring SDD plugin agents — frontmatter, self-containment, skill references, and no-user-interaction rules.
Shared TypeScript coding standards for strict, immutable, type-safe code.
$ npx -y skills add LiorCohen/sdd --skill typescript-standards --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/typescript-standardsContext preview
The summary Claude sees to decide when to auto-load this skill.
Shared TypeScript coding standards for strict, immutable, type-safe code.
name: typescript-standards description: Shared TypeScript coding standards for strict, immutable, type-safe code.
Shared standards for all TypeScript code in this methodology (backend and frontend).
---
All projects must use these TypeScript compiler options:
// tsconfig.json requirements
{
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true
}**Rules:**
---
Use `readonly` on all properties, `ReadonlyArray<T>` for arrays, `Readonly<T>` / `ReadonlyMap` / `ReadonlySet` for generic types. Use `const` exclusively (never `let` or `var`). Use spread operators for updates — never mutate.
See [immutability.md](resources/immutability.md) for full examples and functional alternatives to `let`.
---
**CRITICAL:** `.push()`, `.pop()`, `.shift()`, `.unshift()`, `.splice()`, `.sort()`, `.reverse()`, `.fill()` on arrays; `obj.prop = x`, `delete obj.prop`, `Object.assign(target, ...)` on objects; `.set()`, `.delete()`, `.add()`, `.clear()` on Maps/Sets — all strictly forbidden. Use spread operators and immutable patterns instead.
See [banned-operations.md](resources/banned-operations.md) for the complete reference tables with alternatives.
---
// GOOD: Arrow functions
const createUser = async (deps: Dependencies, args: CreateUserArgs): Promise<CreateUserResult> => {
// ...
};
const handleClick = () => {
// ...
};
// BAD: function keyword
async function createUser(deps: Dependencies, args: CreateUserArgs): Promise<CreateUserResult> {
// ...
}
function handleClick() {
// ...
}**Rule:** Use arrow functions exclusively. Never use the `function` keyword.
---
**CRITICAL:** Never use classes or inheritance unless creating a subclass of Error.
// GOOD: Types and functions
type User = {
readonly id: string;
readonly email: string;
readonly createdAt: Date;
};
const createUser = (args: CreateUserArgs): User => ({
id: generateId(),
email: args.email,
createdAt: new Date(),
});
// GOOD: Error subclass (only valid use of class)
class ValidationError extends Error {
constructor(
message: string,
readonly field: string,
readonly code: string
) {
super(message);
this.name = 'ValidationError';
}
}
class NotFoundError extends Error {
constructor(resource: string, id: string) {
super(`${resource} with id ${id} not found`);
this.name = 'NotFoundError';
}
}
// BAD: Classes for domain objects
class User {
constructor(
public id: string,
public email: string
) {}
updateEmail(email: string) {
this.email = email; // Mutation!
}
}
// BAD: Inheritance hierarchies
class Animal { /* ... */ }
class Dog extends Animal { /* ... */ }
// BAD: Service classes
class UserService {
constructor(private db: Database) {}
async createUser(args: CreateUserArgs) { /* ... */ }
}**Why:**
---
// GOOD: Native methods
const filtered = users.filter(u => u.active);
const updated = { ...user, email: newEmail };
const mapped = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k, v * 2])
);
// BAD: External utility libraries
import { map } from 'lodash'; // Never
import { produce } from 'immer'; // Never
import * as R from 'ramda'; // Never**Rule:** Use only native JavaScript/TypeScript features. No utility libraries like lodash, ramda, or immer.
**Why:** Reduces bundle size, eliminates dependencies, forces understanding of native methods, ensures code remains maintainable without external library knowledge.
---
Named exports only (never default exports). ES modules only (never CommonJS). `index.ts` files contain only imports/exports (no logic). Always import through `index.ts` (never bypass to implementation files). Inside a module, never import from its own `index.ts` — use relative paths to siblings. No file extensions in imports. Use `@/` path alias for deep imports (2+ directory levels). Use `import type` for type-only imports.
See [module-system.md](resources/module-system.md) for full rules with examples.
---
**Rule:** `interface` for function-only contracts (callbacks, loggers, handlers). `type` for everything else. Data types should not contain functions.
// GOOD: interface for function-only contracts
interface Logger {
readonly info: (message: string, data?: unknown) => void;
readonly warn: (message: string, data?: unknown) => void;
readonly error: (message: string, data?: unknown) => void;
}
// GOOD: type for data shapes
type User = {
readonly id: string;
readonly email: string;
readonly createdAt: Date;
};
type ServerMode = 'api' | 'worker' | 'cron';
type HelmSettings = HelmServerSettings | HelmWebappSettings;
// BAD: interface for data
interface User {
readonly id: string;
readonly email: string;
}
// BAD: type for function contracts
type Logger = {
readonly info: (message: string) => void;
};
// BAD: functions inside data types
type User = {
readonly id: string;
readonly getDisplayName: () => string; // Data types should not have methods
};---
Use type aliases to give meaning to primitives. A function accepting `Milliseconds` is
Structure for AI-assisted development AI coding assistants are powerful but chaotic. You prompt, you get code, but then what?
Repo: LiorCohen/sdd
Standards for authoring SDD plugin agents — frontmatter, self-containment, skill references, and no-user-interaction rules.
Standards for authoring SDD plugin commands — frontmatter, user interaction, skill/agent invocation, CLI integration, and output formatting.
Create a commit following repository guidelines with proper versioning and changelog updates.
Two-step self-review at every task lifecycle phase. Step 1 (this skill) runs in-context to gather session signals — files read vs grepped, user pushback, build…
D2 diagramming language reference for architecture diagrams, sequence diagrams, grid layouts, SQL tables, and class diagrams. Produces .d2 files rendered via…
Writes and maintains user-facing documentation for the SDD plugin. Proactively detects when docs are out of sync with plugin capabilities.