@quanvo99/ai-rules 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) 2024 AI Rules CLI
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,230 @@
1
+ # AI Rules CLI
2
+
3
+ A command-line tool that helps developers pull curated AI agent rules from a centralized repository into their projects. No more hunting through scattered rule files - get the exact rules you need for your tech stack with a simple command.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Initialize rules for your project (no installation needed!)
9
+ npx @quanvo99/ai-rules init
10
+
11
+ # Add specific rule categories
12
+ npx @quanvo99/ai-rules add typescript react
13
+
14
+ # Update to latest rules
15
+ npx @quanvo99/ai-rules update
16
+ ```
17
+
18
+ ## What is AI Rules CLI?
19
+
20
+ AI Rules CLI solves the problem of scattered, hard-to-find AI agent rule files across different projects. Instead of manually copying rules from various sources, you can:
21
+
22
+ - **Discover** rules by tech stack using natural language search
23
+ - **Install** only the rules you need for your specific project
24
+ - **Update** to the latest rule versions with a single command
25
+ - **Refine** your selection through intelligent questioning
26
+
27
+ ## Supported AI Agents
28
+
29
+ - **Cursor** - `.cursor/rules/` directory with `.cursorrules` files
30
+ - **Windsurf** - `.windsurf/rules/` directory with `.windsurfrules` files
31
+ - **More coming soon** - Aider, Continue, Cody, and others
32
+
33
+ ## Key Features
34
+
35
+ ### 🎯 Smart Rule Discovery
36
+
37
+ Use natural language to find relevant rules:
38
+
39
+ ```bash
40
+ npx @quanvo99/ai-rules search "nextjs 15 server components tailwind"
41
+ ```
42
+
43
+ ### 🔍 Interactive Refinement
44
+
45
+ Get personalized recommendations through guided questions:
46
+
47
+ - "Are you using App Router or Pages Router?"
48
+ - "What's your primary data fetching strategy?"
49
+ - "Do you prefer Tailwind or styled-components?"
50
+
51
+ ### 📦 Easy Management
52
+
53
+ ```bash
54
+ # See what's installed
55
+ npx @quanvo99/ai-rules status
56
+
57
+ # Add more rules
58
+ npx @quanvo99/ai-rules add nextjs database
59
+
60
+ # Remove unused rules
61
+ npx @quanvo99/ai-rules remove old-framework
62
+
63
+ # Update everything
64
+ npx @quanvo99/ai-rules update
65
+ ```
66
+
67
+ ## How It Works
68
+
69
+ 1. **Initialize** - Choose your AI agent and tech stack
70
+ 2. **Discover** - Search for relevant rules using natural language
71
+ 3. **Refine** - Answer questions to get personalized recommendations
72
+ 4. **Install** - Rules are automatically placed in the correct locations
73
+ 5. **Update** - Keep your rules current with the latest versions
74
+
75
+ ## Project Structure
76
+
77
+ ```
78
+ your-project/
79
+ ├── .cursor/
80
+ │ └── rules/
81
+ │ ├── typescript-strict.md
82
+ │ ├── react-server-components.md
83
+ │ └── tailwind-best-practices.md
84
+ ├── .ai-rules.json # Configuration file
85
+ └── package.json
86
+ ```
87
+
88
+ ## Available Rule Categories
89
+
90
+ ### Languages
91
+
92
+ - **TypeScript** - Strict typing, best practices, advanced patterns
93
+ - **JavaScript** - Modern ES6+, async patterns, error handling
94
+
95
+ ### Frameworks
96
+
97
+ - **React** - Hooks, server components, performance optimization
98
+ - **Next.js** - App Router, Pages Router, SSR/SSG patterns
99
+ - **Vue** - Composition API, Nuxt.js patterns
100
+
101
+ ### Styling
102
+
103
+ - **Tailwind CSS** - Utility-first, component patterns, responsive design
104
+ - **CSS Modules** - Scoped styling, naming conventions
105
+ - **Styled Components** - CSS-in-JS patterns, theming
106
+
107
+ ### Database
108
+
109
+ - **Prisma** - Schema design, query optimization, migrations
110
+ - **MongoDB** - Document modeling, aggregation pipelines
111
+ - **PostgreSQL** - Query patterns, indexing strategies
112
+
113
+ ### Testing
114
+
115
+ - **Jest** - Unit testing, mocking, test organization
116
+ - **Playwright** - E2E testing, page object patterns
117
+ - **Testing Library** - Component testing, accessibility
118
+
119
+ ## Configuration
120
+
121
+ The CLI creates a `.ai-rules.json` file in your project root:
122
+
123
+ ```json
124
+ {
125
+ "agent": "cursor",
126
+ "rules": [
127
+ {
128
+ "id": "typescript-strict",
129
+ "category": "typescript",
130
+ "installedAt": "2024-01-15T10:30:00Z",
131
+ "source": "github.com/votrungquan1999/AI-rules-setup"
132
+ }
133
+ ],
134
+ "preferences": {
135
+ "autoUpdate": false,
136
+ "conflictResolution": "prompt"
137
+ }
138
+ }
139
+ ```
140
+
141
+ ## Commands
142
+
143
+ ### `npx @quanvo99/ai-rules init`
144
+
145
+ Interactive setup wizard that guides you through:
146
+
147
+ - AI agent selection
148
+ - Tech stack identification
149
+ - Rule discovery and selection
150
+ - Installation configuration
151
+
152
+ ### `npx @quanvo99/ai-rules add <categories...>`
153
+
154
+ Add specific rule categories to your project:
155
+
156
+ ```bash
157
+ npx @quanvo99/ai-rules add typescript react nextjs
158
+ ```
159
+
160
+ ### `npx @quanvo99/ai-rules remove <categories...>`
161
+
162
+ Remove rule categories from your project:
163
+
164
+ ```bash
165
+ npx @quanvo99/ai-rules remove old-framework
166
+ ```
167
+
168
+ ### `npx @quanvo99/ai-rules update`
169
+
170
+ Update all installed rules to their latest versions:
171
+
172
+ ```bash
173
+ npx @quanvo99/ai-rules update
174
+ ```
175
+
176
+ ### `npx @quanvo99/ai-rules list [--filter <tag>]`
177
+
178
+ List available rule categories with optional filtering:
179
+
180
+ ```bash
181
+ npx @quanvo99/ai-rules list --filter frontend
182
+ ```
183
+
184
+ ### `npx @quanvo99/ai-rules status`
185
+
186
+ Show currently installed rules and their status:
187
+
188
+ ```bash
189
+ npx @quanvo99/ai-rules status
190
+ ```
191
+
192
+ ### `npx @quanvo99/ai-rules search "<query>"`
193
+
194
+ Search for rules using natural language:
195
+
196
+ ```bash
197
+ npx @quanvo99/ai-rules search "nextjs 15 server components with tailwind"
198
+ ```
199
+
200
+ ### `npx @quanvo99/ai-rules refine`
201
+
202
+ Re-run the refinement process for better rule selection:
203
+
204
+ ```bash
205
+ npx @quanvo99/ai-rules refine
206
+ ```
207
+
208
+ ## Environment Variables
209
+
210
+ You can configure the API endpoint if needed:
211
+
212
+ ```bash
213
+ # Set custom API URL (optional)
214
+ export AI_RULES_API_URL=https://your-api-domain.com
215
+ npx @quanvo99/ai-rules init
216
+ ```
217
+
218
+ ## License
219
+
220
+ MIT License - see [LICENSE](LICENSE) for details.
221
+
222
+ ## Support
223
+
224
+ - 📖 [Documentation](https://github.com/votrungquan1999/AI-rules-setup#readme)
225
+ - 🐛 [Report Issues](https://github.com/votrungquan1999/AI-rules-setup/issues)
226
+ - 💬 [Discussions](https://github.com/votrungquan1999/AI-rules-setup/discussions)
227
+
228
+ ---
229
+
230
+ **Made with ❤️ for the developer community**
package/bin/cli.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require("../dist/cli/index.js");
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Initialize AI rules for the current project
3
+ */
4
+ export declare function initCommand(): Promise<void>;
5
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAgHjD"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initCommand = initCommand;
7
+ const node_path_1 = require("node:path");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const config_1 = require("../lib/config");
10
+ const files_1 = require("../lib/files");
11
+ const github_1 = require("../lib/github");
12
+ const prompts_1 = require("../lib/prompts");
13
+ /**
14
+ * Initialize AI rules for the current project
15
+ */
16
+ async function initCommand() {
17
+ try {
18
+ console.log(chalk_1.default.blue("🚀 Initializing AI Rules...\n"));
19
+ // Fetch available agents
20
+ const agents = await (0, github_1.fetchAvailableAgents)();
21
+ if (agents.length === 0) {
22
+ console.log(chalk_1.default.red("❌ No AI agents found. Make sure the API server is running."));
23
+ process.exit(1);
24
+ }
25
+ // Prompt for agent selection
26
+ const selectedAgent = await (0, prompts_1.promptAgentSelection)(agents);
27
+ console.log(chalk_1.default.green(`✓ Selected agent: ${selectedAgent}\n`));
28
+ // Fetch manifests for selected agent
29
+ const manifests = await (0, github_1.fetchManifests)(selectedAgent);
30
+ if (manifests.length === 0) {
31
+ console.log(chalk_1.default.red("❌ No rule categories found for this agent"));
32
+ return;
33
+ }
34
+ // Prompt for category selection
35
+ const selectedCategories = await (0, prompts_1.promptCategorySelection)(manifests);
36
+ if (selectedCategories.length === 0) {
37
+ console.log(chalk_1.default.yellow("⚠️ No categories selected. Nothing to install."));
38
+ return;
39
+ }
40
+ console.log(chalk_1.default.green(`✓ Selected categories: ${selectedCategories.join(", ")}\n`));
41
+ // Load existing config or create default
42
+ let config;
43
+ try {
44
+ config = await (0, config_1.loadConfig)(process.cwd());
45
+ }
46
+ catch (_error) {
47
+ // Config file doesn't exist, create default config
48
+ console.log("No existing config found, creating new configuration...");
49
+ config = {
50
+ version: "1.0.0",
51
+ agent: selectedAgent,
52
+ categories: [],
53
+ };
54
+ }
55
+ // Process each selected category
56
+ const installedRules = [];
57
+ for (const categoryId of selectedCategories) {
58
+ const manifest = manifests.find((m) => m.id === categoryId);
59
+ if (!manifest) {
60
+ console.log(chalk_1.default.red(`❌ Manifest not found for category: ${categoryId}`));
61
+ continue;
62
+ }
63
+ console.log(chalk_1.default.blue(`📦 Installing ${manifest.id}...`));
64
+ // Process each file in the manifest
65
+ for (const file of manifest.files) {
66
+ try {
67
+ // Fetch file content
68
+ const content = await (0, github_1.fetchRuleFile)(selectedAgent, manifest.category, file.path);
69
+ if (!content) {
70
+ console.log(chalk_1.default.red(`❌ Failed to fetch file: ${file.path}`));
71
+ continue;
72
+ }
73
+ // Extract filename from path (last segment)
74
+ const filename = file.path.split("/").pop() || file.path;
75
+ // Apply naming convention
76
+ const targetPath = (0, files_1.applyNamingConvention)(selectedAgent, filename);
77
+ // Check for conflicts
78
+ const conflict = await (0, files_1.detectConflict)((0, node_path_1.join)(process.cwd(), targetPath));
79
+ if (conflict.hasConflict) {
80
+ const shouldOverwrite = await (0, prompts_1.promptConflictResolution)(targetPath);
81
+ if (!shouldOverwrite) {
82
+ console.log(chalk_1.default.yellow(`⏭️ Skipped: ${targetPath}`));
83
+ continue;
84
+ }
85
+ }
86
+ // Write file
87
+ await (0, files_1.writeRuleFile)(content, (0, node_path_1.join)(process.cwd(), targetPath));
88
+ console.log(chalk_1.default.green(`✓ Installed: ${targetPath}`));
89
+ }
90
+ catch (error) {
91
+ console.log(chalk_1.default.red(`❌ Error processing ${file.path}: ${error}`));
92
+ }
93
+ }
94
+ // Add category to config
95
+ const updatedConfig = (0, config_1.addCategory)(config, categoryId);
96
+ Object.assign(config, updatedConfig);
97
+ installedRules.push(manifest.id);
98
+ }
99
+ // Save updated config
100
+ await (0, config_1.saveConfig)(process.cwd(), config);
101
+ // Display success message
102
+ console.log(chalk_1.default.green(`\n🎉 Successfully installed ${installedRules.length} rule categories:`));
103
+ installedRules.forEach((rule) => {
104
+ console.log(chalk_1.default.green(` • ${rule}`));
105
+ });
106
+ console.log(chalk_1.default.blue(`\n📝 Configuration saved to .ai-rules.json`));
107
+ }
108
+ catch (error) {
109
+ console.error(chalk_1.default.red(`❌ Error during initialization: ${error}`));
110
+ process.exit(1);
111
+ }
112
+ }
113
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const commander_1 = require("commander");
9
+ const init_1 = require("./commands/init");
10
+ const program = new commander_1.Command();
11
+ program
12
+ .name("ai-rules")
13
+ .description("A command-line tool that helps developers pull curated AI agent rules from a centralized repository into their projects")
14
+ .version("0.1.0");
15
+ program
16
+ .command("init")
17
+ .description("Initialize AI rules for the current project")
18
+ .action(async () => {
19
+ try {
20
+ await (0, init_1.initCommand)();
21
+ }
22
+ catch (error) {
23
+ console.error(chalk_1.default.red(`❌ Error: ${error}`));
24
+ process.exit(1);
25
+ }
26
+ });
27
+ program
28
+ .command("help")
29
+ .description("Show help information")
30
+ .action(() => {
31
+ program.help();
32
+ });
33
+ // Handle unknown commands
34
+ program.on("command:*", () => {
35
+ console.error(chalk_1.default.red(`❌ Unknown command: ${program.args.join(" ")}`));
36
+ console.log(chalk_1.default.blue("Use --help to see available commands"));
37
+ process.exit(1);
38
+ });
39
+ // Handle errors
40
+ program.on("error", (error) => {
41
+ console.error(chalk_1.default.red(`❌ Error: ${error.message}`));
42
+ process.exit(1);
43
+ });
44
+ // Parse command line arguments
45
+ program.parse(process.argv);
46
+ // Show help if no command provided
47
+ if (!process.argv.slice(2).length) {
48
+ program.help();
49
+ }
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";;;;;;AAEA,kDAA0B;AAC1B,yCAAoC;AACpC,0CAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACX,yHAAyH,CACzH;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,KAAK,IAAI,EAAE;IAClB,IAAI,CAAC;QACJ,MAAM,IAAA,kBAAW,GAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC,CAAC,CAAC;AAEJ,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,GAAG,EAAE;IACZ,OAAO,CAAC,IAAI,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAEJ,0BAA0B;AAC1B,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,gBAAgB;AAChB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;IAC7B,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,+BAA+B;AAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,mCAAmC;AACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,OAAO,CAAC,IAAI,EAAE,CAAC;AAChB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Config } from "./types";
2
+ /**
3
+ * Loads configuration from .ai-rules.json file or returns default config
4
+ * @param projectRoot - Path to the project root directory
5
+ * @returns Configuration object
6
+ */
7
+ export declare function loadConfig(projectRoot: string): Promise<Config>;
8
+ /**
9
+ * Saves configuration to .ai-rules.json file
10
+ * @param projectRoot - Path to the project root directory
11
+ * @param config - Configuration object to save
12
+ */
13
+ export declare function saveConfig(projectRoot: string, config: Config): Promise<void>;
14
+ /**
15
+ * Adds a category to the configuration
16
+ * @param config - Current configuration object
17
+ * @param category - Category to add
18
+ * @returns Updated configuration object
19
+ */
20
+ export declare function addCategory(config: Config, category: string): Config;
21
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BrE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYpE"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfig = loadConfig;
4
+ exports.saveConfig = saveConfig;
5
+ exports.addCategory = addCategory;
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_path_1 = require("node:path");
8
+ /**
9
+ * Loads configuration from .ai-rules.json file or returns default config
10
+ * @param projectRoot - Path to the project root directory
11
+ * @returns Configuration object
12
+ */
13
+ async function loadConfig(projectRoot) {
14
+ const configPath = (0, node_path_1.join)(projectRoot, ".ai-rules.json");
15
+ try {
16
+ const content = await (0, promises_1.readFile)(configPath, "utf-8");
17
+ const config = JSON.parse(content);
18
+ // Validate that the config has required properties
19
+ if (!config.version || !config.agent || !Array.isArray(config.categories)) {
20
+ throw new Error("Invalid config format");
21
+ }
22
+ return config;
23
+ }
24
+ catch (_error) {
25
+ // If config file is missing or malformed, write default config to disk and return it
26
+ const defaultConfig = {
27
+ version: "1.0.0",
28
+ agent: "cursor",
29
+ categories: [],
30
+ };
31
+ // Ensure directory exists and write the default config
32
+ const dir = (0, node_path_1.dirname)(configPath);
33
+ await (0, promises_1.mkdir)(dir, { recursive: true });
34
+ const content = JSON.stringify(defaultConfig, null, 2);
35
+ await (0, promises_1.writeFile)(configPath, content, "utf-8");
36
+ return defaultConfig;
37
+ }
38
+ }
39
+ /**
40
+ * Saves configuration to .ai-rules.json file
41
+ * @param projectRoot - Path to the project root directory
42
+ * @param config - Configuration object to save
43
+ */
44
+ async function saveConfig(projectRoot, config) {
45
+ const configPath = (0, node_path_1.join)(projectRoot, ".ai-rules.json");
46
+ // Create directory structure if it doesn't exist
47
+ const dir = (0, node_path_1.dirname)(configPath);
48
+ await (0, promises_1.mkdir)(dir, { recursive: true });
49
+ // Write config with pretty formatting
50
+ const content = JSON.stringify(config, null, 2);
51
+ await (0, promises_1.writeFile)(configPath, content, "utf-8");
52
+ }
53
+ /**
54
+ * Adds a category to the configuration
55
+ * @param config - Current configuration object
56
+ * @param category - Category to add
57
+ * @returns Updated configuration object
58
+ */
59
+ function addCategory(config, category) {
60
+ // Check if category already exists
61
+ if (config.categories.includes(category)) {
62
+ // Category already exists, don't add duplicate
63
+ return config;
64
+ }
65
+ // Add new category
66
+ return {
67
+ ...config,
68
+ categories: [...config.categories, category],
69
+ };
70
+ }
71
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":";;AASA,gCA4BC;AAOD,gCAUC;AAQD,kCAYC;AA1ED,+CAA8D;AAC9D,yCAA0C;AAG1C;;;;GAIG;AACI,KAAK,UAAU,UAAU,CAAC,WAAmB;IACnD,MAAM,UAAU,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IACvD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,mDAAmD;QACnD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1C,CAAC;QAED,OAAO,MAAgB,CAAC;IACzB,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QACjB,qFAAqF;QACrF,MAAM,aAAa,GAAW;YAC7B,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,EAAE;SACd,CAAC;QAEF,uDAAuD;QACvD,MAAM,GAAG,GAAG,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC;QAChC,MAAM,IAAA,gBAAK,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAE9C,OAAO,aAAa,CAAC;IACtB,CAAC;AACF,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAc;IACnE,MAAM,UAAU,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAEvD,iDAAiD;IACjD,MAAM,GAAG,GAAG,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC;IAChC,MAAM,IAAA,gBAAK,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtC,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,MAAc,EAAE,QAAgB;IAC3D,mCAAmC;IACnC,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,+CAA+C;QAC/C,OAAO,MAAM,CAAC;IACf,CAAC;IAED,mBAAmB;IACnB,OAAO;QACN,GAAG,MAAM;QACT,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC;KAC5C,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { AIAgent, type ConflictResult } from "./types";
2
+ /**
3
+ * Detects if a file conflict exists at the given path
4
+ * @param filePath - Path to check for conflicts
5
+ * @returns Conflict detection result
6
+ */
7
+ export declare function detectConflict(filePath: string): Promise<ConflictResult>;
8
+ /**
9
+ * Writes rule file content to the specified path, creating directories as needed
10
+ * @param content - Content to write to the file
11
+ * @param targetPath - Target file path
12
+ */
13
+ export declare function writeRuleFile(content: string, targetPath: string): Promise<void>;
14
+ /**
15
+ * Applies tool-specific naming conventions to convert source filename to target path
16
+ * @param agent - AI agent type
17
+ * @param filename - Source filename (preserves original extension)
18
+ * @returns Target file path following agent conventions
19
+ */
20
+ export declare function applyNamingConvention(agent: AIAgent, filename: string): string;
21
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/files.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAW9E;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqB9E"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectConflict = detectConflict;
4
+ exports.writeRuleFile = writeRuleFile;
5
+ exports.applyNamingConvention = applyNamingConvention;
6
+ const node_fs_1 = require("node:fs");
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_path_1 = require("node:path");
9
+ const types_1 = require("./types");
10
+ /**
11
+ * Detects if a file conflict exists at the given path
12
+ * @param filePath - Path to check for conflicts
13
+ * @returns Conflict detection result
14
+ */
15
+ async function detectConflict(filePath) {
16
+ try {
17
+ await (0, promises_1.access)(filePath, node_fs_1.constants.F_OK);
18
+ return {
19
+ hasConflict: true,
20
+ };
21
+ }
22
+ catch {
23
+ return {
24
+ hasConflict: false,
25
+ };
26
+ }
27
+ }
28
+ /**
29
+ * Writes rule file content to the specified path, creating directories as needed
30
+ * @param content - Content to write to the file
31
+ * @param targetPath - Target file path
32
+ */
33
+ async function writeRuleFile(content, targetPath) {
34
+ // Create directory structure if it doesn't exist
35
+ const dir = (0, node_path_1.dirname)(targetPath);
36
+ await (0, promises_1.mkdir)(dir, { recursive: true });
37
+ // Write the file
38
+ await (0, promises_1.writeFile)(targetPath, content, "utf-8");
39
+ }
40
+ /**
41
+ * Applies tool-specific naming conventions to convert source filename to target path
42
+ * @param agent - AI agent type
43
+ * @param filename - Source filename (preserves original extension)
44
+ * @returns Target file path following agent conventions
45
+ */
46
+ function applyNamingConvention(agent, filename) {
47
+ switch (agent) {
48
+ case types_1.AIAgent.CURSOR:
49
+ return `.cursor/rules/${filename}`;
50
+ case types_1.AIAgent.WINDSURF:
51
+ // For Windsurf, use the filename as the category name but keep original extension
52
+ return `.windsurf/rules/${filename}`;
53
+ case types_1.AIAgent.AIDER:
54
+ return `.aider/rules/${filename}`;
55
+ case types_1.AIAgent.CONTINUE:
56
+ return `.continue/rules/${filename}`;
57
+ case types_1.AIAgent.CODY:
58
+ return `.cody/rules/${filename}`;
59
+ default:
60
+ throw new Error(`Unsupported AI agent: ${agent}`);
61
+ }
62
+ }
63
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../../src/cli/lib/files.ts"],"names":[],"mappings":";;AAUA,wCAWC;AAOD,sCAOC;AAQD,sDAqBC;AAhED,qCAAoC;AACpC,+CAA4D;AAC5D,yCAAoC;AACpC,mCAAuD;AAEvD;;;;GAIG;AACI,KAAK,UAAU,cAAc,CAAC,QAAgB;IACpD,IAAI,CAAC;QACJ,MAAM,IAAA,iBAAM,EAAC,QAAQ,EAAE,mBAAS,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO;YACN,WAAW,EAAE,IAAI;SACjB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO;YACN,WAAW,EAAE,KAAK;SAClB,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,UAAkB;IACtE,iDAAiD;IACjD,MAAM,GAAG,GAAG,IAAA,mBAAO,EAAC,UAAU,CAAC,CAAC;IAChC,MAAM,IAAA,gBAAK,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtC,iBAAiB;IACjB,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,KAAc,EAAE,QAAgB;IACrE,QAAQ,KAAK,EAAE,CAAC;QACf,KAAK,eAAO,CAAC,MAAM;YAClB,OAAO,iBAAiB,QAAQ,EAAE,CAAC;QAEpC,KAAK,eAAO,CAAC,QAAQ;YACpB,kFAAkF;YAClF,OAAO,mBAAmB,QAAQ,EAAE,CAAC;QAEtC,KAAK,eAAO,CAAC,KAAK;YACjB,OAAO,gBAAgB,QAAQ,EAAE,CAAC;QAEnC,KAAK,eAAO,CAAC,QAAQ;YACpB,OAAO,mBAAmB,QAAQ,EAAE,CAAC;QAEtC,KAAK,eAAO,CAAC,IAAI;YAChB,OAAO,eAAe,QAAQ,EAAE,CAAC;QAElC;YACC,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;AACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Manifest } from "../../server/types";
2
+ /**
3
+ * Fetches available AI agents from the API
4
+ * @returns Array of available agent names
5
+ */
6
+ export declare function fetchAvailableAgents(): Promise<string[]>;
7
+ /**
8
+ * Fetches all manifests for a specific agent from the API
9
+ * @param agent - AI agent name (e.g., 'cursor', 'windsurf')
10
+ * @returns Array of manifest objects
11
+ */
12
+ export declare function fetchManifests(agent: string): Promise<Manifest[]>;
13
+ /**
14
+ * Fetches content of a specific rule file from the API
15
+ * @param agent - AI agent name (e.g., 'cursor', 'windsurf')
16
+ * @param category - Rule category name (e.g., 'typescript', 'react')
17
+ * @param filename - Name of the rule file
18
+ * @returns File content as string, or null if file doesn't exist
19
+ */
20
+ export declare function fetchRuleFile(agent: string, category: string, filename: string): Promise<string | null>;
21
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/github.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA0DnD;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ9D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAcvE;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqB7G"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchAvailableAgents = fetchAvailableAgents;
4
+ exports.fetchManifests = fetchManifests;
5
+ exports.fetchRuleFile = fetchRuleFile;
6
+ // API configuration
7
+ const API_BASE_URL = process.env.AI_RULES_API_URL || "http://localhost:3000";
8
+ // Cache for API responses to avoid multiple calls
9
+ let cachedRules = null;
10
+ let cacheTimestamp = 0;
11
+ const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
12
+ /**
13
+ * Fetches rules data from the API with caching
14
+ * @returns Complete rules data from the API
15
+ */
16
+ async function fetchRulesData() {
17
+ const now = Date.now();
18
+ // Return cached data if it's still fresh
19
+ if (cachedRules && now - cacheTimestamp < CACHE_DURATION) {
20
+ return cachedRules;
21
+ }
22
+ try {
23
+ const response = await fetch(`${API_BASE_URL}/api/rules`);
24
+ if (!response.ok) {
25
+ throw new Error(`API request failed: ${response.status} ${response.statusText}`);
26
+ }
27
+ const data = (await response.json());
28
+ // Update cache
29
+ cachedRules = data;
30
+ cacheTimestamp = now;
31
+ return data;
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Failed to fetch rules from API: ${error instanceof Error ? error.message : "Unknown error"}`);
35
+ }
36
+ }
37
+ /**
38
+ * Fetches available AI agents from the API
39
+ * @returns Array of available agent names
40
+ */
41
+ async function fetchAvailableAgents() {
42
+ try {
43
+ const data = await fetchRulesData();
44
+ return Object.keys(data.agents);
45
+ }
46
+ catch (error) {
47
+ console.error("Error fetching available agents:", error);
48
+ return [];
49
+ }
50
+ }
51
+ /**
52
+ * Fetches all manifests for a specific agent from the API
53
+ * @param agent - AI agent name (e.g., 'cursor', 'windsurf')
54
+ * @returns Array of manifest objects
55
+ */
56
+ async function fetchManifests(agent) {
57
+ try {
58
+ const data = await fetchRulesData();
59
+ const agentData = data.agents[agent];
60
+ if (!agentData) {
61
+ return [];
62
+ }
63
+ return Object.values(agentData.categories).map((category) => category.manifest);
64
+ }
65
+ catch (error) {
66
+ console.error(`Error fetching manifests for agent ${agent}:`, error);
67
+ return [];
68
+ }
69
+ }
70
+ /**
71
+ * Fetches content of a specific rule file from the API
72
+ * @param agent - AI agent name (e.g., 'cursor', 'windsurf')
73
+ * @param category - Rule category name (e.g., 'typescript', 'react')
74
+ * @param filename - Name of the rule file
75
+ * @returns File content as string, or null if file doesn't exist
76
+ */
77
+ async function fetchRuleFile(agent, category, filename) {
78
+ try {
79
+ const data = await fetchRulesData();
80
+ const agentData = data.agents[agent];
81
+ if (!agentData) {
82
+ return null;
83
+ }
84
+ const categoryData = agentData.categories[category];
85
+ if (!categoryData) {
86
+ return null;
87
+ }
88
+ // Find the file in the array by filename
89
+ const file = categoryData.files.find((f) => f.filename === filename);
90
+ return file?.content || null;
91
+ }
92
+ catch (error) {
93
+ console.error(`Error fetching rule file ${agent}/${category}/${filename}:`, error);
94
+ return null;
95
+ }
96
+ }
97
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../../src/cli/lib/github.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Manifest } from "./types";
2
+ /**
3
+ * Prompts user to select an AI agent
4
+ * @param agents - Array of available agent names
5
+ * @returns Selected agent name
6
+ */
7
+ export declare function promptAgentSelection(agents: string[]): Promise<string>;
8
+ /**
9
+ * Prompts user to select rule categories
10
+ * @param manifests - Array of available manifests
11
+ * @returns Array of selected category names
12
+ */
13
+ export declare function promptCategorySelection(manifests: Manifest[]): Promise<string[]>;
14
+ /**
15
+ * Prompts user to preview a specific manifest
16
+ * @param manifest - The manifest to preview
17
+ * @returns True if user wants to continue, false to go back
18
+ */
19
+ export declare function promptPreview(manifest: Manifest): Promise<boolean>;
20
+ /**
21
+ * Prompts user for conflict resolution
22
+ * @param filePath - Path to the conflicting file
23
+ * @returns True if user wants to overwrite, false otherwise
24
+ */
25
+ export declare function promptConflictResolution(filePath: string): Promise<boolean>;
26
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAmCxC;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5E;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkCtF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAaxE;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWjF"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.promptAgentSelection = promptAgentSelection;
7
+ exports.promptCategorySelection = promptCategorySelection;
8
+ exports.promptPreview = promptPreview;
9
+ exports.promptConflictResolution = promptConflictResolution;
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const inquirer_1 = __importDefault(require("inquirer"));
12
+ /**
13
+ * Displays a preview of the selected manifest with full details
14
+ * @param manifest - The manifest to preview
15
+ */
16
+ function showPreview(manifest) {
17
+ console.clear();
18
+ console.log(chalk_1.default.cyan.bold(`\n${manifest.id}`));
19
+ console.log(chalk_1.default.gray("─".repeat(60)));
20
+ console.log(`Category: ${manifest.category}`);
21
+ console.log(`Files: ${manifest.files.length}`);
22
+ console.log(`\nDescription:\n${manifest.description}`);
23
+ console.log(`\nTags: ${manifest.tags.join(", ")}`);
24
+ console.log(`\nFiles to install:`);
25
+ manifest.files.forEach((file) => {
26
+ console.log(chalk_1.default.green(` • ${file.path}`));
27
+ console.log(chalk_1.default.dim(` ${file.description}`));
28
+ });
29
+ if (manifest.dependencies?.length) {
30
+ console.log(`\nDependencies: ${manifest.dependencies.join(", ")}`);
31
+ }
32
+ if (manifest.conflicts?.length) {
33
+ console.log(`\nConflicts: ${manifest.conflicts.join(", ")}`);
34
+ }
35
+ console.log(chalk_1.default.gray("\n[Press any key to return to selection]"));
36
+ // Wait for keypress
37
+ process.stdin.once("data", () => {
38
+ console.clear();
39
+ });
40
+ }
41
+ /**
42
+ * Prompts user to select an AI agent
43
+ * @param agents - Array of available agent names
44
+ * @returns Selected agent name
45
+ */
46
+ async function promptAgentSelection(agents) {
47
+ const { agent } = await inquirer_1.default.prompt([
48
+ {
49
+ type: "list",
50
+ name: "agent",
51
+ message: "Select an AI agent:",
52
+ choices: agents.map((agentName) => ({
53
+ name: chalk_1.default.cyan.bold(agentName),
54
+ value: agentName,
55
+ })),
56
+ validate: (input) => {
57
+ if (!input) {
58
+ return "Please select an agent";
59
+ }
60
+ return true;
61
+ },
62
+ },
63
+ ]);
64
+ return agent;
65
+ }
66
+ /**
67
+ * Prompts user to select rule categories
68
+ * @param manifests - Array of available manifests
69
+ * @returns Array of selected category names
70
+ */
71
+ async function promptCategorySelection(manifests) {
72
+ if (manifests.length === 0) {
73
+ return [];
74
+ }
75
+ // Format choices with enhanced visual hierarchy
76
+ const choices = manifests.map((manifest) => {
77
+ const tagLine = chalk_1.default.gray(`[${manifest.tags.slice(0, 3).join(", ")}]`);
78
+ const descLine = manifest.description.length > 60 ? `${manifest.description.slice(0, 60)}…` : manifest.description;
79
+ return {
80
+ name: `${chalk_1.default.cyan.bold(manifest.id)} ${tagLine}\n ${chalk_1.default.dim(descLine)}`,
81
+ value: manifest.id,
82
+ short: manifest.id,
83
+ };
84
+ });
85
+ const { categories } = await inquirer_1.default.prompt([
86
+ {
87
+ type: "checkbox",
88
+ name: "categories",
89
+ message: "Select rule categories to install:\n(↑↓ to move, Space to select, Enter to confirm)",
90
+ choices,
91
+ pageSize: 10, // Enable pagination
92
+ validate: (input) => {
93
+ if (!input || input.length === 0) {
94
+ return "Please select at least one category";
95
+ }
96
+ return true;
97
+ },
98
+ },
99
+ ]);
100
+ return categories;
101
+ }
102
+ /**
103
+ * Prompts user to preview a specific manifest
104
+ * @param manifest - The manifest to preview
105
+ * @returns True if user wants to continue, false to go back
106
+ */
107
+ async function promptPreview(manifest) {
108
+ showPreview(manifest);
109
+ const { continueSelection } = await inquirer_1.default.prompt([
110
+ {
111
+ type: "confirm",
112
+ name: "continueSelection",
113
+ message: "Continue with selection?",
114
+ default: true,
115
+ },
116
+ ]);
117
+ return continueSelection;
118
+ }
119
+ /**
120
+ * Prompts user for conflict resolution
121
+ * @param filePath - Path to the conflicting file
122
+ * @returns True if user wants to overwrite, false otherwise
123
+ */
124
+ async function promptConflictResolution(filePath) {
125
+ const { overwrite } = await inquirer_1.default.prompt([
126
+ {
127
+ type: "confirm",
128
+ name: "overwrite",
129
+ message: `File ${filePath} already exists. Overwrite?`,
130
+ default: false,
131
+ },
132
+ ]);
133
+ return overwrite;
134
+ }
135
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../src/cli/lib/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Manifest file structure for rule categories
3
+ */
4
+ export interface Manifest {
5
+ /** Unique identifier for the rule category */
6
+ id: string;
7
+ /** Category name (e.g., 'typescript', 'react') */
8
+ category: string;
9
+ /** Tags for filtering and search */
10
+ tags: string[];
11
+ /** Human-readable description of the rules */
12
+ description: string;
13
+ /** List of rule files in this category */
14
+ files: ManifestFile[];
15
+ /** Optional dependencies on other rule categories */
16
+ dependencies?: string[];
17
+ /** Optional conflicts with other rule categories */
18
+ conflicts?: string[];
19
+ }
20
+ /**
21
+ * Individual file entry in a manifest
22
+ */
23
+ export interface ManifestFile {
24
+ /** Relative path to the file from the category directory */
25
+ path: string;
26
+ /** Description of what this file contains */
27
+ description: string;
28
+ }
29
+ /**
30
+ * Configuration file structure (.ai-rules.json)
31
+ */
32
+ export interface Config {
33
+ /** Configuration schema version */
34
+ version: string;
35
+ /** Selected AI agent (cursor, windsurf, etc.) */
36
+ agent: string;
37
+ /** List of installed rule categories */
38
+ categories: string[];
39
+ }
40
+ /**
41
+ * File mapping from source to target location
42
+ */
43
+ export interface FileMapping {
44
+ /** Source file path (relative to rule category) */
45
+ source: string;
46
+ /** Target file path (relative to project root) */
47
+ target: string;
48
+ }
49
+ /**
50
+ * Available AI agents
51
+ */
52
+ export declare enum AIAgent {
53
+ CURSOR = "cursor",
54
+ WINDSURF = "windsurf",
55
+ AIDER = "aider",
56
+ CONTINUE = "continue",
57
+ CODY = "cody"
58
+ }
59
+ /**
60
+ * Tool-specific file naming conventions
61
+ */
62
+ export interface ToolConventions {
63
+ /** Base directory for rule files */
64
+ baseDir: string;
65
+ /** File extension for rule files */
66
+ extension: string;
67
+ /** Function to convert source filename to target filename */
68
+ renameFile: (source: string, category: string) => string;
69
+ }
70
+ /**
71
+ * Conflict detection result
72
+ */
73
+ export interface ConflictResult {
74
+ /** Whether a conflict exists */
75
+ hasConflict: boolean;
76
+ /** Absolute file path that caused the conflict (present when hasConflict is true) */
77
+ filePath?: string;
78
+ /** Suggested action for the caller (e.g., 'overwrite') */
79
+ suggestedAction?: "overwrite";
80
+ }
81
+ /**
82
+ * CLI command options
83
+ */
84
+ export interface InitOptions {
85
+ /** Force overwrite existing files without prompting */
86
+ force?: boolean;
87
+ /** Dry run mode - don't actually write files */
88
+ dryRun?: boolean;
89
+ /** Verbose output */
90
+ verbose?: boolean;
91
+ /** Specific agent to use */
92
+ agent?: string;
93
+ /** Specific categories to install */
94
+ categories?: string[];
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,oBAAY,OAAO;IAClB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,IAAI,SAAS;CACb;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gCAAgC;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,uDAAuD;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AIAgent = void 0;
4
+ /**
5
+ * Available AI agents
6
+ */
7
+ var AIAgent;
8
+ (function (AIAgent) {
9
+ AIAgent["CURSOR"] = "cursor";
10
+ AIAgent["WINDSURF"] = "windsurf";
11
+ AIAgent["AIDER"] = "aider";
12
+ AIAgent["CONTINUE"] = "continue";
13
+ AIAgent["CODY"] = "cody";
14
+ })(AIAgent || (exports.AIAgent = AIAgent = {}));
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/cli/lib/types.ts"],"names":[],"mappings":";;;AAoDA;;GAEG;AACH,IAAY,OAMX;AAND,WAAY,OAAO;IAClB,4BAAiB,CAAA;IACjB,gCAAqB,CAAA;IACrB,0BAAe,CAAA;IACf,gCAAqB,CAAA;IACrB,wBAAa,CAAA;AACd,CAAC,EANW,OAAO,uBAAP,OAAO,QAMlB"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * File object interface for storing rule files
3
+ */
4
+ export interface RuleFile {
5
+ filename: string;
6
+ content: string;
7
+ }
8
+ /**
9
+ * Manifest interface (copied from CLI types to avoid circular dependency)
10
+ */
11
+ export interface Manifest {
12
+ id: string;
13
+ category: string;
14
+ tags: string[];
15
+ description: string;
16
+ version?: string;
17
+ lastUpdated?: string;
18
+ files: Array<{
19
+ path: string;
20
+ description: string;
21
+ required?: boolean;
22
+ }>;
23
+ dependencies?: string[];
24
+ conflicts?: string[];
25
+ }
26
+ /**
27
+ * Database document type for stored rules data
28
+ * Follows the database patterns with Document suffix
29
+ */
30
+ export interface StoredRulesDocument {
31
+ agent: string;
32
+ category: string;
33
+ manifest: Manifest;
34
+ files: RuleFile[];
35
+ githubCommitSha: string;
36
+ lastFetched: Date;
37
+ createdAt: Date;
38
+ updatedAt: Date;
39
+ }
40
+ /**
41
+ * Data structure for creating/updating stored rules
42
+ * Used when inserting or updating rules in the database
43
+ */
44
+ export interface RulesDataToStore {
45
+ agent: string;
46
+ category: string;
47
+ manifest: Manifest;
48
+ files: RuleFile[];
49
+ githubCommitSha: string;
50
+ }
51
+ /**
52
+ * Static base types for rule data structure
53
+ */
54
+ /**
55
+ * Represents a single category with its manifest and files
56
+ */
57
+ export interface RuleCategory {
58
+ manifest: Manifest;
59
+ files: RuleFile[];
60
+ }
61
+ /**
62
+ * Represents an agent with all its categories
63
+ */
64
+ export interface RuleAgent {
65
+ categories: {
66
+ [categoryName: string]: RuleCategory;
67
+ };
68
+ }
69
+ /**
70
+ * Complete rules data structure returned by the API
71
+ * Matches the existing API response format
72
+ */
73
+ export interface RulesData {
74
+ agents: {
75
+ [agentName: string]: RuleAgent;
76
+ };
77
+ }
78
+ /**
79
+ * GitHub API response types
80
+ */
81
+ export interface GitHubFile {
82
+ name: string;
83
+ path: string;
84
+ type: "file" | "dir";
85
+ download_url?: string;
86
+ }
87
+ export interface GitHubError {
88
+ message: string;
89
+ documentation_url?: string;
90
+ }
91
+ export declare const RULES_DATA_COLLECTION_NAME = "rules_data";
92
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/server/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,IAAI,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,UAAU,EAAE;QACX,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAAC;KACrC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,MAAM,EAAE;QACP,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;KAC/B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,0BAA0B,eAAe,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RULES_DATA_COLLECTION_NAME = void 0;
4
+ exports.RULES_DATA_COLLECTION_NAME = "rules_data";
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/server/types.ts"],"names":[],"mappings":";;;AAoGa,QAAA,0BAA0B,GAAG,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@quanvo99/ai-rules",
3
+ "version": "0.1.0",
4
+ "description": "CLI tool for managing AI agent rules across projects",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "ai-rules": "bin/cli.js"
8
+ },
9
+ "preferGlobal": true,
10
+ "files": [
11
+ "dist/",
12
+ "bin/",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "prepublishOnly": "cd .. && npm run build:cli"
18
+ },
19
+ "keywords": [
20
+ "ai",
21
+ "rules",
22
+ "cli",
23
+ "cursor",
24
+ "windsurf",
25
+ "aider"
26
+ ],
27
+ "author": "Vo Trung Quan",
28
+ "license": "MIT",
29
+ "engines": {
30
+ "node": ">=18.0.0"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/votrungquan1999/AI-rules-setup.git"
35
+ },
36
+ "homepage": "https://github.com/votrungquan1999/AI-rules-setup#readme",
37
+ "bugs": {
38
+ "url": "https://github.com/votrungquan1999/AI-rules-setup/issues"
39
+ },
40
+ "dependencies": {
41
+ "chalk": "^5.3.0",
42
+ "commander": "^11.1.0",
43
+ "execa": "^8.0.1",
44
+ "inquirer": "^9.2.12"
45
+ }
46
+ }