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
Markdown
# 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!_ 🎉