cursor-kit-cli 1.0.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/dist/cli.cjs ADDED
@@ -0,0 +1,709 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli.ts
27
+ var import_citty6 = require("citty");
28
+
29
+ // src/utils/branding.ts
30
+ var import_figlet = __toESM(require("figlet"), 1);
31
+ var import_gradient_string = __toESM(require("gradient-string"), 1);
32
+ var import_picocolors = __toESM(require("picocolors"), 1);
33
+ var cursorGradient = (0, import_gradient_string.default)(["#00DC82", "#36E4DA", "#0047E1"]);
34
+ function printBanner() {
35
+ const banner = import_figlet.default.textSync("Cursor Kit", {
36
+ font: "ANSI Shadow",
37
+ horizontalLayout: "fitted"
38
+ });
39
+ console.log(cursorGradient.multiline(banner));
40
+ console.log();
41
+ console.log(
42
+ import_picocolors.default.dim(" ") + import_picocolors.default.bold(import_picocolors.default.cyan("\u2726")) + import_picocolors.default.dim(" Supercharge your Cursor IDE with rules & commands")
43
+ );
44
+ console.log();
45
+ }
46
+ function printSuccess(message) {
47
+ console.log(import_picocolors.default.green("\u2713") + import_picocolors.default.dim(" ") + message);
48
+ }
49
+ function printInfo(message) {
50
+ console.log(import_picocolors.default.cyan("\u2139") + import_picocolors.default.dim(" ") + message);
51
+ }
52
+ function printDivider() {
53
+ console.log(import_picocolors.default.dim("\u2500".repeat(50)));
54
+ }
55
+ function printVersion(version) {
56
+ console.log(
57
+ import_picocolors.default.dim(" v") + cursorGradient(version) + import_picocolors.default.dim(" \u2022 Made with \u2665")
58
+ );
59
+ console.log();
60
+ }
61
+ function highlight(text2) {
62
+ return import_picocolors.default.cyan(text2);
63
+ }
64
+
65
+ // src/commands/init.ts
66
+ var import_citty = require("citty");
67
+ var p = __toESM(require("@clack/prompts"), 1);
68
+ var import_picocolors2 = __toESM(require("picocolors"), 1);
69
+ var import_giget = require("giget");
70
+
71
+ // src/utils/fs.ts
72
+ var import_node_fs = require("fs");
73
+ var import_node_path = require("path");
74
+ function ensureDir(path) {
75
+ if (!(0, import_node_fs.existsSync)(path)) {
76
+ (0, import_node_fs.mkdirSync)(path, { recursive: true });
77
+ }
78
+ }
79
+ function fileExists(path) {
80
+ return (0, import_node_fs.existsSync)(path);
81
+ }
82
+ function dirExists(path) {
83
+ return (0, import_node_fs.existsSync)(path) && (0, import_node_fs.statSync)(path).isDirectory();
84
+ }
85
+ function readFile(path) {
86
+ return (0, import_node_fs.readFileSync)(path, "utf-8");
87
+ }
88
+ function writeFile(path, content) {
89
+ ensureDir((0, import_node_path.dirname)(path));
90
+ (0, import_node_fs.writeFileSync)(path, content, "utf-8");
91
+ }
92
+ function removeFile(path) {
93
+ if ((0, import_node_fs.existsSync)(path)) {
94
+ (0, import_node_fs.rmSync)(path, { recursive: true });
95
+ }
96
+ }
97
+ function listFiles(dir, extension) {
98
+ if (!dirExists(dir)) return [];
99
+ const files = (0, import_node_fs.readdirSync)(dir);
100
+ if (extension) {
101
+ return files.filter((f) => f.endsWith(extension));
102
+ }
103
+ return files;
104
+ }
105
+ function getCursorDir(cwd = process.cwd()) {
106
+ return (0, import_node_path.join)(cwd, ".cursor");
107
+ }
108
+ function getCommandsDir(cwd = process.cwd()) {
109
+ return (0, import_node_path.join)(getCursorDir(cwd), "commands");
110
+ }
111
+ function getRulesDir(cwd = process.cwd()) {
112
+ return (0, import_node_path.join)(getCursorDir(cwd), "rules");
113
+ }
114
+
115
+ // src/utils/constants.ts
116
+ var REPO_URL = "github:duongductrong/cursor-kit";
117
+ var REPO_REF = "master";
118
+
119
+ // src/commands/init.ts
120
+ var initCommand = (0, import_citty.defineCommand)({
121
+ meta: {
122
+ name: "init",
123
+ description: "Initialize .cursor/commands and .cursor/rules in your project"
124
+ },
125
+ args: {
126
+ force: {
127
+ type: "boolean",
128
+ alias: "f",
129
+ description: "Overwrite existing files",
130
+ default: false
131
+ },
132
+ commands: {
133
+ type: "boolean",
134
+ alias: "c",
135
+ description: "Only initialize commands",
136
+ default: false
137
+ },
138
+ rules: {
139
+ type: "boolean",
140
+ alias: "r",
141
+ description: "Only initialize rules",
142
+ default: false
143
+ }
144
+ },
145
+ async run({ args }) {
146
+ const cwd = process.cwd();
147
+ const cursorDir = getCursorDir(cwd);
148
+ const commandsDir = getCommandsDir(cwd);
149
+ const rulesDir = getRulesDir(cwd);
150
+ const initBoth = !args.commands && !args.rules;
151
+ const shouldInitCommands = initBoth || args.commands;
152
+ const shouldInitRules = initBoth || args.rules;
153
+ 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
+ const s = p.spinner();
170
+ try {
171
+ ensureDir(cursorDir);
172
+ if (shouldInitCommands) {
173
+ s.start("Fetching commands templates...");
174
+ await (0, import_giget.downloadTemplate)(`${REPO_URL}/templates/commands#${REPO_REF}`, {
175
+ dir: commandsDir,
176
+ force: true
177
+ });
178
+ s.stop("Commands initialized");
179
+ }
180
+ if (shouldInitRules) {
181
+ s.start("Fetching rules templates...");
182
+ await (0, import_giget.downloadTemplate)(`${REPO_URL}/templates/rules#${REPO_REF}`, {
183
+ dir: rulesDir,
184
+ force: true
185
+ });
186
+ s.stop("Rules initialized");
187
+ }
188
+ printDivider();
189
+ console.log();
190
+ const commandFiles = listFiles(commandsDir, ".md");
191
+ const ruleFiles = listFiles(rulesDir, ".mdc");
192
+ if (shouldInitCommands && commandFiles.length > 0) {
193
+ printSuccess(
194
+ `Commands: ${highlight(commandFiles.length.toString())} templates`
195
+ );
196
+ commandFiles.forEach((f) => {
197
+ console.log(import_picocolors2.default.dim(` \u2514\u2500 ${f}`));
198
+ });
199
+ }
200
+ if (shouldInitRules && ruleFiles.length > 0) {
201
+ printSuccess(
202
+ `Rules: ${highlight(ruleFiles.length.toString())} templates`
203
+ );
204
+ ruleFiles.forEach((f) => {
205
+ console.log(import_picocolors2.default.dim(` \u2514\u2500 ${f}`));
206
+ });
207
+ }
208
+ console.log();
209
+ p.outro(import_picocolors2.default.green("\u2728 Cursor Kit initialized successfully!"));
210
+ } catch (error) {
211
+ s.stop("Failed");
212
+ p.cancel(
213
+ `Error: ${error instanceof Error ? error.message : "Unknown error"}`
214
+ );
215
+ process.exit(1);
216
+ }
217
+ }
218
+ });
219
+
220
+ // src/commands/add.ts
221
+ var import_citty2 = require("citty");
222
+ var p2 = __toESM(require("@clack/prompts"), 1);
223
+ var import_picocolors3 = __toESM(require("picocolors"), 1);
224
+ var import_node_path2 = require("path");
225
+ var COMMAND_TEMPLATE = `You are a helpful assistant. Describe what this command does.
226
+
227
+ ## Instructions
228
+ - Step 1: ...
229
+ - Step 2: ...
230
+
231
+ ## Rules
232
+ - Be concise
233
+ - Focus on the task
234
+
235
+ START: Wait for user input.
236
+ `;
237
+ var RULE_TEMPLATE = `---
238
+ description: Describe when this rule should apply
239
+ globs:
240
+ alwaysApply: false
241
+ ---
242
+
243
+ # Rule Title
244
+
245
+ Describe the rule behavior here.
246
+
247
+ ## Guidelines
248
+ - Guideline 1
249
+ - Guideline 2
250
+ `;
251
+ function generateSlug(name) {
252
+ return name.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
253
+ }
254
+ var addCommand = (0, import_citty2.defineCommand)({
255
+ meta: {
256
+ name: "add",
257
+ description: "Add a new command or rule"
258
+ },
259
+ args: {
260
+ type: {
261
+ type: "string",
262
+ alias: "t",
263
+ description: "Type: 'command' or 'rule'"
264
+ },
265
+ name: {
266
+ type: "string",
267
+ alias: "n",
268
+ description: "Name of the command or rule"
269
+ }
270
+ },
271
+ async run({ args }) {
272
+ p2.intro(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" cursor-kit add ")));
273
+ let itemType;
274
+ let itemName;
275
+ if (args.type && ["command", "rule"].includes(args.type)) {
276
+ itemType = args.type;
277
+ } else {
278
+ const typeResult = await p2.select({
279
+ message: "What do you want to add?",
280
+ options: [
281
+ {
282
+ value: "command",
283
+ label: "Command",
284
+ hint: "A reusable prompt template"
285
+ },
286
+ {
287
+ value: "rule",
288
+ label: "Rule",
289
+ hint: "Project-specific AI behavior rules"
290
+ }
291
+ ]
292
+ });
293
+ if (p2.isCancel(typeResult)) {
294
+ p2.cancel("Operation cancelled");
295
+ process.exit(0);
296
+ }
297
+ itemType = typeResult;
298
+ }
299
+ if (args.name) {
300
+ itemName = args.name;
301
+ } else {
302
+ const nameResult = await p2.text({
303
+ message: `Enter ${itemType} name:`,
304
+ placeholder: itemType === "command" ? "my-command" : "my-rule",
305
+ validate: (value) => {
306
+ if (!value.trim()) return "Name is required";
307
+ if (value.length < 2) return "Name must be at least 2 characters";
308
+ return void 0;
309
+ }
310
+ });
311
+ if (p2.isCancel(nameResult)) {
312
+ p2.cancel("Operation cancelled");
313
+ process.exit(0);
314
+ }
315
+ itemName = nameResult;
316
+ }
317
+ const slug = generateSlug(itemName);
318
+ const isCommand = itemType === "command";
319
+ const targetDir = isCommand ? getCommandsDir() : getRulesDir();
320
+ const extension = isCommand ? ".md" : ".mdc";
321
+ const filePath = (0, import_node_path2.join)(targetDir, `${slug}${extension}`);
322
+ if (fileExists(filePath)) {
323
+ const shouldOverwrite = await p2.confirm({
324
+ message: `${highlight(slug + extension)} already exists. Overwrite?`,
325
+ initialValue: false
326
+ });
327
+ if (p2.isCancel(shouldOverwrite) || !shouldOverwrite) {
328
+ p2.cancel("Operation cancelled");
329
+ process.exit(0);
330
+ }
331
+ }
332
+ const s = p2.spinner();
333
+ s.start(`Creating ${itemType}...`);
334
+ try {
335
+ ensureDir(targetDir);
336
+ const template = isCommand ? COMMAND_TEMPLATE : RULE_TEMPLATE;
337
+ writeFile(filePath, template);
338
+ s.stop(`${itemType.charAt(0).toUpperCase() + itemType.slice(1)} created`);
339
+ console.log();
340
+ console.log(import_picocolors3.default.dim(" File: ") + highlight(filePath));
341
+ console.log();
342
+ p2.outro(
343
+ import_picocolors3.default.green(`\u2728 ${itemType.charAt(0).toUpperCase() + itemType.slice(1)} created! Edit the file to customize it.`)
344
+ );
345
+ } catch (error) {
346
+ s.stop("Failed");
347
+ p2.cancel(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
348
+ process.exit(1);
349
+ }
350
+ }
351
+ });
352
+
353
+ // src/commands/pull.ts
354
+ var import_citty3 = require("citty");
355
+ var p3 = __toESM(require("@clack/prompts"), 1);
356
+ var import_picocolors4 = __toESM(require("picocolors"), 1);
357
+ var import_giget2 = require("giget");
358
+ var pullCommand = (0, import_citty3.defineCommand)({
359
+ meta: {
360
+ name: "pull",
361
+ description: "Pull latest updates from cursor-kit repository"
362
+ },
363
+ args: {
364
+ commands: {
365
+ type: "boolean",
366
+ alias: "c",
367
+ description: "Only pull commands",
368
+ default: false
369
+ },
370
+ rules: {
371
+ type: "boolean",
372
+ alias: "r",
373
+ description: "Only pull rules",
374
+ default: false
375
+ },
376
+ force: {
377
+ type: "boolean",
378
+ alias: "f",
379
+ description: "Force overwrite without confirmation",
380
+ default: false
381
+ }
382
+ },
383
+ async run({ args }) {
384
+ const pullBoth = !args.commands && !args.rules;
385
+ const shouldPullCommands = pullBoth || args.commands;
386
+ const shouldPullRules = pullBoth || args.rules;
387
+ p3.intro(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" cursor-kit pull ")));
388
+ const commandsDir = getCommandsDir();
389
+ const rulesDir = getRulesDir();
390
+ const existingCommands = listFiles(commandsDir, ".md");
391
+ const existingRules = listFiles(rulesDir, ".mdc");
392
+ const hasExisting = existingCommands.length > 0 || existingRules.length > 0;
393
+ if (hasExisting && !args.force) {
394
+ printInfo("Current status:");
395
+ if (existingCommands.length > 0) {
396
+ console.log(import_picocolors4.default.dim(` Commands: ${existingCommands.length} files`));
397
+ }
398
+ if (existingRules.length > 0) {
399
+ console.log(import_picocolors4.default.dim(` Rules: ${existingRules.length} files`));
400
+ }
401
+ console.log();
402
+ const shouldContinue = await p3.confirm({
403
+ message: "This will merge with existing files. Continue?",
404
+ initialValue: true
405
+ });
406
+ if (p3.isCancel(shouldContinue) || !shouldContinue) {
407
+ p3.cancel("Operation cancelled");
408
+ process.exit(0);
409
+ }
410
+ }
411
+ const s = p3.spinner();
412
+ try {
413
+ ensureDir(getCursorDir());
414
+ if (shouldPullCommands) {
415
+ s.start("Pulling commands...");
416
+ await (0, import_giget2.downloadTemplate)(`${REPO_URL}/templates/commands#${REPO_REF}`, {
417
+ dir: commandsDir,
418
+ force: true
419
+ });
420
+ s.stop("Commands updated");
421
+ }
422
+ if (shouldPullRules) {
423
+ s.start("Pulling rules...");
424
+ await (0, import_giget2.downloadTemplate)(`${REPO_URL}/templates/rules#${REPO_REF}`, {
425
+ dir: rulesDir,
426
+ force: true
427
+ });
428
+ s.stop("Rules updated");
429
+ }
430
+ printDivider();
431
+ console.log();
432
+ const newCommands = listFiles(commandsDir, ".md");
433
+ const newRules = listFiles(rulesDir, ".mdc");
434
+ if (shouldPullCommands) {
435
+ const added = newCommands.length - existingCommands.length;
436
+ printSuccess(
437
+ `Commands: ${highlight(newCommands.length.toString())} total` + (added > 0 ? import_picocolors4.default.green(` (+${added} new)`) : "")
438
+ );
439
+ }
440
+ if (shouldPullRules) {
441
+ const added = newRules.length - existingRules.length;
442
+ printSuccess(
443
+ `Rules: ${highlight(newRules.length.toString())} total` + (added > 0 ? import_picocolors4.default.green(` (+${added} new)`) : "")
444
+ );
445
+ }
446
+ console.log();
447
+ p3.outro(import_picocolors4.default.green("\u2728 Successfully pulled latest updates!"));
448
+ } catch (error) {
449
+ s.stop("Failed");
450
+ p3.cancel(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
451
+ process.exit(1);
452
+ }
453
+ }
454
+ });
455
+
456
+ // src/commands/list.ts
457
+ var import_citty4 = require("citty");
458
+ var p4 = __toESM(require("@clack/prompts"), 1);
459
+ var import_picocolors5 = __toESM(require("picocolors"), 1);
460
+ var import_node_path3 = require("path");
461
+ function extractDescription(content, isCommand) {
462
+ if (isCommand) {
463
+ const firstLine = content.trim().split("\n")[0];
464
+ if (firstLine && !firstLine.startsWith("#") && !firstLine.startsWith("---")) {
465
+ return firstLine.slice(0, 60) + (firstLine.length > 60 ? "..." : "");
466
+ }
467
+ } else {
468
+ const match = content.match(/description:\s*(.+)/);
469
+ if (match) {
470
+ return match[1].trim().slice(0, 60) + (match[1].length > 60 ? "..." : "");
471
+ }
472
+ }
473
+ return void 0;
474
+ }
475
+ function getItems(dir, extension, isCommand) {
476
+ const files = listFiles(dir, extension);
477
+ return files.map((file) => {
478
+ const filePath = (0, import_node_path3.join)(dir, file);
479
+ const content = fileExists(filePath) ? readFile(filePath) : "";
480
+ return {
481
+ name: file.replace(extension, ""),
482
+ path: filePath,
483
+ description: extractDescription(content, isCommand)
484
+ };
485
+ });
486
+ }
487
+ var listCommand = (0, import_citty4.defineCommand)({
488
+ meta: {
489
+ name: "list",
490
+ description: "List all commands and rules"
491
+ },
492
+ args: {
493
+ commands: {
494
+ type: "boolean",
495
+ alias: "c",
496
+ description: "Only list commands",
497
+ default: false
498
+ },
499
+ rules: {
500
+ type: "boolean",
501
+ alias: "r",
502
+ description: "Only list rules",
503
+ default: false
504
+ },
505
+ verbose: {
506
+ type: "boolean",
507
+ alias: "v",
508
+ description: "Show full file paths",
509
+ default: false
510
+ }
511
+ },
512
+ async run({ args }) {
513
+ const listBoth = !args.commands && !args.rules;
514
+ const shouldListCommands = listBoth || args.commands;
515
+ const shouldListRules = listBoth || args.rules;
516
+ p4.intro(import_picocolors5.default.bgCyan(import_picocolors5.default.black(" cursor-kit list ")));
517
+ const commandsDir = getCommandsDir();
518
+ const rulesDir = getRulesDir();
519
+ const commands = shouldListCommands ? getItems(commandsDir, ".md", true) : [];
520
+ const rules = shouldListRules ? getItems(rulesDir, ".mdc", false) : [];
521
+ if (commands.length === 0 && rules.length === 0) {
522
+ console.log();
523
+ console.log(import_picocolors5.default.yellow(" No commands or rules found."));
524
+ console.log(import_picocolors5.default.dim(" Run ") + highlight("cursor-kit init") + import_picocolors5.default.dim(" to get started."));
525
+ console.log();
526
+ p4.outro(import_picocolors5.default.dim("Nothing to show"));
527
+ return;
528
+ }
529
+ printDivider();
530
+ if (shouldListCommands && commands.length > 0) {
531
+ console.log();
532
+ console.log(import_picocolors5.default.bold(import_picocolors5.default.cyan(" \u{1F4DC} Commands")) + import_picocolors5.default.dim(` (${commands.length})`));
533
+ console.log();
534
+ commands.forEach((cmd) => {
535
+ console.log(` ${import_picocolors5.default.green("\u25CF")} ${highlight(cmd.name)}`);
536
+ if (cmd.description) {
537
+ console.log(import_picocolors5.default.dim(` ${cmd.description}`));
538
+ }
539
+ if (args.verbose) {
540
+ console.log(import_picocolors5.default.dim(` ${cmd.path}`));
541
+ }
542
+ });
543
+ }
544
+ if (shouldListRules && rules.length > 0) {
545
+ console.log();
546
+ console.log(import_picocolors5.default.bold(import_picocolors5.default.cyan(" \u{1F4CB} Rules")) + import_picocolors5.default.dim(` (${rules.length})`));
547
+ console.log();
548
+ rules.forEach((rule) => {
549
+ console.log(` ${import_picocolors5.default.green("\u25CF")} ${highlight(rule.name)}`);
550
+ if (rule.description) {
551
+ console.log(import_picocolors5.default.dim(` ${rule.description}`));
552
+ }
553
+ if (args.verbose) {
554
+ console.log(import_picocolors5.default.dim(` ${rule.path}`));
555
+ }
556
+ });
557
+ }
558
+ console.log();
559
+ printDivider();
560
+ const total = commands.length + rules.length;
561
+ p4.outro(import_picocolors5.default.dim(`Total: ${total} item${total !== 1 ? "s" : ""}`));
562
+ }
563
+ });
564
+
565
+ // src/commands/remove.ts
566
+ var import_citty5 = require("citty");
567
+ var p5 = __toESM(require("@clack/prompts"), 1);
568
+ var import_picocolors6 = __toESM(require("picocolors"), 1);
569
+ var import_node_path4 = require("path");
570
+ var removeCommand = (0, import_citty5.defineCommand)({
571
+ meta: {
572
+ name: "remove",
573
+ description: "Remove a command or rule"
574
+ },
575
+ args: {
576
+ type: {
577
+ type: "string",
578
+ alias: "t",
579
+ description: "Type: 'command' or 'rule'"
580
+ },
581
+ name: {
582
+ type: "string",
583
+ alias: "n",
584
+ description: "Name of the command or rule to remove"
585
+ },
586
+ force: {
587
+ type: "boolean",
588
+ alias: "f",
589
+ description: "Skip confirmation",
590
+ default: false
591
+ }
592
+ },
593
+ async run({ args }) {
594
+ p5.intro(import_picocolors6.default.bgCyan(import_picocolors6.default.black(" cursor-kit remove ")));
595
+ const commandsDir = getCommandsDir();
596
+ const rulesDir = getRulesDir();
597
+ const commands = listFiles(commandsDir, ".md").map((f) => f.replace(".md", ""));
598
+ const rules = listFiles(rulesDir, ".mdc").map((f) => f.replace(".mdc", ""));
599
+ if (commands.length === 0 && rules.length === 0) {
600
+ console.log();
601
+ console.log(import_picocolors6.default.yellow(" No commands or rules to remove."));
602
+ console.log();
603
+ p5.outro(import_picocolors6.default.dim("Nothing to do"));
604
+ return;
605
+ }
606
+ let itemType;
607
+ let itemName;
608
+ if (args.type && ["command", "rule"].includes(args.type)) {
609
+ itemType = args.type;
610
+ } else {
611
+ const typeOptions = [];
612
+ if (commands.length > 0) {
613
+ typeOptions.push({
614
+ value: "command",
615
+ label: "Command",
616
+ hint: `${commands.length} available`
617
+ });
618
+ }
619
+ if (rules.length > 0) {
620
+ typeOptions.push({
621
+ value: "rule",
622
+ label: "Rule",
623
+ hint: `${rules.length} available`
624
+ });
625
+ }
626
+ const typeResult = await p5.select({
627
+ message: "What do you want to remove?",
628
+ options: typeOptions
629
+ });
630
+ if (p5.isCancel(typeResult)) {
631
+ p5.cancel("Operation cancelled");
632
+ process.exit(0);
633
+ }
634
+ itemType = typeResult;
635
+ }
636
+ const isCommand = itemType === "command";
637
+ const items = isCommand ? commands : rules;
638
+ const dir = isCommand ? commandsDir : rulesDir;
639
+ const extension = isCommand ? ".md" : ".mdc";
640
+ if (items.length === 0) {
641
+ p5.cancel(`No ${itemType}s found`);
642
+ process.exit(0);
643
+ }
644
+ if (args.name && items.includes(args.name)) {
645
+ itemName = args.name;
646
+ } else {
647
+ const itemOptions = items.map((item) => ({
648
+ value: item,
649
+ label: item
650
+ }));
651
+ const nameResult = await p5.select({
652
+ message: `Select ${itemType} to remove:`,
653
+ options: itemOptions
654
+ });
655
+ if (p5.isCancel(nameResult)) {
656
+ p5.cancel("Operation cancelled");
657
+ process.exit(0);
658
+ }
659
+ itemName = nameResult;
660
+ }
661
+ const filePath = (0, import_node_path4.join)(dir, `${itemName}${extension}`);
662
+ if (!fileExists(filePath)) {
663
+ p5.cancel(`${itemType} '${itemName}' not found`);
664
+ process.exit(1);
665
+ }
666
+ if (!args.force) {
667
+ const shouldDelete = await p5.confirm({
668
+ message: `Are you sure you want to delete ${highlight(itemName + extension)}?`,
669
+ initialValue: false
670
+ });
671
+ if (p5.isCancel(shouldDelete) || !shouldDelete) {
672
+ p5.cancel("Operation cancelled");
673
+ process.exit(0);
674
+ }
675
+ }
676
+ try {
677
+ removeFile(filePath);
678
+ console.log();
679
+ printSuccess(`Removed ${highlight(itemName + extension)}`);
680
+ console.log();
681
+ p5.outro(import_picocolors6.default.green("\u2728 Done!"));
682
+ } catch (error) {
683
+ p5.cancel(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
684
+ process.exit(1);
685
+ }
686
+ }
687
+ });
688
+
689
+ // src/cli.ts
690
+ var main = (0, import_citty6.defineCommand)({
691
+ meta: {
692
+ name: "cursor-kit",
693
+ version: "0.1.0",
694
+ description: "CLI toolkit to manage Cursor IDE rules and commands"
695
+ },
696
+ setup() {
697
+ printBanner();
698
+ printVersion("0.1.0");
699
+ },
700
+ subCommands: {
701
+ init: initCommand,
702
+ add: addCommand,
703
+ pull: pullCommand,
704
+ list: listCommand,
705
+ remove: removeCommand
706
+ }
707
+ });
708
+ (0, import_citty6.runMain)(main);
709
+ //# sourceMappingURL=cli.cjs.map