cursor-kit-cli 1.0.4-beta.2 → 1.1.0-beta.3
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/README.md +7 -6
- package/dist/cli.cjs +314 -59
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +310 -59
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +13 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/commands/docs.md +18 -27
- package/templates/commands/explain.md +21 -13
- package/templates/commands/fix.md +64 -143
- package/templates/commands/implement.md +35 -0
- package/templates/commands/refactor.md +34 -56
- package/templates/commands/review.md +14 -9
- package/templates/commands/test.md +16 -11
- package/templates/manifest.json +23 -0
- package/templates/rules/{frontend-design-skills.mdc → frontend-design.mdc} +2 -2
- package/templates/rules/toc.mdc +20 -0
- package/templates/commands/debug.md +0 -52
- package/templates/commands/implementation.md +0 -40
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ cursor-kit init # Initialize both commands and rules
|
|
|
52
52
|
cursor-kit init -c # Only initialize commands
|
|
53
53
|
cursor-kit init -r # Only initialize rules
|
|
54
54
|
cursor-kit init -f # Force overwrite existing files
|
|
55
|
+
cursor-kit init -a # Install all templates without selection prompts
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
### `add`
|
|
@@ -105,22 +106,22 @@ After running `cursor-kit init`, your project will have:
|
|
|
105
106
|
your-project/
|
|
106
107
|
└── .cursor/
|
|
107
108
|
├── commands/ # Prompt templates (.md)
|
|
108
|
-
│ ├── debug.md
|
|
109
109
|
│ ├── docs.md
|
|
110
110
|
│ ├── explain.md
|
|
111
111
|
│ ├── fix.md
|
|
112
|
-
│ ├──
|
|
112
|
+
│ ├── implement.md
|
|
113
113
|
│ ├── refactor.md
|
|
114
114
|
│ ├── review.md
|
|
115
115
|
│ └── test.md
|
|
116
116
|
└── rules/ # AI behavior rules (.mdc)
|
|
117
117
|
├── coding-style.mdc
|
|
118
|
-
├── frontend-design
|
|
118
|
+
├── frontend-design.mdc
|
|
119
119
|
├── git.mdc
|
|
120
120
|
├── performance.mdc
|
|
121
121
|
├── react.mdc
|
|
122
122
|
├── security.mdc
|
|
123
123
|
├── testing.mdc
|
|
124
|
+
├── toc.mdc
|
|
124
125
|
└── typescript.mdc
|
|
125
126
|
```
|
|
126
127
|
|
|
@@ -130,11 +131,10 @@ your-project/
|
|
|
130
131
|
|
|
131
132
|
| Command | Description |
|
|
132
133
|
|---------|-------------|
|
|
133
|
-
| `debug` | Systematic bug investigation |
|
|
134
134
|
| `docs` | Create or update documentation |
|
|
135
135
|
| `explain` | Clear technical explanations |
|
|
136
136
|
| `fix` | Diagnose and fix bugs with root cause analysis |
|
|
137
|
-
| `
|
|
137
|
+
| `implement` | Convert feature ideas into actionable plans |
|
|
138
138
|
| `refactor` | Improve code quality without changing behavior |
|
|
139
139
|
| `review` | Comprehensive code review checklist |
|
|
140
140
|
| `test` | Generate comprehensive test suites |
|
|
@@ -144,12 +144,13 @@ your-project/
|
|
|
144
144
|
| Rule | Description |
|
|
145
145
|
|------|-------------|
|
|
146
146
|
| `coding-style` | Core coding conventions and best practices |
|
|
147
|
-
| `frontend-design
|
|
147
|
+
| `frontend-design` | Typography, aesthetics, and UI guidelines |
|
|
148
148
|
| `git` | Commit and branching conventions |
|
|
149
149
|
| `performance` | Performance optimization patterns |
|
|
150
150
|
| `react` | React component patterns |
|
|
151
151
|
| `security` | Security guidelines |
|
|
152
152
|
| `testing` | Testing standards |
|
|
153
|
+
| `toc` | Table of contents for rule selection |
|
|
153
154
|
| `typescript` | TypeScript best practices |
|
|
154
155
|
|
|
155
156
|
## 🛠️ Development
|
package/dist/cli.cjs
CHANGED
|
@@ -23,8 +23,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
mod
|
|
24
24
|
));
|
|
25
25
|
|
|
26
|
+
// node_modules/.pnpm/tsup@8.5.1_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
|
|
27
|
+
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
28
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
29
|
+
|
|
26
30
|
// src/cli.ts
|
|
27
31
|
var import_citty6 = require("citty");
|
|
32
|
+
var import_node_module = require("module");
|
|
28
33
|
|
|
29
34
|
// src/utils/branding.ts
|
|
30
35
|
var import_figlet = __toESM(require("figlet"), 1);
|
|
@@ -54,7 +59,7 @@ function printDivider() {
|
|
|
54
59
|
}
|
|
55
60
|
function printVersion(version) {
|
|
56
61
|
console.log(
|
|
57
|
-
import_picocolors.default.dim("
|
|
62
|
+
import_picocolors.default.dim(" ") + cursorGradient(`v${version}`) + import_picocolors.default.dim(" \u2022 Made with \u2665")
|
|
58
63
|
);
|
|
59
64
|
console.log();
|
|
60
65
|
}
|
|
@@ -66,7 +71,7 @@ function highlight(text2) {
|
|
|
66
71
|
var import_citty = require("citty");
|
|
67
72
|
var p = __toESM(require("@clack/prompts"), 1);
|
|
68
73
|
var import_picocolors2 = __toESM(require("picocolors"), 1);
|
|
69
|
-
var
|
|
74
|
+
var import_node_path3 = require("path");
|
|
70
75
|
|
|
71
76
|
// src/utils/fs.ts
|
|
72
77
|
var import_node_fs = require("fs");
|
|
@@ -111,12 +116,190 @@ function getCommandsDir(cwd = process.cwd()) {
|
|
|
111
116
|
function getRulesDir(cwd = process.cwd()) {
|
|
112
117
|
return (0, import_node_path.join)(getCursorDir(cwd), "rules");
|
|
113
118
|
}
|
|
119
|
+
function getConflictingFiles(dir, files) {
|
|
120
|
+
if (!dirExists(dir)) return [];
|
|
121
|
+
return files.filter((file) => fileExists((0, import_node_path.join)(dir, file)));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/utils/templates.ts
|
|
125
|
+
var import_node_path2 = require("path");
|
|
126
|
+
var import_node_url = require("url");
|
|
114
127
|
|
|
115
128
|
// src/utils/constants.ts
|
|
116
129
|
var REPO_URL = "github:duongductrong/cursor-kit";
|
|
117
130
|
var REPO_REF = "master";
|
|
131
|
+
var REPO_RAW_URL = "https://raw.githubusercontent.com/duongductrong/cursor-kit/master";
|
|
132
|
+
var TEMPLATE_PATHS = {
|
|
133
|
+
commands: "templates/commands",
|
|
134
|
+
rules: "templates/rules"
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/utils/templates.ts
|
|
138
|
+
function getLocalTemplatesDir() {
|
|
139
|
+
const currentDir = (0, import_node_path2.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
140
|
+
return (0, import_node_path2.join)(currentDir, "..", "templates");
|
|
141
|
+
}
|
|
142
|
+
function getLocalManifest() {
|
|
143
|
+
const templatesDir = getLocalTemplatesDir();
|
|
144
|
+
const manifestPath = (0, import_node_path2.join)(templatesDir, "manifest.json");
|
|
145
|
+
if (fileExists(manifestPath)) {
|
|
146
|
+
try {
|
|
147
|
+
return JSON.parse(readFile(manifestPath));
|
|
148
|
+
} catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const commandsDir = (0, import_node_path2.join)(templatesDir, "commands");
|
|
153
|
+
const rulesDir = (0, import_node_path2.join)(templatesDir, "rules");
|
|
154
|
+
if (!dirExists(commandsDir) && !dirExists(rulesDir)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
commands: dirExists(commandsDir) ? listFiles(commandsDir, ".md") : [],
|
|
159
|
+
rules: dirExists(rulesDir) ? listFiles(rulesDir, ".mdc") : []
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function getLocalTemplateContent(type, filename) {
|
|
163
|
+
const templatesDir = getLocalTemplatesDir();
|
|
164
|
+
const filePath = (0, import_node_path2.join)(templatesDir, type, filename);
|
|
165
|
+
if (fileExists(filePath)) {
|
|
166
|
+
return readFile(filePath);
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
async function fetchTemplateManifest() {
|
|
171
|
+
const localManifest = getLocalManifest();
|
|
172
|
+
if (localManifest) {
|
|
173
|
+
return localManifest;
|
|
174
|
+
}
|
|
175
|
+
const url = `${REPO_RAW_URL}/templates/manifest.json`;
|
|
176
|
+
const response = await fetch(url);
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
throw new Error(`Failed to fetch template manifest: ${response.statusText}`);
|
|
179
|
+
}
|
|
180
|
+
return response.json();
|
|
181
|
+
}
|
|
182
|
+
async function fetchTemplateContent(type, filename) {
|
|
183
|
+
const localContent = getLocalTemplateContent(type, filename);
|
|
184
|
+
if (localContent !== null) {
|
|
185
|
+
return localContent;
|
|
186
|
+
}
|
|
187
|
+
const templatePath = TEMPLATE_PATHS[type];
|
|
188
|
+
const url = `${REPO_RAW_URL}/${templatePath}/${filename}`;
|
|
189
|
+
const response = await fetch(url);
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
throw new Error(`Failed to fetch template ${filename}: ${response.statusText}`);
|
|
192
|
+
}
|
|
193
|
+
return response.text();
|
|
194
|
+
}
|
|
195
|
+
async function fetchMultipleTemplates(type, filenames) {
|
|
196
|
+
const results = /* @__PURE__ */ new Map();
|
|
197
|
+
const fetchPromises = filenames.map(async (filename) => {
|
|
198
|
+
const content = await fetchTemplateContent(type, filename);
|
|
199
|
+
return { filename, content };
|
|
200
|
+
});
|
|
201
|
+
const settled = await Promise.allSettled(fetchPromises);
|
|
202
|
+
for (const result of settled) {
|
|
203
|
+
if (result.status === "fulfilled") {
|
|
204
|
+
results.set(result.value.filename, result.value.content);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
function getTemplateLabel(filename) {
|
|
210
|
+
const nameWithoutExt = filename.replace(/\.(md|mdc)$/, "");
|
|
211
|
+
return nameWithoutExt.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
212
|
+
}
|
|
118
213
|
|
|
119
214
|
// src/commands/init.ts
|
|
215
|
+
async function selectTemplates(type, availableTemplates) {
|
|
216
|
+
const selectionMode = await p.select({
|
|
217
|
+
message: `How would you like to add ${type}?`,
|
|
218
|
+
options: [
|
|
219
|
+
{
|
|
220
|
+
value: "all",
|
|
221
|
+
label: `Add all ${availableTemplates.length} ${type}`,
|
|
222
|
+
hint: "Install everything"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
value: "select",
|
|
226
|
+
label: "Select specific items",
|
|
227
|
+
hint: "Choose which ones to install"
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
});
|
|
231
|
+
if (p.isCancel(selectionMode)) return selectionMode;
|
|
232
|
+
if (selectionMode === "all") {
|
|
233
|
+
return availableTemplates;
|
|
234
|
+
}
|
|
235
|
+
const selectedTemplates = await p.multiselect({
|
|
236
|
+
message: `Select ${type} to add:`,
|
|
237
|
+
options: availableTemplates.map((template) => ({
|
|
238
|
+
value: template,
|
|
239
|
+
label: getTemplateLabel(template),
|
|
240
|
+
hint: template
|
|
241
|
+
})),
|
|
242
|
+
required: true
|
|
243
|
+
});
|
|
244
|
+
return selectedTemplates;
|
|
245
|
+
}
|
|
246
|
+
async function handleConflicts(type, conflictingFiles) {
|
|
247
|
+
console.log();
|
|
248
|
+
console.log(
|
|
249
|
+
import_picocolors2.default.yellow(`\u26A0 ${conflictingFiles.length} existing ${type} found:`)
|
|
250
|
+
);
|
|
251
|
+
for (const file of conflictingFiles) {
|
|
252
|
+
console.log(import_picocolors2.default.dim(` \u2514\u2500 ${file}`));
|
|
253
|
+
}
|
|
254
|
+
console.log();
|
|
255
|
+
const strategy = await p.select({
|
|
256
|
+
message: "How would you like to handle conflicts?",
|
|
257
|
+
options: [
|
|
258
|
+
{
|
|
259
|
+
value: "overwrite",
|
|
260
|
+
label: "Overwrite existing files",
|
|
261
|
+
hint: "Replace all conflicting files"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
value: "merge",
|
|
265
|
+
label: "Merge (keep existing, add new only)",
|
|
266
|
+
hint: "Skip files that already exist"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
value: "cancel",
|
|
270
|
+
label: "Cancel",
|
|
271
|
+
hint: "Abort the operation"
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
});
|
|
275
|
+
return strategy;
|
|
276
|
+
}
|
|
277
|
+
async function installTemplates(type, targetDir, selectedTemplates, conflictStrategy) {
|
|
278
|
+
const result = { added: [], skipped: [] };
|
|
279
|
+
const conflictingFiles = getConflictingFiles(targetDir, selectedTemplates);
|
|
280
|
+
let templatesToInstall;
|
|
281
|
+
if (conflictStrategy === "merge") {
|
|
282
|
+
templatesToInstall = selectedTemplates.filter(
|
|
283
|
+
(t) => !conflictingFiles.includes(t)
|
|
284
|
+
);
|
|
285
|
+
result.skipped = conflictingFiles.filter(
|
|
286
|
+
(f) => selectedTemplates.includes(f)
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
templatesToInstall = selectedTemplates;
|
|
290
|
+
}
|
|
291
|
+
if (templatesToInstall.length === 0) {
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
const templates = await fetchMultipleTemplates(type, templatesToInstall);
|
|
295
|
+
ensureDir(targetDir);
|
|
296
|
+
for (const [filename, content] of templates) {
|
|
297
|
+
const filePath = (0, import_node_path3.join)(targetDir, filename);
|
|
298
|
+
writeFile(filePath, content);
|
|
299
|
+
result.added.push(filename);
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
120
303
|
var initCommand = (0, import_citty.defineCommand)({
|
|
121
304
|
meta: {
|
|
122
305
|
name: "init",
|
|
@@ -126,7 +309,7 @@ var initCommand = (0, import_citty.defineCommand)({
|
|
|
126
309
|
force: {
|
|
127
310
|
type: "boolean",
|
|
128
311
|
alias: "f",
|
|
129
|
-
description: "Overwrite existing files",
|
|
312
|
+
description: "Overwrite existing files without prompting",
|
|
130
313
|
default: false
|
|
131
314
|
},
|
|
132
315
|
commands: {
|
|
@@ -140,6 +323,12 @@ var initCommand = (0, import_citty.defineCommand)({
|
|
|
140
323
|
alias: "r",
|
|
141
324
|
description: "Only initialize rules",
|
|
142
325
|
default: false
|
|
326
|
+
},
|
|
327
|
+
all: {
|
|
328
|
+
type: "boolean",
|
|
329
|
+
alias: "a",
|
|
330
|
+
description: "Install all templates without selection prompts",
|
|
331
|
+
default: false
|
|
143
332
|
}
|
|
144
333
|
},
|
|
145
334
|
async run({ args }) {
|
|
@@ -151,62 +340,126 @@ var initCommand = (0, import_citty.defineCommand)({
|
|
|
151
340
|
const shouldInitCommands = initBoth || args.commands;
|
|
152
341
|
const shouldInitRules = initBoth || args.rules;
|
|
153
342
|
p.intro(import_picocolors2.default.bgCyan(import_picocolors2.default.black(" cursor-kit init ")));
|
|
154
|
-
const commandsExist = dirExists(commandsDir) && listFiles(commandsDir).length > 0;
|
|
155
|
-
const rulesExist = dirExists(rulesDir) && listFiles(rulesDir).length > 0;
|
|
156
|
-
if ((commandsExist || rulesExist) && !args.force) {
|
|
157
|
-
const existingItems = [];
|
|
158
|
-
if (commandsExist) existingItems.push("commands");
|
|
159
|
-
if (rulesExist) existingItems.push("rules");
|
|
160
|
-
const shouldContinue = await p.confirm({
|
|
161
|
-
message: `Existing ${existingItems.join(" and ")} found. Overwrite?`,
|
|
162
|
-
initialValue: false
|
|
163
|
-
});
|
|
164
|
-
if (p.isCancel(shouldContinue) || !shouldContinue) {
|
|
165
|
-
p.cancel("Operation cancelled");
|
|
166
|
-
process.exit(0);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
343
|
const s = p.spinner();
|
|
344
|
+
let manifest;
|
|
345
|
+
try {
|
|
346
|
+
s.start("Fetching template manifest...");
|
|
347
|
+
manifest = await fetchTemplateManifest();
|
|
348
|
+
s.stop("Template manifest loaded");
|
|
349
|
+
} catch (error) {
|
|
350
|
+
s.stop("Failed to fetch manifest");
|
|
351
|
+
p.cancel(
|
|
352
|
+
`Error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
353
|
+
);
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
const results = {};
|
|
170
357
|
try {
|
|
171
358
|
ensureDir(cursorDir);
|
|
172
359
|
if (shouldInitCommands) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
360
|
+
let selectedCommands;
|
|
361
|
+
if (args.all) {
|
|
362
|
+
selectedCommands = manifest.commands;
|
|
363
|
+
} else {
|
|
364
|
+
const selection = await selectTemplates("commands", manifest.commands);
|
|
365
|
+
if (p.isCancel(selection)) {
|
|
366
|
+
p.cancel("Operation cancelled");
|
|
367
|
+
process.exit(0);
|
|
368
|
+
}
|
|
369
|
+
selectedCommands = selection;
|
|
370
|
+
}
|
|
371
|
+
const conflictingCommands = getConflictingFiles(
|
|
372
|
+
commandsDir,
|
|
373
|
+
selectedCommands
|
|
374
|
+
);
|
|
375
|
+
let commandStrategy = "overwrite";
|
|
376
|
+
if (conflictingCommands.length > 0 && !args.force) {
|
|
377
|
+
const strategy = await handleConflicts("commands", conflictingCommands);
|
|
378
|
+
if (p.isCancel(strategy) || strategy === "cancel") {
|
|
379
|
+
p.cancel("Operation cancelled");
|
|
380
|
+
process.exit(0);
|
|
381
|
+
}
|
|
382
|
+
commandStrategy = strategy;
|
|
383
|
+
}
|
|
384
|
+
s.start("Installing commands...");
|
|
385
|
+
results.commands = await installTemplates(
|
|
386
|
+
"commands",
|
|
387
|
+
commandsDir,
|
|
388
|
+
selectedCommands,
|
|
389
|
+
commandStrategy
|
|
390
|
+
);
|
|
391
|
+
s.stop("Commands installed");
|
|
179
392
|
}
|
|
180
393
|
if (shouldInitRules) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
394
|
+
let selectedRules;
|
|
395
|
+
if (args.all) {
|
|
396
|
+
selectedRules = manifest.rules;
|
|
397
|
+
} else {
|
|
398
|
+
const selection = await selectTemplates("rules", manifest.rules);
|
|
399
|
+
if (p.isCancel(selection)) {
|
|
400
|
+
p.cancel("Operation cancelled");
|
|
401
|
+
process.exit(0);
|
|
402
|
+
}
|
|
403
|
+
selectedRules = selection;
|
|
404
|
+
}
|
|
405
|
+
const conflictingRules = getConflictingFiles(rulesDir, selectedRules);
|
|
406
|
+
let ruleStrategy = "overwrite";
|
|
407
|
+
if (conflictingRules.length > 0 && !args.force) {
|
|
408
|
+
const strategy = await handleConflicts("rules", conflictingRules);
|
|
409
|
+
if (p.isCancel(strategy) || strategy === "cancel") {
|
|
410
|
+
p.cancel("Operation cancelled");
|
|
411
|
+
process.exit(0);
|
|
412
|
+
}
|
|
413
|
+
ruleStrategy = strategy;
|
|
414
|
+
}
|
|
415
|
+
s.start("Installing rules...");
|
|
416
|
+
results.rules = await installTemplates(
|
|
417
|
+
"rules",
|
|
418
|
+
rulesDir,
|
|
419
|
+
selectedRules,
|
|
420
|
+
ruleStrategy
|
|
421
|
+
);
|
|
422
|
+
s.stop("Rules installed");
|
|
187
423
|
}
|
|
188
424
|
printDivider();
|
|
189
425
|
console.log();
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
426
|
+
if (results.commands) {
|
|
427
|
+
const { added, skipped } = results.commands;
|
|
428
|
+
if (added.length > 0 || skipped.length > 0) {
|
|
429
|
+
printSuccess(
|
|
430
|
+
`Commands: ${highlight(added.length.toString())} added${skipped.length > 0 ? `, ${import_picocolors2.default.yellow(skipped.length.toString())} skipped` : ""}`
|
|
431
|
+
);
|
|
432
|
+
for (const f of added) {
|
|
433
|
+
console.log(import_picocolors2.default.dim(` \u2514\u2500 ${import_picocolors2.default.green("+")} ${f}`));
|
|
434
|
+
}
|
|
435
|
+
for (const f of skipped) {
|
|
436
|
+
console.log(import_picocolors2.default.dim(` \u2514\u2500 ${import_picocolors2.default.yellow("\u25CB")} ${f} (kept existing)`));
|
|
437
|
+
}
|
|
438
|
+
}
|
|
199
439
|
}
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
440
|
+
if (results.rules) {
|
|
441
|
+
const { added, skipped } = results.rules;
|
|
442
|
+
if (added.length > 0 || skipped.length > 0) {
|
|
443
|
+
printSuccess(
|
|
444
|
+
`Rules: ${highlight(added.length.toString())} added${skipped.length > 0 ? `, ${import_picocolors2.default.yellow(skipped.length.toString())} skipped` : ""}`
|
|
445
|
+
);
|
|
446
|
+
for (const f of added) {
|
|
447
|
+
console.log(import_picocolors2.default.dim(` \u2514\u2500 ${import_picocolors2.default.green("+")} ${f}`));
|
|
448
|
+
}
|
|
449
|
+
for (const f of skipped) {
|
|
450
|
+
console.log(import_picocolors2.default.dim(` \u2514\u2500 ${import_picocolors2.default.yellow("\u25CB")} ${f} (kept existing)`));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
const totalAdded = (results.commands?.added.length ?? 0) + (results.rules?.added.length ?? 0);
|
|
455
|
+
const totalSkipped = (results.commands?.skipped.length ?? 0) + (results.rules?.skipped.length ?? 0);
|
|
456
|
+
if (totalAdded === 0 && totalSkipped > 0) {
|
|
457
|
+
console.log();
|
|
458
|
+
p.outro(import_picocolors2.default.yellow("No new templates added (all selected files already exist)"));
|
|
459
|
+
} else {
|
|
460
|
+
console.log();
|
|
461
|
+
p.outro(import_picocolors2.default.green("\u2728 Cursor Kit initialized successfully!"));
|
|
207
462
|
}
|
|
208
|
-
console.log();
|
|
209
|
-
p.outro(import_picocolors2.default.green("\u2728 Cursor Kit initialized successfully!"));
|
|
210
463
|
} catch (error) {
|
|
211
464
|
s.stop("Failed");
|
|
212
465
|
p.cancel(
|
|
@@ -221,7 +474,7 @@ var initCommand = (0, import_citty.defineCommand)({
|
|
|
221
474
|
var import_citty2 = require("citty");
|
|
222
475
|
var p2 = __toESM(require("@clack/prompts"), 1);
|
|
223
476
|
var import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
224
|
-
var
|
|
477
|
+
var import_node_path4 = require("path");
|
|
225
478
|
var COMMAND_TEMPLATE = `You are a helpful assistant. Describe what this command does.
|
|
226
479
|
|
|
227
480
|
## Instructions
|
|
@@ -318,7 +571,7 @@ var addCommand = (0, import_citty2.defineCommand)({
|
|
|
318
571
|
const isCommand = itemType === "command";
|
|
319
572
|
const targetDir = isCommand ? getCommandsDir() : getRulesDir();
|
|
320
573
|
const extension = isCommand ? ".md" : ".mdc";
|
|
321
|
-
const filePath = (0,
|
|
574
|
+
const filePath = (0, import_node_path4.join)(targetDir, `${slug}${extension}`);
|
|
322
575
|
if (fileExists(filePath)) {
|
|
323
576
|
const shouldOverwrite = await p2.confirm({
|
|
324
577
|
message: `${highlight(slug + extension)} already exists. Overwrite?`,
|
|
@@ -354,7 +607,7 @@ var addCommand = (0, import_citty2.defineCommand)({
|
|
|
354
607
|
var import_citty3 = require("citty");
|
|
355
608
|
var p3 = __toESM(require("@clack/prompts"), 1);
|
|
356
609
|
var import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
357
|
-
var
|
|
610
|
+
var import_giget = require("giget");
|
|
358
611
|
var pullCommand = (0, import_citty3.defineCommand)({
|
|
359
612
|
meta: {
|
|
360
613
|
name: "pull",
|
|
@@ -413,7 +666,7 @@ var pullCommand = (0, import_citty3.defineCommand)({
|
|
|
413
666
|
ensureDir(getCursorDir());
|
|
414
667
|
if (shouldPullCommands) {
|
|
415
668
|
s.start("Pulling commands...");
|
|
416
|
-
await (0,
|
|
669
|
+
await (0, import_giget.downloadTemplate)(`${REPO_URL}/templates/commands#${REPO_REF}`, {
|
|
417
670
|
dir: commandsDir,
|
|
418
671
|
force: true
|
|
419
672
|
});
|
|
@@ -421,7 +674,7 @@ var pullCommand = (0, import_citty3.defineCommand)({
|
|
|
421
674
|
}
|
|
422
675
|
if (shouldPullRules) {
|
|
423
676
|
s.start("Pulling rules...");
|
|
424
|
-
await (0,
|
|
677
|
+
await (0, import_giget.downloadTemplate)(`${REPO_URL}/templates/rules#${REPO_REF}`, {
|
|
425
678
|
dir: rulesDir,
|
|
426
679
|
force: true
|
|
427
680
|
});
|
|
@@ -457,7 +710,7 @@ var pullCommand = (0, import_citty3.defineCommand)({
|
|
|
457
710
|
var import_citty4 = require("citty");
|
|
458
711
|
var p4 = __toESM(require("@clack/prompts"), 1);
|
|
459
712
|
var import_picocolors5 = __toESM(require("picocolors"), 1);
|
|
460
|
-
var
|
|
713
|
+
var import_node_path5 = require("path");
|
|
461
714
|
function extractDescription(content, isCommand) {
|
|
462
715
|
if (isCommand) {
|
|
463
716
|
const firstLine = content.trim().split("\n")[0];
|
|
@@ -475,7 +728,7 @@ function extractDescription(content, isCommand) {
|
|
|
475
728
|
function getItems(dir, extension, isCommand) {
|
|
476
729
|
const files = listFiles(dir, extension);
|
|
477
730
|
return files.map((file) => {
|
|
478
|
-
const filePath = (0,
|
|
731
|
+
const filePath = (0, import_node_path5.join)(dir, file);
|
|
479
732
|
const content = fileExists(filePath) ? readFile(filePath) : "";
|
|
480
733
|
return {
|
|
481
734
|
name: file.replace(extension, ""),
|
|
@@ -566,7 +819,7 @@ var listCommand = (0, import_citty4.defineCommand)({
|
|
|
566
819
|
var import_citty5 = require("citty");
|
|
567
820
|
var p5 = __toESM(require("@clack/prompts"), 1);
|
|
568
821
|
var import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
569
|
-
var
|
|
822
|
+
var import_node_path6 = require("path");
|
|
570
823
|
var removeCommand = (0, import_citty5.defineCommand)({
|
|
571
824
|
meta: {
|
|
572
825
|
name: "remove",
|
|
@@ -658,7 +911,7 @@ var removeCommand = (0, import_citty5.defineCommand)({
|
|
|
658
911
|
}
|
|
659
912
|
itemName = nameResult;
|
|
660
913
|
}
|
|
661
|
-
const filePath = (0,
|
|
914
|
+
const filePath = (0, import_node_path6.join)(dir, `${itemName}${extension}`);
|
|
662
915
|
if (!fileExists(filePath)) {
|
|
663
916
|
p5.cancel(`${itemType} '${itemName}' not found`);
|
|
664
917
|
process.exit(1);
|
|
@@ -687,15 +940,17 @@ var removeCommand = (0, import_citty5.defineCommand)({
|
|
|
687
940
|
});
|
|
688
941
|
|
|
689
942
|
// src/cli.ts
|
|
943
|
+
var require2 = (0, import_node_module.createRequire)(importMetaUrl);
|
|
944
|
+
var pkg = require2("../package.json");
|
|
690
945
|
var main = (0, import_citty6.defineCommand)({
|
|
691
946
|
meta: {
|
|
692
947
|
name: "cursor-kit",
|
|
693
|
-
version:
|
|
948
|
+
version: pkg.version,
|
|
694
949
|
description: "CLI toolkit to manage Cursor IDE rules and commands"
|
|
695
950
|
},
|
|
696
951
|
setup() {
|
|
697
952
|
printBanner();
|
|
698
|
-
printVersion(
|
|
953
|
+
printVersion(pkg.version);
|
|
699
954
|
},
|
|
700
955
|
subCommands: {
|
|
701
956
|
init: initCommand,
|