Skip to content

Commit 742b55b

Browse files
committed
chore: update CLI to use commander for argument parsing and enhance documentation
- Replaced `yargs` with `commander` for CLI argument parsing. - Updated `.clinerules` to reflect new dependencies and CLI options. - Modified `package.json` to include `commander` as a runtime dependency. - Enhanced README with updated CLI usage instructions and examples. - Refactored `src/cli.ts` to implement new command structure and validation. - Added new tests for CLI functionality and conversion logic. - Updated `build.config.ts` to include `src/cli` entry point.
1 parent abdb3c8 commit 742b55b

File tree

18 files changed

+2750
-3191
lines changed

18 files changed

+2750
-3191
lines changed

.clinerules

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ This file captures project-specific intelligence, patterns, user preferences, an
1818
## 2. Key Technical Patterns & Decisions (Initial)
1919

2020
* **Dependencies:**
21-
* Runtime: `gray-matter`, `yargs`, `fast-glob`.
21+
* Runtime: `gray-matter`, `commander`, `fast-glob`.
2222
* Dev/Build: `typescript`, `unbuild`, `vitest`, `biome`.
2323
* **Node.js Version:** ≥18 LTS.
2424
* **Module System:** ESM primary, CJS for API compatibility.
2525
* **Streaming:** Use `stream.pipeline()` for I/O.
2626
* **Error Handling:** Standardized error codes (E01-E03) and non-zero exit codes.
2727
* **CI/CD:** GitHub Actions for lint, test, publish. (To be implemented)
28+
* **CLI Argument Parsing:** Use `commander` options (`-i`, `-o`, `-d`) exclusively for file/directory paths. Positional arguments for paths are not supported.
2829

2930
## 3. Tool Usage Patterns (for Cline)
3031

@@ -51,11 +52,12 @@ This file captures project-specific intelligence, patterns, user preferences, an
5152
* **Windows CMD Quirks:** Excluded from MVP, but potential future complexity. Focus on PowerShell for Windows.
5253
* **Future Schema Changes:** Plan for extensibility/warnings for future rule schema updates (v1.2).
5354
* **Complex Glob Patterns:** Document Windsurf's constraints; may need fallback for very complex cases.
54-
* **Dependency Discrepancy:** PRD's "zero runtime deps" vs. `fast-glob` for directory mode. Acknowledged that `fast-glob` is a necessary runtime dep for full CLI functionality.
55+
* **Dependency Discrepancy:** PRD's "zero runtime deps" vs. `commander` (for CLI parsing) and `fast-glob` (for directory mode). Acknowledged that these are necessary runtime dependencies for full CLI functionality.
5556

5657
## 6. Evolution of Project Decisions
5758

5859
* (To be populated as decisions are made or changed throughout the project lifecycle)
60+
* **8 May 2025:** Refactored CLI (`src/cli.ts`) to remove positional file arguments and rely more on `commander` options and validation (`.conflicts()`). Custom validation retained for `-d` requiring `-o`.
5961

6062
---
6163
This file will be updated iteratively as the project progresses.

.vscode/settings.json

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
{
2-
"typescript.tsdk": "node_modules/typescript/lib",
3-
"eslint.enable": false,
4-
"prettier.enable": false,
5-
"editor.defaultFormatter": "biomejs.biome",
6-
"editor.formatOnSave": true,
7-
"editor.formatOnPaste": true,
8-
"emmet.showExpandedAbbreviation": "never",
9-
"editor.codeActionsOnSave": {
10-
"quickfix.biome": "explicit",
11-
"source.organizeImports.biome": "explicit"
12-
},
13-
"[typescript]": {
14-
"editor.defaultFormatter": "biomejs.biome"
15-
},
16-
"[json]": {
17-
"editor.defaultFormatter": "biomejs.biome"
18-
},
19-
"[javascript]": {
20-
"editor.defaultFormatter": "biomejs.biome"
21-
},
22-
"[jsonc]": {
23-
"editor.defaultFormatter": "biomejs.biome"
24-
},
25-
"[typescriptreact]": {
26-
"editor.defaultFormatter": "biomejs.biome"
27-
}
2+
"typescript.tsdk": "node_modules/typescript/lib",
3+
"eslint.enable": false,
4+
"prettier.enable": false,
5+
"editor.defaultFormatter": "biomejs.biome",
6+
"editor.formatOnSave": true,
7+
"editor.formatOnPaste": true,
8+
"emmet.showExpandedAbbreviation": "never",
9+
"editor.codeActionsOnSave": {
10+
"quickfix.biome": "explicit",
11+
"source.organizeImports.biome": "explicit"
12+
},
13+
"[typescript]": {
14+
"editor.defaultFormatter": "biomejs.biome"
15+
},
16+
"[json]": {
17+
"editor.defaultFormatter": "biomejs.biome"
18+
},
19+
"[javascript]": {
20+
"editor.defaultFormatter": "biomejs.biome"
21+
},
22+
"[jsonc]": {
23+
"editor.defaultFormatter": "biomejs.biome"
24+
},
25+
"[typescriptreact]": {
26+
"editor.defaultFormatter": "biomejs.biome"
27+
}
2828
}

README.md

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@
3636
* **Fast** – converts a 1 kB rule in < 50 ms. Blink and you’ll miss it.
3737
* **Lossless metadata mapping** – front‑matter stays intact, content unchanged.
3838
* **CI‑ready** – deterministic, non‑interactive, exit codes you can trust.
39-
* **Tiny footprint**zero deps in runtime (only `graymatter` & `yargs` at CLI layer).
39+
* **Tiny footprint**minimal runtime dependencies (`gray-matter`, `commander`, `fast-glob` for CLI).
4040

4141
---
4242

4343
## ✨ Key Features
4444

45-
| Feature | Description |
46-
| ------------------------------- | ----------------------------------------------------------------------- |
47-
| 🔄 **Bidirectional conversion** | `cuws` detects the source format or let you force it. |
48-
| 📂 **Directory mode** | Convert whole trees while mirroring structure. |
49-
| 🏗️ **TypeScript API** | Import `convertString()` or `convertDirectory()` in your build scripts. |
50-
| 🪝 **Streaming first** | Works perfectly in Unix pipes & GitHub Actions. |
51-
| 🐚 **Single‑file binary** | ES module with hashbang—no compilation required. |
45+
| Feature | Description |
46+
| ------------------------------- | ----------------------------------------------------------------------------------- |
47+
| 🔄 **Bidirectional conversion** | `cuws` detects the source format or let you force it. |
48+
| 📂 **Directory mode** | Convert whole trees while mirroring structure (requires output directory specified). |
49+
| 🏗️ **TypeScript API** | Import `convertString()`, `convertFile()`, or `convertDirectory()` in your scripts. |
50+
| 🪝 **Streaming first** | Works perfectly in Unix pipes & GitHub Actions. |
51+
| 🐚 **Single‑file binary** | ES module with hashbang—no compilation required. |
5252

5353
---
5454

@@ -64,8 +64,8 @@ cuws -i .cursor/rules/auth.mdc -o .windsurf/rules/auth.md
6464
# Pipe via stdin/stdout
6565
git show HEAD:my-rule.mdc | cuws --reverse > my-rule-cursor.mdc
6666

67-
# Batch convert an entire repo (dry‑run first)
68-
cuws -d . --reverse --dry-run
67+
# Batch convert an entire repo (dry‑run first, output to 'converted-rules' directory)
68+
cuws -d . -o ./converted-rules --reverse --dry-run
6969
```
7070

7171
---
@@ -92,22 +92,42 @@ yarn add -D cursor-windsurf-convert # or npm i -D ...
9292
cuws [options]
9393
```
9494

95-
| Flag | Default | Description | |
96-
| --------------------- | ----------- | ------------------------------------ | ----------------------- |
97-
| `-i, --input <path>` | `-` | Path to source file or `-` for stdin | |
98-
| `-o, --output <path>` | `-` | Path to dest file or `-` for stdout | |
99-
| `-r, --reverse` | off | Treat input as Windsurf Cursor | |
100-
| \`--force \<cursor | windsurf>\` | | Override auto‑detection |
101-
| `-d, --dir <path>` | | Recursively convert directory | |
102-
| `--dry-run` | off | Print planned actions, don’t write | |
103-
| `--verbose` | off | Extra logging | |
95+
| Flag | Default | Description |
96+
| --------------------- | ----------- | --------------------------------------------------------------------------- |
97+
| `-i, --input <path>` | `-` | Path to source file or `-` for stdin. Conflicts with `-d`. |
98+
| `-o, --output <path>` | `-` | Path to dest file (with `-i`) or output directory (required with `-d`). |
99+
| `-r, --reverse` | `false` | Convert from Windsurf (.md) to Cursor (.mdc). |
100+
| `--force <format>` | | Override auto-detection (`cursor` or `windsurf`). |
101+
| `-d, --dir <path>` | | Recursively convert directory. Requires `-o` for output. Conflicts with `-i`. |
102+
| `--dry-run` | `false` | Print planned actions, don’t write files. |
103+
| `--verbose` | `false` | Extra logging. |
104104

105105
### Programmatic API
106106

107-
```ts
108-
import { convertString } from 'cursor-windsurf-convert';
107+
```typescript
108+
import {
109+
convertString,
110+
convertFile,
111+
convertDirectory,
112+
} from 'cursor-windsurf-convert';
113+
114+
// Convert a string
115+
const cursorRuleContent = '...'; // content of a .mdc file
116+
const windsurfRuleContent = convertString(cursorRuleContent, 'cw');
117+
118+
// Convert a single file
119+
async function exampleConvertFile() {
120+
const outputPath = await convertFile('path/to/source.mdc', 'path/to/output.md');
121+
console.log(`Converted file written to: ${outputPath}`);
122+
}
109123

110-
const windsRule = convertString(cursorRule, 'cw');
124+
// Convert a directory
125+
async function exampleConvertDirectory() {
126+
const results = await convertDirectory('path/to/source-dir', 'path/to/output-dir');
127+
results.forEach(result => {
128+
console.log(`${result.sourcePath} -> ${result.destinationPath} (${result.status})`);
129+
});
130+
}
111131
```
112132

113133
See [API docs](docs/API.md) for full typings.
@@ -141,7 +161,7 @@ See [API docs](docs/API.md) for full typings.
141161
"name": "cursor-windsurf-convert",
142162
"version": "1.0.0",
143163
"bin": {
144-
"cuws": "dist/cli.js" // or ./cli.js if TS-to-ES buildless
164+
"cuws": "dist/cli.mjs"
145165
},
146166
...
147167
}
@@ -153,17 +173,14 @@ The CLI file **must** start with `#!/usr/bin/env node` and be `chmod +x`.
153173

154174
## 🤝 Contributing
155175

156-
PRs welcome! Check the [open issues](https://github.com/YOUR_ORG/cursor-windsurf-convert/issues) or open a new one. Please read our [CODE\_OF\_CONDUCT](CODE_OF_CONDUCT.md) first.
176+
PRs welcome! Check the [open issues](https://github.com/gmickel/cursor-windsurf-convert/issues) or open a new one. Also see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
157177

158178
---
159179

160180
## 🏄 Roadmap
161181

162182
* [x] One‑file conversion
163183
* [x] Directory batch mode
164-
* [ ] Legacy `.cursorrules` support
165-
* [ ] JSON schema validation
166-
* [ ] Native Rust port 🚀
167184

168185
---
169186

@@ -172,7 +189,6 @@ PRs welcome! Check the [open issues](https://github.com/YOUR_ORG/cursor-windsurf
172189
| Q | A |
173190
| ---------------------------------- | ---------------------------------------------- |
174191
| *Does it change my markdown body?* | Nope. Only the YAML/MD header is mapped. |
175-
| *Will Windows paths work?* | Yes via PowerShell. CMD ecosphere PRs welcome. |
176192
| *Can I embed this in my own tool?* | Absolutely—import the TS API. |
177193

178194
---

build.config.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import { defineBuildConfig } from 'unbuild'
1+
import { defineBuildConfig } from 'unbuild';
22

33
export default defineBuildConfig({
4-
entries: [
5-
'src/index',
6-
],
4+
entries: ['src/index', 'src/cli'],
75
declaration: 'node16',
86
clean: true,
97
rollup: {
10-
inlineDependencies: [
11-
'@antfu/utils',
12-
],
8+
inlineDependencies: ['@antfu/utils'],
139
},
14-
})
10+
});

package.json

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,19 @@
1313
"url": "git+https://github.com/gmickel/cursor-windsurf-convert.git"
1414
},
1515
"bugs": "https://github.com/gmickel/cursor-windsurf-convert/issues",
16-
"keywords": [
17-
"cursor",
18-
"windsurf",
19-
"rules",
20-
"converter"
21-
],
16+
"keywords": ["cursor", "windsurf", "rules", "converter"],
2217
"sideEffects": false,
2318
"exports": {
2419
".": "./dist/index.mjs",
2520
"./package.json": "./package.json"
2621
},
2722
"bin": {
28-
"cuws": "dist/cli.js"
23+
"cuws": "dist/cli.mjs"
2924
},
3025
"main": "./dist/index.mjs",
3126
"module": "./dist/index.mjs",
3227
"types": "./dist/index.d.mts",
33-
"files": [
34-
"dist"
35-
],
28+
"files": ["dist"],
3629
"scripts": {
3730
"build": "unbuild",
3831
"dev": "unbuild --stub",
@@ -48,20 +41,22 @@
4841
"devDependencies": {
4942
"@antfu/ni": "catalog:cli",
5043
"@antfu/utils": "catalog:inlined",
44+
"@biomejs/biome": "^1.9.4",
5145
"@types/node": "catalog:types",
5246
"bumpp": "catalog:cli",
5347
"tinyexec": "catalog:utils",
5448
"tsx": "catalog:cli",
5549
"typescript": "catalog:cli",
50+
"ultracite": "^4.2.4",
5651
"unbuild": "catalog:cli",
5752
"vite": "catalog:cli",
5853
"vitest": "catalog:testing",
5954
"vitest-package-exports": "catalog:testing",
6055
"yaml": "catalog:testing"
6156
},
6257
"dependencies": {
58+
"commander": "^13.1.0",
6359
"fast-glob": "^3.3.3",
64-
"gray-matter": "^4.0.3",
65-
"yargs": "^17.7.2"
60+
"gray-matter": "^4.0.3"
6661
}
6762
}

0 commit comments

Comments
 (0)