UNPKG

eslint-plugin-vibe-coder

Version:

ESLint plugin with custom rules to prevent common bad practices made by robots (and humans who code like robots)

251 lines (176 loc) 7.16 kB
# ESLint Plugin: Vibe Coder 🤖🚫 > **Stop robots from ruining your code vibes!** This ESLint plugin contains custom rules designed to prevent common bad practices that AI assistants (and humans who code like robots) often make. Because sometimes the best code is the code that doesn't overthink everything. ## 🎯 What This Plugin Does We've all been there - you ask an AI to help with some code, and it gives you a 500-line solution for a problem that could be solved in 10 lines. Or it creates variable names that look like they were generated by a random string generator. This plugin helps prevent those "robot moments" in your codebase by enforcing rules that encourage clear, explicit, and human-readable code. ## 🚀 Installation ```bash npm install --save-dev eslint-plugin-vibe-coder ``` ## 📝 Usage Add `vibe-coder` to your ESLint configuration: ```js // .eslintrc.js module.exports = { extends: ['plugin:vibe-coder/recommended'], }; ``` Or configure individual rules: ```js // .eslintrc.js module.exports = { plugins: ['vibe-coder'], rules: { 'vibe-coder/no-optional-properties': 'error', }, }; ``` ## 🛡️ Rules ### `no-optional-properties` **What it does:** Prevents optional properties in TypeScript types and interfaces to encourage explicit design decisions. **Why this rule exists:** Optional properties often indicate unclear requirements or lazy design. They can make code harder to understand and maintain because: - They create uncertainty about what data is actually required - They lead to defensive programming patterns with lots of null checks - They make APIs less predictable and harder to use correctly - They often indicate that the developer hasn't thought through the requirements clearly This rule prevents all forms of optional properties to encourage explicit design decisions and clearer APIs. **What it catches:** ```typescript interface User { name?: string; // ❌ Error: Optional property avatar: string | null; // ❌ Error: Union with null metadata: string | undefined; // ❌ Error: Union with undefined email: string; } ``` **What it allows:** ```typescript interface User { name: string; // ✅ Good: Required property role: 'admin' | 'user' | 'guest'; // ✅ Good: Union without undefined/null email: string; } ``` **Configuration:** ```js module.exports = { rules: { 'vibe-coder/no-optional-properties': 'error', }, }; ``` **Error Messages:** - `"Optional properties should be avoided. Use required properties instead."` ## 🤔 When to Use This Rule **Use this rule when:** - You want to enforce explicit API design - You're building libraries or frameworks where API clarity is crucial - You want to prevent defensive programming patterns - You're working on a team and want consistent, predictable interfaces **Consider disabling this rule when:** - Working with external APIs that you can't control - Dealing with legacy code that can't be immediately refactored - Working with data that is genuinely optional by nature (like form fields) ## 🔄 Migration Guide If you're adding this rule to an existing codebase, here's how to handle common patterns: ### Before (with optional properties): ```typescript interface UserForm { firstName?: string; lastName?: string; email?: string; phone?: string; } ``` ### After (explicit design): ```typescript // Option 1: All required interface UserForm { firstName: string; lastName: string; email: string; phone: string; } // Option 2: Separate interfaces for different states interface UserFormPartial { firstName: string; lastName: string; email: string; phone: string; } interface UserFormComplete extends UserFormPartial { verifiedAt: Date; termsAccepted: boolean; } ``` ## 🔍 Edge Cases Not Currently Detected The rule currently detects basic optional properties and union types with `undefined`/`null`, but some advanced TypeScript patterns are not yet covered: - **Generic Type Parameters**: `interface Container<T = string>` - **Conditional Types**: `type OptionalIf<T, U> = T extends U ? string | undefined : string` - **Mapped Types**: `type Partial<T> = { [P in keyof T]?: T[P] }` - **Utility Types**: `Partial<User>`, `PickOptional<T, K>` - **Function Parameter Types**: `(data: string | undefined) => void` - **Template Literal Types**: `type OptionalField<T> = \`${string & keyof T}?\`` - **Complex Union Types**: Union types with optional branches in complex structures ## 🤖 Why "Anti-Robot" Rules? Let's be honest - AI assistants (including the one that might have helped write this README 😄) have some common tendencies: 1. **Over-engineering everything** - Why use a simple function when you can create a full-blown class hierarchy? 2. **Verbose naming** - `calculateUserAuthenticationTokenValidationStatus` instead of `isValidToken` 3. **Magic patterns** - Using complex design patterns when a simple approach would work 4. **Copy-paste syndrome** - Repeating the same boilerplate everywhere 5. **Documentation overkill** - Commenting every single line of obvious code 6. **Optional everything** - Making properties optional instead of thinking through the design This plugin helps keep your code human-friendly and maintainable by enforcing rules that encourage clear, explicit design decisions. ## 🛠️ Development ### Prerequisites - Node.js 18+ - ESLint 8+ ### Setup ```bash npm install npm run build ``` ### Testing ```bash npm test ``` ### Linting ```bash npm run lint npm run lint:fix ``` ## 📄 License MIT - Feel free to use this to keep your codebase robot-free! ## 🤝 Contributing Have an idea for a rule that prevents robot coding practices? We'd love to hear it! Just make sure your contribution follows the vibe coding principles - keep it simple and human-readable. ### Adding New Rules When adding new rules, consider: 1. **Does it prevent a common "robot" pattern?** - The rule should target patterns that AI assistants commonly generate 2. **Is it clear and explicit?** - The rule should encourage better, more explicit code 3. **Does it have good examples?** - Provide clear before/after examples 4. **Is it configurable?** - Allow users to disable the rule when needed ## 🔄 CI/CD This project uses GitHub Actions for continuous integration and deployment. The workflow automatically: - Builds and tests on multiple Node.js versions - Publishes to npm on push to main branch - Creates GitHub releases on tag pushes See [`.github/README.md`](.github/README.md) for detailed setup instructions. ## 🚀 Releasing To release a new version: ```bash # For patch releases (1.0.0 -> 1.0.1) npm run release:patch # For minor releases (1.0.0 -> 1.1.0) npm run release:minor # For major releases (1.0.0 -> 2.0.0) npm run release:major ``` The release script will: 1. Update the version in `package.json` 2. Build and test the project 3. Commit changes and create a git tag 4. Push to GitHub, triggering the CI/CD pipeline 5. Automatically publish to npm --- _Remember: The best code is the code that another human can understand and maintain. Let's keep it that way!_ 🎉