spaghetti-slicer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 neerajram30
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # 🍝 spaghetti-slicer
2
+
3
+ [![npm version](https://img.shields.io/npm/v/spaghetti-slicer.svg?style=flat-square)](https://www.npmjs.com/package/spaghetti-slicer)
4
+ [![license](https://img.shields.io/npm/l/spaghetti-slicer.svg?style=flat-square)](https://github.com/neerajram30/spaghetti-slicer/blob/main/LICENSE)
5
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
6
+ [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
7
+
8
+ A highly opinionated frontend best practices auditor for React & TypeScript codebases. It is designed to automatically scan, analyze, and slice away "spaghetti code" before it reaches productionβ€”especially code generated by AI coding assistants like Cursor, v0, Bolt, and Lovable.
9
+
10
+ ---
11
+
12
+ ## ✨ Features
13
+
14
+ - ⚑ **Zero Config**: Works out of the box with zero setup. Point it at your code and let it slice.
15
+ - πŸ“Š **Quantifiable Scores**: Generates a weighted score out of 100 across 5 core categories, grading your repository from **Excellent** to **Poor**.
16
+ - πŸ› οΈ **Built for AI-Generated Code**: Catches common anti-patterns that LLMs frequently introduce (such as state bloat, inline fetching, and missing dimensions).
17
+ - πŸ€– **CI/CD Friendly**: Fail pipelines automatically with `--min-score` when code quality falls below your team's threshold.
18
+ - πŸ“‹ **Flexible Output**: Print beautiful console summaries with `ora` spinners and `boxen` layouts, or stream raw JSON to stdout using `--json`.
19
+
20
+ ---
21
+
22
+ ## πŸš€ Installation
23
+
24
+ ### Run instantly with `npx` (No Install)
25
+ ```bash
26
+ npx spaghetti-slicer ./src
27
+ ```
28
+
29
+ ### Install Globally
30
+ ```bash
31
+ npm install -g spaghetti-slicer
32
+
33
+ # Run audit
34
+ spaghetti-slicer ./src
35
+ ```
36
+
37
+ ---
38
+
39
+ ## πŸ› οΈ Usage & CLI Flags
40
+
41
+ ```bash
42
+ # Audit a whole folder or specific files
43
+ spaghetti-slicer ./src
44
+ spaghetti-slicer ./src/components/Button.tsx
45
+
46
+ # Exit with code 1 if score drops below 80 (perfect for CI checks)
47
+ spaghetti-slicer ./src --min-score=80
48
+
49
+ # Filter rules to run only a specific category
50
+ spaghetti-slicer ./src --rule=architecture
51
+ spaghetti-slicer ./src --rule=react
52
+
53
+ # Print clean JSON for external scripting
54
+ spaghetti-slicer ./src --json
55
+
56
+ # Show interactive lint/eslint autofix recommendations
57
+ spaghetti-slicer ./src --fix
58
+ ```
59
+
60
+ ---
61
+
62
+ ## πŸ” Code Quality Rules
63
+
64
+ `spaghetti-slicer` runs rules in several core categories:
65
+
66
+ ### πŸ›οΈ Architecture (Weight: 25%)
67
+
68
+ | Rule ID | Severity | Description |
69
+ |:---|:---:|:---|
70
+ | `component-length` | πŸ”΄ Critical | Components exceeding 200 lines should be broken up |
71
+ | `business-logic-in-jsx` | 🟑 Warning | Inline data operations (`.filter()`, `.reduce()`, `.sort()`) in JSX |
72
+ | `direct-fetch-in-component` | πŸ”΄ Critical | Making raw HTTP fetch/axios requests directly inside component bodies |
73
+ | `state-bloat` | 🟑 Warning | Defining more than 5 `useState` hooks in a single component |
74
+ | `hardcoded-secrets-endpoints` | πŸ”΄ Critical | Hardcoded raw URL strings or potential API credentials/keys |
75
+
76
+ ### βš›οΈ React (Weight: 20%)
77
+
78
+ | Rule ID | Severity | Description |
79
+ |:---|:---:|:---|
80
+ | `index-as-key` | πŸ”΄ Critical | Array iteration index used as the React `key` prop |
81
+ | `missing-error-boundary` | 🟑 Warning | Codebase lacks any React Error Boundary components |
82
+ | `no-sub-renders` | 🟑 Warning | Helper render functions (e.g. `renderHeader()`) nested in components |
83
+ | `fat-controller` | 🟑 Warning | Non-JSX javascript logic exceeds 75% of a component's total line length |
84
+
85
+ ### ⚑ Performance (Weight: 15%)
86
+
87
+ | Rule ID | Severity | Description |
88
+ |:---|:---:|:---|
89
+ | `image-missing-dimensions` | 🟑 Warning | `<img>` or `<Image>` tags missing `width` or `height` attributes (causes CLS) |
90
+
91
+ ---
92
+
93
+ ## πŸ’‘ Code Patterns: Bad vs. Good
94
+
95
+ Here's how `spaghetti-slicer` helps you clean up common code smells:
96
+
97
+ ### 1. Direct Fetch in Component (`direct-fetch-in-component`)
98
+ * ❌ **Bad:** Making raw API calls inside a render or useEffect lifecycle.
99
+ ```tsx
100
+ export function UserProfile() {
101
+ useEffect(() => {
102
+ fetch('/api/user/profile').then(res => res.json()).then(data => {...});
103
+ }, []);
104
+ return <div>User Profile</div>;
105
+ }
106
+ ```
107
+ * **Good:** Extract to a custom hook or API service layer.
108
+ ```tsx
109
+ import { useUserProfile } from '../hooks/useUserProfile';
110
+
111
+ export function UserProfile() {
112
+ const { profile, loading } = useUserProfile();
113
+ return <div>User Profile</div>;
114
+ }
115
+ ```
116
+
117
+ ### 2. State Bloat (`state-bloat`)
118
+ * ❌ **Bad:** Managing component states using too many individual hooks.
119
+ ```tsx
120
+ const [name, setName] = useState('');
121
+ const [email, setEmail] = useState('');
122
+ const [age, setAge] = useState(0);
123
+ const [address, setAddress] = useState('');
124
+ const [phone, setPhone] = useState('');
125
+ const [company, setCompany] = useState(''); // ⚠️ State Bloat Triggered (6 hooks)
126
+ ```
127
+ * **Good:** Merge related states or delegate to `useReducer` / state containers.
128
+ ```tsx
129
+ const [formData, setFormData] = useState({
130
+ name: '', email: '', age: 0, address: '', phone: '', company: ''
131
+ });
132
+ ```
133
+
134
+ ### 3. Nested Helper Renders (`no-sub-renders`)
135
+ * ❌ **Bad:** Defining sub-rendering helper functions inside the main component body.
136
+ ```tsx
137
+ export function ProductCard({ title, price }) {
138
+ const renderBadge = () => <span className="badge">New</span>; // ⚠️ Defined inside Card
139
+ return (
140
+ <div>
141
+ <h3>{title}</h3>
142
+ {renderBadge()}
143
+ </div>
144
+ );
145
+ }
146
+ ```
147
+ * **Good:** Extract to its own component.
148
+ ```tsx
149
+ function Badge() {
150
+ return <span className="badge">New</span>;
151
+ }
152
+
153
+ export function ProductCard({ title, price }) {
154
+ return (
155
+ <div>
156
+ <h3>{title}</h3>
157
+ <Badge />
158
+ </div>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ## πŸ“ˆ Scoring System
166
+
167
+ Your project starts with a score of **100** for each category. Points are deducted per violation:
168
+ * πŸ”΄ **Critical Violation**: `-10 points`
169
+ * 🟑 **Warning Violation**: `-5 points`
170
+ * πŸ”΅ **Info Violation**: `-2 points`
171
+
172
+ A total score is calculated using the weighted averages of all categories. Your repository is then assigned a Grade:
173
+
174
+ | Score | Grade | Description |
175
+ |:---:|:---:|:---|
176
+ | **90 – 100** | βœ… **Excellent** | Clean codebase, minimal code smells |
177
+ | **75 – 89** | βœ… **Good** | Solid structure, minor refactoring recommended |
178
+ | **60 – 74** | ⚠️ **Needs Work** | Code smells present, potential architectural issues |
179
+ | **< 60** | ❌ **Poor** | High risk of bugs and difficult maintenance |
180
+
181
+ ---
182
+
183
+ ## πŸ€– GitHub Actions CI/CD Integration
184
+
185
+ Catch regressions automatically on every Pull Request. Add this workflow as `.github/workflows/spaghetti-slicer.yml`:
186
+
187
+ ```yaml
188
+ name: Code Quality Audit
189
+ on: [pull_request]
190
+
191
+ jobs:
192
+ audit:
193
+ runs-on: ubuntu-latest
194
+ steps:
195
+ - name: Checkout Code
196
+ uses: actions/checkout@v4
197
+
198
+ - name: Setup Node.js
199
+ uses: actions/setup-node@v4
200
+ with:
201
+ node-version: '20'
202
+ cache: 'npm'
203
+
204
+ - name: Install Dependencies
205
+ run: npm ci
206
+
207
+ - name: Build Project
208
+ run: npm run build
209
+
210
+ - name: Run Spaghetti Slicer
211
+ # Exit and fail the action if quality score falls below 80%
212
+ run: npx spaghetti-slicer ./src --min-score=80
213
+ ```
214
+
215
+ ---
216
+
217
+ ## βš™οΈ Local Development & Contributing
218
+
219
+ We welcome community contributions to add more rules or improve CLI performance!
220
+
221
+ ### Prerequisites & Setup
222
+ 1. Fork and clone the repository.
223
+ 2. Install dependencies:
224
+ ```bash
225
+ npm install
226
+ ```
227
+
228
+ ### Running Tests
229
+ We use `vitest` for fast static-analysis rule validation:
230
+ ```bash
231
+ # Run tests once
232
+ npm run test:run
233
+
234
+ # Run tests in watch mode
235
+ npm run test
236
+ ```
237
+
238
+ ### Linking the CLI locally
239
+ Test your local changes against any separate project directory on your computer:
240
+ ```bash
241
+ # 1. From the spaghetti-slicer repository directory
242
+ npm run build
243
+ npm link
244
+
245
+ # 2. Run globally linked CLI in another project directory
246
+ spaghetti-slicer /path/to/other-project/src
247
+ ```
248
+
249
+ ### Adding a New Rule
250
+ 1. Create your rule under `src/rules/<category>/<rule-name>.ts` implementing the `Rule` interface.
251
+ 2. Register the rule in `src/rules/index.ts`.
252
+ 3. Write test cases covering pass and fail fixtures under `tests/rules/<category>/<rule-name>.test.ts`.
253
+ 4. Run `npm run test:run` to confirm everything works!
254
+
255
+ ---
256
+
257
+ ## πŸ“„ License
258
+
259
+ This project is open-source and licensed under the [MIT License](LICENSE).
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node