ai-vibes 1.0.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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +345 -0
  3. package/dist/cli.js +325 -0
  4. package/package.json +44 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ai-vibes
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,345 @@
1
+ # ai-vibes
2
+
3
+ > A tiny CLI that scaffolds AI steering rules for your codebase.
4
+
5
+ **The problem:** Your AI assistant writes amazing code... that looks nothing like the rest of your codebase. 🤦
6
+
7
+ **The solution:** Give your AI the vibe check it deserves. Define your team's standards once, and let every AI assistant follow them.
8
+
9
+ Think of it as `.editorconfig` but for AI behavior. Or a style guide that AIs actually read.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ # No installation needed - use npx
15
+ npx ai-vibes init
16
+
17
+ # Or install globally
18
+ npm install -g ai-vibes
19
+ ```
20
+
21
+ **Requirements:** Node.js 18+
22
+
23
+ ## Usage
24
+
25
+ ```bash
26
+ # Interactive mode - prompts you for directory and manifest names
27
+ npx ai-vibes init
28
+
29
+ # Or skip the prompts with flags
30
+ npx ai-vibes init --dir vibes --manifest vibes.yaml
31
+
32
+ # Minimal mode - 3 essential files (recommended)
33
+ npx ai-vibes init --minimal
34
+
35
+ # Overwrite existing files
36
+ npx ai-vibes init --force
37
+ ```
38
+
39
+ This creates:
40
+
41
+ - `vibes.yaml` - Manifest file
42
+ - `vibes/` - Directory with rule documents
43
+
44
+ ## What You Get
45
+
46
+ ### Minimal Mode (3 files)
47
+
48
+ - `security.md` - Never commit secrets, validate inputs
49
+ - `unit-tests.md` - Test behavior, cover edge cases
50
+ - `naming.md` - Consistent naming conventions
51
+
52
+ ### Full Mode (11 files)
53
+
54
+ Everything in minimal, plus:
55
+
56
+ - `architecture.md` - Follow existing patterns
57
+ - `performance.md` - Optimization guidelines
58
+ - `code-review.md` - Review standards
59
+ - `error-handling.md` - Error patterns
60
+ - `documentation.md` - Doc standards
61
+ - `accessibility.md` - a11y guidelines
62
+ - `api-design.md` - RESTful conventions
63
+ - `git-workflow.md` - Commit standards
64
+
65
+ ## Daily Usage
66
+
67
+ ### Working with AI Assistants
68
+
69
+ Once set up, reference your guidelines when using AI tools:
70
+
71
+ **GitHub Copilot:**
72
+
73
+ ```
74
+ @workspace Follow the guidelines in vibes.yaml
75
+ ```
76
+
77
+ **Cursor:**
78
+
79
+ ```
80
+ Create an API endpoint following the guidelines in vibes.yaml
81
+ ```
82
+
83
+ **Claude/ChatGPT:**
84
+
85
+ ```bash
86
+ cat vibes.yaml vibes/*.md
87
+ # Paste into your conversation
88
+ ```
89
+
90
+ ### Updating Guidelines
91
+
92
+ ```bash
93
+ # Edit a rule
94
+ vim vibes/security.md
95
+
96
+ # Commit changes
97
+ git add vibes/
98
+ git commit -m "docs: update security guidelines for API keys"
99
+ ```
100
+
101
+ ## CLI Options
102
+
103
+ ```
104
+ npx ai-vibes init [options]
105
+
106
+ Options:
107
+ --minimal 3 essential files instead of 11
108
+ --force Overwrite existing files
109
+ --dir <name> Directory name (interactive prompt if not provided)
110
+ --manifest <filename> Manifest filename (interactive prompt if not provided)
111
+ -h, --help Display help
112
+ ```
113
+
114
+ **Interactive Mode:** If you don't provide `--dir` or `--manifest`, you'll be prompted:
115
+
116
+ ```
117
+ Directory name for rule documents (default: vibes):
118
+ Manifest filename (default: vibes.yaml):
119
+ ```
120
+
121
+ ## What It Does
122
+
123
+ ✅ Creates `vibes.yaml` manifest
124
+ ✅ Creates rule documents in Markdown
125
+ ✅ Provides starter templates
126
+ ✅ Gives you a place to say "No, AI, we don't do that here"
127
+
128
+ ## What It Doesn't Do
129
+
130
+ ❌ Does not validate rules (it's not a linter, calm down)
131
+ ❌ Does not enforce rules (you still need code review)
132
+ ❌ Does not integrate with AI tools directly (BYOAI - Bring Your Own AI)
133
+ ❌ Does not make coffee ☕
134
+
135
+ ai-vibes is intentionally minimal - it scaffolds the structure, you customize the content. Think of it as the starter pack for your AI's training montage.
136
+
137
+ ## How It Works
138
+
139
+ ```mermaid
140
+ graph TD
141
+ A[🚀 Run: npx ai-vibes init] --> B[📄 Creates vibes.yaml manifest]
142
+ B --> C[📁 Creates vibes/ directory with rule files]
143
+ C --> D[✏️ You customize the markdown files]
144
+ D --> E[🤖 Share with AI assistants]
145
+ E --> F[✨ AI follows your team's standards]
146
+
147
+ style A fill:#4CAF50,stroke:#2E7D32,color:#fff
148
+ style B fill:#2196F3,stroke:#1565C0,color:#fff
149
+ style C fill:#2196F3,stroke:#1565C0,color:#fff
150
+ style D fill:#FF9800,stroke:#E65100,color:#fff
151
+ style E fill:#9C27B0,stroke:#6A1B9A,color:#fff
152
+ style F fill:#4CAF50,stroke:#2E7D32,color:#fff
153
+ ```
154
+
155
+ **The magic:** The manifest (`vibes.yaml`) acts as a single source of truth that AI tools can read to discover all your coding standards in one place.
156
+
157
+ ## Setup Guide
158
+
159
+ ### Step-by-Step Setup
160
+
161
+ **1. Navigate to your project**
162
+
163
+ ```bash
164
+ cd /path/to/your-project
165
+ ```
166
+
167
+ **2. Run ai-vibes**
168
+
169
+ ```bash
170
+ npx ai-vibes init
171
+ ```
172
+
173
+ **3. Answer the prompts** (or press Enter for defaults)
174
+
175
+ ```
176
+ Directory name for rule documents (default: vibes):
177
+ Manifest filename (default: vibes.yaml):
178
+ ```
179
+
180
+ **4. Choose your mode**
181
+
182
+ - Want all 11 templates? Just press Enter
183
+ - Want minimal (3 files)? Run with `--minimal` flag
184
+
185
+ **5. Verify the files were created**
186
+
187
+ ```bash
188
+ ls vibes/ # Shows your rule files
189
+ cat vibes.yaml # Shows your manifest
190
+ ```
191
+
192
+ **6. Customize for your team**
193
+
194
+ Edit the generated files to match your standards:
195
+
196
+ ```bash
197
+ # Add your security requirements
198
+ vim vibes/security.md
199
+
200
+ # Define your naming conventions
201
+ vim vibes/naming.md
202
+
203
+ # Set testing expectations
204
+ vim vibes/unit-tests.md
205
+ ```
206
+
207
+ **7. Commit to version control**
208
+
209
+ ```bash
210
+ git add vibes.yaml vibes/
211
+ git commit -m "docs: add AI coding guidelines"
212
+ git push
213
+ ```
214
+
215
+ **8. Share with your AI assistant**
216
+
217
+ Now whenever you use an AI tool, reference your guidelines:
218
+
219
+ ```
220
+ @workspace Follow the guidelines in vibes.yaml
221
+ ```
222
+
223
+ **9. Keep it updated**
224
+
225
+ As your team's practices evolve, update the markdown files:
226
+
227
+ ```bash
228
+ vim vibes/security.md # Add new security pattern
229
+ git commit -am "docs: add OAuth2 security requirements"
230
+ ```
231
+
232
+ ### What Gets Created
233
+
234
+ **Minimal Mode** (`--minimal`):
235
+
236
+ ```
237
+ your-project/
238
+ ├── vibes.yaml # Manifest with 3 rules
239
+ └── vibes/
240
+ ├── security.md # Security guidelines
241
+ ├── unit-tests.md # Testing standards
242
+ └── naming.md # Naming conventions
243
+ ```
244
+
245
+ **Full Mode** (default):
246
+
247
+ ```
248
+ your-project/
249
+ ├── vibes.yaml # Manifest with 11 rules
250
+ └── vibes/
251
+ ├── security.md # Security guidelines
252
+ ├── unit-tests.md # Testing standards
253
+ ├── naming.md # Naming conventions
254
+ ├── architecture.md # Architecture patterns
255
+ ├── performance.md # Performance guidelines
256
+ ├── code-review.md # Review standards
257
+ ├── error-handling.md # Error patterns
258
+ ├── documentation.md # Documentation standards
259
+ ├── accessibility.md # Accessibility guidelines
260
+ ├── api-design.md # API conventions
261
+ └── git-workflow.md # Git standards
262
+ ```
263
+
264
+ ### Automation
265
+
266
+ Skip the prompts for CI/CD or scripts:
267
+
268
+ ```bash
269
+ npx ai-vibes init --dir .github/ai-rules --manifest ai-rules.yaml --minimal --force
270
+ ```
271
+
272
+ ## Manifest Format
273
+
274
+ `vibes.yaml` maps rule IDs to file paths:
275
+
276
+ ```yaml
277
+ version: 1
278
+
279
+ rules:
280
+ security: "vibes/security.md"
281
+ unit-tests: "vibes/unit-tests.md"
282
+ naming: "vibes/naming.md"
283
+
284
+ order:
285
+ - security
286
+ - unit-tests
287
+ - naming
288
+
289
+ modes:
290
+ codegen:
291
+ include: [security, unit-tests, naming]
292
+ review:
293
+ include: [security, naming]
294
+ ```
295
+
296
+ ## Examples
297
+
298
+ ### Basic Setup
299
+
300
+ ```bash
301
+ npx ai-vibes init --minimal
302
+ ```
303
+
304
+ ### Monorepo
305
+
306
+ ```bash
307
+ cd packages/api
308
+ npx ai-vibes init --dir ../../.ai-rules --manifest ../../ai-rules.yaml
309
+ ```
310
+
311
+ ### Custom Location
312
+
313
+ ```bash
314
+ npx ai-vibes init --dir .github/ai-guidelines
315
+ ```
316
+
317
+ ## FAQ
318
+
319
+ **Do I need to install this?**
320
+ No, use `npx ai-vibes init`. One command, zero commitment. Like a coding one-night stand, but productive.
321
+
322
+ **Can I customize the templates?**
323
+ Yes! That's literally the entire point. These are starting points, not commandments carved in stone.
324
+
325
+ **Can I add more rules?**
326
+ Absolutely. Got opinions about how semicolons should be used? Write a rule. Passionate about proper emoji usage in commit messages? Add it to the manifest.
327
+
328
+ **Should I commit these files?**
329
+ Yes! Version control means time travel, and future-you will thank past-you for documenting these decisions.
330
+
331
+ **Does this work with [my AI tool]?**
332
+ If your AI can read Markdown (spoiler: they all can), then yes. We're tool-agnostic. Bring your favorite AI, we'll provide the guidelines.
333
+
334
+ ## Contributing
335
+
336
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
337
+
338
+ ## License
339
+
340
+ MIT
341
+
342
+ ---
343
+
344
+ **Repository:** https://github.com/HelpBits/ai-vibes
345
+ **Version:** 1.0.0
package/dist/cli.js ADDED
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/init.ts
7
+ import { writeFile, mkdir, access } from "fs/promises";
8
+ import { join } from "path";
9
+ import { createInterface } from "readline";
10
+
11
+ // src/templates.ts
12
+ var security_md = '# Security\n\n## Purpose\n\nDefine security expectations for AI-generated code in this repo.\n\n## Do\n\n- **Never commit secrets** \u2013 no API keys, tokens, passwords in code or logs\n- **Validate all inputs** \u2013 especially user-provided data, query params, form fields\n- **Use environment variables** for secrets (e.g., `.env` files, not committed)\n- **Sanitize outputs** \u2013 prevent XSS, SQL injection, command injection\n- **Follow least privilege** \u2013 grant minimal necessary permissions\n- **Keep dependencies updated** \u2013 regularly audit and update packages\n- **Use secure defaults** \u2013 HTTPS, secure cookies, strong crypto\n- **Log security events** \u2013 failed auth attempts, suspicious activity (without logging sensitive data)\n\n## Don\'t\n\n- **Don\'t hardcode credentials** \u2013 ever\n- **Don\'t trust user input** \u2013 always validate and sanitize\n- **Don\'t use weak crypto** \u2013 no MD5, SHA1 for passwords; use bcrypt, argon2, or scrypt\n- **Don\'t expose stack traces** \u2013 in production error messages\n- **Don\'t add risky dependencies casually** \u2013 vet packages before installing\n- **Don\'t skip security headers** \u2013 CSP, HSTS, X-Frame-Options, etc.\n\n## Examples\n\n### \u2705 Good: Environment variables\n\n```javascript\nconst apiKey = process.env.API_KEY;\nif (!apiKey) {\n throw new Error("API_KEY not configured");\n}\n```\n\n### \u274C Bad: Hardcoded secret\n\n```javascript\nconst apiKey = "sk-1234567890abcdef"; // NEVER do this\n```\n\n### \u2705 Good: Input validation\n\n```javascript\nfunction getUser(userId) {\n if (!/^[0-9]+$/.test(userId)) {\n throw new Error("Invalid user ID");\n }\n return db.query("SELECT * FROM users WHERE id = ?", [userId]);\n}\n```\n\n### \u274C Bad: SQL injection risk\n\n```javascript\nfunction getUser(userId) {\n return db.query(`SELECT * FROM users WHERE id = ${userId}`); // vulnerable\n}\n```\n';
13
+ var unit_tests_md = '# Unit Tests\n\n## Purpose\n\nDefine how AI should write and maintain unit tests in this repo.\n\n## Do\n\n- **Update tests when behavior changes** \u2013 tests should reflect current expected behavior\n- **Cover edge cases** \u2013 empty inputs, null, undefined, boundary values\n- **Test error paths** \u2013 not just happy paths\n- **Use descriptive test names** \u2013 `it(\'should return 404 when user not found\')`\n- **Keep tests fast** \u2013 mock external dependencies (APIs, databases)\n- **Test one thing per test** \u2013 focused assertions\n- **Use test fixtures** \u2013 reusable test data\n- **Assert meaningful outputs** \u2013 not just "doesn\'t crash"\n\n## Don\'t\n\n- **Don\'t test implementation details** \u2013 test behavior, not private methods\n- **Don\'t write flaky tests** \u2013 avoid timeouts, race conditions\n- **Don\'t skip failing tests** \u2013 fix or remove them\n- **Don\'t copy-paste tests** \u2013 extract shared setup\n- **Don\'t mock everything** \u2013 test real logic when possible\n- **Don\'t ignore test failures** \u2013 they indicate real issues\n\n## Examples\n\n### \u2705 Good: Behavior-focused test\n\n```javascript\ndescribe("UserService", () => {\n it("should throw error when creating user with duplicate email", async () => {\n await createUser({ email: "test@example.com" });\n\n await expect(createUser({ email: "test@example.com" })).rejects.toThrow(\n "Email already exists",\n );\n });\n});\n```\n\n### \u2705 Good: Edge case coverage\n\n```javascript\ndescribe("calculateDiscount", () => {\n it("should return 0 for negative prices", () => {\n expect(calculateDiscount(-10)).toBe(0);\n });\n\n it("should return 0 for null price", () => {\n expect(calculateDiscount(null)).toBe(0);\n });\n\n it("should handle zero price", () => {\n expect(calculateDiscount(0)).toBe(0);\n });\n});\n```\n\n### \u274C Bad: Testing implementation details\n\n```javascript\nit("should call internal _parseData method", () => {\n const spy = jest.spyOn(service, "_parseData");\n service.process(data);\n expect(spy).toHaveBeenCalled(); // testing internals, not behavior\n});\n```\n';
14
+ var naming_md = '# Naming Conventions\n\n## Purpose\n\nDefine naming standards for consistency across the codebase.\n\n## Do\n\n- **Use descriptive names** \u2013 `getUserById` not `get`\n- **Follow language conventions** \u2013 camelCase for JS/TS, snake_case for Python\n- **Be consistent** \u2013 if the repo uses `fetch*`, don\'t add `get*` functions\n- **Use plural for collections** \u2013 `users`, `items`\n- **Use verb-noun for functions** \u2013 `createUser`, `deletePost`\n- **Use clear boolean names** \u2013 `isActive`, `hasPermission`, `canEdit`\n- **Avoid abbreviations** \u2013 unless widely known (HTTP, API, ID)\n- **Match domain language** \u2013 use terms from the product/business\n\n## Don\'t\n\n- **Don\'t be cryptic** \u2013 `a`, `tmp`, `data2`\n- **Don\'t use misleading names** \u2013 `get*` should not modify state\n- **Don\'t mix conventions** \u2013 pick one and stick with it\n- **Don\'t use generic names** \u2013 `handler`, `manager`, `helper` without context\n- **Don\'t overuse prefixes** \u2013 `myFunction`, `theVariable`\n\n## Examples\n\n### \u2705 Good: Clear function names\n\n```javascript\nfunction createUser(userData) {}\nfunction deletePost(postId) {}\nfunction isAuthenticated(user) {}\n```\n\n### \u274C Bad: Vague names\n\n```javascript\nfunction process(d) {} // what does this do?\nfunction handle() {} // handle what?\nfunction doStuff() {} // too generic\n```\n\n### \u2705 Good: Descriptive variables\n\n```javascript\nconst activeUsers = users.filter((u) => u.isActive);\nconst maxRetries = 3;\nconst apiBaseUrl = "https://api.example.com";\n```\n\n### \u274C Bad: Unclear variables\n\n```javascript\nconst arr = users.filter((u) => u.isActive); // what kind of array?\nconst num = 3; // what number?\nconst url = "https://api.example.com"; // which URL?\n```\n\n### \u2705 Good: Boolean naming\n\n```javascript\nconst isLoading = true;\nconst hasPermission = user.role === "admin";\nconst canDelete = isOwner || isAdmin;\n```\n\n### \u274C Bad: Unclear booleans\n\n```javascript\nconst loading = true; // could be a loading indicator element\nconst permission = true; // which permission?\nconst delete = true; // "delete" is ambiguous\n```\n';
15
+ var architecture_md = "# Architecture\n\n## Purpose\n\nDefine architectural patterns and organization principles for this repo.\n\n## Do\n\n- **Follow existing patterns** \u2013 if the repo has a structure, maintain it\n- **Put code in the right place** \u2013 controllers, services, models, utils\n- **Reuse existing utilities** \u2013 check before creating new helper functions\n- **Keep modules focused** \u2013 single responsibility principle\n- **Minimize dependencies** \u2013 between modules\n- **Document architecture decisions** \u2013 why, not just what\n- **Use dependency injection** \u2013 for testability\n- **Separate concerns** \u2013 business logic, data access, presentation\n\n## Don't\n\n- **Don't create new patterns** \u2013 without justification or discussion\n- **Don't duplicate functionality** \u2013 search for existing solutions first\n- **Don't tightly couple modules** \u2013 avoid circular dependencies\n- **Don't mix layers** \u2013 keep business logic out of controllers\n- **Don't bypass abstractions** \u2013 use the data layer, don't query directly\n- **Don't ignore folder structure** \u2013 respect the repo's organization\n\n## Examples\n\n### \u2705 Good: Layered architecture\n\n```javascript\n// controller/userController.js\nexport async function getUser(req, res) {\n const user = await userService.findById(req.params.id);\n res.json(user);\n}\n\n// service/userService.js\nexport async function findById(id) {\n return userRepository.findById(id);\n}\n\n// repository/userRepository.js\nexport async function findById(id) {\n return db.query(\"SELECT * FROM users WHERE id = ?\", [id]);\n}\n```\n\n### \u274C Bad: Mixed concerns\n\n```javascript\n// controller/userController.js\nexport async function getUser(req, res) {\n // Don't put database queries directly in controllers\n const user = await db.query(\"SELECT * FROM users WHERE id = ?\", [\n req.params.id,\n ]);\n res.json(user);\n}\n```\n\n### \u2705 Good: Reusing utilities\n\n```javascript\nimport { formatDate } from \"../utils/date\";\nimport { validateEmail } from \"../utils/validation\";\n\nconst formattedDate = formatDate(user.createdAt);\n```\n\n### \u274C Bad: Duplicating utilities\n\n```javascript\n// Creating new date formatting when one exists\nfunction myDateFormatter(date) {\n // duplicates existing formatDate utility\n}\n```\n";
16
+ var performance_md = "# Performance\n\n## Purpose\n\nDefine performance expectations and optimization guidelines for AI-generated code.\n\n## Do\n\n- **Measure before optimizing** \u2013 use profilers and benchmarks\n- **Use appropriate data structures** \u2013 Map for lookups, Set for uniqueness, Array for ordered data\n- **Cache expensive operations** \u2013 memoize, cache API calls, precompute when possible\n- **Avoid unnecessary re-renders** \u2013 React.memo, useMemo, useCallback where appropriate\n- **Lazy load when possible** \u2013 code splitting, dynamic imports, lazy components\n- **Optimize loops** \u2013 avoid nested loops with large datasets, use early returns\n- **Use efficient algorithms** \u2013 consider Big O complexity\n- **Debounce/throttle** \u2013 for frequent events (scroll, resize, input)\n- **Optimize images** \u2013 compress, use appropriate formats, lazy load\n- **Monitor bundle size** \u2013 keep dependencies lean\n\n## Don't\n\n- **Don't premature optimize** \u2013 optimize hot paths only after measuring\n- **Don't block the main thread** \u2013 use Web Workers for heavy computation\n- **Don't fetch in loops** \u2013 batch API calls, use Promise.all\n- **Don't ignore memory leaks** \u2013 clean up event listeners, timers, subscriptions\n- **Don't load everything upfront** \u2013 use pagination, infinite scroll, virtualization\n- **Don't ignore Core Web Vitals** \u2013 LCP, FID, CLS matter for UX\n\n## Examples\n\n### \u2705 Good: Memoization\n\n```javascript\nconst cache = new Map();\n\nfunction expensiveOperation(key) {\n if (cache.has(key)) return cache.get(key);\n\n const result = /* expensive computation */;\n cache.set(key, result);\n return result;\n}\n```\n\n### \u274C Bad: Repeated computation\n\n```javascript\nfunction expensiveOperation(key) {\n return /* expensive computation every time */;\n}\n```\n\n### \u2705 Good: Batch API calls\n\n```javascript\nconst userIds = [1, 2, 3, 4, 5];\nconst users = await fetchUsers(userIds); // Single request\n```\n\n### \u274C Bad: N+1 queries\n\n```javascript\nconst users = [];\nfor (const id of userIds) {\n users.push(await fetchUser(id)); // 5 separate requests!\n}\n```\n";
17
+ var code_review_md = "# Code Review\n\n## Purpose\n\nDefine standards for code reviews and what to look for when reviewing AI-generated code.\n\n## Do\n\n- **Check for security issues** \u2013 SQL injection, XSS, hardcoded secrets\n- **Verify error handling** \u2013 proper try/catch, error messages, fallbacks\n- **Review test coverage** \u2013 edge cases covered, meaningful assertions\n- **Check naming consistency** \u2013 follows repo conventions\n- **Verify documentation** \u2013 complex logic explained, JSDoc/comments where needed\n- **Look for duplication** \u2013 reusable code extracted to functions/modules\n- **Check dependencies** \u2013 necessary, up-to-date, no suspicious packages\n- **Verify accessibility** \u2013 semantic HTML, ARIA labels, keyboard navigation\n- **Check performance** \u2013 no obvious bottlenecks, efficient algorithms\n- **Review git history** \u2013 clear commit messages, logical commits\n\n## Don't\n\n- **Don't approve blindly** \u2013 actually read and understand the changes\n- **Don't nitpick style** \u2013 let linters/formatters handle it\n- **Don't block on preferences** \u2013 focus on correctness and maintainability\n- **Don't merge with unresolved comments** \u2013 address or explicitly defer\n- **Don't skip testing** \u2013 actually run the code locally\n- **Don't assume AI is always right** \u2013 LLMs make mistakes\n\n## Examples\n\n### \u2705 Good: Constructive feedback\n\n```\nThis function could throw if userId is undefined.\nConsider adding validation:\n if (!userId) throw new Error('userId required');\n```\n\n### \u274C Bad: Vague criticism\n\n```\nThis doesn't look right\n```\n\n### \u2705 Good: Security catch\n\n```\n\u26A0\uFE0F SQL injection risk here - use parameterized queries:\n db.query('SELECT * FROM users WHERE id = ?', [userId])\n```\n";
18
+ var error_handling_md = "# Error Handling\n\n## Purpose\n\nDefine how errors should be handled and reported in AI-generated code.\n\n## Do\n\n- **Use try/catch for async operations** \u2013 especially API calls, file I/O\n- **Throw meaningful errors** \u2013 descriptive messages, include context\n- **Use custom error classes** \u2013 for domain-specific errors\n- **Log errors properly** \u2013 include stack traces, context, but not secrets\n- **Handle errors at appropriate level** \u2013 don't catch too early\n- **Provide fallbacks** \u2013 graceful degradation when possible\n- **Validate inputs early** \u2013 fail fast with clear errors\n- **Use error boundaries** \u2013 in React/UI frameworks\n- **Return error objects** \u2013 instead of throwing in some cases (Result pattern)\n- **Document error cases** \u2013 what exceptions can be thrown\n\n## Don't\n\n- **Don't swallow errors** \u2013 empty catch blocks hide bugs\n- **Don't expose internals** \u2013 no stack traces in production to users\n- **Don't use errors for control flow** \u2013 errors are for exceptional cases\n- **Don't log secrets** \u2013 no passwords, tokens, PII in error logs\n- **Don't ignore promise rejections** \u2013 always handle with .catch or try/catch\n- **Don't use generic messages** \u2013 \"Something went wrong\" isn't helpful\n\n## Examples\n\n### \u2705 Good: Specific error with context\n\n```javascript\nasync function getUser(userId) {\n if (!userId) {\n throw new Error(\"userId is required\");\n }\n\n try {\n return await api.fetchUser(userId);\n } catch (error) {\n throw new Error(`Failed to fetch user ${userId}: ${error.message}`);\n }\n}\n```\n\n### \u274C Bad: Swallowed error\n\n```javascript\nasync function getUser(userId) {\n try {\n return await api.fetchUser(userId);\n } catch (error) {\n // Silent failure - bug is hidden!\n }\n}\n```\n\n### \u2705 Good: Error boundary (React)\n\n```javascript\nclass ErrorBoundary extends React.Component {\n state = { hasError: false };\n\n static getDerivedStateFromError(error) {\n return { hasError: true };\n }\n\n componentDidCatch(error, info) {\n logError(error, info);\n }\n\n render() {\n if (this.state.hasError) {\n return <ErrorFallback />;\n }\n return this.props.children;\n }\n}\n```\n";
19
+ var documentation_md = "# Documentation\n\n## Purpose\n\nDefine documentation standards for AI-generated code.\n\n## Do\n\n- **Document the \"why\" not the \"what\"** \u2013 code shows what, comments explain why\n- **Add JSDoc for public APIs** \u2013 parameters, return types, examples\n- **Document complex logic** \u2013 algorithms, business rules, non-obvious code\n- **Keep README updated** \u2013 installation, usage, examples\n- **Add inline comments** \u2013 for tricky parts, workarounds, TODOs\n- **Document breaking changes** \u2013 in CHANGELOG or commit messages\n- **Include examples** \u2013 especially for libraries and utilities\n- **Document edge cases** \u2013 what assumptions are made\n- **Link to related docs** \u2013 design docs, tickets, RFCs\n- **Keep docs close to code** \u2013 avoid docs getting stale\n\n## Don't\n\n- **Don't state the obvious** \u2013 `// increment i` is useless\n- **Don't let docs drift** \u2013 update docs when code changes\n- **Don't over-document** \u2013 clear code needs fewer comments\n- **Don't write novels** \u2013 be concise and clear\n- **Don't document implementation details** \u2013 unless necessary\n- **Don't use outdated examples** \u2013 test your examples\n\n## Examples\n\n### \u2705 Good: Explains \"why\"\n\n```javascript\n// Using setTimeout instead of setInterval because the API call\n// can take longer than 5s, which would cause requests to queue up\nsetTimeout(() => pollAPI(), 5000);\n```\n\n### \u274C Bad: States the obvious\n\n```javascript\n// Call the API\ncallAPI();\n```\n\n### \u2705 Good: JSDoc with examples\n\n```javascript\n/**\n * Formats a date for display in the UI\n * @param {Date} date - The date to format\n * @param {string} locale - The locale (e.g., 'en-US', 'es-ES')\n * @returns {string} Formatted date string\n * @example\n * formatDate(new Date(), 'en-US') // \"Jan 1, 2024\"\n */\nfunction formatDate(date, locale) {\n return new Intl.DateTimeFormat(locale).format(date);\n}\n```\n\n### \u2705 Good: Complex logic explanation\n\n```javascript\n// We're using a binary search here because the data is sorted\n// and can be very large (100k+ items). Linear search would be O(n).\n// This gives us O(log n) performance.\nfunction binarySearch(arr, target) {\n // ...\n}\n```\n";
20
+ var accessibility_md = '# Accessibility (a11y)\n\n## Purpose\n\nDefine accessibility standards for AI-generated UI code to ensure inclusivity.\n\n## Do\n\n- **Use semantic HTML** \u2013 `<button>`, `<nav>`, `<main>`, not just `<div>`\n- **Add ARIA labels** \u2013 when semantic HTML isn\'t enough\n- **Ensure keyboard navigation** \u2013 tab order, focus management, shortcuts\n- **Provide alt text** \u2013 for all images (empty alt="" for decorative)\n- **Use sufficient color contrast** \u2013 WCAG AA minimum (4.5:1 for text)\n- **Make clickable areas large** \u2013 44x44px minimum touch targets\n- **Support screen readers** \u2013 test with VoiceOver, NVDA, JAWS\n- **Add skip links** \u2013 "Skip to main content" for keyboard users\n- **Use labels for inputs** \u2013 properly associated with `for`/`id`\n- **Test with keyboard only** \u2013 tab, enter, escape, arrows\n\n## Don\'t\n\n- **Don\'t rely on color alone** \u2013 use icons, text, patterns too\n- **Don\'t use `<div>` for buttons** \u2013 use `<button>` or proper ARIA\n- **Don\'t auto-play media** \u2013 provide controls, respect prefers-reduced-motion\n- **Don\'t break zoom** \u2013 avoid `maximum-scale=1` in viewport\n- **Don\'t use placeholder as label** \u2013 placeholders disappear on input\n- **Don\'t forget focus styles** \u2013 never `outline: none` without alternative\n- **Don\'t hide content** \u2013 that should be available to screen readers\n\n## Examples\n\n### \u2705 Good: Semantic HTML\n\n```jsx\n<button onClick={handleClick}>Delete</button>\n```\n\n### \u274C Bad: Div as button\n\n```jsx\n<div onClick={handleClick}>Delete</div>\n```\n\n### \u2705 Good: Proper label\n\n```jsx\n<label htmlFor="email">Email</label>\n<input id="email" type="email" />\n```\n\n### \u274C Bad: Placeholder as label\n\n```jsx\n<input type="email" placeholder="Email" />\n```\n\n### \u2705 Good: Icon with label\n\n```jsx\n<button aria-label="Close dialog">\n <XIcon />\n</button>\n```\n\n### \u2705 Good: Keyboard support\n\n```javascript\nfunction handleKeyDown(e) {\n if (e.key === "Escape") {\n closeModal();\n }\n if (e.key === "Enter" || e.key === " ") {\n handleAction();\n }\n}\n```\n';
21
+ var api_design_md = '# API Design\n\n## Purpose\n\nDefine standards for designing APIs (REST, GraphQL, internal modules).\n\n## Do\n\n- **Use RESTful conventions** \u2013 GET (read), POST (create), PUT/PATCH (update), DELETE\n- **Version your API** \u2013 /v1/, /v2/, or header-based versioning\n- **Use plural nouns** \u2013 `/users`, `/posts`, not `/user`, `/post`\n- **Return proper HTTP status codes** \u2013 200 success, 201 created, 400 bad request, 404 not found, 500 error\n- **Include pagination** \u2013 for list endpoints (limit, offset or cursor)\n- **Validate inputs** \u2013 return 400 with clear error messages\n- **Use consistent naming** \u2013 camelCase or snake_case, pick one\n- **Include timestamps** \u2013 createdAt, updatedAt for resources\n- **Document your API** \u2013 OpenAPI/Swagger specs\n- **Handle errors gracefully** \u2013 return error objects with code and message\n\n## Don\'t\n\n- **Don\'t use verbs in URLs** \u2013 use HTTP methods instead\n- **Don\'t expose internal IDs** \u2013 use UUIDs or opaque identifiers\n- **Don\'t return different structures** \u2013 for same endpoint in different states\n- **Don\'t forget rate limiting** \u2013 protect against abuse\n- **Don\'t expose stack traces** \u2013 in production error responses\n- **Don\'t break backward compatibility** \u2013 without versioning\n- **Don\'t use GET for mutations** \u2013 GET should be idempotent\n\n## Examples\n\n### \u2705 Good: RESTful design\n\n```\nGET /v1/users # List users\nGET /v1/users/123 # Get user\nPOST /v1/users # Create user\nPATCH /v1/users/123 # Update user\nDELETE /v1/users/123 # Delete user\n```\n\n### \u274C Bad: Non-RESTful\n\n```\nGET /getUsers\nPOST /createUser\nPOST /deleteUser\n```\n\n### \u2705 Good: Error response\n\n```json\n{\n "error": {\n "code": "INVALID_EMAIL",\n "message": "Email address is not valid",\n "field": "email"\n }\n}\n```\n\n### \u274C Bad: Vague error\n\n```json\n{\n "error": "Bad request"\n}\n```\n\n### \u2705 Good: Pagination\n\n```json\n{\n "data": [...],\n "pagination": {\n "total": 1000,\n "page": 1,\n "pageSize": 20,\n "totalPages": 50\n }\n}\n```\n';
22
+ var git_workflow_md = "# Git Workflow\n\n## Purpose\n\nDefine Git commit and branch standards for AI-generated code changes.\n\n## Do\n\n- **Write clear commit messages** \u2013 use conventional commits format\n- **Make atomic commits** \u2013 one logical change per commit\n- **Use descriptive branch names** \u2013 feature/add-login, fix/memory-leak\n- **Keep commits small** \u2013 easier to review and revert\n- **Test before committing** \u2013 ensure code works\n- **Write commit body** \u2013 for complex changes, explain why\n- **Reference issues** \u2013 \"Fixes #123\" in commit message\n- **Squash before merge** \u2013 keep main branch clean (if team convention)\n- **Pull before push** \u2013 avoid merge conflicts\n- **Use feature branches** \u2013 never commit directly to main\n\n## Don't\n\n- **Don't commit secrets** \u2013 use .gitignore, check before push\n- **Don't commit commented code** \u2013 delete it, Git has history\n- **Don't commit build artifacts** \u2013 node_modules, dist/, .env\n- **Don't use vague messages** \u2013 \"fix bug\", \"update code\"\n- **Don't commit WIP** \u2013 to shared branches\n- **Don't rewrite public history** \u2013 no force push to main/shared branches\n- **Don't make giant commits** \u2013 breaks down to reviewable chunks\n\n## Examples\n\n### \u2705 Good: Conventional commit\n\n```\nfeat: add user authentication with JWT\n\nImplements login, logout, and token refresh endpoints.\nUses bcrypt for password hashing and validates tokens\non protected routes.\n\nFixes #45\n```\n\n### \u274C Bad: Vague message\n\n```\nupdated stuff\n```\n\n### \u2705 Good: Branch naming\n\n```\nfeature/user-authentication\nfix/login-button-spacing\nrefactor/api-client-structure\ndocs/update-readme\n```\n\n### \u274C Bad: Branch naming\n\n```\nmy-branch\ntest\nnew-stuff\n```\n\n### Conventional Commit Types\n\n- `feat:` New feature\n- `fix:` Bug fix\n- `docs:` Documentation\n- `style:` Formatting, no code change\n- `refactor:` Code restructuring\n- `test:` Adding tests\n- `chore:` Maintenance tasks\n- `perf:` Performance improvement\n\n```\n\n```\n";
23
+ var TEMPLATES = {
24
+ "security.md": security_md,
25
+ "unit-tests.md": unit_tests_md,
26
+ "naming.md": naming_md,
27
+ "architecture.md": architecture_md,
28
+ "performance.md": performance_md,
29
+ "code-review.md": code_review_md,
30
+ "error-handling.md": error_handling_md,
31
+ "documentation.md": documentation_md,
32
+ "accessibility.md": accessibility_md,
33
+ "api-design.md": api_design_md,
34
+ "git-workflow.md": git_workflow_md
35
+ };
36
+ var RULE_DEFINITIONS = [
37
+ {
38
+ "id": "security",
39
+ "filename": "security.md",
40
+ "minimal": true,
41
+ "modes": [
42
+ "codegen",
43
+ "review",
44
+ "test",
45
+ "docs",
46
+ "ops"
47
+ ]
48
+ },
49
+ {
50
+ "id": "unit-tests",
51
+ "filename": "unit-tests.md",
52
+ "minimal": true,
53
+ "modes": [
54
+ "codegen",
55
+ "test"
56
+ ]
57
+ },
58
+ {
59
+ "id": "naming",
60
+ "filename": "naming.md",
61
+ "minimal": true,
62
+ "modes": [
63
+ "codegen",
64
+ "review"
65
+ ]
66
+ },
67
+ {
68
+ "id": "architecture",
69
+ "filename": "architecture.md",
70
+ "minimal": false,
71
+ "modes": [
72
+ "codegen",
73
+ "review",
74
+ "ops"
75
+ ]
76
+ },
77
+ {
78
+ "id": "performance",
79
+ "filename": "performance.md",
80
+ "minimal": false,
81
+ "modes": [
82
+ "codegen",
83
+ "review"
84
+ ]
85
+ },
86
+ {
87
+ "id": "code-review",
88
+ "filename": "code-review.md",
89
+ "minimal": false,
90
+ "modes": [
91
+ "review"
92
+ ]
93
+ },
94
+ {
95
+ "id": "error-handling",
96
+ "filename": "error-handling.md",
97
+ "minimal": false,
98
+ "modes": [
99
+ "codegen",
100
+ "review"
101
+ ]
102
+ },
103
+ {
104
+ "id": "documentation",
105
+ "filename": "documentation.md",
106
+ "minimal": false,
107
+ "modes": [
108
+ "codegen",
109
+ "docs"
110
+ ]
111
+ },
112
+ {
113
+ "id": "accessibility",
114
+ "filename": "accessibility.md",
115
+ "minimal": false,
116
+ "modes": [
117
+ "codegen",
118
+ "review"
119
+ ]
120
+ },
121
+ {
122
+ "id": "api-design",
123
+ "filename": "api-design.md",
124
+ "minimal": false,
125
+ "modes": [
126
+ "codegen",
127
+ "review",
128
+ "ops"
129
+ ]
130
+ },
131
+ {
132
+ "id": "git-workflow",
133
+ "filename": "git-workflow.md",
134
+ "minimal": false,
135
+ "modes": [
136
+ "docs",
137
+ "ops"
138
+ ]
139
+ }
140
+ ];
141
+ function loadTemplate(filename) {
142
+ const template = TEMPLATES[filename];
143
+ if (!template) {
144
+ throw new Error(`Template not found: ${filename}`);
145
+ }
146
+ return template;
147
+ }
148
+ function generateManifest(options) {
149
+ const { dir, minimal } = options;
150
+ const activeRules = RULE_DEFINITIONS.filter(
151
+ (rule) => minimal ? rule.minimal : true
152
+ );
153
+ const rules = activeRules.map((rule) => ` ${rule.id}: "${dir}/${rule.filename}"`).join("\n");
154
+ const order = activeRules.map((rule) => ` - ${rule.id}`).join("\n");
155
+ const modeNames = ["codegen", "review", "test", "docs", "ops"];
156
+ const modesSection = modeNames.map((modeName) => {
157
+ const rulesForMode = activeRules.filter((rule) => rule.modes.includes(modeName)).map((rule) => rule.id);
158
+ return ` ${modeName}:
159
+ include: [${rulesForMode.join(", ")}]`;
160
+ }).join("\n");
161
+ return `version: 1
162
+
163
+ about:
164
+ name: "Repo Vibes"
165
+ description: "How AIs should work in this repo"
166
+
167
+ rules:
168
+ ${rules}
169
+
170
+ order:
171
+ ${order}
172
+
173
+ modes:
174
+ ${modesSection}
175
+ `;
176
+ }
177
+ function getRuleTemplates(minimal) {
178
+ return RULE_DEFINITIONS.filter((rule) => minimal ? rule.minimal : true).map((rule) => ({
179
+ filename: rule.filename,
180
+ content: loadTemplate(rule.filename)
181
+ }));
182
+ }
183
+
184
+ // src/init.ts
185
+ function prompt(question, defaultValue) {
186
+ const rl = createInterface({
187
+ input: process.stdin,
188
+ output: process.stdout
189
+ });
190
+ return new Promise((resolve) => {
191
+ rl.question(`${question} (default: ${defaultValue}): `, (answer) => {
192
+ rl.close();
193
+ resolve(answer.trim() || defaultValue);
194
+ });
195
+ });
196
+ }
197
+ function validateOptions(options) {
198
+ const { dir, manifest } = options;
199
+ if (!dir || dir.trim() === "") {
200
+ throw new Error("Directory name cannot be empty");
201
+ }
202
+ if (dir.includes("..") || dir.startsWith("/") || dir.startsWith("\\")) {
203
+ throw new Error("Directory name cannot contain path traversal patterns or be absolute");
204
+ }
205
+ const invalidDirChars = /[<>:"|?*\x00-\x1F]/;
206
+ if (invalidDirChars.test(dir)) {
207
+ throw new Error("Directory name contains invalid characters");
208
+ }
209
+ if (!manifest || manifest.trim() === "") {
210
+ throw new Error("Manifest filename cannot be empty");
211
+ }
212
+ if (!manifest.endsWith(".yaml") && !manifest.endsWith(".yml")) {
213
+ throw new Error("Manifest filename must end with .yaml or .yml");
214
+ }
215
+ if (manifest.includes("/") || manifest.includes("\\")) {
216
+ throw new Error("Manifest filename cannot contain path separators");
217
+ }
218
+ const invalidFileChars = /[<>:"|?*\x00-\x1F]/;
219
+ if (invalidFileChars.test(manifest)) {
220
+ throw new Error("Manifest filename contains invalid characters");
221
+ }
222
+ }
223
+ async function init(options) {
224
+ const { force, minimal } = options;
225
+ const dir = options.dir || await prompt("Directory name for rule documents", "vibes");
226
+ const manifest = options.manifest || await prompt("Manifest filename", "vibes.yaml");
227
+ validateOptions({ force, minimal, dir, manifest });
228
+ const cwd = process.cwd();
229
+ const results = [];
230
+ const manifestPath = join(cwd, manifest);
231
+ const manifestExists = await fileExists(manifestPath);
232
+ if (!manifestExists || force) {
233
+ try {
234
+ const manifestContent = generateManifest({ dir, minimal });
235
+ await writeFile(manifestPath, manifestContent, "utf-8");
236
+ results.push({
237
+ path: manifest,
238
+ status: manifestExists ? "overwritten" : "created"
239
+ });
240
+ } catch (error) {
241
+ throw new Error(`Failed to write manifest file: ${error instanceof Error ? error.message : "Unknown error"}`);
242
+ }
243
+ } else {
244
+ results.push({
245
+ path: manifest,
246
+ status: "skipped"
247
+ });
248
+ }
249
+ try {
250
+ const rulesDir2 = join(cwd, dir);
251
+ await mkdir(rulesDir2, { recursive: true });
252
+ } catch (error) {
253
+ throw new Error(`Failed to create directory '${dir}': ${error instanceof Error ? error.message : "Unknown error"}`);
254
+ }
255
+ const rulesDir = join(cwd, dir);
256
+ const templates = getRuleTemplates(minimal);
257
+ for (const template of templates) {
258
+ const filePath = join(rulesDir, template.filename);
259
+ const fileAlreadyExists = await fileExists(filePath);
260
+ if (!fileAlreadyExists || force) {
261
+ try {
262
+ await writeFile(filePath, template.content, "utf-8");
263
+ results.push({
264
+ path: join(dir, template.filename),
265
+ status: fileAlreadyExists ? "overwritten" : "created"
266
+ });
267
+ } catch (error) {
268
+ throw new Error(`Failed to write rule file '${template.filename}': ${error instanceof Error ? error.message : "Unknown error"}`);
269
+ }
270
+ } else {
271
+ results.push({
272
+ path: join(dir, template.filename),
273
+ status: "skipped"
274
+ });
275
+ }
276
+ }
277
+ printSummary(results);
278
+ if (results.some((r) => r.status === "created" || r.status === "overwritten")) {
279
+ console.log("\nIf this saves your team time, consider sponsoring the project:");
280
+ console.log("https://github.com/sponsors/ai-vibes");
281
+ }
282
+ }
283
+ async function fileExists(path) {
284
+ try {
285
+ await access(path);
286
+ return true;
287
+ } catch {
288
+ return false;
289
+ }
290
+ }
291
+ function printSummary(results) {
292
+ const created = results.filter((r) => r.status === "created");
293
+ const skipped = results.filter((r) => r.status === "skipped");
294
+ const overwritten = results.filter((r) => r.status === "overwritten");
295
+ if (created.length > 0) {
296
+ console.log("\n\u2713 Created:");
297
+ created.forEach((r) => console.log(` - ${r.path}`));
298
+ }
299
+ if (overwritten.length > 0) {
300
+ console.log("\n\u2713 Overwritten:");
301
+ overwritten.forEach((r) => console.log(` - ${r.path}`));
302
+ }
303
+ if (skipped.length > 0) {
304
+ console.log("\n\u25CB Skipped (already exists):");
305
+ skipped.forEach((r) => console.log(` - ${r.path}`));
306
+ }
307
+ }
308
+
309
+ // src/cli.ts
310
+ var program = new Command();
311
+ program.name("ai-vibes").description("Initialize a standard, repo-local AI steering manifest and rule documents").version("1.0.0");
312
+ program.command("init").description("Initialize vibes.yaml and starter rule documents").option("--force", "Overwrite existing files", false).option("--minimal", "Create minimal starter set (3 essential files: security, unit-tests, naming)", false).option("--dir <name>", "Directory name for rule documents").option("--manifest <filename>", "Manifest filename").action(async (options) => {
313
+ try {
314
+ await init({
315
+ force: options.force,
316
+ minimal: options.minimal,
317
+ dir: options.dir,
318
+ manifest: options.manifest
319
+ });
320
+ } catch (error) {
321
+ console.error("Error initializing ai-vibes:", error);
322
+ process.exit(1);
323
+ }
324
+ });
325
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "ai-vibes",
3
+ "version": "1.0.0",
4
+ "description": "A tiny CLI that initializes a standard, repo-local AI steering manifest and rule documents",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "bin": {
8
+ "ai-vibes": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "generate": "node scripts/generate-templates.js",
17
+ "prebuild": "npm run generate",
18
+ "build": "tsup src/cli.ts --format esm --clean",
19
+ "dev": "tsup src/cli.ts --format esm --watch",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "ai",
24
+ "llm",
25
+ "rules",
26
+ "guidelines",
27
+ "code-quality",
28
+ "conventions",
29
+ "cli"
30
+ ],
31
+ "author": "",
32
+ "license": "MIT",
33
+ "engines": {
34
+ "node": ">=18.0.0"
35
+ },
36
+ "dependencies": {
37
+ "commander": "^12.1.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^20.11.0",
41
+ "tsup": "^8.0.1",
42
+ "typescript": "^5.3.3"
43
+ }
44
+ }