commit 1fb75872247fc7fe0a20b5428f679ed6318bcff9 Author: Zhongwei Li Date: Sat Nov 29 18:14:32 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..808b37e --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "ts-quality", + "description": "TypeScript quality enforcement with instant file-scoped checks and architectural review. Auto-activated skill runs typecheck and lint after each file write. Includes /ts-review command for comprehensive code analysis.", + "version": "1.0.0", + "author": { + "name": "Clifton Cunningham", + "email": "clifton.cunningham@gmail.com" + }, + "skills": [ + "./skills/ts-quality" + ], + "commands": [ + "./commands/" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2ab6da --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# ts-quality + +TypeScript quality enforcement with instant file-scoped checks and architectural review. Auto-activated skill runs typecheck and lint after each file write. Includes /ts-review command for comprehensive code analysis. diff --git a/commands/ts-review.md b/commands/ts-review.md new file mode 100644 index 0000000..6fcfc09 --- /dev/null +++ b/commands/ts-review.md @@ -0,0 +1,486 @@ +--- +name: ts-review +description: Perform architectural review of uncommitted TypeScript code with quality checks and pragmatic improvement suggestions +--- + +# TypeScript Architectural Review + +This command performs a comprehensive architectural review of uncommitted TypeScript code, combining quality checks with architectural analysis to provide concrete, pragmatic suggestions for improvement. + +## What This Command Does + +When invoked, this command: + +1. **Identifies Uncommitted Changes** - Uses `git diff` to find modified/new .ts/.tsx files +2. **Runs Quality Checks** - Same criteria as typescript-quality skill: + - Type checking (`pnpm typecheck`) + - Linting (`pnpm lint`) + - Building (`pnpm build`) +3. **Performs Architectural Review** - Analyzes code structure, design patterns, and provides concrete improvements +4. **Delivers Pragmatic Suggestions** - Actionable recommendations, not theoretical perfection + +## Usage + +```bash +/ts-review +``` + +Run this command before committing TypeScript changes to ensure both quality and good architectural design. + +## Instructions + +When this command is invoked, follow these steps: + +### 1. Identify Changed Files and Check Size + +**Step 1: Find changed TypeScript files** + +```bash +# Get list of modified TypeScript files (both staged and unstaged) +{ git diff --name-only; git diff --cached --name-only; } | sort -u | grep -E '\.(ts|tsx)$' + +# Also get untracked TypeScript files +git ls-files --others --exclude-standard | grep -E '\.(ts|tsx)$' +``` + +**If no TypeScript files found:** +- Report: "No uncommitted TypeScript files found. Nothing to review." +- Exit + +**Step 2: Check total diff size (for planning purposes)** + +```bash +# Count total lines changed (gives us a sense of changeset size) +{ git diff; git diff --cached; } | wc -l +``` + +**If diff is larger than 1000 lines:** +- Report: "Large changeset detected (X lines across Y TypeScript files). This review may take a while." +- List all changed TypeScript files +- **Use the AskUserQuestion tool** to let the user choose: + - Option 1: "Review all files now" + - Option 2: "Let me select specific files to review" + - Option 3: "Review files one at a time" +- Based on user's choice, proceed accordingly + +**If diff is 1000 lines or less:** +- Proceed with full review of all changed TypeScript files + +### 2. Run Quality Checks (ZERO TOLERANCE) + +Execute quality checks sequentially, stopping at first failure: + +```bash +pnpm typecheck && pnpm lint && pnpm build +``` + +**If any check fails:** +- Report the specific errors with file paths and line numbers +- DO NOT proceed to architectural review +- Exit with clear instructions to fix errors first + +**If all checks pass:** +- Report: "āœ“ All quality checks passed" +- Proceed to architectural review + +### 3. Read Changed Files + +**Use the Read tool to analyze all changed TypeScript files** from step 1. + +For each file in the list: +- Use the Read tool to get the current file contents +- Analyze the code structure, patterns, and potential issues +- Focus your review on understanding what changed and why + +**Build understanding:** +- Understand what functionality is being added/modified in each file +- Identify architectural patterns in the code +- Look for potential issues in the implementation +- Consider how changes fit into the broader codebase structure + +### 4. Perform Architectural Review + +Analyze the uncommitted code for: + +#### A. Design Patterns & Principles + +**SOLID Principles:** +- **Single Responsibility**: Does each class/function have one clear purpose? +- **Open/Closed**: Is code open for extension, closed for modification? +- **Liskov Substitution**: Can subclasses replace parent classes without breaking? +- **Interface Segregation**: Are interfaces focused and not bloated? +- **Dependency Inversion**: Does code depend on abstractions, not concretions? + +**Common Issues to Flag:** +- God classes/functions doing too much +- Tight coupling between modules +- Circular dependencies +- Missing abstractions +- Violation of separation of concerns + +#### B. Code Structure & Organization + +**File Organization:** +- Are related functions/classes grouped logically? +- Is the file size reasonable (< 500 lines generally)? +- Should code be split into multiple files? +- Are imports organized and minimal? + +**Function/Method Design:** +- Are functions focused on a single task? +- Is complexity reasonable (cyclomatic complexity < 10)? +- Are parameter counts reasonable (< 5 parameters)? +- Are functions too long (> 50 lines warrants review)? + +**Class Design:** +- Are classes cohesive (methods work with shared state)? +- Is inheritance used appropriately (favor composition)? +- Are class responsibilities clear? + +#### C. Type Safety & TypeScript Usage + +**Type Quality:** +- Are types explicit where clarity is needed? +- Is `any` being abused? (should use `unknown` or proper types) +- Are union types used effectively? +- Are generics used where appropriate? +- Are type guards used for runtime safety? + +**Type Organization:** +- Should types be extracted to separate files? +- Are complex types well-documented? +- Are types reusable across the codebase? + +#### D. Error Handling & Resilience + +**Error Handling:** +- Are errors handled appropriately? +- Are error messages informative? +- Are errors typed (custom error classes)? +- Is error propagation clear? + +**Edge Cases:** +- Are null/undefined cases handled? +- Are boundary conditions considered? +- Is input validation present? + +#### E. Testability & Maintainability + +**Testability:** +- Can the code be easily unit tested? +- Are dependencies injectable? +- Is business logic separated from infrastructure? +- Are side effects isolated? + +**Maintainability:** +- Is code self-documenting with clear names? +- Are complex sections commented? +- Is there duplication that should be extracted? +- Can code be understood by other developers? + +#### F. Performance & Efficiency + +**Common Performance Issues:** +- Unnecessary re-renders (React components) +- N+1 query problems +- Missing memoization for expensive operations +- Inefficient algorithms (O(n²) when O(n) exists) +- Large object copying + +**Note**: Only flag performance issues that are clearly problematic, not micro-optimizations. + +### 5. Generate Pragmatic Suggestions + +For each issue found, provide: + +1. **Location**: File path and line numbers (e.g., `src/auth/login.ts:45-67`) +2. **Issue**: Clear description of the problem +3. **Impact**: Why this matters (coupling, testing, performance, etc.) +4. **Suggestion**: Concrete, actionable fix (not theoretical) +5. **Example**: Show before/after code when helpful + +**Format each suggestion as:** + +```markdown +### Issue: [Brief Title] + +**Location:** `file/path.ts:line-range` + +**Problem:** +[Clear description of what's wrong] + +**Impact:** +[Why this matters - coupling, maintainability, bugs, performance] + +**Suggestion:** +[Concrete steps to improve] + +**Example:** +[Optional: before/after code snippet] +``` + +### 6. Prioritize Suggestions + +Organize suggestions by priority: + +**šŸ”“ Critical (Fix Now):** +- Severe SOLID violations +- Major coupling issues +- Security concerns +- Clear bug risks + +**🟔 Important (Fix Soon):** +- Moderate design issues +- Testability problems +- Maintainability concerns +- Performance issues + +**🟢 Nice to Have (Consider):** +- Minor improvements +- Consistency issues +- Optimization opportunities + +### 7. Provide Summary + +End with a summary: + +```markdown +## Summary + +**Files Reviewed:** [count] +**Quality Checks:** āœ“ All passed +**Issues Found:** +- šŸ”“ Critical: [count] +- 🟔 Important: [count] +- 🟢 Nice to Have: [count] + +**Overall Assessment:** +[1-2 sentence summary of code quality] + +**Top Priority:** +[Most important thing to address] +``` + +## Best Practices for Reviews + +### Be Pragmatic, Not Pedantic + +- Focus on issues that genuinely impact quality +- Don't flag style issues already caught by linting +- Avoid theoretical concerns without real impact +- Prioritize maintainability and clarity + +### Be Concrete, Not Abstract + +- āŒ "This violates separation of concerns" +- āœ… "Extract database logic from this component into a repository class - see example below" + +### Be Helpful, Not Critical + +- Frame suggestions as improvements, not criticisms +- Acknowledge good patterns when you see them +- Explain the "why" behind suggestions + +### Be Realistic About Refactoring + +- Don't suggest massive refactors for small changes +- Consider the context and scope of the commit +- Focus on incremental improvements +- Note when bigger refactors might be valuable "in the future" + +## Edge Cases + +### No Issues Found + +If the code is genuinely good: + +```markdown +## Review Complete + +**Files Reviewed:** [count] +**Quality Checks:** āœ“ All passed +**Architectural Issues:** None found + +**Assessment:** +The uncommitted TypeScript code follows good architectural practices. The code is: +- Well-structured and organized +- Properly typed with good TypeScript usage +- Testable and maintainable +- Following SOLID principles appropriately + +No changes recommended. Code is ready to commit. +``` + +### Only Quality Check Failures + +If quality checks fail before architectural review: + +```markdown +## Quality Checks Failed + +**Files Reviewed:** [count] +**Quality Check Status:** āœ— Failed + +The following quality checks must pass before architectural review: + +[Error output from failed checks] + +Please fix these errors and run `/ts-review` again. +``` + +### Mixed Results + +Some files good, some with issues - provide granular feedback per file. + +## Example Output + +```markdown +# TypeScript Architectural Review + +**Date:** 2025-01-15 +**Uncommitted Files:** 3 TypeScript files + +## Quality Checks + +āœ“ Type checking passed +āœ“ Linting passed +āœ“ Build passed +āœ“ Tests passed (12/12) + +--- + +## Architectural Review + +### šŸ”“ Critical: God Class with Multiple Responsibilities + +**Location:** `src/services/UserService.ts:15-250` + +**Problem:** +The `UserService` class handles authentication, profile management, email notifications, and database operations. This violates the Single Responsibility Principle. + +**Impact:** +- Difficult to test (must mock database, email, auth) +- Changes to email logic risk breaking authentication +- Class has 250 lines and growing + +**Suggestion:** +Split into focused services: +1. `AuthService` - handles login/logout/tokens +2. `UserProfileService` - manages user profiles +3. `UserNotificationService` - sends user emails +4. `UserRepository` - database operations + +Keep `UserService` as a facade if needed, delegating to specialized services. + +**Example:** +```typescript +// Before: One class doing everything +class UserService { + login() { /* auth logic */ } + updateProfile() { /* profile logic */ } + sendEmail() { /* email logic */ } + saveToDb() { /* db logic */ } +} + +// After: Focused services +class AuthService { + constructor(private userRepo: UserRepository) {} + login() { /* auth logic */ } +} + +class UserProfileService { + constructor( + private userRepo: UserRepository, + private notificationService: UserNotificationService + ) {} + updateProfile() { /* profile logic */ } +} +``` + +--- + +### 🟔 Important: Missing Abstraction for Third-Party API + +**Location:** `src/api/PaymentProcessor.ts:45-89` + +**Problem:** +Stripe API calls are made directly throughout the code with hardcoded endpoints and no abstraction layer. + +**Impact:** +- Cannot easily switch payment providers +- Difficult to test (must mock Stripe SDK directly) +- Stripe-specific logic scattered across files + +**Suggestion:** +Create a `PaymentGateway` interface and `StripePaymentGateway` implementation: + +```typescript +interface PaymentGateway { + processPayment(amount: number, token: string): Promise + refund(transactionId: string): Promise +} + +class StripePaymentGateway implements PaymentGateway { + // Stripe-specific implementation +} + +// Easy to test with a mock +class MockPaymentGateway implements PaymentGateway { + // Test implementation +} +``` + +--- + +### 🟢 Nice to Have: Extract Complex Type + +**Location:** `src/types/api.ts:120-145` + +**Problem:** +Inline type definition for API response is complex and reused in 3 places with slight variations. + +**Suggestion:** +Extract to a named type with generic parameter for variations: + +```typescript +type ApiResponse = { + data: T + status: 'success' | 'error' + metadata: { + timestamp: number + requestId: string + } +} +``` + +--- + +## Summary + +**Files Reviewed:** 3 +**Quality Checks:** āœ“ All passed +**Issues Found:** +- šŸ”“ Critical: 1 +- 🟔 Important: 1 +- 🟢 Nice to Have: 1 + +**Overall Assessment:** +Code quality is good, but the UserService class needs immediate refactoring to improve testability and maintainability. + +**Top Priority:** +Split UserService into focused services (AuthService, UserProfileService, etc.) +``` + +## Requirements + +This command requires: + +- **Git repository** - Uses git to identify uncommitted files +- **pnpm** - For running quality checks +- **TypeScript** - Configured in the project +- **Linter, build, test** - Same requirements as typescript-quality skill + +## Related + +- **typescript-quality skill** - Automatically enforces quality checks when modifying TypeScript files +- Use `/ts-review` for deeper architectural analysis before commits diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..266dcca --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,49 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:cliftonc/claude-plugins:plugins/ts-quality", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "ee7cac4da24f14f7c165bfc47863dc484b66a19c", + "treeHash": "edd55642beb1a6605dba65b24a659651b4b60c76cc08c6eea6f87791e9704bee", + "generatedAt": "2025-11-28T10:15:40.715841Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "ts-quality", + "description": "TypeScript quality enforcement with instant file-scoped checks and architectural review. Auto-activated skill runs typecheck and lint after each file write. Includes /ts-review command for comprehensive code analysis.", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "64977d45fff0ba9ec055af36f8e27cf96b1500298f1f35cc5a3f437e7b1c9c57" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "5f297abbab9be43c700539b5d8e6827b70a259183a1dfceb009c3b4384f84686" + }, + { + "path": "commands/ts-review.md", + "sha256": "7d22f729b5b94353dd42f9608675cf989e4394721d49ece2f01e6cd95d0c8796" + }, + { + "path": "skills/ts-quality/SKILL.md", + "sha256": "d71d2c3c6023cfdc416fda38292657260ed8fd41edf81c59cc82b6403ff96535" + } + ], + "dirSha256": "edd55642beb1a6605dba65b24a659651b4b60c76cc08c6eea6f87791e9704bee" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/ts-quality/SKILL.md b/skills/ts-quality/SKILL.md new file mode 100644 index 0000000..a4c2827 --- /dev/null +++ b/skills/ts-quality/SKILL.md @@ -0,0 +1,210 @@ +--- +name: ts-quality +description: Enforce TypeScript quality standards immediately after writing or modifying .ts/.tsx files. Run type checking and linting on each changed file for instant feedback. Use after creating/editing TypeScript files, or when quality checks, typecheck, lint, or validate are mentioned. +--- + +# TypeScript Quality Enforcement + +This skill helps maintain TypeScript code quality by running instant checks on each file after it's written or modified. + +## What This Skill Does + +When activated, this skill ensures TypeScript code meets quality standards by: + +1. **Type Checking** - Runs `pnpm exec tsc --noEmit ` to ensure zero TypeScript type errors +2. **Linting** - Runs `pnpm lint ` to enforce code style consistency + +Checks run on the SPECIFIC FILE that was just written/modified, not the entire project. + +## When to Use This Skill + +Activate this skill: + +- **Immediately after writing or modifying any .ts or .tsx file** +- After creating new TypeScript files +- After editing existing TypeScript files +- When user mentions: "quality checks", "typecheck", "lint", "validate code" +- Before creating git commits +- During code review processes + +## Quality Standards + +**ZERO TOLERANCE POLICY**: No lint errors or type errors are acceptable. + +### Required Checks (in sequence): + +1. **Type Checking** - File-scoped typecheck + - Must pass with zero errors + - Validates TypeScript type safety for the specific file + +2. **Linting** - File-scoped lint + - Must pass with zero errors + - Enforces consistent code formatting and style + +## Instructions + +When this skill is active, follow these steps: + +### 1. Announce Activation + +Immediately inform the user that quality checks are running: + +``` +šŸ” Checking {filename}... +``` + +Replace `{filename}` with the actual file path (e.g., `src/utils/auth.ts`). + +### 2. Identify the File to Check + +Determine which TypeScript file was just written or modified. This is the file to check. + +### 3. Run File-Scoped Quality Checks + +Execute checks sequentially on the SPECIFIC FILE ONLY: + +```bash +# Type check the specific file +pnpm exec tsc --noEmit path/to/file.ts + +# Lint the specific file +pnpm lint path/to/file.ts +``` + +**Important**: +- Only check the file that was written/modified +- Do NOT run project-wide checks +- Each command must succeed before the next runs + +### 4. Report Results + +**If all checks pass:** +Report success clearly: +``` +āœ“ {filename}: typecheck and lint passed +``` + +**If any check fails:** +- Report the specific errors with line numbers +- Format: `āœ— {filename}: found N errors` +- Show the actual error messages +- DO NOT proceed to subsequent checks +- DO NOT allow commits with failing checks +- Fix the errors before continuing + +## Type Safety Guidelines + +### DO: + +- Use explicit types for function parameters and return values +- Leverage TypeScript's type inference for simple variable assignments +- Use `unknown` instead of `any` when the type is truly unknown +- Define interfaces for object shapes +- Use type guards for runtime validation of external data +- Document complex types with JSDoc comments + +### DO NOT: + +- Use `any` without explicit justification in comments +- Ignore TypeScript errors (no `@ts-ignore` without explanation) +- Skip typecheck before committing +- Commit code with lint errors +- Use `@ts-expect-error` to suppress valid errors +- Bypass quality checks "just this once" + +## Examples + +### Example 1: Creating New TypeScript File + +**User**: "Create a new TypeScript component for user authentication" + +**Actions**: +1. Create the file with proper types (explicit parameter and return types) +2. Avoid using `any` types +3. After file creation, immediately run quality checks: + - Announce: `šŸ” Checking src/components/Auth.tsx...` + - Run: `pnpm exec tsc --noEmit src/components/Auth.tsx` + - Run: `pnpm lint src/components/Auth.tsx` + - Report: `āœ“ src/components/Auth.tsx: typecheck and lint passed` +4. Only consider the task complete when checks pass + +### Example 2: Modifying Existing Code + +**User**: "Update the session processing logic to handle new event types" + +**Actions**: +1. Make changes to the file maintaining type safety +2. After saving the file, immediately run quality checks: + - Announce: `šŸ” Checking packages/session/src/processor.ts...` + - Run: `pnpm exec tsc --noEmit packages/session/src/processor.ts` + - Run: `pnpm lint packages/session/src/processor.ts` + - Report results: + - If passed: `āœ“ packages/session/src/processor.ts: typecheck and lint passed` + - If failed: `āœ— packages/session/src/processor.ts: found 2 errors` (then show errors) + +### Example 3: File with Errors + +**User**: Writes a file with type errors + +**Actions**: +1. Announce: `šŸ” Checking src/utils/helper.ts...` +2. Run typecheck: `pnpm exec tsc --noEmit src/utils/helper.ts` +3. Detect errors and report: + ``` + āœ— src/utils/helper.ts: found 3 errors + + src/utils/helper.ts:15:5 - error TS2322: Type 'string' is not assignable to type 'number'. + src/utils/helper.ts:22:10 - error TS2339: Property 'foo' does not exist on type 'User'. + src/utils/helper.ts:35:3 - error TS2345: Argument of type 'null' is not assignable to parameter of type 'string'. + ``` +4. Do NOT proceed to lint +5. Wait for user to fix errors + +## Integration with pnpm Workspaces + +This skill works with pnpm workspace monorepos by checking individual files in their packages. + +File-scoped checks work across packages without needing to change directories. + +## Quick Reference Commands + +```bash +# File-scoped typecheck (fast, targeted) +pnpm exec tsc --noEmit path/to/file.ts + +# File-scoped lint +pnpm lint path/to/file.ts + +# Both checks in sequence +pnpm exec tsc --noEmit path/to/file.ts && pnpm lint path/to/file.ts +``` + +## Error Handling + +When errors occur: + +1. **Type Errors**: Show the file, line number, and error message +2. **Lint Errors**: Show the file, line number, rule violated, and how to fix + +Always provide actionable information to help fix the errors. + +## Best Practices + +- **Check after every file write** - Instant feedback prevents accumulating errors +- **Fix errors immediately** - Don't accumulate technical debt +- **Type errors first** - Must be resolved before linting +- **Never commit failing code** - No exceptions +- **File-scoped only** - Don't run project-wide checks +- **Pragmatic quality** - Focus on correctness, not perfection + +## Requirements + +This skill requires projects to have: + +- **pnpm** installed +- **TypeScript** installed and configured +- **Linter** (Biome, ESLint, or similar) configured + +The skill uses: +- `pnpm exec tsc --noEmit ` for type checking +- `pnpm lint ` for linting