Skip to content

Commit 2ea67a4

Browse files
committed
[03.6]: added convert command
1 parent 4e68913 commit 2ea67a4

16 files changed

Lines changed: 1823 additions & 1079 deletions

File tree

.cursor/rules/good-behaviour.mdc

Lines changed: 0 additions & 14 deletions
This file was deleted.

.cursor/rules/vibe-tools.mdc

Lines changed: 0 additions & 174 deletions
This file was deleted.

ARCHITECTURE.md

Lines changed: 130 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ vibe-rules/
2121
├── src/ # Source code
2222
│ ├── cli.ts # Command-line interface
2323
│ ├── commands/ # CLI command action handlers (Added)
24-
│ │ └── install.ts # Action handler for the 'install' command (Added)
24+
│ │ ├── install.ts # Action handler for the 'install' command (Added)
25+
│ │ ├── save.ts # Action handler for the 'save' command (Added)
26+
│ │ ├── load.ts # Action handler for the 'load' command (Added)
27+
│ │ ├── list.ts # Action handler for the 'list' command (Added)
28+
│ │ └── convert.ts # Action handler for the 'convert' command (Added)
2529
│ ├── index.ts # Main exports
2630
│ ├── types.ts # Type definitions (Updated: RuleType.UNIFIED)
2731
│ ├── schemas.ts # Zod schema definitions
@@ -64,6 +68,7 @@ vibe-rules/
6468
├── web/ # Web interface
6569
│ ├── pages/ # Vue/Nuxt pages
6670
│ │ └── index.vue # Landing page
71+
│ │ └── local-usage.vue # Local usage guide
6772
│ ├── public/ # Public assets
6873
│ └── nuxt.config.ts # Nuxt configuration
6974
├── package.json # Project metadata and dependencies (including import-meta-resolve polyfill, dynamic build/test scripts, CI automation)
@@ -255,13 +260,17 @@ It handles parsing of command-line arguments, options, and delegates the executi
255260
- `clearExistingRules(pkgName: string, editorType: RuleType, options: { global?: boolean; target?: string }): Promise<void>` (Added)
256261
- Clears previously installed rule files associated with a specific NPM package before installing new ones.
257262
- Determines the target directory based on `editorType` and `options`.
258-
- **Behavior for Single-File Providers** (e.g., Windsurf, Claude Code, Codex):
259-
- Reads the determined single target file (e.g., `.windsurfrules`, `CLAUDE.md`).
263+
- **Fixed Bug (Latest)**: Now correctly handles single-file providers by ensuring only the parent directory is created, not the file itself as a directory. The `singleFileProviders` array has been updated to include all single-file providers: `WINDSURF`, `CLAUDE_CODE`, `GEMINI`, `CODEX`, `AMP`, `ZED`, `UNIFIED`.
264+
- **Behavior for Single-File Providers** (e.g., Windsurf, Claude Code, Codex, AMP, ZED, Unified):
265+
- For non-existing file paths: Creates only the parent directory using `fs.ensureDir(path.dirname(defaultPath))` instead of incorrectly creating the file path as a directory.
266+
- Reads the determined single target file (e.g., `.windsurfrules`, `CLAUDE.md`, `AGENTS.md`, `AGENT.md`, `.rules`).
260267
- Removes any XML-like blocks within the file where the tag name starts with the package prefix (e.g., finds and removes `<pkgName_rule1>...</pkgName_rule1>`, `<pkgName_anotherRule>...</pkgName_anotherRule>`).
261268
- Writes the modified content back to the file.
262269
- Does _not_ delete the file itself.
263-
- **Behavior for Multi-File Providers** (e.g., Cursor, Clinerules):
270+
- **Behavior for Multi-File Providers** (e.g., Cursor, Clinerules, VSCode):
271+
- For non-existing directory paths: Creates the directory using `fs.ensureDir(defaultPath)`.
264272
- Deletes files within the target directory whose names start with `${pkgName}_`.
273+
- Handles cases where target paths don't exist gracefully.
265274

266275
#### Commands
267276

@@ -288,11 +297,91 @@ It handles parsing of command-line arguments, options, and delegates the executi
288297
- `install <editor> [packageName] [options]`
289298
- Defines the CLI options and arguments for the install command.
290299
- Delegates the action to `installCommandAction` from `src/commands/install.ts`.
300+
- `convert <sourceFormat> <targetFormat> <sourcePath> [options]`
301+
- Defines the CLI options and arguments for the convert command.
302+
- Enables seamless rule conversion between different editor formats.
303+
- Supports both directory-based (cursor, clinerules, vscode) and file-based (windsurf, claude-code, etc.) conversions.
304+
- Delegates the action to `convertCommandAction` from `src/commands/convert.ts`.
291305

292306
### src/commands/install.ts (Added)
293307

294308
Contains the action handler for the `vibe-rules install` command and handles the complex module loading requirements for both CommonJS and ES modules.
295309

310+
### src/commands/convert.ts (Added)
311+
312+
Contains the action handler for the `vibe-rules convert` command with comprehensive rule format conversion capabilities.
313+
314+
#### Functions
315+
316+
- `convertCommandAction(sourceFormat: string, targetFormat: string, sourcePath: string, options: ConvertOptions): Promise<void>` (Exported)
317+
- Main handler for the `convert` command.
318+
- Validates source and target formats using `validateAndGetRuleType`.
319+
- Determines if source is a directory or file using `fs.stat`.
320+
- Extracts rules using format-specific extraction functions.
321+
- Converts each rule using the target format provider.
322+
- Supports both directory and file-based conversion with proper error handling.
323+
324+
#### Rule Extraction Functions
325+
326+
- `extractRulesFromDirectory(sourceType: RuleType, dirPath: string): Promise<StoredRuleConfig[]>`
327+
328+
- Extracts rules from directories based on source format (Cursor, Clinerules, VSCode).
329+
- Delegates to format-specific directory extraction functions.
330+
331+
- `extractRulesFromFile(sourceType: RuleType, filePath: string): Promise<StoredRuleConfig[]>`
332+
- Extracts rules from individual files based on source format.
333+
- Supports all single-file formats (Windsurf, Claude Code, Codex, Amp, ZED, Unified).
334+
335+
#### Format-Specific Extraction Functions
336+
337+
- `extractFromCursorDirectory(dirPath: string)`: Extracts rules from `.cursor/rules/*.mdc` files with frontmatter parsing.
338+
- `extractFromCursorFile(filePath: string)`: Extracts metadata and content from individual Cursor `.mdc` files.
339+
- `extractFromClinerulesDireatory(dirPath: string)`: Extracts rules from `.clinerules/*.md` files.
340+
- `extractFromVSCodeDirectory(dirPath: string)`: Extracts rules from `.github/instructions/*.instructions.md` files.
341+
- `extractFromVSCodeFile(filePath: string)`: Extracts metadata from VSCode instruction files with frontmatter.
342+
- `extractFromWindsurfFile(filePath: string)`: Extracts tagged rule blocks from `.windsurfrules` file.
343+
- `extractFromClaudeCodeFile(filePath: string)`: Extracts rules from `CLAUDE.md` with integration wrapper support.
344+
- `extractFromCodexFile(filePath: string)`: Extracts rules from `AGENTS.md` with integration wrapper support.
345+
- `extractFromAmpFile(filePath: string)`: Extracts rules from `AGENT.md` file.
346+
- `extractFromTaggedFile(filePath: string)`: Generic extraction for XML-like tagged blocks (ZED, Unified).
347+
- `extractFromTaggedFileWithWrapper(filePath: string, wrapperStart: string)`: Extraction for tagged blocks within comment wrappers (Claude Code, Codex).
348+
349+
#### Utility Functions
350+
351+
- `parseMetadataFromContent(content: string): RuleGeneratorOptions`: Parses metadata from rule content text.
352+
- `removeMetadataFromContent(content: string): string`: Removes metadata lines from rule content.
353+
- `validateAndGetRuleType(format: string, type: 'source' | 'target'): RuleType | null`: Validates and converts format strings to RuleType enum.
354+
- `escapeRegex(string: string): string`: Escapes special regex characters.
355+
356+
#### Supported Conversions
357+
358+
**Source Formats (Directory-based):**
359+
360+
- `cursor`: Converts from `.cursor/rules/*.mdc` files with frontmatter metadata
361+
- `clinerules`/`roo`: Converts from `.clinerules/*.md` files
362+
- `vscode`: Converts from `.github/instructions/*.instructions.md` files
363+
364+
**Source Formats (File-based):**
365+
366+
- `windsurf`: Converts from `.windsurfrules` file with tagged blocks
367+
- `claude-code`: Converts from `CLAUDE.md` file with integration wrapper
368+
- `codex`: Converts from `AGENTS.md` file with integration wrapper
369+
- `amp`: Converts from `AGENT.md` file with tagged blocks
370+
- `zed`/`unified`: Converts from `.rules` file with tagged blocks
371+
372+
**Target Formats:**
373+
374+
- All supported editor formats via their respective providers
375+
- Automatic metadata preservation and format-specific adaptation
376+
- Smart target path resolution using `getDefaultTargetPath`
377+
378+
#### Error Handling
379+
380+
- Comprehensive validation of source and target formats
381+
- File system error handling with user-friendly messages
382+
- Graceful handling of missing files or invalid formats
383+
- Proper exit codes for CLI integration
384+
296385
### src/commands/save.ts (Added)
297386

298387
Contains the action handler for the `vibe-rules save` command with enhanced metadata extraction and storage capabilities.
@@ -369,10 +458,19 @@ Contains the action handler for the `vibe-rules list` command with unified rule
369458
- **Metadata Handling**: Extracts and applies metadata (`alwaysApply`, `globs`) from rule objects to the provider options.
370459
- **Error Handling**: Provides specific error messages for different failure modes (module not found, syntax errors, initialization errors).
371460
- Returns the count of successfully applied rules.
372-
- `clearExistingRules(pkgName: string, editorType: RuleType, options: { global?: boolean }): Promise<void>`
373-
- Clears previously installed rules for a given package and editor type.
374-
- **Single-File Providers** (Windsurf, Claude Code, Codex): Uses regex to remove XML-like blocks matching `<pkgName_ruleName>...</pkgName_ruleName>` patterns from the target file.
375-
- **Multi-File Providers** (Cursor, Clinerules): Deletes files starting with `${pkgName}_` in the target directory.
461+
- `clearExistingRules(pkgName: string, editorType: RuleType, options: { global?: boolean; target?: string }): Promise<void>` (Added)
462+
- Clears previously installed rule files associated with a specific NPM package before installing new ones.
463+
- Determines the target directory based on `editorType` and `options`.
464+
- **Fixed Bug (Latest)**: Now correctly handles single-file providers by ensuring only the parent directory is created, not the file itself as a directory. The `singleFileProviders` array has been updated to include all single-file providers: `WINDSURF`, `CLAUDE_CODE`, `GEMINI`, `CODEX`, `AMP`, `ZED`, `UNIFIED`.
465+
- **Behavior for Single-File Providers** (e.g., Windsurf, Claude Code, Codex, AMP, ZED, Unified):
466+
- For non-existing file paths: Creates only the parent directory using `fs.ensureDir(path.dirname(defaultPath))` instead of incorrectly creating the file path as a directory.
467+
- Reads the determined single target file (e.g., `.windsurfrules`, `CLAUDE.md`, `AGENTS.md`, `AGENT.md`, `.rules`).
468+
- Removes any XML-like blocks within the file where the tag name starts with the package prefix (e.g., finds and removes `<pkgName_rule1>...</pkgName_rule1>`, `<pkgName_anotherRule>...</pkgName_anotherRule>`).
469+
- Writes the modified content back to the file.
470+
- Does _not_ delete the file itself.
471+
- **Behavior for Multi-File Providers** (e.g., Cursor, Clinerules, VSCode):
472+
- For non-existing directory paths: Creates the directory using `fs.ensureDir(defaultPath)`.
473+
- Deletes files within the target directory whose names start with `${pkgName}_`.
376474
- Handles cases where target paths don't exist gracefully.
377475
- `importModuleFromCwd(ruleModulePath: string): Promise<any>`
378476
- **Dual-Strategy Module Loading**: Implements a robust approach for loading modules that works with both CommonJS and ES modules.
@@ -856,6 +954,30 @@ Implementation of the `RuleProvider` interface for Amp AI coding assistant with
856954
- **Rule Insertion:** Appends new rules directly to the file without special integration blocks.
857955
- **Local Only:** Always ignores `isGlobal` parameter as Amp only supports local project files.
858956

957+
## Web Interface
958+
959+
### web/app/pages/index.vue
960+
961+
The main landing page for the `vibe-rules` web interface.
962+
963+
#### Key Sections
964+
965+
- **Hero Section**: Introduces `vibe-rules` with a quick start guide.
966+
- **Features Section**: Highlights key features like `save`, `load`, and `convert`.
967+
- **Supported Editors Section**: Lists all the editors that `vibe-rules` supports.
968+
969+
### web/app/pages/local-usage.vue
970+
971+
A detailed guide on how to use `vibe-rules` in a local development environment.
972+
973+
#### Key Sections
974+
975+
- **Installation**: Instructions on how to install `vibe-rules` globally.
976+
- **Basic Commands**: Detailed explanation of the `save`, `list`, and `load` commands.
977+
- **Convert Rule Formats**: Explains how to use the `convert` command to migrate rules between different editor formats.
978+
- **Install from NPM**: Guide on how to install rules from NPM packages.
979+
- **Supported Editors & Formats**: A list of all supported editors and their corresponding formats.
980+
859981
## New Documentation Files
860982

861983
### UNIFIED_RULES_CONVENTION.md (Added)

0 commit comments

Comments
 (0)